diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
index 07410e948..1b3704f57 100644
--- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
+++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
@@ -122,7 +122,7 @@ import code.transactionattribute.MappedTransactionAttribute
import code.transactionrequests.{MappedTransactionRequest, MappedTransactionRequestTypeCharge, TransactionRequestReasons}
import code.usercustomerlinks.MappedUserCustomerLink
import code.userlocks.UserLocks
-import code.users.{UserAgreement, UserAttribute, UserInitAction, UserInvitation}
+import code.users.{UserAgreement, UserAttribute, UserInitAction, UserInvitation, Users}
import code.util.Helper.MdcLoggable
import code.util.{Helper, HydraUtil}
import code.validation.JsonSchemaValidation
@@ -130,7 +130,7 @@ import code.views.Views
import code.views.system.{AccountAccess, ViewDefinition}
import code.webhook.{BankAccountNotificationWebhook, MappedAccountWebhook, SystemAccountNotificationWebhook, WebhookHelperActors}
import code.webuiprops.WebUiProps
-import com.openbankproject.commons.model.ErrorMessage
+import com.openbankproject.commons.model.{ErrorMessage, User}
import com.openbankproject.commons.util.Functions.Implicits._
import com.openbankproject.commons.util.{ApiVersion, Functions}
import javax.mail.{Authenticator, PasswordAuthentication}
@@ -611,7 +611,11 @@ class Boot extends MdcLoggable {
// In case it's true we use that value to set up a new cookie value
S.param("locale") match {
case Full(requestedLocale) if requestedLocale != null => {
- val computedLocale = I18NUtil.computeLocale(requestedLocale)
+ val computedLocale: Locale = I18NUtil.computeLocale(requestedLocale)
+ val id: Long = AuthUser.getCurrentUser.map(_.user.userPrimaryKey.value).getOrElse(0)
+ Users.users.vend.getResourceUserByResourceUserId(id).map {
+ u => u.LastUsedLocale(computedLocale.toString).save
+ }
S.addCookie(HTTPCookie(localeCookieName, requestedLocale))
computedLocale
}
diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
index 80fa55a34..3a7178a6d 100644
--- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
+++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
@@ -95,7 +95,7 @@ object SwaggerDefinitionsJSON {
accountRoutings = List(accountRouting)
)
- val createViewJson = CreateViewJson(
+ val createViewJsonV300 = CreateViewJsonV300(
name = "_test",
description = "This view is for family",
metadata_view ="_test",
@@ -186,9 +186,103 @@ object SwaggerDefinitionsJSON {
)
)
- val createSystemViewJson = createViewJson.copy(name = "test", metadata_view = "test", is_public = false)
+ val createSystemViewJsonV300 = createViewJsonV300.copy(name = "test", metadata_view = "test", is_public = false)
- val updateViewJSON = UpdateViewJSON(
+ val createSystemViewJsonV500 = CreateViewJsonV500(
+ name = "_test",
+ description = "This view is for family",
+ metadata_view ="_test",
+ is_public = false,
+ which_alias_to_use = "family",
+ hide_metadata_if_alias_used = false,
+ allowed_actions = List(
+ "can_see_transaction_this_bank_account",
+ "can_see_transaction_other_bank_account",
+ "can_see_transaction_metadata",
+ "can_see_transaction_label",
+ "can_see_transaction_amount",
+ "can_see_transaction_type",
+ "can_see_transaction_currency",
+ "can_see_transaction_start_date",
+ "can_see_transaction_finish_date",
+ "can_see_transaction_balance",
+ "can_see_comments",
+ "can_see_narrative",
+ "can_see_tags",
+ "can_see_images",
+ "can_see_bank_account_owners",
+ "can_see_bank_account_type",
+ "can_see_bank_account_balance",
+ "can_see_bank_account_currency",
+ "can_see_bank_account_label",
+ "can_see_bank_account_national_identifier",
+ "can_see_bank_account_swift_bic",
+ "can_see_bank_account_iban",
+ "can_see_bank_account_number",
+ "can_see_bank_account_bank_name",
+ "can_see_other_account_national_identifier",
+ "can_see_other_account_swift_bic",
+ "can_see_other_account_iban",
+ "can_see_other_account_bank_name",
+ "can_see_other_account_number",
+ "can_see_other_account_metadata",
+ "can_see_other_account_kind",
+ "can_see_more_info",
+ "can_see_url",
+ "can_see_image_url",
+ "can_see_open_corporates_url",
+ "can_see_corporate_location",
+ "can_see_physical_location",
+ "can_see_public_alias",
+ "can_see_private_alias",
+ "can_add_more_info",
+ "can_add_url",
+ "can_add_image_url",
+ "can_add_open_corporates_url",
+ "can_add_corporate_location",
+ "can_add_physical_location",
+ "can_add_public_alias",
+ "can_add_private_alias",
+ "can_delete_corporate_location",
+ "can_delete_physical_location",
+ "can_edit_narrative",
+ "can_add_comment",
+ "can_delete_comment",
+ "can_add_tag",
+ "can_delete_tag",
+ "can_add_image",
+ "can_delete_image",
+ "can_add_where_tag",
+ "can_see_where_tag",
+ "can_delete_where_tag",
+ "can_create_counterparty",
+ //V300 New
+ "can_see_bank_routing_scheme",
+ "can_see_bank_routing_address",
+ "can_see_bank_account_routing_scheme",
+ "can_see_bank_account_routing_address",
+ "can_see_other_bank_routing_scheme",
+ "can_see_other_bank_routing_address",
+ "can_see_other_account_routing_scheme",
+ "can_see_other_account_routing_address",
+ //v310
+ "can_query_available_funds",
+ "can_add_transaction_request_to_own_account",
+ "can_add_transaction_request_to_any_account",
+ "can_see_bank_account_credit_limit",
+ //v400
+ "can_create_direct_debit",
+ "can_create_standing_order",
+
+ //payments
+ "can_add_transaction_request_to_any_account"
+ ),
+ // Version 5.0.0
+ can_grant_access_to_views = Some(List("owner")),
+ can_revoke_access_to_views = Some(List("owner"))
+ )
+
+ val updateViewJsonV300 = UpdateViewJsonV300(
description = "this is for family",
is_public = true,
metadata_view = SYSTEM_OWNER_VIEW_ID,
@@ -267,8 +361,91 @@ object SwaggerDefinitionsJSON {
"can_query_available_funds"
)
)
+ lazy val updateSystemViewJson310 = updateViewJsonV300.copy(is_public = false, is_firehose = Some(false))
- lazy val updateSystemViewJson310 = updateViewJSON.copy(is_public = false, is_firehose = Some(false))
+ val updateViewJsonV500 = UpdateViewJsonV500(
+ description = "this is for family",
+ is_public = true,
+ metadata_view = SYSTEM_OWNER_VIEW_ID,
+ which_alias_to_use = "family",
+ hide_metadata_if_alias_used = true,
+ allowed_actions = List(
+ "can_see_transaction_this_bank_account",
+ "can_see_transaction_other_bank_account",
+ "can_see_transaction_metadata",
+ "can_see_transaction_label",
+ "can_see_transaction_amount",
+ "can_see_transaction_type",
+ "can_see_transaction_currency",
+ "can_see_transaction_start_date",
+ "can_see_transaction_finish_date",
+ "can_see_transaction_balance",
+ "can_see_comments",
+ "can_see_narrative", "can_see_tags",
+ "can_see_images",
+ "can_see_bank_account_owners",
+ "can_see_bank_account_type",
+ "can_see_bank_account_balance",
+ "can_see_bank_account_currency",
+ "can_see_bank_account_label",
+ "can_see_bank_account_national_identifier",
+ "can_see_bank_account_swift_bic",
+ "can_see_bank_account_iban",
+ "can_see_bank_account_number",
+ "can_see_bank_account_bank_name",
+ "can_see_other_account_national_identifier",
+ "can_see_other_account_swift_bic",
+ "can_see_other_account_iban",
+ "can_see_other_account_bank_name",
+ "can_see_other_account_number",
+ "can_see_other_account_metadata",
+ "can_see_other_account_kind",
+ "can_see_more_info",
+ "can_see_url",
+ "can_see_image_url",
+ "can_see_open_corporates_url",
+ "can_see_corporate_location",
+ "can_see_physical_location",
+ "can_see_public_alias",
+ "can_see_private_alias",
+ "can_add_more_info",
+ "can_add_url",
+ "can_add_image_url",
+ "can_add_open_corporates_url",
+ "can_add_corporate_location",
+ "can_add_physical_location",
+ "can_add_public_alias",
+ "can_add_private_alias",
+ "can_delete_corporate_location",
+ "can_delete_physical_location",
+ "can_edit_narrative",
+ "can_add_comment",
+ "can_delete_comment",
+ "can_add_tag",
+ "can_delete_tag",
+ "can_add_image",
+ "can_delete_image",
+ "can_add_where_tag",
+ "can_see_where_tag",
+ "can_delete_where_tag",
+ "can_create_counterparty",
+ //V300 New
+ "can_see_bank_routing_scheme",
+ "can_see_bank_routing_address",
+ "can_see_bank_account_routing_scheme",
+ "can_see_bank_account_routing_address",
+ "can_see_other_bank_routing_scheme",
+ "can_see_other_bank_routing_address",
+ "can_see_other_account_routing_scheme",
+ "can_see_other_account_routing_address",
+ //v310
+ "can_query_available_funds"
+ ),
+ // Version 5.0.0
+ can_grant_access_to_views = Some(List("owner")),
+ can_revoke_access_to_views = Some(List("owner"))
+ )
+ lazy val updateSystemViewJson500 = updateViewJsonV500.copy(is_public = false, is_firehose = Some(false))
val transactionTypeIdSwagger = TransactionTypeId(value = "123")
@@ -834,8 +1011,8 @@ object SwaggerDefinitionsJSON {
)
val bankRoutingJsonV121 = BankRoutingJsonV121(
- scheme = "Bank_ID",
- address = "gh.29.uk"
+ scheme = schemeExample.value,
+ address = addressExample.value
)
val bankJSON = BankJSON(
@@ -859,6 +1036,14 @@ object SwaggerDefinitionsJSON {
list = List(bankAttributeBankResponseJsonV400)
)
+ val postBankJson400 = PostBankJson400(
+ id = "gh.29.uk",
+ short_name = "short_name ",
+ full_name = "full_name",
+ logo = "logo",
+ website = "www.openbankproject.com",
+ bank_routings = List(bankRoutingJsonV121)
+ )
val bankJson400 = BankJson400(
id = "gh.29.uk",
short_name = "short_name ",
@@ -869,23 +1054,22 @@ object SwaggerDefinitionsJSON {
attributes = Some(List(bankAttributeBankResponseJsonV400))
)
val bankJson500 = BankJson500(
- id = "gh.29.uk",
- bank_code = "bank_code ",
- full_name = "full_name",
- logo = "logo",
- website = "www.openbankproject.com",
+ id = bankIdExample.value,
+ bank_code = bankCodeExample.value,
+ full_name = bankFullNameExample.value,
+ logo = bankLogoUrlExample.value,
+ website = bankLogoUrlExample.value,
bank_routings = List(bankRoutingJsonV121),
attributes = Some(List(bankAttributeBankResponseJsonV400))
)
val postBankJson500 = PostBankJson500(
- id = Some("gh.29.uk"),
- bank_code = "bank_code",
- full_name = Some("full_name"),
- logo = Some("logo"),
- website = Some("www.openbankproject.com"),
- bank_routings = Some(List(bankRoutingJsonV121)),
- attributes = Some(List(bankAttributeBankResponseJsonV400))
+ id = Some(idExample.value),
+ bank_code = bankCodeExample.value,
+ full_name = Some(fullNameExample.value),
+ logo = Some(logoExample.value),
+ website = Some(websiteExample.value),
+ bank_routings = Some(List(bankRoutingJsonV121))
)
val banksJSON400 = BanksJson400(
@@ -1281,7 +1465,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
highest_education_attained = ExampleValue.highestEducationAttainedExample.value,
employment_status = ExampleValue.employmentStatusExample.value,
@@ -1298,7 +1482,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
highest_education_attained = ExampleValue.highestEducationAttainedExample.value,
employment_status = ExampleValue.employmentStatusExample.value,
@@ -2002,7 +2186,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
highest_education_attained = ExampleValue.highestEducationAttainedExample.value,
employment_status = ExampleValue.employmentStatusExample.value,
@@ -2136,7 +2320,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2172,7 +2356,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = customerCreditRatingJSON,
credit_limit = amountOfMoneyJsonV121,
@@ -2192,7 +2376,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = "19900101",
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List("19900101"),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2221,7 +2405,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = customerCreditRatingJSON,
credit_limit = amountOfMoneyJsonV121,
@@ -2236,12 +2420,13 @@ object SwaggerDefinitionsJSON {
val postCustomerJsonV500 =
PostCustomerJsonV500(
legal_name = ExampleValue.legalNameExample.value,
- mobile_phone_number = ExampleValue.mobileNumberExample.value,
+ customer_number = Some(ExampleValue.customerNumberExample.value),
+ mobile_phone_number = ExampleValue.mobilePhoneNumberExample.value,
email = Some(ExampleValue.emailExample.value),
face_image = Some(customerFaceImageJson),
date_of_birth = Some(DateWithDayExampleObject),
relationship_status = Some(ExampleValue.relationshipStatusExample.value),
- dependants = Some(ExampleValue.dependentsExample.value.toInt),
+ dependants = Some(ExampleValue.dependantsExample.value.toInt),
dob_of_dependants = Some(List(DateWithDayExampleObject)),
credit_rating = Some(customerCreditRatingJSON),
credit_limit = Some(amountOfMoneyJsonV121),
@@ -2264,7 +2449,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2341,7 +2526,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2366,7 +2551,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = DateWithDayExampleObject,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List(DateWithDayExampleObject),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2390,7 +2575,7 @@ object SwaggerDefinitionsJSON {
face_image = customerFaceImageJson,
date_of_birth = "19900101",
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
dob_of_dependants = List("19900101"),
credit_rating = Option(customerCreditRatingJSON),
credit_limit = Option(amountOfMoneyJsonV121),
@@ -2409,7 +2594,7 @@ object SwaggerDefinitionsJSON {
val putUpdateCustomerDataJsonV310 = PutUpdateCustomerDataJsonV310(
face_image = customerFaceImageJson,
relationship_status = ExampleValue.relationshipStatusExample.value,
- dependants = ExampleValue.dependentsExample.value.toInt,
+ dependants = ExampleValue.dependantsExample.value.toInt,
highest_education_attained = ExampleValue.highestEducationAttainedExample.value,
employment_status = ExampleValue.employmentStatusExample.value
)
@@ -2735,6 +2920,104 @@ object SwaggerDefinitionsJSON {
views = List(viewJSONV220)
)
+
+ val viewJsonV500 = ViewJsonV500(
+ id = "1234",
+ short_name = "short_name",
+ description = "description",
+ metadata_view = SYSTEM_OWNER_VIEW_ID,
+ is_public = true,
+ is_system = true,
+ alias = "No",
+ hide_metadata_if_alias_used = true,
+ can_add_comment = true,
+ can_add_corporate_location = true,
+ can_add_image = true,
+ can_add_image_url = true,
+ can_add_more_info = true,
+ can_add_open_corporates_url = true,
+ can_add_physical_location = true,
+ can_add_private_alias = true,
+ can_add_public_alias = true,
+ can_add_tag = true,
+ can_add_url = true,
+ can_add_where_tag = true,
+ can_delete_comment = true,
+ can_add_counterparty = true,
+ can_delete_corporate_location = true,
+ can_delete_image = true,
+ can_delete_physical_location = true,
+ can_delete_tag = true,
+ can_delete_where_tag = true,
+ can_edit_owner_comment = true,
+ can_see_bank_account_balance = true,
+ can_query_available_funds = true,
+ can_see_bank_account_bank_name = true,
+ can_see_bank_account_currency = true,
+ can_see_bank_account_iban = true,
+ can_see_bank_account_label = true,
+ can_see_bank_account_national_identifier = true,
+ can_see_bank_account_number = true,
+ can_see_bank_account_owners = true,
+ can_see_bank_account_swift_bic = true,
+ can_see_bank_account_type = true,
+ can_see_comments = true,
+ can_see_corporate_location = true,
+ can_see_image_url = true,
+ can_see_images = true,
+ can_see_more_info = true,
+ can_see_open_corporates_url = true,
+ can_see_other_account_bank_name = true,
+ can_see_other_account_iban = true,
+ can_see_other_account_kind = true,
+ can_see_other_account_metadata = true,
+ can_see_other_account_national_identifier = true,
+ can_see_other_account_number = true,
+ can_see_other_account_swift_bic = true,
+ can_see_owner_comment = true,
+ can_see_physical_location = true,
+ can_see_private_alias = true,
+ can_see_public_alias = true,
+ can_see_tags = true,
+ can_see_transaction_amount = true,
+ can_see_transaction_balance = true,
+ can_see_transaction_currency = true,
+ can_see_transaction_description = true,
+ can_see_transaction_finish_date = true,
+ can_see_transaction_metadata = true,
+ can_see_transaction_other_bank_account = true,
+ can_see_transaction_start_date = true,
+ can_see_transaction_this_bank_account = true,
+ can_see_transaction_type = true,
+ can_see_url = true,
+ can_see_where_tag = true,
+ //V300 new
+ can_see_bank_routing_scheme = true,
+ can_see_bank_routing_address = true,
+ can_see_bank_account_routing_scheme = true,
+ can_see_bank_account_routing_address = true,
+ can_see_other_bank_routing_scheme = true,
+ can_see_other_bank_routing_address = true,
+ can_see_other_account_routing_scheme = true,
+ can_see_other_account_routing_address = true,
+ can_add_transaction_request_to_own_account = true, //added following two for payments
+ can_add_transaction_request_to_any_account = true,
+ can_see_bank_account_credit_limit = true,
+ can_create_direct_debit = true,
+ can_create_standing_order = true,
+ can_grant_access_to_views = List("Owner"),
+ can_revoke_access_to_views = List("Owner")
+ )
+
+ val viewsJsonV500 = ViewsJsonV500(
+ views = List(viewJsonV500)
+ )
+
+ val viewIdJsonV500 = ViewIdJsonV500(id = "owner")
+ val viewIdsJsonV500 = ViewsIdsJsonV500(
+ views = List(viewIdJsonV500)
+ )
+
val fXRateJSON = FXRateJsonV220(
bank_id = bankIdExample.value,
from_currency_code = "EUR",
@@ -3334,12 +3617,12 @@ object SwaggerDefinitionsJSON {
bank_id = bankIdExample.value,
label = labelExample.value,
number = numberExample.value,
- owners = "user_id:b27327a2-a822-41e5-a909-0150da688939,provider:https://finx22openplatform.fintech-galaxy.com,user_name:synth_user_1_54891",
+ owners = List(FastFirehoseOwners(user_id="b27327a2-a822-41e5-a909-0150da688939",provider="https://finx22openplatform.fintech-galaxy.com,user_name:synth_user_1_54891", user_name="")),
product_code = productCodeExample.value,
balance = amountOfMoneyJsonV121,
- account_routings = "bank_id:bisb.com,account_id:c590e38e-847c-466f-9a62-f2ad67daf106",
- account_attributes= "type:INTEGER,code:Loan1,value:0," +
- "type:STRING,code:Loan1,value:4421.783"
+ account_routings = List(FastFirehoseRoutings(bank_id="bisb.com",account_id="c590e38e-847c-466f-9a62-f2ad67daf106")),
+ account_attributes= List(FastFirehoseAttributes(`type`="INTEGER",code="Loan1",value="0"),
+ FastFirehoseAttributes(`type`="STRING",code="Loan1",value="4421.783"))
)
diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala
index db9ac975c..e5891fcaa 100644
--- a/obp-api/src/main/scala/code/api/util/APIUtil.scala
+++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala
@@ -806,6 +806,12 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
null
else
text
+
+ def nullToString(text : String) =
+ if(text == null)
+ null
+ else
+ text
def stringOptionOrNull(text : Option[String]) =
text match {
diff --git a/obp-api/src/main/scala/code/api/util/ApiRole.scala b/obp-api/src/main/scala/code/api/util/ApiRole.scala
index 653b2d60c..ab72e1180 100644
--- a/obp-api/src/main/scala/code/api/util/ApiRole.scala
+++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala
@@ -351,6 +351,9 @@ object ApiRole {
case class CanReadMetrics (requiresBankId: Boolean = false) extends ApiRole
lazy val canReadMetrics = CanReadMetrics()
+
+ case class CanGetMetricsAtOneBank(requiresBankId: Boolean = true) extends ApiRole
+ lazy val canGetMetricsAtOneBank = CanGetMetricsAtOneBank()
case class CanGetConfig(requiresBankId: Boolean = false) extends ApiRole
lazy val canGetConfig = CanGetConfig()
diff --git a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
index dcd1ea231..aafce8994 100644
--- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
+++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
@@ -499,7 +499,7 @@ object ErrorMessages {
val ConsentUserCannotBeAdded = "OBP-35026: The Consent's User cannot be added."
val ConsentUserAuthContextCannotBeAdded = "OBP-35027: The Consent's User Auth Context cannot be added."
val ConsentRequestNotFound = "OBP-35028: Consent Request not found by CONSENT_REQUEST_ID. "
- val ConsentRequestAlreadyUsed = "OBP-35029: The CONSENT_REQUEST_ID is used to create Consent. "
+ val ConsentRequestIsInvalid = "OBP-35029: The CONSENT_REQUEST_ID is invalid. "
//Authorisations
val AuthorisationNotFound = "OBP-36001: Authorisation not found. Please specify valid values for PAYMENT_ID and AUTHORISATION_ID. "
diff --git a/obp-api/src/main/scala/code/api/util/ExampleValue.scala b/obp-api/src/main/scala/code/api/util/ExampleValue.scala
index 6e153f99b..04afb8fda 100644
--- a/obp-api/src/main/scala/code/api/util/ExampleValue.scala
+++ b/obp-api/src/main/scala/code/api/util/ExampleValue.scala
@@ -1,7 +1,7 @@
package code.api.util
-import code.api.util.APIUtil.{DateWithMs, DateWithMsExampleString, parseDate}
+import code.api.util.APIUtil.{DateWithMs, DateWithMsExampleString, oneYearAgoDate, formatDate, oneYearAgo, parseDate}
import code.api.util.ErrorMessages.{InvalidJsonFormat, UnknownError, UserHasMissingRoles, UserNotLoggedIn}
import net.liftweb.json.JsonDSL._
import code.api.util.Glossary.{glossaryItems, makeGlossaryItem}
@@ -23,13 +23,14 @@ case class ConnectorField(value: String, description: String) {
object ExampleValue {
val NoDescriptionProvided = "no-description-provided"
- val NoExampleProvided = "no-example-provided"
+ val NoExampleProvided = ""
val booleanTrue = "true"
lazy val bankIdGlossary = glossaryItems.find(_.title == "Bank.bank_id").map(_.textDescription)
lazy val bankIdExample = ConnectorField("gh.29.uk", s"A string that MUST uniquely identify the bank on this OBP instance. It COULD be a UUID but is generally a short string that easily identifies the bank / brand it represents.")
lazy val bank_idExample = bankIdExample
+ glossaryItems += makeGlossaryItem("Bank.bank_id", bankIdExample)
lazy val accountIdExample = ConnectorField("8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0", s"A string that, in combination with the bankId MUST uniquely identify the account on this OBP instance. SHOULD be a UUID. MUST NOT be able to guess accountNumber from accountId. OBP-API or Adapter keeps a mapping between accountId and accountNumber. AccountId is a non reversible hash of the human readable account number.")
lazy val account_idExample = accountIdExample
@@ -96,7 +97,10 @@ object ExampleValue {
lazy val relationshipStatusExample = ConnectorField("single", s"relationship status")
glossaryItems += makeGlossaryItem("Customer.relationshipStatus", relationshipStatusExample)
- lazy val dependentsExample = ConnectorField("1", s"the number of dependents")
+ lazy val dependantsExample = ConnectorField("1", s"the number of dependants")
+ glossaryItems += makeGlossaryItem("Customer.dependants", dependantsExample)
+
+ lazy val dependentsExample = ConnectorField("2", s"the number of dependents") // Dominant form in American English
glossaryItems += makeGlossaryItem("Customer.dependents", dependentsExample)
lazy val kycStatusExample = ConnectorField(booleanTrue, s"This is boolean to indicate if the cusomter's KYC has been checked.")
@@ -785,7 +789,7 @@ object ExampleValue {
lazy val customerUserIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("customer_user_id", customerUserIdExample)
- lazy val bankCodeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val bankCodeExample = ConnectorField("CGHZ",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("bank_code", bankCodeExample)
lazy val averageResponseTimeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -848,7 +852,7 @@ object ExampleValue {
lazy val canAddTransactionRequestToAnyAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("can_add_transaction_request_to_any_account", canAddTransactionRequestToAnyAccountExample)
- lazy val websiteExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val websiteExample = ConnectorField("www.openbankproject.com",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("website", websiteExample)
lazy val atmIdExample = ConnectorField("atme0352a-9a0f-4bfa-b30b-9003aa467f51","A string that MUST uniquely identify the ATM on this OBP instance.")
@@ -962,7 +966,7 @@ object ExampleValue {
lazy val accountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("account", accountExample)
- lazy val idExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val idExample = ConnectorField("d8839721-ad8f-45dd-9f78-2080414b93f9",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("id", idExample)
lazy val canAddCorporateLocationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -1031,7 +1035,7 @@ object ExampleValue {
lazy val toDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("to_date", toDateExample)
- lazy val bankRoutingsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val bankRoutingsExample = ConnectorField("bank routing in form of (scheme, address)",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("bank_routings", bankRoutingsExample)
lazy val canSeeOpenCorporatesUrlExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -1085,9 +1089,6 @@ object ExampleValue {
lazy val temporaryCreditDocumentationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("temporary_credit_documentation", temporaryCreditDocumentationExample)
- lazy val dependantsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
- glossaryItems += makeGlossaryItem("dependants", dependantsExample)
-
lazy val locationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("location", locationExample)
@@ -1275,7 +1276,7 @@ object ExampleValue {
lazy val wednesdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("wednesday", wednesdayExample)
- lazy val lastOkDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val lastOkDateExample = ConnectorField(formatDate(oneYearAgoDate),NoDescriptionProvided)
glossaryItems += makeGlossaryItem("last_ok_date", lastOkDateExample)
lazy val transactionTypesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -1591,7 +1592,7 @@ object ExampleValue {
lazy val dateInsertedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("date_inserted", dateInsertedExample)
- lazy val schemeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val schemeExample = ConnectorField("scheme value",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("scheme", schemeExample)
lazy val customerAddressIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -1762,7 +1763,7 @@ object ExampleValue {
lazy val branchTypeExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("branch_type", branchTypeExample)
- lazy val fullNameExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val fullNameExample = ConnectorField("full name string",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("full_name", fullNameExample)
lazy val canCreateDirectDebitExample = ConnectorField(booleanTrue,NoDescriptionProvided)
@@ -1861,7 +1862,7 @@ object ExampleValue {
lazy val postedExample = ConnectorField("2020-01-27",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("posted", postedExample)
- lazy val logoExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val logoExample = ConnectorField("logo url",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("logo", logoExample)
lazy val topApisExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -1987,7 +1988,7 @@ object ExampleValue {
lazy val toCurrencyCodeExample = ConnectorField("EUR",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("to_currency_code", toCurrencyCodeExample)
- lazy val dobOfDependantsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val dobOfDependantsExample = ConnectorField("[2019-09-08, 2017-07-12]",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("dob_of_dependants", dobOfDependantsExample)
lazy val settlementAccountsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -2059,7 +2060,7 @@ object ExampleValue {
lazy val createdByUserIdExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("created_by_user_id", createdByUserIdExample)
- lazy val attributesExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val attributesExample = ConnectorField("attribute value in form of (name, value)",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("attributes", attributesExample)
lazy val revokedExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
@@ -2071,7 +2072,7 @@ object ExampleValue {
lazy val currentCreditDocumentationExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
glossaryItems += makeGlossaryItem("current_credit_documentation", currentCreditDocumentationExample)
- lazy val mobilePhoneNumberExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
+ lazy val mobilePhoneNumberExample = ConnectorField("+49 30 901820",NoDescriptionProvided)
glossaryItems += makeGlossaryItem("mobile_phone_number", mobilePhoneNumberExample)
lazy val saturdayExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
diff --git a/obp-api/src/main/scala/code/api/util/NewStyle.scala b/obp-api/src/main/scala/code/api/util/NewStyle.scala
index c2c1333b5..27c7c8f28 100644
--- a/obp-api/src/main/scala/code/api/util/NewStyle.scala
+++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala
@@ -654,6 +654,9 @@ object NewStyle extends MdcLoggable{
Views.views.vend.systemViewFuture(viewId) map {
unboxFullOrFail(_, callContext, s"$SystemViewNotFound. Current ViewId is $viewId")
}
+ }
+ def systemViews(): Future[List[View]] = {
+ Views.views.vend.getSystemViews()
}
def grantAccessToCustomView(view : View, user: User, callContext: Option[CallContext]) : Future[View] = {
view.isSystem match {
@@ -2522,6 +2525,53 @@ object NewStyle extends MdcLoggable{
) map {
i => (unboxFullOrFail(i._1, callContext, CreateCustomerError), i._2)
}
+ def createCustomerC2(
+ bankId: BankId,
+ legalName: String,
+ customerNumber: String,
+ mobileNumber: String,
+ email: String,
+ faceImage:
+ CustomerFaceImageTrait,
+ dateOfBirth: Date,
+ relationshipStatus: String,
+ dependents: Int,
+ dobOfDependents: List[Date],
+ highestEducationAttained: String,
+ employmentStatus: String,
+ kycStatus: Boolean,
+ lastOkDate: Date,
+ creditRating: Option[CreditRatingTrait],
+ creditLimit: Option[AmountOfMoneyTrait],
+ title: String,
+ branchId: String,
+ nameSuffix: String,
+ callContext: Option[CallContext]): OBPReturnType[Customer] =
+ Connector.connector.vend.createCustomerC2(
+ bankId: BankId,
+ legalName: String,
+ customerNumber: String,
+ mobileNumber: String,
+ email: String,
+ faceImage:
+ CustomerFaceImageTrait,
+ dateOfBirth: Date,
+ relationshipStatus: String,
+ dependents: Int,
+ dobOfDependents: List[Date],
+ highestEducationAttained: String,
+ employmentStatus: String,
+ kycStatus: Boolean,
+ lastOkDate: Date,
+ creditRating: Option[CreditRatingTrait],
+ creditLimit: Option[AmountOfMoneyTrait],
+ title: String,
+ branchId: String,
+ nameSuffix: String,
+ callContext: Option[CallContext]
+ ) map {
+ i => (unboxFullOrFail(i._1, callContext, CreateCustomerError), i._2)
+ }
def updateCustomerScaData(customerId: String,
mobileNumber: Option[String],
diff --git a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
index bf6b74580..ef6011af0 100644
--- a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
+++ b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
@@ -366,7 +366,31 @@ object JSONFactory1_4_0 extends MdcLoggable{
* @return Bank.bank_id
*/
def getGlossaryItemTitle(parameter: String): String = {
- glossaryItems.find(_.title.toLowerCase.contains(s"${parameter.toLowerCase}")).map(_.title).getOrElse("").replaceAll(" ","-")
+ def isUrlParameter(): Boolean = {
+ List(
+ "BANK_ID",
+ "ACCOUNT_ID",
+ "CUSTOMER_ID",
+ "TRANSACTION_ID",
+ "ATTRIBUTE_ID",
+ "VIEW_ID",
+ "USER_ID",
+ "PRODUCT_CODE",
+ "PRODUCT_ID",
+ "OPERATION_ID",
+ "ENDPOINT_TAG_ID",
+ ).exists(_ == parameter)
+ }
+ parameter match {
+ case _ if isUrlParameter() =>
+ glossaryItems
+ .find(_.title.toLowerCase.contains(s"${parameter.toLowerCase}"))
+ .map(_.title).getOrElse("").replaceAll(" ","-")
+ case _ =>
+ glossaryItems
+ .find(_.title.toLowerCase.equals(s"${parameter.toLowerCase}"))
+ .map(_.title).getOrElse("").replaceAll(" ","-")
+ }
}
/**
@@ -420,31 +444,31 @@ object JSONFactory1_4_0 extends MdcLoggable{
* @param parameter BANK_ID
* @return [BANK_ID](/glossary#Bank.bank_id):gh.29.uk
*/
- def prepareDescription(parameter: String, types: List[(String, Boolean)]): String = {
+ def prepareDescription(parameter: String, optionalTypeFields: List[(String, Boolean)]): String = {
val glossaryItemTitle = getGlossaryItemTitle(parameter)
val exampleFieldValue = getExampleFieldValue(parameter)
def boldIfMandatory() = {
- types.exists(i => i._1 == parameter && i._2 == false) match {
+ optionalTypeFields.exists(i => i._1 == parameter && i._2 == false) match {
case true =>
- s"**$parameter**"
+ s"***$parameter**"
case false =>
s"$parameter"
}
}
- if(exampleFieldValue.contains(ExampleValue.NoExampleProvided)){
+ if(glossaryItemTitle.contains("jsonstring")){
""
} else {
- s"""
- |
- |* [${boldIfMandatory()}](/glossary#$glossaryItemTitle): $exampleFieldValue
- |
- |""".stripMargin
- }
+ s"""
+ |
+ |* [${boldIfMandatory()}](/glossary#$glossaryItemTitle): $exampleFieldValue
+ |
+ |""".stripMargin
+ }
}
def prepareJsonFieldDescription(jsonBody: scala.Product, jsonType: String): String = {
jsonBody.productIterator
- val (jsonBodyJValue: json.JValue, types) = jsonBody match {
+ val (jsonBodyJValue: json.JValue, optionalTypeFields) = jsonBody match {
case JvalueCaseClass(jValue) =>
val types = Nil
(jValue, types)
@@ -455,9 +479,14 @@ object JSONFactory1_4_0 extends MdcLoggable{
(decompose(jsonBody), types)
}
- val jsonBodyFields =JsonUtils.collectFieldNames(jsonBodyJValue).keySet.toList.sorted
+ // Group by is mandatory criteria and sort those 2 groups by name of the field
+ val jsonBodyFieldsOptional = JsonUtils.collectFieldNames(jsonBodyJValue).keySet.toList
+ .filter(x => optionalTypeFields.exists(i => i._1 == x && i._2 == true)).sorted
+ val jsonBodyFieldsMandatory = JsonUtils.collectFieldNames(jsonBodyJValue).keySet.toList
+ .filter(x => optionalTypeFields.exists(i => i._1 == x && i._2 == false)).sorted
+ val jsonBodyFields = jsonBodyFieldsMandatory ::: jsonBodyFieldsOptional
- val jsonFieldsDescription = jsonBodyFields.map(i => prepareDescription(i, types))
+ val jsonFieldsDescription = jsonBodyFields.map(i => prepareDescription(i, optionalTypeFields))
val jsonTitleType = if (jsonType.contains("request")) "\n\n\n**JSON request body fields:**\n\n" else "\n\n\n**JSON response body fields:**\n\n"
diff --git a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala
index 37a3c27a7..d94cab176 100644
--- a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala
+++ b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala
@@ -148,7 +148,7 @@ trait APIMethods300 {
|
| You MUST use a leading _ (underscore) in the view name because other view names are reserved for OBP [system views](/index#group-View-System).
| """,
- SwaggerDefinitionsJSON.createViewJson,
+ SwaggerDefinitionsJSON.createViewJsonV300,
viewJsonV300,
List(
UserNotLoggedIn,
@@ -233,7 +233,7 @@ trait APIMethods300 {
|
|The json sent is the same as during view creation (above), with one difference: the 'name' field
|of a view is not editable (it is only set when a view is created)""",
- updateViewJSON,
+ updateViewJsonV300,
viewJsonV300,
List(
InvalidJsonFormat,
@@ -251,7 +251,7 @@ trait APIMethods300 {
val res =
for {
(Full(u), callContext) <- authenticatedAccess(cc)
- updateJson <- Future { tryo{json.extract[UpdateViewJSON]} } map {
+ updateJson <- Future { tryo{json.extract[UpdateViewJsonV300]} } map {
val msg = s"$InvalidJsonFormat The Json body should be the $UpdateViewJSON "
x => unboxFullOrFail(x, callContext, msg)
}
@@ -270,7 +270,7 @@ trait APIMethods300 {
(account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext)
} yield {
for {
- updatedView <- account.updateView(u, viewId, updateJson)
+ updatedView <- account.updateView(u, viewId, updateJson.toUpdateViewJson)
} yield {
(JSONFactory300.createViewJSON(updatedView), HttpCode.`200`(callContext))
}
diff --git a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
index 4489abe34..330543c9f 100644
--- a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
+++ b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala
@@ -71,7 +71,44 @@ import scala.util.Try
//started - view relevant case classes
-
+case class CreateViewJsonV300(
+ name: String,
+ description: String,
+ metadata_view: String,
+ is_public: Boolean,
+ which_alias_to_use: String,
+ hide_metadata_if_alias_used: Boolean,
+ allowed_actions : List[String]
+) {
+ def toCreateViewJson = CreateViewJson(
+ name = this.name,
+ description = this.description,
+ metadata_view = this.metadata_view,
+ is_public = this.is_public,
+ which_alias_to_use = this.which_alias_to_use,
+ hide_metadata_if_alias_used = this.hide_metadata_if_alias_used,
+ allowed_actions = this.allowed_actions
+ )
+}
+case class UpdateViewJsonV300(
+ description: String,
+ metadata_view: String,
+ is_public: Boolean,
+ is_firehose: Option[Boolean] = None,
+ which_alias_to_use: String,
+ hide_metadata_if_alias_used: Boolean,
+ allowed_actions: List[String]
+) {
+ def toUpdateViewJson = UpdateViewJSON(
+ description = this.description,
+ metadata_view = this.metadata_view,
+ is_public = this.is_public,
+ is_firehose = this.is_firehose,
+ which_alias_to_use = this.which_alias_to_use,
+ hide_metadata_if_alias_used = this.hide_metadata_if_alias_used,
+ allowed_actions = this.allowed_actions
+ )
+}
case class ViewsJsonV300(
views : List[ViewJsonV300]
)
diff --git a/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala b/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala
index 7a4673397..a7f17f7a7 100644
--- a/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala
+++ b/obp-api/src/main/scala/code/api/v3_1_0/APIMethods310.scala
@@ -3,6 +3,7 @@ package code.api.v3_1_0
import java.text.SimpleDateFormat
import java.util.UUID
import java.util.regex.Pattern
+
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
import code.api.ResourceDocs1_4_0.{MessageDocsSwaggerDefinitions, ResourceDocsAPIMethodsUtil, SwaggerDefinitionsJSON, SwaggerJSONFactory}
import code.api.util.APIUtil.{getWebUIPropsPairs, _}
@@ -16,7 +17,7 @@ import code.api.v1_2_1.{JSONFactory, RateLimiting}
import code.api.v2_0_0.CreateMeetingJson
import code.api.v2_1_0._
import code.api.v2_2_0.{CreateAccountJSONV220, JSONFactory220}
-import code.api.v3_0_0.JSONFactory300
+import code.api.v3_0_0.{CreateViewJsonV300, JSONFactory300}
import code.api.v3_0_0.JSONFactory300.createAdapterInfoJson
import code.api.v3_1_0.JSONFactory310._
import code.bankconnectors.rest.RestConnector_vMar2019
@@ -3880,7 +3881,7 @@ trait APIMethods310 {
|
| Please note that system views cannot be public. In case you try to set it you will get the error $SystemViewCannotBePublicError
| """,
- SwaggerDefinitionsJSON.createSystemViewJson,
+ SwaggerDefinitionsJSON.createSystemViewJsonV300,
viewJsonV300,
List(
UserNotLoggedIn,
@@ -3900,12 +3901,12 @@ trait APIMethods310 {
_ <- NewStyle.function.hasEntitlement("", user.userId, canCreateSystemView, callContext)
failMsg = s"$InvalidJsonFormat The Json body should be the $CreateViewJson "
createViewJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
- json.extract[CreateViewJson]
+ json.extract[CreateViewJsonV300]
}
_ <- Helper.booleanToFuture(SystemViewCannotBePublicError, failCode=400, cc=callContext) {
createViewJson.is_public == false
}
- view <- NewStyle.function.createSystemView(createViewJson, callContext)
+ view <- NewStyle.function.createSystemView(createViewJson.toCreateViewJson, callContext)
} yield {
(JSONFactory310.createViewJSON(view), HttpCode.`201`(callContext))
}
@@ -3929,7 +3930,7 @@ trait APIMethods310 {
"user does not have owner access"
),
List(apiTagSystemView, apiTagNewStyle),
- Some(List(canCreateSystemView))
+ Some(List(canDeleteSystemView))
)
lazy val deleteSystemView: OBPEndpoint = {
diff --git a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
index b4d4460b6..8d3ac5a7b 100644
--- a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
+++ b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
@@ -3969,7 +3969,7 @@ trait APIMethods400 {
| - Outgoing account (name: Default outgoing settlement account, Account ID: OBP_DEFAULT_OUTGOING_ACCOUNT_ID, currency: EUR)
|
|""",
- bankJson400,
+ postBankJson400,
bankJson400,
List(
InvalidJsonFormat,
diff --git a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala
index 1d918551b..d848a9545 100644
--- a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala
+++ b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala
@@ -106,6 +106,14 @@ case class BankJson400(
bank_routings: List[BankRoutingJsonV121],
attributes: Option[List[BankAttributeBankResponseJsonV400]]
)
+case class PostBankJson400(
+ id: String,
+ short_name: String,
+ full_name: String,
+ logo: String,
+ website: String,
+ bank_routings: List[BankRoutingJsonV121]
+)
case class BanksJson400(banks: List[BankJson400])
@@ -236,11 +244,11 @@ case class FastFirehoseAccountJsonV400(
bank_id: String,
label: String,
number: String,
- owners: String,
+ owners: List[FastFirehoseOwners],
product_code: String,
balance: AmountOfMoneyJsonV121,
- account_routings: String ,
- account_attributes: String
+ account_routings: List[FastFirehoseRoutings] ,
+ account_attributes: List[FastFirehoseAttributes]
)
case class FastFirehoseAccountsJsonV400(
diff --git a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala
index 2dd674f7c..a843299b3 100644
--- a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala
+++ b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala
@@ -1,6 +1,9 @@
package code.api.v5_0_0
-import java.util.Date
+import java.util.concurrent.ThreadLocalRandom
+
+import code.accountattribute.AccountAttributeX
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
import code.api.util.APIUtil._
import code.api.util.ApiRole._
@@ -14,20 +17,23 @@ import code.api.v3_0_0.JSONFactory300
import code.api.v3_1_0._
import code.api.v4_0_0.JSONFactory400.createCustomersMinimalJson
import code.api.v4_0_0.{JSONFactory400, PutProductJsonV400}
-import code.api.v5_0_0.JSONFactory500.createPhysicalCardJson
+import code.api.v5_0_0.JSONFactory500.{createPhysicalCardJson, createViewJsonV500, createViewsJsonV500, createViewsIdsJsonV500}
import code.bankconnectors.Connector
import code.consent.{ConsentRequests, Consents}
import code.entitlement.Entitlement
+import code.metrics.APIMetrics
+import code.model._
import code.model.dataAccess.BankAccountCreation
import code.transactionrequests.TransactionRequests.TransactionRequestTypes.{apply => _}
import code.util.Helper
+import code.util.Helper.booleanToFuture
import code.views.Views
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model.enums.StrongCustomerAuthentication
-import com.openbankproject.commons.model.{AccountAttribute, AccountId, AccountRouting, BankAccount, BankId, BankIdAccountId, CardAction, CardAttributeCommons, CardCollectionInfo, CardPostedInfo, CardReplacementInfo, CardReplacementReason, CreditLimit, CreditRating, CustomerFaceImage, CustomerId, PinResetInfo, PinResetReason, ProductCode, TransactionRequestType, UserAuthContextUpdateStatus, View, ViewId}
+import com.openbankproject.commons.model._
import com.openbankproject.commons.util.ApiVersion
-import net.liftweb.common.{Box, Empty, Full}
+import net.liftweb.common.{Empty, Full}
import net.liftweb.http.Req
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
@@ -41,7 +47,6 @@ import code.util.Helper.booleanToFuture
import scala.collection.immutable.{List, Nil}
import scala.collection.mutable.ArrayBuffer
-import scala.concurrent
import scala.concurrent.Future
import scala.util.Random
@@ -763,6 +768,7 @@ trait APIMethods500 {
UserNotLoggedIn,
$BankNotFound,
InvalidJsonFormat,
+ ConsentRequestIsInvalid,
ConsentAllowedScaMethods,
RolesAllowedInConsent,
ViewsAllowedInConsent,
@@ -788,7 +794,7 @@ trait APIMethods500 {
)) map {
i => unboxFullOrFail(i,callContext, ConsentRequestNotFound)
}
- _ <- Helper.booleanToFuture(ConsentRequestAlreadyUsed, cc=callContext){
+ _ <- Helper.booleanToFuture(ConsentRequestIsInvalid, cc=callContext){
Consents.consentProvider.vend.getConsentByConsentRequestId(consentRequestId).isEmpty
}
_ <- Helper.booleanToFuture(ConsentAllowedScaMethods, cc=callContext){
@@ -988,9 +994,12 @@ trait APIMethods500 {
_ <- Helper.booleanToFuture(failMsg = InvalidJsonContent + s" The field dependants(${postedData.dependants.getOrElse(0)}) not equal the length(${postedData.dob_of_dependants.getOrElse(Nil).length }) of dob_of_dependants array", 400, cc.callContext) {
postedData.dependants.getOrElse(0) == postedData.dob_of_dependants.getOrElse(Nil).length
}
- (customer, callContext) <- NewStyle.function.createCustomer(
+ customerNumber = postedData.customer_number.getOrElse(Random.nextInt(Integer.MAX_VALUE).toString)
+ (_, callContext) <- NewStyle.function.checkCustomerNumberAvailable(bankId, customerNumber, cc.callContext)
+ (customer, callContext) <- NewStyle.function.createCustomerC2(
bankId,
postedData.legal_name,
+ customerNumber,
postedData.mobile_phone_number,
postedData.email.getOrElse(""),
CustomerFaceImage(
@@ -1010,7 +1019,7 @@ trait APIMethods500 {
postedData.title.getOrElse(""),
postedData.branch_id.getOrElse(""),
postedData.name_suffix.getOrElse(""),
- cc.callContext,
+ callContext,
)
} yield {
(JSONFactory310.createCustomerJson(customer), HttpCode.`201`(callContext))
@@ -1443,6 +1452,354 @@ trait APIMethods500 {
}
}
+
+ staticResourceDocs += ResourceDoc(
+ getViewsForBankAccount,
+ implementedInApiVersion,
+ nameOf(getViewsForBankAccount),
+ "GET",
+ "/banks/BANK_ID/accounts/ACCOUNT_ID/views",
+ "Get Views for Account",
+ s"""#Views
+ |
+ |
+ |Views in Open Bank Project provide a mechanism for fine grained access control and delegation to Accounts and Transactions. Account holders use the 'owner' view by default. Delegated access is made through other views for example 'accountants', 'share-holders' or 'tagging-application'. Views can be created via the API and each view has a list of entitlements.
+ |
+ |Views on accounts and transactions filter the underlying data to redact certain fields for certain users. For instance the balance on an account may be hidden from the public. The way to know what is possible on a view is determined in the following JSON.
+ |
+ |**Data:** When a view moderates a set of data, some fields my contain the value `null` rather than the original value. This indicates either that the user is not allowed to see the original data or the field is empty.
+ |
+ |There is currently one exception to this rule; the 'holder' field in the JSON contains always a value which is either an alias or the real name - indicated by the 'is_alias' field.
+ |
+ |**Action:** When a user performs an action like trying to post a comment (with POST API call), if he is not allowed, the body response will contain an error message.
+ |
+ |**Metadata:**
+ |Transaction metadata (like images, tags, comments, etc.) will appears *ONLY* on the view where they have been created e.g. comments posted to the public view only appear on the public view.
+ |
+ |The other account metadata fields (like image_URL, more_info, etc.) are unique through all the views. Example, if a user edits the 'more_info' field in the 'team' view, then the view 'authorities' will show the new value (if it is allowed to do it).
+ |
+ |# All
+ |*Optional*
+ |
+ |Returns the list of the views created for account ACCOUNT_ID at BANK_ID.
+ |
+ |${authenticationRequiredMessage(true)} and the user needs to have access to the owner view.""",
+ emptyObjectJson,
+ viewsJsonV500,
+ List(
+ $UserNotLoggedIn,
+ $BankAccountNotFound,
+ UnknownError
+ ),
+ List(apiTagView, apiTagAccount, apiTagNewStyle))
+
+ lazy val getViewsForBankAccount : OBPEndpoint = {
+ //get the available views on an bank account
+ case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonGet req => {
+ cc =>
+ val res =
+ for {
+ _ <- Helper.booleanToFuture(failMsg = UserNoOwnerView +"userId : " + cc.userId + ". account : " + accountId, cc=cc.callContext){
+ cc.loggedInUser.hasOwnerViewAccess(BankIdAccountId(bankId, accountId))
+ }
+ } yield {
+ for {
+ views <- Full(Views.views.vend.availableViewsForAccount(BankIdAccountId(bankId, accountId)))
+ } yield {
+ (createViewsJsonV500(views), HttpCode.`200`(cc.callContext))
+ }
+ }
+ res map { fullBoxOrException(_) } map { unboxFull(_) }
+ }
+ }
+
+ staticResourceDocs += ResourceDoc(
+ deleteSystemView,
+ implementedInApiVersion,
+ "deleteSystemView",
+ "DELETE",
+ "/system-views/VIEW_ID",
+ "Delete System View",
+ "Deletes the system view specified by VIEW_ID",
+ emptyObjectJson,
+ emptyObjectJson,
+ List(
+ UserNotLoggedIn,
+ BankAccountNotFound,
+ UnknownError,
+ "user does not have owner access"
+ ),
+ List(apiTagSystemView, apiTagNewStyle),
+ Some(List(canDeleteSystemView))
+ )
+
+ lazy val deleteSystemView: OBPEndpoint = {
+ case "system-views" :: viewId :: Nil JsonDelete req => {
+ cc =>
+ for {
+ _ <- NewStyle.function.systemView(ViewId(viewId), cc.callContext)
+ view <- NewStyle.function.deleteSystemView(ViewId(viewId), cc.callContext)
+ } yield {
+ (Full(view), HttpCode.`200`(cc.callContext))
+ }
+ }
+ }
+
+ staticResourceDocs += ResourceDoc(
+ getMetricsAtBank,
+ implementedInApiVersion,
+ nameOf(getMetricsAtBank),
+ "GET",
+ "/management/metrics/banks/BANK_ID",
+ "Get Metrics at Bank",
+ s"""Get the all metrics at the Bank specified by BANK_ID
+ |
+ |require CanReadMetrics role
+ |
+ |Filters Part 1.*filtering* (no wilde cards etc.) parameters to GET /management/metrics
+ |
+ |Should be able to filter on the following metrics fields
+ |
+ |eg: /management/metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&limit=50&offset=2
+ |
+ |1 from_date (defaults to one week before current date): eg:from_date=$DateWithMsExampleString
+ |
+ |2 to_date (defaults to current date) eg:to_date=$DateWithMsExampleString
+ |
+ |3 limit (for pagination: defaults to 50) eg:limit=200
+ |
+ |4 offset (for pagination: zero index, defaults to 0) eg: offset=10
+ |
+ |5 sort_by (defaults to date field) eg: sort_by=date
+ | possible values:
+ | "url",
+ | "date",
+ | "user_name",
+ | "app_name",
+ | "developer_email",
+ | "implemented_by_partial_function",
+ | "implemented_in_version",
+ | "consumer_id",
+ | "verb"
+ |
+ |6 direction (defaults to date desc) eg: direction=desc
+ |
+ |eg: /management/metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&limit=10000&offset=0&anon=false&app_name=TeatApp&implemented_in_version=v2.1.0&verb=POST&user_id=c7b6cb47-cb96-4441-8801-35b57456753a&user_name=susan.uk.29@example.com&consumer_id=78
+ |
+ |Other filters:
+ |
+ |7 consumer_id (if null ignore)
+ |
+ |8 user_id (if null ignore)
+ |
+ |9 anon (if null ignore) only support two value : true (return where user_id is null.) or false (return where user_id is not null.)
+ |
+ |10 url (if null ignore), note: can not contain '&'.
+ |
+ |11 app_name (if null ignore)
+ |
+ |12 implemented_by_partial_function (if null ignore),
+ |
+ |13 implemented_in_version (if null ignore)
+ |
+ |14 verb (if null ignore)
+ |
+ |15 correlation_id (if null ignore)
+ |
+ |16 duration (if null ignore) non digit chars will be silently omitted
+ |
+ """.stripMargin,
+ emptyObjectJson,
+ metricsJson,
+ List(
+ $UserNotLoggedIn,
+ UserHasMissingRoles,
+ UnknownError
+ ),
+ List(apiTagMetric, apiTagApi, apiTagNewStyle),
+ Some(List(canGetMetricsAtOneBank)))
+
+ lazy val getMetricsAtBank : OBPEndpoint = {
+ case "management" :: "metrics" :: "banks" :: bankId :: Nil JsonGet _ => {
+ cc => {
+ for {
+ httpParams <- NewStyle.function.extractHttpParamsFromUrl(cc.url)
+ (obpQueryParams, callContext) <- createQueriesByHttpParamsFuture(httpParams, cc.callContext)
+ metrics <- Future(APIMetrics.apiMetrics.vend.getAllMetrics(obpQueryParams ::: List(OBPBankId(bankId))))
+ } yield {
+ (JSONFactory210.createMetricsJson(metrics), HttpCode.`200`(callContext))
+ }
+ }
+ }
+ }
+
+ staticResourceDocs += ResourceDoc(
+ getSystemView,
+ implementedInApiVersion,
+ "getSystemView",
+ "GET",
+ "/system-views/VIEW_ID",
+ "Get System View",
+ s"""Get System View
+ |
+ |${authenticationRequiredMessage(true)}
+ |
+ """.stripMargin,
+ emptyObjectJson,
+ viewJsonV500,
+ List(
+ $UserNotLoggedIn,
+ $BankNotFound,
+ UnknownError
+ ),
+ List(apiTagSystemView, apiTagNewStyle),
+ Some(List(canGetSystemView))
+ )
+
+ lazy val getSystemView: OBPEndpoint = {
+ case "system-views" :: viewId :: Nil JsonGet _ => {
+ cc =>
+ for {
+ view <- NewStyle.function.systemView(ViewId(viewId), cc.callContext)
+ } yield {
+ (createViewJsonV500(view), HttpCode.`200`(cc.callContext))
+ }
+ }
+ }
+
+ staticResourceDocs += ResourceDoc(
+ getSystemViewsIds,
+ implementedInApiVersion,
+ nameOf(getSystemViewsIds),
+ "GET",
+ "/system-views-ids",
+ "Get Ids of System Views",
+ s"""Get Ids of System Views
+ |
+ |${authenticationRequiredMessage(true)}
+ |
+ """.stripMargin,
+ emptyObjectJson,
+ viewIdsJsonV500,
+ List(
+ $UserNotLoggedIn,
+ $BankNotFound,
+ UnknownError
+ ),
+ List(apiTagSystemView, apiTagNewStyle),
+ Some(List(canGetSystemView))
+ )
+
+ lazy val getSystemViewsIds: OBPEndpoint = {
+ case "system-views-ids" :: Nil JsonGet _ => {
+ cc =>
+ for {
+ views <- NewStyle.function.systemViews()
+ } yield {
+ (createViewsIdsJsonV500(views), HttpCode.`200`(cc.callContext))
+ }
+ }
+ }
+
+
+ staticResourceDocs += ResourceDoc(
+ createSystemView,
+ implementedInApiVersion,
+ nameOf(createSystemView),
+ "POST",
+ "/system-views",
+ "Create System View",
+ s"""Create a system view
+ |
+ | ${authenticationRequiredMessage(true)} and the user needs to have access to the $canCreateSystemView entitlement.
+ | The 'alias' field in the JSON can take one of two values:
+ |
+ | * _public_: to use the public alias if there is one specified for the other account.
+ | * _private_: to use the public alias if there is one specified for the other account.
+ |
+ | * _''(empty string)_: to use no alias; the view shows the real name of the other account.
+ |
+ | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown.
+ |
+ | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`.
+ |
+ | Please note that system views cannot be public. In case you try to set it you will get the error $SystemViewCannotBePublicError
+ | """,
+ createSystemViewJsonV500,
+ viewJsonV500,
+ List(
+ $UserNotLoggedIn,
+ InvalidJsonFormat,
+ UnknownError
+ ),
+ List(apiTagSystemView, apiTagNewStyle),
+ Some(List(canCreateSystemView))
+ )
+
+ lazy val createSystemView : OBPEndpoint = {
+ //creates a system view
+ case "system-views" :: Nil JsonPost json -> _ => {
+ cc =>
+ for {
+ createViewJson <- NewStyle.function.tryons(failMsg = s"$InvalidJsonFormat The Json body should be the $CreateViewJson ", 400, cc.callContext) {
+ json.extract[CreateViewJsonV500]
+ }
+ _ <- Helper.booleanToFuture(SystemViewCannotBePublicError, failCode=400, cc=cc.callContext) {
+ createViewJson.is_public == false
+ }
+ view <- NewStyle.function.createSystemView(createViewJson.toCreateViewJson, cc.callContext)
+ } yield {
+ (createViewJsonV500(view), HttpCode.`201`(cc.callContext))
+ }
+ }
+ }
+
+
+ staticResourceDocs += ResourceDoc(
+ updateSystemView,
+ implementedInApiVersion,
+ nameOf(updateSystemView),
+ "PUT",
+ "/system-views/VIEW_ID",
+ "Update System View",
+ s"""Update an existing view on a bank account
+ |
+ |${authenticationRequiredMessage(true)} and the user needs to have access to the owner view.
+ |
+ |The json sent is the same as during view creation (above), with one difference: the 'name' field
+ |of a view is not editable (it is only set when a view is created)""",
+ updateSystemViewJson500,
+ viewJsonV500,
+ List(
+ InvalidJsonFormat,
+ $UserNotLoggedIn,
+ BankAccountNotFound,
+ UnknownError
+ ),
+ List(apiTagSystemView, apiTagNewStyle),
+ Some(List(canUpdateSystemView))
+ )
+
+ lazy val updateSystemView : OBPEndpoint = {
+ //updates a view on a bank account
+ case "system-views" :: viewId :: Nil JsonPut json -> _ => {
+ cc =>
+ for {
+ updateJson <- Future { tryo{json.extract[UpdateViewJsonV500]} } map {
+ val msg = s"$InvalidJsonFormat The Json body should be the $UpdateViewJSON "
+ x => unboxFullOrFail(x, cc.callContext, msg)
+ }
+ _ <- Helper.booleanToFuture(SystemViewCannotBePublicError, failCode=400, cc=cc.callContext) {
+ updateJson.is_public == false
+ }
+ _ <- NewStyle.function.systemView(ViewId(viewId), cc.callContext)
+ updatedView <- NewStyle.function.updateSystemView(ViewId(viewId), updateJson.toUpdateViewJson, cc.callContext)
+ } yield {
+ (JSONFactory310.createViewJSON(updatedView), HttpCode.`200`(cc.callContext))
+ }
+ }
+ }
+
staticResourceDocs += ResourceDoc(
createCustomerAccountLink,
implementedInApiVersion,
diff --git a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala
index 8279312df..c47f679b6 100644
--- a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala
+++ b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala
@@ -28,23 +28,22 @@ package code.api.v5_0_0
import java.lang
import java.util.Date
-import code.api.util.APIUtil.{stringOptionOrNull, stringOrNull}
+
+import code.api.util.APIUtil.{nullToString, stringOptionOrNull, stringOrNull}
import code.api.v1_2_1.BankRoutingJsonV121
-import code.api.v1_4_0.JSONFactory1_4_0.{CustomerFaceImageJson, MetaJsonV140}
import code.api.v1_3_0.JSONFactory1_3_0.{cardActionsToString, createAccountJson, createPinResetJson, createReplacementJson}
import code.api.v1_3_0.{PinResetJSON, ReplacementJSON}
-import code.api.v1_4_0.JSONFactory1_4_0.CustomerFaceImageJson
+import code.api.v1_4_0.JSONFactory1_4_0.{CustomerFaceImageJson, MetaJsonV140}
import code.api.v2_1_0.CustomerCreditRatingJSON
import code.api.v3_0_0.{AdapterInfoJsonV300, CustomerAttributeResponseJsonV300, JSONFactory300}
import code.api.v3_1_0.{AccountAttributeResponseJson, AccountBasicV310, CustomerWithAttributesJsonV310, PhysicalCardWithAttributesJsonV310, PostConsentEntitlementJsonV310}
import code.api.v4_0_0.BankAttributeBankResponseJsonV400
import code.bankattribute.BankAttribute
import code.customeraccountlinks.CustomerAccountLinkTrait
-import com.openbankproject.commons.model.{AccountAttribute, AccountRouting, AccountRoutingJsonV121, AmountOfMoneyJsonV121, Bank, BankAccount, CardAttribute, Customer, CustomerAttribute, InboundAdapterInfoInternal, InboundStatusMessage, PhysicalCardTrait, User, UserAuthContext, UserAuthContextUpdate, View, ViewBasic}
+import com.openbankproject.commons.model.{AccountAttribute, AccountRouting, AccountRoutingJsonV121, AmountOfMoneyJsonV121, Bank, BankAccount, CardAttribute, CreateViewJson, Customer, CustomerAttribute, InboundAdapterInfoInternal, InboundStatusMessage, PhysicalCardTrait, UpdateViewJSON, User, UserAuthContext, UserAuthContextUpdate, View, ViewBasic}
import net.liftweb.json.JsonAST.JValue
import net.liftweb.util.Helpers
-import scala.collection.immutable
import scala.collection.immutable.List
case class PostBankJson500(
@@ -53,8 +52,7 @@ case class PostBankJson500(
full_name: Option[String],
logo: Option[String],
website: Option[String],
- bank_routings: Option[List[BankRoutingJsonV121]],
- attributes: Option[List[BankAttributeBankResponseJsonV400]]
+ bank_routings: Option[List[BankRoutingJsonV121]]
)
case class BankJson500(
@@ -78,6 +76,7 @@ case class CreateAccountRequestJsonV500(
case class PostCustomerJsonV500(
legal_name: String,
+ customer_number: Option[String] = None,
mobile_phone_number: String,
email: Option[String] = None,
face_image: Option[CustomerFaceImageJson] = None,
@@ -381,6 +380,147 @@ case class AdapterInfoJsonV500(
)
+case class CreateViewJsonV500(
+ name: String,
+ description: String,
+ metadata_view: String,
+ is_public: Boolean,
+ which_alias_to_use: String,
+ hide_metadata_if_alias_used: Boolean,
+ allowed_actions : List[String],
+ can_grant_access_to_views : Option[List[String]] = None,
+ can_revoke_access_to_views : Option[List[String]] = None
+ ) {
+ def toCreateViewJson = CreateViewJson(
+ name = this.name,
+ description = this.description,
+ metadata_view = this.metadata_view,
+ is_public = this.is_public,
+ which_alias_to_use = this.which_alias_to_use,
+ hide_metadata_if_alias_used = this.hide_metadata_if_alias_used,
+ allowed_actions = this.allowed_actions,
+ can_grant_access_to_views = this.can_grant_access_to_views,
+ can_revoke_access_to_views = this.can_revoke_access_to_views
+ )
+}
+case class UpdateViewJsonV500(
+ description: String,
+ metadata_view: String,
+ is_public: Boolean,
+ is_firehose: Option[Boolean] = None,
+ which_alias_to_use: String,
+ hide_metadata_if_alias_used: Boolean,
+ allowed_actions: List[String],
+ can_grant_access_to_views : Option[List[String]] = None,
+ can_revoke_access_to_views : Option[List[String]] = None
+ ) {
+ def toUpdateViewJson = UpdateViewJSON(
+ description = this.description,
+ metadata_view = this.metadata_view,
+ is_public = this.is_public,
+ is_firehose = this.is_firehose,
+ which_alias_to_use = this.which_alias_to_use,
+ hide_metadata_if_alias_used = this.hide_metadata_if_alias_used,
+ allowed_actions = this.allowed_actions,
+ can_grant_access_to_views = this.can_grant_access_to_views,
+ can_revoke_access_to_views = this.can_revoke_access_to_views
+ )
+}
+case class ViewsJsonV500(views : List[ViewJsonV500])
+
+case class ViewIdJsonV500(id: String)
+case class ViewsIdsJsonV500(views : List[ViewIdJsonV500])
+
+case class ViewJsonV500(
+ val id: String,
+ val short_name: String,
+ val description: String,
+ val metadata_view: String,
+ val is_public: Boolean,
+ val is_system: Boolean,
+ val is_firehose: Option[Boolean] = None,
+ val alias: String,
+ val hide_metadata_if_alias_used: Boolean,
+ val can_grant_access_to_views : List[String],
+ val can_revoke_access_to_views : List[String],
+ val can_add_comment : Boolean,
+ val can_add_corporate_location : Boolean,
+ val can_add_image : Boolean,
+ val can_add_image_url: Boolean,
+ val can_add_more_info: Boolean,
+ val can_add_open_corporates_url : Boolean,
+ val can_add_physical_location : Boolean,
+ val can_add_private_alias : Boolean,
+ val can_add_public_alias : Boolean,
+ val can_add_tag : Boolean,
+ val can_add_url: Boolean,
+ val can_add_where_tag : Boolean,
+ val can_delete_comment: Boolean,
+ val can_add_counterparty : Boolean,
+ val can_delete_corporate_location : Boolean,
+ val can_delete_image : Boolean,
+ val can_delete_physical_location : Boolean,
+ val can_delete_tag : Boolean,
+ val can_delete_where_tag : Boolean,
+ val can_edit_owner_comment: Boolean,
+ val can_see_bank_account_balance: Boolean,
+ val can_query_available_funds: Boolean,
+ val can_see_bank_account_bank_name: Boolean,
+ val can_see_bank_account_currency: Boolean,
+ val can_see_bank_account_iban: Boolean,
+ val can_see_bank_account_label: Boolean,
+ val can_see_bank_account_national_identifier: Boolean,
+ val can_see_bank_account_number: Boolean,
+ val can_see_bank_account_owners: Boolean,
+ val can_see_bank_account_swift_bic: Boolean,
+ val can_see_bank_account_type: Boolean,
+ val can_see_comments: Boolean,
+ val can_see_corporate_location: Boolean,
+ val can_see_image_url: Boolean,
+ val can_see_images: Boolean,
+ val can_see_more_info: Boolean,
+ val can_see_open_corporates_url: Boolean,
+ val can_see_other_account_bank_name: Boolean,
+ val can_see_other_account_iban: Boolean,
+ val can_see_other_account_kind: Boolean,
+ val can_see_other_account_metadata: Boolean,
+ val can_see_other_account_national_identifier: Boolean,
+ val can_see_other_account_number: Boolean,
+ val can_see_other_account_swift_bic: Boolean,
+ val can_see_owner_comment: Boolean,
+ val can_see_physical_location: Boolean,
+ val can_see_private_alias: Boolean,
+ val can_see_public_alias: Boolean,
+ val can_see_tags: Boolean,
+ val can_see_transaction_amount: Boolean,
+ val can_see_transaction_balance: Boolean,
+ val can_see_transaction_currency: Boolean,
+ val can_see_transaction_description: Boolean,
+ val can_see_transaction_finish_date: Boolean,
+ val can_see_transaction_metadata: Boolean,
+ val can_see_transaction_other_bank_account: Boolean,
+ val can_see_transaction_start_date: Boolean,
+ val can_see_transaction_this_bank_account: Boolean,
+ val can_see_transaction_type: Boolean,
+ val can_see_url: Boolean,
+ val can_see_where_tag: Boolean,
+ //V300 new
+ val can_see_bank_routing_scheme: Boolean,
+ val can_see_bank_routing_address: Boolean,
+ val can_see_bank_account_routing_scheme: Boolean,
+ val can_see_bank_account_routing_address: Boolean,
+ val can_see_other_bank_routing_scheme: Boolean,
+ val can_see_other_bank_routing_address: Boolean,
+ val can_see_other_account_routing_scheme: Boolean,
+ val can_see_other_account_routing_address: Boolean,
+ val can_add_transaction_request_to_own_account: Boolean, //added following two for payments
+ val can_add_transaction_request_to_any_account: Boolean,
+ val can_see_bank_account_credit_limit: Boolean,
+ val can_create_direct_debit: Boolean,
+ val can_create_standing_order: Boolean
+ )
+
+
object JSONFactory500 {
def createUserAuthContextJson(userAuthContext: UserAuthContext): UserAuthContextJsonV500 = {
@@ -579,7 +719,7 @@ object JSONFactory500 {
enabled = card.enabled,
cancelled = card.cancelled,
on_hot_list = card.onHotList,
- technology = stringOrNull(card.technology),
+ technology = nullToString(card.technology),
networks = card.networks,
allows = card.allows.map(cardActionsToString).toList,
account = createAccountJson(card.account, user),
@@ -604,7 +744,116 @@ object JSONFactory500 {
def createCustomerAccountLinksJon(customerAccountLinks: List[CustomerAccountLinkTrait]): CustomerAccountLinksJson = {
CustomerAccountLinksJson(customerAccountLinks.map(createCustomerAccountLinkJson))
- }
+ }
+
+
+
+ def createViewJsonV500(view : View) : ViewJsonV500 = {
+ val alias =
+ if(view.usePublicAliasIfOneExists)
+ "public"
+ else if(view.usePrivateAliasIfOneExists)
+ "private"
+ else
+ ""
+
+ ViewJsonV500(
+ id = view.viewId.value,
+ short_name = stringOrNull(view.name),
+ description = stringOrNull(view.description),
+ metadata_view= view.metadataView,
+ is_public = view.isPublic,
+ is_system = view.isSystem,
+ alias = alias,
+ hide_metadata_if_alias_used = view.hideOtherAccountMetadataIfAlias,
+ can_add_comment = view.canAddComment,
+ can_add_corporate_location = view.canAddCorporateLocation,
+ can_add_image = view.canAddImage,
+ can_add_image_url = view.canAddImageURL,
+ can_add_more_info = view.canAddMoreInfo,
+ can_add_open_corporates_url = view.canAddOpenCorporatesUrl,
+ can_add_physical_location = view.canAddPhysicalLocation,
+ can_add_private_alias = view.canAddPrivateAlias,
+ can_add_public_alias = view.canAddPublicAlias,
+ can_add_tag = view.canAddTag,
+ can_add_url = view.canAddURL,
+ can_add_where_tag = view.canAddWhereTag,
+ can_delete_comment = view.canDeleteComment,
+ can_add_counterparty = view.canAddCounterparty,
+ can_delete_corporate_location = view.canDeleteCorporateLocation,
+ can_delete_image = view.canDeleteImage,
+ can_delete_physical_location = view.canDeletePhysicalLocation,
+ can_delete_tag = view.canDeleteTag,
+ can_delete_where_tag = view.canDeleteWhereTag,
+ can_edit_owner_comment = view.canEditOwnerComment,
+ can_see_bank_account_balance = view.canSeeBankAccountBalance,
+ can_query_available_funds = view.canQueryAvailableFunds,
+ can_see_bank_account_bank_name = view.canSeeBankAccountBankName,
+ can_see_bank_account_currency = view.canSeeBankAccountCurrency,
+ can_see_bank_account_iban = view.canSeeBankAccountIban,
+ can_see_bank_account_label = view.canSeeBankAccountLabel,
+ can_see_bank_account_national_identifier = view.canSeeBankAccountNationalIdentifier,
+ can_see_bank_account_number = view.canSeeBankAccountNumber,
+ can_see_bank_account_owners = view.canSeeBankAccountOwners,
+ can_see_bank_account_swift_bic = view.canSeeBankAccountSwift_bic,
+ can_see_bank_account_type = view.canSeeBankAccountType,
+ can_see_comments = view.canSeeComments,
+ can_see_corporate_location = view.canSeeCorporateLocation,
+ can_see_image_url = view.canSeeImageUrl,
+ can_see_images = view.canSeeImages,
+ can_see_more_info = view.canSeeMoreInfo,
+ can_see_open_corporates_url = view.canSeeOpenCorporatesUrl,
+ can_see_other_account_bank_name = view.canSeeOtherAccountBankName,
+ can_see_other_account_iban = view.canSeeOtherAccountIBAN,
+ can_see_other_account_kind = view.canSeeOtherAccountKind,
+ can_see_other_account_metadata = view.canSeeOtherAccountMetadata,
+ can_see_other_account_national_identifier = view.canSeeOtherAccountNationalIdentifier,
+ can_see_other_account_number = view.canSeeOtherAccountNumber,
+ can_see_other_account_swift_bic = view.canSeeOtherAccountSWIFT_BIC,
+ can_see_owner_comment = view.canSeeOwnerComment,
+ can_see_physical_location = view.canSeePhysicalLocation,
+ can_see_private_alias = view.canSeePrivateAlias,
+ can_see_public_alias = view.canSeePublicAlias,
+ can_see_tags = view.canSeeTags,
+ can_see_transaction_amount = view.canSeeTransactionAmount,
+ can_see_transaction_balance = view.canSeeTransactionBalance,
+ can_see_transaction_currency = view.canSeeTransactionCurrency,
+ can_see_transaction_description = view.canSeeTransactionDescription,
+ can_see_transaction_finish_date = view.canSeeTransactionFinishDate,
+ can_see_transaction_metadata = view.canSeeTransactionMetadata,
+ can_see_transaction_other_bank_account = view.canSeeTransactionOtherBankAccount,
+ can_see_transaction_start_date = view.canSeeTransactionStartDate,
+ can_see_transaction_this_bank_account = view.canSeeTransactionThisBankAccount,
+ can_see_transaction_type = view.canSeeTransactionType,
+ can_see_url = view.canSeeUrl,
+ can_see_where_tag = view.canSeeWhereTag,
+ //V300 new
+ can_see_bank_routing_scheme = view.canSeeBankRoutingScheme,
+ can_see_bank_routing_address = view.canSeeBankRoutingAddress,
+ can_see_bank_account_routing_scheme = view.canSeeBankAccountRoutingScheme,
+ can_see_bank_account_routing_address = view.canSeeBankAccountRoutingAddress,
+ can_see_other_bank_routing_scheme = view.canSeeOtherBankRoutingScheme,
+ can_see_other_bank_routing_address = view.canSeeOtherBankRoutingAddress,
+ can_see_other_account_routing_scheme = view.canSeeOtherAccountRoutingScheme,
+ can_see_other_account_routing_address= view.canSeeOtherAccountRoutingAddress,
+ can_add_transaction_request_to_own_account = view.canAddTransactionRequestToOwnAccount, //added following two for payments
+ can_add_transaction_request_to_any_account = view.canAddTransactionRequestToAnyAccount,
+ can_see_bank_account_credit_limit = view.canSeeBankAccountCreditLimit,
+ can_create_direct_debit = view.canCreateDirectDebit,
+ can_create_standing_order = view.canCreateStandingOrder,
+ // Version 5.0.0
+ can_grant_access_to_views = view.canGrantAccessToViews.getOrElse(Nil),
+ can_revoke_access_to_views = view.canRevokeAccessToViews.getOrElse(Nil),
+ )
+ }
+ def createViewsJsonV500(views : List[View]) : ViewsJsonV500 = {
+ ViewsJsonV500(views.map(createViewJsonV500))
+ }
+
+
+ def createViewsIdsJsonV500(views : List[View]) : ViewsIdsJsonV500 = {
+ ViewsIdsJsonV500(views.map(i => ViewIdJsonV500(i.viewId.value)))
+ }
def createAdapterInfoJson(inboundAdapterInfoInternal: InboundAdapterInfoInternal, startTime: Long): AdapterInfoJsonV500 = {
AdapterInfoJsonV500(
diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala
index 9e44598b7..7812c087f 100644
--- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala
+++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala
@@ -1945,7 +1945,31 @@ trait Connector extends MdcLoggable {
nameSuffix: String,
callContext: Option[CallContext],
): OBPReturnType[Box[Customer]] = Future{(Failure(setUnimplementedError), callContext)}
-
+
+ def createCustomerC2(
+ bankId: BankId,
+ legalName: String,
+ customerNumber: String,
+ mobileNumber: String,
+ email: String,
+ faceImage:
+ CustomerFaceImageTrait,
+ dateOfBirth: Date,
+ relationshipStatus: String,
+ dependents: Int,
+ dobOfDependents: List[Date],
+ highestEducationAttained: String,
+ employmentStatus: String,
+ kycStatus: Boolean,
+ lastOkDate: Date,
+ creditRating: Option[CreditRatingTrait],
+ creditLimit: Option[AmountOfMoneyTrait],
+ title: String,
+ branchId: String,
+ nameSuffix: String,
+ callContext: Option[CallContext],
+ ): OBPReturnType[Box[Customer]] = Future{(Failure(setUnimplementedError), callContext)}
+
def updateCustomerScaData(customerId: String,
mobileNumber: Option[String],
email: Option[String],
diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala
index c0b64a85a..f301ae241 100644
--- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala
+++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala
@@ -873,6 +873,60 @@ object LocalMappedConnector extends Connector with MdcLoggable {
}
private def findFirehoseAccounts(bankId: BankId, ordering: SQLSyntax, limit: Int, offset: Int)(implicit session: DBSession = AutoSession) = {
+ def parseOwners(owners: String): List[FastFirehoseOwners] = {
+ if(!owners.isEmpty) {
+ transformString(owners).map {
+ i =>
+ FastFirehoseOwners(
+ user_id = i("user_id").mkString(""),
+ provider = i("provider").mkString(""),
+ user_name = i("user_name").mkString("")
+ )
+ }
+ } else {
+ List()
+ }
+ }
+ def parseRoutings(owners: String): List[FastFirehoseRoutings] = {
+ if(!owners.isEmpty) {
+ transformString(owners).map {
+ i =>
+ FastFirehoseRoutings(
+ bank_id = i("bank_id").mkString(""),
+ account_id = i("account_id").mkString("")
+ )
+ }
+ } else {
+ List()
+ }
+ }
+ def parseAttributes(owners: String): List[FastFirehoseAttributes] = {
+ if(!owners.isEmpty) {
+ transformString(owners).map {
+ i =>
+ FastFirehoseAttributes(
+ `type` = i("type").mkString(""),
+ code = i("code").mkString(""),
+ value = i("value").mkString("")
+ )
+ }
+ } else {
+ List()
+ }
+ }
+ def transformString(owners: String): List[Map[String, List[String]]] = {
+ val splitToRows: List[String] = owners.split("::").toList
+ val keyValuePairs: List[List[(String, String)]] = splitToRows.map { i=>
+ i.split(",").toList.map {
+ x =>
+ val keyValue: Array[String] = x.split(":")
+ if(keyValue.size == 2) (keyValue(0), keyValue(1)) else (keyValue(0), "")
+ }
+ }
+ val maps: List[Map[String, List[String]]] = keyValuePairs.map(_.groupBy(_._1).map { case (k,v) => (k,v.map(_._2))})
+ maps
+ }
+
val sqlResult = sql"""
|select
| mappedbankaccount.theaccountid as account_id,
@@ -887,7 +941,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
| ||resourceuser.provider_
| ||',user_name:'
| ||resourceuser.name_,
- | ',') as owners
+ | '::') as owners
| from resourceuser
| where
| resourceuser.id = mapperaccountholders.user_c
@@ -901,7 +955,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
| ||bankaccountrouting.bankid
| ||',account_id:'
| ||bankaccountrouting.accountid,
- | ','
+ | '::'
| ) as account_routings
| from bankaccountrouting
| where
@@ -915,7 +969,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
| ||mappedaccountattribute.mcode
| ||',value:'
| ||mappedaccountattribute.mvalue,
- | ',') as account_attributes
+ | '::') as account_attributes
| from mappedaccountattribute
| where
| mappedaccountattribute.maccountid = mappedbankaccount.theaccountid
@@ -930,28 +984,31 @@ object LocalMappedConnector extends Connector with MdcLoggable {
|
|
|""".stripMargin
- .map(
+ .map {
rs => // Map result to case class
+ val owners = parseOwners(rs.stringOpt(5).map(_.toString).getOrElse(""))
+ val routings = parseRoutings(rs.stringOpt(9).map(_.toString).getOrElse(""))
+ val attributes = parseAttributes(rs.stringOpt(10).map(_.toString).getOrElse(""))
FastFirehoseAccount(
id = rs.stringOpt(1).map(_.toString).getOrElse(null),
- bankId= rs.stringOpt(2).map(_.toString).getOrElse(null),
- label= rs.stringOpt(3).map(_.toString).getOrElse(null),
+ bankId = rs.stringOpt(2).map(_.toString).getOrElse(null),
+ label = rs.stringOpt(3).map(_.toString).getOrElse(null),
number = rs.stringOpt(4).map(_.toString).getOrElse(null),
- owners = rs.stringOpt(5).map(_.toString).getOrElse(null),
- productCode = rs.stringOpt(6).map(_.toString).getOrElse(null),
+ owners = owners,
+ productCode = rs.stringOpt(6).map(_.toString).getOrElse(null),
balance = AmountOfMoney(
currency = rs.stringOpt(7).map(_.toString).getOrElse(null),
- amount = rs.bigIntOpt(8).map( a =>
+ amount = rs.bigIntOpt(8).map(a =>
Helper.smallestCurrencyUnitToBigDecimal(
a.longValue(),
rs.stringOpt(7).getOrElse("EUR")
).toString()
).getOrElse(null)
),
- accountRoutings = rs.stringOpt(9).map(_.toString).getOrElse(null),
- accountAttributes = rs.stringOpt(10).map(_.toString).getOrElse(null)
+ accountRoutings = routings,
+ accountAttributes = attributes
)
- ).list().apply()
+ }.list().apply()
sqlResult
}
@@ -3434,6 +3491,52 @@ object LocalMappedConnector extends Connector with MdcLoggable {
), callContext)
}
+ override def createCustomerC2(
+ bankId: BankId,
+ legalName: String,
+ customerNumber: String,
+ mobileNumber: String,
+ email: String,
+ faceImage:
+ CustomerFaceImageTrait,
+ dateOfBirth: Date,
+ relationshipStatus: String,
+ dependents: Int,
+ dobOfDependents: List[Date],
+ highestEducationAttained: String,
+ employmentStatus: String,
+ kycStatus: Boolean,
+ lastOkDate: Date,
+ creditRating: Option[CreditRatingTrait],
+ creditLimit: Option[AmountOfMoneyTrait],
+ title: String,
+ branchId: String,
+ nameSuffix: String,
+ callContext: Option[CallContext]
+ ): OBPReturnType[Box[Customer]] = Future {
+ (CustomerX.customerProvider.vend.addCustomer(
+ bankId,
+ customerNumber,
+ legalName,
+ mobileNumber,
+ email,
+ faceImage,
+ dateOfBirth,
+ relationshipStatus,
+ dependents,
+ dobOfDependents,
+ highestEducationAttained,
+ employmentStatus,
+ kycStatus,
+ lastOkDate,
+ creditRating,
+ creditLimit,
+ title,
+ branchId,
+ nameSuffix
+ ), callContext)
+ }
+
override def updateCustomerScaData(customerId: String,
mobileNumber: Option[String],
email: Option[String],
diff --git a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala
index e644ad523..e1654d828 100644
--- a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala
+++ b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala
@@ -125,6 +125,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
.flatMap(consumerIdToPrimaryKey)
.map(By(MappedMetric.consumerId, _) )
+ val bankId = queryParams.collect { case OBPBankId(value) => Like(MappedMetric.url, s"%banks/$value%") }.headOption
val userId = queryParams.collect { case OBPUserId(value) => By(MappedMetric.userId, value) }.headOption
val url = queryParams.collect { case OBPUrl(value) => By(MappedMetric.url, value) }.headOption
val appName = queryParams.collect { case OBPAppName(value) => By(MappedMetric.appName, value) }.headOption
@@ -149,6 +150,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
ordering,
consumerId.toSeq,
userId.toSeq,
+ bankId.toSeq,
url.toSeq,
appName.toSeq,
implementedInVersion.toSeq,
diff --git a/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala b/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala
index fc53e3a85..5e3145c46 100644
--- a/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala
+++ b/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala
@@ -85,6 +85,9 @@ class ResourceUser extends LongKeyedMapper[ResourceUser] with User with ManyToMa
override def defaultValue = false
}
object LastMarketingAgreementSignedDate extends MappedDate(this)
+ object LastUsedLocale extends MappedString(this, 10) {
+ override def defaultValue = null
+ }
def emailAddress = {
val e = email.get
@@ -114,6 +117,7 @@ class ResourceUser extends LongKeyedMapper[ResourceUser] with User with ManyToMa
override def createdByUserInvitationId = if(CreatedByUserInvitationId.get == null) None else if (CreatedByUserInvitationId.get.isEmpty) None else Some(CreatedByUserInvitationId.get) //null --> None
override def isDeleted: Option[Boolean] = if(IsDeleted.jdbcFriendly(IsDeleted.calcFieldName) == null) None else Some(IsDeleted.get) // null --> None
override def lastMarketingAgreementSignedDate: Option[Date] = if(IsDeleted.jdbcFriendly(LastMarketingAgreementSignedDate.calcFieldName) == null) None else Some(LastMarketingAgreementSignedDate.get) // null --> None
+ override def lastUsedLocale: Option[String] = if(LastUsedLocale.get == null) None else Some(LastUsedLocale.get) // null --> None
}
object ResourceUser extends ResourceUser with LongKeyedMetaMapper[ResourceUser]{
diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataViews.scala b/obp-api/src/main/scala/code/remotedata/RemotedataViews.scala
index 0273b4900..6b904b47d 100644
--- a/obp-api/src/main/scala/code/remotedata/RemotedataViews.scala
+++ b/obp-api/src/main/scala/code/remotedata/RemotedataViews.scala
@@ -69,6 +69,10 @@ object RemotedataViews extends ObpActorInit with Views {
def systemViewFuture(viewId : ViewId) : Future[Box[View]] =
(actor ? cc.systemViewFuture(viewId)).mapTo[Box[View]]
+ def getSystemViews() : Future[List[View]] =
+ (actor ? cc.getSystemViews()).mapTo[List[View]]
+
+
def createView(bankAccountId: BankIdAccountId, view: CreateViewJson): Box[View] = getValueFromFuture(
(actor ? cc.createView(bankAccountId, view)).mapTo[Box[View]]
)
diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataViewsActor.scala b/obp-api/src/main/scala/code/remotedata/RemotedataViewsActor.scala
index 4b49b6941..3923b2a33 100644
--- a/obp-api/src/main/scala/code/remotedata/RemotedataViewsActor.scala
+++ b/obp-api/src/main/scala/code/remotedata/RemotedataViewsActor.scala
@@ -64,6 +64,10 @@ class RemotedataViewsActor extends Actor with ObpActorHelper with MdcLoggable {
case cc.systemView(viewId: ViewId) =>
logger.debug("view(" + viewId + ")")
sender ! (mapper.systemView(viewId))
+
+ case cc.getSystemViews() =>
+ logger.debug("getSystemViews()")
+ sender ! (mapper.getSystemViews())
case cc.customViewFuture(viewId: ViewId, bankAccountId: BankIdAccountId) =>
logger.debug("customViewFuture(" + viewId +", "+ bankAccountId + ")")
diff --git a/obp-api/src/main/scala/code/views/MapperViews.scala b/obp-api/src/main/scala/code/views/MapperViews.scala
index 0f606b142..8f0895c01 100644
--- a/obp-api/src/main/scala/code/views/MapperViews.scala
+++ b/obp-api/src/main/scala/code/views/MapperViews.scala
@@ -340,6 +340,15 @@ object MapperViews extends Views with MdcLoggable {
def systemView(viewId : ViewId) : Box[View] = {
ViewDefinition.findSystemView(viewId.value)
}
+ def getSystemViews() : Future[List[View]] = {
+ Future {
+ ViewDefinition.findAll(
+ NullRef(ViewDefinition.bank_id),
+ NullRef(ViewDefinition.account_id),
+ By(ViewDefinition.isSystem_, true)
+ )
+ }
+ }
def systemViewFuture(viewId : ViewId) : Future[Box[View]] = {
Future {
systemView(viewId)
diff --git a/obp-api/src/main/scala/code/views/Views.scala b/obp-api/src/main/scala/code/views/Views.scala
index 1793b371e..6776966d1 100644
--- a/obp-api/src/main/scala/code/views/Views.scala
+++ b/obp-api/src/main/scala/code/views/Views.scala
@@ -55,6 +55,7 @@ trait Views {
def systemView(viewId : ViewId) : Box[View]
def customViewFuture(viewId : ViewId, bankAccountId: BankIdAccountId) : Future[Box[View]]
def systemViewFuture(viewId : ViewId) : Future[Box[View]]
+ def getSystemViews(): Future[List[View]]
//always return a view id String, not error here.
def getMetadataViewId(bankAccountId: BankIdAccountId, viewId : ViewId) = Views.views.vend.customView(viewId, bankAccountId).map(_.metadataView).openOr(viewId.value)
@@ -154,6 +155,7 @@ class RemotedataViewsCaseClasses {
def apply(viewId: ViewId, bankAccountId: BankIdAccountId): Box[View] = this (viewId, bankAccountId)
}
case class systemView(viewId : ViewId)
+ case class getSystemViews()
case class customViewFuture(viewId : ViewId, bankAccountId: BankIdAccountId)
case class systemViewFuture(viewId : ViewId)
case class getOrCreateAccountView(account: BankIdAccountId, viewName: String)
diff --git a/obp-api/src/main/scala/code/views/system/ViewDefinition.scala b/obp-api/src/main/scala/code/views/system/ViewDefinition.scala
index 87f50fc2d..21e62737e 100644
--- a/obp-api/src/main/scala/code/views/system/ViewDefinition.scala
+++ b/obp-api/src/main/scala/code/views/system/ViewDefinition.scala
@@ -49,6 +49,12 @@ class ViewDefinition extends View with LongKeyedMapper[ViewDefinition] with Many
object hideOtherAccountMetadataIfAlias_ extends MappedBoolean(this){
override def defaultValue = false
}
+ object canGrantAccessToViews_ extends MappedText(this){
+ override def defaultValue = ""
+ }
+ object canRevokeAccessToViews_ extends MappedText(this){
+ override def defaultValue = ""
+ }
object canSeeTransactionThisBankAccount_ extends MappedBoolean(this){
override def defaultValue = false
}
@@ -303,6 +309,9 @@ class ViewDefinition extends View with LongKeyedMapper[ViewDefinition] with Many
isPublic_(viewData.is_public)
isFirehose_(viewData.is_firehose.getOrElse(false))
metadataView_(viewData.metadata_view)
+
+ canGrantAccessToViews_(viewData.can_grant_access_to_views.getOrElse(Nil).mkString(","))
+ canRevokeAccessToViews_(viewData.can_revoke_access_to_views.getOrElse(Nil).mkString(","))
val actions = viewData.allowed_actions
@@ -408,6 +417,19 @@ class ViewDefinition extends View with LongKeyedMapper[ViewDefinition] with Many
def usePublicAliasIfOneExists: Boolean = usePublicAliasIfOneExists_.get
def hideOtherAccountMetadataIfAlias: Boolean = hideOtherAccountMetadataIfAlias_.get
+ override def canGrantAccessToViews : Option[List[String]] = {
+ canGrantAccessToViews_.get == null || canGrantAccessToViews_.get.isEmpty() match {
+ case true => None
+ case _ => Some(canGrantAccessToViews_.get.split(",").toList.map(_.trim))
+ }
+ }
+ override def canRevokeAccessToViews : Option[List[String]] = {
+ canRevokeAccessToViews_.get == null || canRevokeAccessToViews_.get.isEmpty() match {
+ case true => None
+ case _ => Some(canRevokeAccessToViews_.get.split(",").toList.map(_.trim))
+ }
+ }
+
//reading access
//transaction fields
diff --git a/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala b/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala
index 61ed5b330..992dbdc3e 100644
--- a/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala
+++ b/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala
@@ -23,7 +23,7 @@ object MappedWebUiPropsProvider extends WebUiPropsProvider {
override def createOrUpdate(webUiProps: WebUiPropsT): Box[WebUiPropsT] = {
WebUiProps.find(By(WebUiProps.Name, webUiProps.name))
.or(Full(WebUiProps.create))
- .map(_.Name(webUiProps.name).Value(webUiProps.value).saveMe())
+ .map(_.Name(webUiProps.name.trim()).Value(webUiProps.value).saveMe())
}
override def delete(webUiPropsId: String):Box[Boolean] = WebUiProps.find(By(WebUiProps.WebUiPropsId, webUiPropsId)) match {
@@ -81,6 +81,6 @@ class WebUiProps extends WebUiPropsT with LongKeyedMapper[WebUiProps] with IdPK
}
object WebUiProps extends WebUiProps with LongKeyedMetaMapper[WebUiProps] {
- override def dbIndexes = UniqueIndex(WebUiPropsId) :: super.dbIndexes
+ override def dbIndexes = UniqueIndex(WebUiPropsId) :: UniqueIndex(Name) :: super.dbIndexes
}
diff --git a/obp-api/src/test/resources/frozen_type_meta_data b/obp-api/src/test/resources/frozen_type_meta_data
index 16644ec28..e88e048f6 100644
Binary files a/obp-api/src/test/resources/frozen_type_meta_data and b/obp-api/src/test/resources/frozen_type_meta_data differ
diff --git a/obp-api/src/test/scala/code/api/v2_2_0/API2_2_0Test.scala b/obp-api/src/test/scala/code/api/v2_2_0/API2_2_0Test.scala
index f70decf91..25a7fe76c 100644
--- a/obp-api/src/test/scala/code/api/v2_2_0/API2_2_0Test.scala
+++ b/obp-api/src/test/scala/code/api/v2_2_0/API2_2_0Test.scala
@@ -29,7 +29,7 @@ package code.api.v2_2_0
import code.api.Constant._
import _root_.net.liftweb.json.Serialization.write
import com.openbankproject.commons.model.ErrorMessage
-import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJson
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
import code.api.util.APIUtil.OAuth._
import code.api.v1_2._
import code.api.v1_2_1.UpdateViewJsonV121
@@ -67,7 +67,7 @@ class API2_2_0Test extends V220ServerSetup with DefaultUsers {
/********************* API test methods ********************/
//System view, owner
- val postBodySystemViewJson = createViewJson.copy(name=SYSTEM_OWNER_VIEW_ID)
+ val postBodySystemViewJson = createViewJsonV300.copy(name=SYSTEM_OWNER_VIEW_ID).toCreateViewJson
def randomBank : String = {
val banksJson = getBanksInfo.body.extract[BanksJSON]
@@ -90,7 +90,7 @@ class API2_2_0Test extends V220ServerSetup with DefaultUsers {
viewsIdsToGrant
}
- def randomView(isPublic: Boolean, alias: String) = createViewJson
+ def randomView(isPublic: Boolean, alias: String) = createViewJsonV300.toCreateViewJson
def getBanksInfo : APIResponse = {
diff --git a/obp-api/src/test/scala/code/api/v3_0_0/ViewsTests.scala b/obp-api/src/test/scala/code/api/v3_0_0/ViewsTests.scala
index 2a11ce5ca..1d6df40d9 100644
--- a/obp-api/src/test/scala/code/api/v3_0_0/ViewsTests.scala
+++ b/obp-api/src/test/scala/code/api/v3_0_0/ViewsTests.scala
@@ -53,9 +53,9 @@ class ViewsTests extends V300ServerSetup {
//Custom view, name starts from `_`
- val postBodyViewJson = createViewJson
+ val postBodyViewJson = createViewJsonV300.toCreateViewJson
//System view, owner
- val postBodySystemViewJson = createViewJson.copy(name=SYSTEM_OWNER_VIEW_ID).copy(metadata_view = SYSTEM_OWNER_VIEW_ID)
+ val postBodySystemViewJson = createViewJsonV300.copy(name=SYSTEM_OWNER_VIEW_ID).copy(metadata_view = SYSTEM_OWNER_VIEW_ID).toCreateViewJson
def getAccountViews(bankId : String, accountId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
val request = v3_0Request / "banks" / bankId / "accounts" / accountId / "views" <@(consumerAndToken)
diff --git a/obp-api/src/test/scala/code/api/v3_1_0/SystemViewsTests.scala b/obp-api/src/test/scala/code/api/v3_1_0/SystemViewsTests.scala
index 14315bc7d..3f5a853f0 100644
--- a/obp-api/src/test/scala/code/api/v3_1_0/SystemViewsTests.scala
+++ b/obp-api/src/test/scala/code/api/v3_1_0/SystemViewsTests.scala
@@ -72,7 +72,7 @@ class SystemViewsTests extends V310ServerSetup {
// Custom view, name starts from `_`
// System view, owner
val randomSystemViewId = APIUtil.generateUUID()
- val postBodySystemViewJson = createSystemViewJson.copy(name=randomSystemViewId).copy(metadata_view = randomSystemViewId)
+ val postBodySystemViewJson = createSystemViewJsonV300.copy(name=randomSystemViewId).copy(metadata_view = randomSystemViewId).toCreateViewJson
val systemViewId = MapperViews.getNewViewPermalink(postBodySystemViewJson.name)
def getSystemView(viewId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
diff --git a/obp-api/src/test/scala/code/api/v4_0_0/AccountAccessTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/AccountAccessTest.scala
index 232c3eac5..324b7dc2f 100644
--- a/obp-api/src/test/scala/code/api/v4_0_0/AccountAccessTest.scala
+++ b/obp-api/src/test/scala/code/api/v4_0_0/AccountAccessTest.scala
@@ -2,7 +2,7 @@ package code.api.v4_0_0
import com.openbankproject.commons.model.ErrorMessage
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
-import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJson
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole
import com.openbankproject.commons.util.ApiVersion
@@ -37,7 +37,7 @@ class AccountAccessTest extends V400ServerSetup {
lazy val bankAccount = randomPrivateAccountViaEndpoint(bankId)
lazy val ownerView = randomOwnerViewPermalinkViaEndpoint(bankId, bankAccount)
lazy val postAccountAccessJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400("_test_view", false))
- lazy val postBodyViewJson = createViewJson
+ lazy val postBodyViewJson = createViewJsonV300.toCreateViewJson
def createAnAccount(bankId: String, user: Option[(Consumer,Token)]): CreateAccountResponseJsonV310 = {
val addAccountJson = SwaggerDefinitionsJSON.createAccountRequestJsonV310.copy(user_id = resourceUser1.userId, balance = AmountOfMoneyJsonV121("EUR","0"))
diff --git a/obp-api/src/test/scala/code/api/v4_0_0/DeleteAccountCascadeTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/DeleteAccountCascadeTest.scala
index 78fc1d02c..bf77ecf97 100644
--- a/obp-api/src/test/scala/code/api/v4_0_0/DeleteAccountCascadeTest.scala
+++ b/obp-api/src/test/scala/code/api/v4_0_0/DeleteAccountCascadeTest.scala
@@ -1,7 +1,7 @@
package code.api.v4_0_0
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
-import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJson
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole
import code.api.util.ApiRole.CanDeleteAccountCascade
@@ -74,7 +74,7 @@ class DeleteAccountCascadeTest extends V400ServerSetup {
//it is an asynchronous process, need some time to be done.
TimeUnit.SECONDS.sleep(3)
- val postBodyView = createViewJson.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false)
+ val postBodyView = createViewJsonV300.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false).toCreateViewJson
createViewViaEndpoint(bankId, account.account_id, postBodyView, user1)
createAccountAttributeViaEndpoint(
diff --git a/obp-api/src/test/scala/code/api/v4_0_0/DeleteBankCascadeTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/DeleteBankCascadeTest.scala
index 3a555758d..42bd389da 100644
--- a/obp-api/src/test/scala/code/api/v4_0_0/DeleteBankCascadeTest.scala
+++ b/obp-api/src/test/scala/code/api/v4_0_0/DeleteBankCascadeTest.scala
@@ -1,7 +1,7 @@
package code.api.v4_0_0
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
-import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJson
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
import code.api.util.APIUtil.OAuth._
import code.api.util.{APIUtil, ApiRole}
import code.api.util.ApiRole.{CanDeleteAccountCascade, CanDeleteBankCascade}
@@ -76,7 +76,7 @@ class DeleteBankCascadeTest extends V400ServerSetup {
val account = response400.body.extract[CreateAccountResponseJsonV310]
account.account_id should not be empty
- val postBodyView = createViewJson.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false)
+ val postBodyView = createViewJsonV300.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false).toCreateViewJson
createViewViaEndpoint(bankId, account.account_id, postBodyView, user1)
createAccountAttributeViaEndpoint(
diff --git a/obp-api/src/test/scala/code/api/v4_0_0/V400ServerSetup.scala b/obp-api/src/test/scala/code/api/v4_0_0/V400ServerSetup.scala
index 63484a769..8a5be8e5f 100644
--- a/obp-api/src/test/scala/code/api/v4_0_0/V400ServerSetup.scala
+++ b/obp-api/src/test/scala/code/api/v4_0_0/V400ServerSetup.scala
@@ -4,7 +4,7 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import code.api.Constant._
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
-import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJson
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
import code.api.util.APIUtil.OAuth.{Consumer, Token, _}
import code.api.util.ApiRole.{CanCreateAccountAttributeAtOneBank, CanCreateCustomer, CanCreateProduct, _}
import code.api.util.{APIUtil, ApiRole}
@@ -359,7 +359,7 @@ trait V400ServerSetup extends ServerSetupWithTestData with DefaultUsers {
// Create to account
val toAccount = createAccountViaEndpoint(bank.bankId.value, addAccountJson2, user1)
// Create a custom view
- val customViewJson = createViewJson.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false)
+ val customViewJson = createViewJsonV300.copy(name = "_cascade_delete", metadata_view = "_cascade_delete", is_public = false).toCreateViewJson
val customView = createViewViaEndpoint(bank.bankId.value, fromAccount.account_id, customViewJson, user1)
// Grant access to the view
grantUserAccessToViewViaEndpoint(
diff --git a/obp-api/src/test/scala/code/api/v5_0_0/MetricsTest.scala b/obp-api/src/test/scala/code/api/v5_0_0/MetricsTest.scala
new file mode 100644
index 000000000..25c2bcdf3
--- /dev/null
+++ b/obp-api/src/test/scala/code/api/v5_0_0/MetricsTest.scala
@@ -0,0 +1,96 @@
+/**
+Open Bank Project - API
+Copyright (C) 2011-2019, TESOBE GmbH.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+Email: contact@tesobe.com
+TESOBE GmbH.
+Osloer Strasse 16/17
+Berlin 13359, Germany
+
+This product includes software developed at
+TESOBE (http://www.tesobe.com/)
+
+ */
+package code.api.v5_0_0
+
+import code.api.util.APIUtil.OAuth._
+import code.api.util.ApiRole.CanGetMetricsAtOneBank
+import code.api.util.ErrorMessages.{UserHasMissingRoles, UserNotLoggedIn}
+import code.api.v2_1_0.MetricsJson
+import code.api.v5_0_0.APIMethods500.Implementations5_0_0
+import code.entitlement.Entitlement
+import code.setup.APIResponse
+import com.github.dwickern.macros.NameOf.nameOf
+import com.openbankproject.commons.model.ErrorMessage
+import com.openbankproject.commons.util.ApiVersion
+import org.scalatest.Tag
+
+class MetricsTest extends V500ServerSetup {
+ override def beforeAll(): Unit = {
+ super.beforeAll()
+ }
+
+ override def afterAll(): Unit = {
+ super.afterAll()
+ }
+
+ /**
+ * Test tags
+ * Example: To run tests with tag "getPermissions":
+ * mvn test -D tagsToInclude
+ *
+ * This is made possible by the scalatest maven plugin
+ */
+ object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString)
+ object ApiEndpoint1 extends Tag(nameOf(Implementations5_0_0.getMetricsAtBank))
+
+ lazy val bankId = testBankId1.value
+
+ def getMetrics(consumerAndToken: Option[(Consumer, Token)], bankId: String): APIResponse = {
+ val request = v5_0_0_Request / "management" / "metrics" / "banks" / bankId <@(consumerAndToken)
+ makeGetRequest(request)
+ }
+
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint1")
+ val response400 = getMetrics(None, bankId)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint1")
+ val response400 = getMetrics(user1, bankId)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message contains (UserHasMissingRoles + CanGetMetricsAtOneBank) should be (true)
+ }
+ }
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint1")
+ Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetMetricsAtOneBank.toString)
+ val response400 = getMetrics(user1, bankId)
+ Then("We should get a 200")
+ response400.code should equal(200)
+ response400.body.extract[MetricsJson]
+ }
+ }
+
+}
diff --git a/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala b/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala
new file mode 100644
index 000000000..4397ffa3f
--- /dev/null
+++ b/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala
@@ -0,0 +1,314 @@
+/**
+Open Bank Project - API
+Copyright (C) 2011-2019, TESOBE GmbH.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+Email: contact@tesobe.com
+TESOBE GmbH.
+Osloer Strasse 16/17
+Berlin 13359, Germany
+
+This product includes software developed at
+TESOBE (http://www.tesobe.com/)
+
+ */
+package code.api.v5_0_0
+
+import _root_.net.liftweb.json.Serialization.write
+import code.api.Constant._
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
+import code.api.util.APIUtil
+import code.api.util.APIUtil.OAuth._
+import code.api.util.ApiRole.{CanCreateSystemView, CanDeleteSystemView, CanGetSystemView, CanUpdateSystemView}
+import code.api.util.ErrorMessages.{UserHasMissingRoles, UserNotLoggedIn}
+import code.api.v5_0_0.APIMethods500.Implementations5_0_0
+import code.entitlement.Entitlement
+import code.setup.APIResponse
+import code.views.MapperViews
+import code.views.system.AccountAccess
+import com.github.dwickern.macros.NameOf.nameOf
+import com.openbankproject.commons.model.{CreateViewJson, ErrorMessage, UpdateViewJSON}
+import com.openbankproject.commons.util.ApiVersion
+import net.liftweb.mapper.By
+import org.scalatest.Tag
+
+import scala.collection.immutable.List
+
+class SystemViewsTests extends V500ServerSetup {
+ override def beforeAll(): Unit = {
+ super.beforeAll()
+ }
+
+ override def afterAll(): Unit = {
+ super.afterAll()
+ }
+
+ /**
+ * Test tags
+ * Example: To run tests with tag "getPermissions":
+ * mvn test -D tagsToInclude
+ *
+ * This is made possible by the scalatest maven plugin
+ */
+ object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString)
+ object ApiEndpoint1 extends Tag(nameOf(Implementations5_0_0.getSystemView))
+ object ApiEndpoint2 extends Tag(nameOf(Implementations5_0_0.createSystemView))
+ object ApiEndpoint3 extends Tag(nameOf(Implementations5_0_0.updateSystemView))
+ object ApiEndpoint4 extends Tag(nameOf(Implementations5_0_0.deleteSystemView))
+ object ApiEndpoint5 extends Tag(nameOf(Implementations5_0_0.getSystemViewsIds))
+
+ // Custom view, name starts from `_`
+ // System view, owner
+ val randomSystemViewId = APIUtil.generateUUID()
+ val postBodySystemViewJson = createSystemViewJsonV500
+ .copy(name=randomSystemViewId)
+ .copy(metadata_view = randomSystemViewId).toCreateViewJson
+ val systemViewId = MapperViews.getNewViewPermalink(postBodySystemViewJson.name)
+
+ def getSystemView(viewId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = v5_0_0_Request / "system-views" / viewId <@(consumerAndToken)
+ makeGetRequest(request)
+ }
+ def getSystemViewsIds(consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = v5_0_0_Request / "system-views-ids" <@(consumerAndToken)
+ makeGetRequest(request)
+ }
+ def postSystemView(view: CreateViewJson, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = (v5_0_0_Request / "system-views").POST <@(consumerAndToken)
+ makePostRequest(request, write(view))
+ }
+ def putSystemView(viewId : String, view: UpdateViewJSON, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = (v5_0_0_Request / "system-views" / viewId).PUT <@(consumerAndToken)
+ makePutRequest(request, write(view))
+ }
+ def deleteSystemView(viewId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = (v5_0_0_Request / "system-views" / viewId).DELETE <@(consumerAndToken)
+ makeDeleteRequest(request)
+ }
+ def createSystemView(viewId: String): Boolean = {
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateSystemView.toString)
+ val postBody = postBodySystemViewJson.copy(name=viewId).copy(metadata_view = viewId)
+ val response400 = postSystemView(postBody, user1)
+ response400.code == 201
+ }
+
+
+
+ feature(s"test $ApiEndpoint2 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint2")
+ val response400 = postSystemView(postBodySystemViewJson, None)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint2 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint2")
+ val response400 = postSystemView(postBodySystemViewJson, user1)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanCreateSystemView)
+ }
+ }
+ feature(s"test $ApiEndpoint2 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint2")
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateSystemView.toString)
+ val response400 = postSystemView(postBodySystemViewJson, user1)
+ Then("We should get a 201")
+ response400.code should equal(201)
+ response400.body.extract[ViewJsonV500]
+ }
+ }
+
+
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint1")
+ val response400 = getSystemView("", None)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint1")
+ val response400 = getSystemView("", user1)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetSystemView)
+ }
+ }
+ feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ val viewId = APIUtil.generateUUID()
+ createSystemView(viewId)
+ When(s"We make a request $ApiEndpoint1")
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetSystemView.toString)
+ val response400 = getSystemView(viewId, user1)
+ Then("We should get a 200")
+ response400.code should equal(200)
+ response400.body.extract[ViewJsonV500]
+ }
+ }
+
+
+ feature(s"test $ApiEndpoint3 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint3, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint3")
+ val response400 = getSystemView("", None)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint3 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint3, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint3")
+ val response400 = getSystemView("", user1)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetSystemView)
+ }
+ }
+ feature(s"test $ApiEndpoint3 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("we will update a view on a bank account", ApiEndpoint3, VersionOfApi) {
+ val updatedViewDescription = "aloha"
+ val updatedAliasToUse = "public"
+ val allowedActions = List("can_see_images", "can_delete_comment")
+
+ def viewUpdateJson(originalView : ViewJsonV500) = {
+ //it's not perfect, assumes too much about originalView (i.e. randomView(true, ""))
+ UpdateViewJSON(
+ description = updatedViewDescription,
+ metadata_view = originalView.metadata_view,
+ is_public = originalView.is_public,
+ is_firehose = Some(true),
+ which_alias_to_use = updatedAliasToUse,
+ hide_metadata_if_alias_used = !originalView.hide_metadata_if_alias_used,
+ allowed_actions = allowedActions,
+ can_grant_access_to_views = Some(originalView.can_grant_access_to_views),
+ can_revoke_access_to_views = Some(originalView.can_revoke_access_to_views)
+ )
+ }
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateSystemView.toString)
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanUpdateSystemView.toString)
+
+ Given("A view exists")
+ val creationReply = postSystemView(postBodySystemViewJson, user1)
+ creationReply.code should equal (201)
+ val createdView : ViewJsonV500 = creationReply.body.extract[ViewJsonV500]
+ createdView.id should not startWith("_")
+ createdView.can_see_images should equal(true)
+ createdView.can_delete_comment should equal(true)
+ createdView.can_delete_physical_location should equal(true)
+ createdView.can_edit_owner_comment should equal(true)
+ createdView.description should not equal(updatedViewDescription)
+ createdView.hide_metadata_if_alias_used should equal(false)
+
+ When("We use a valid access token and valid put json")
+ val reply = putSystemView(createdView.id, viewUpdateJson(createdView), user1)
+ Then("We should get back the updated view")
+ reply.code should equal (200)
+ val updatedView = reply.body.extract[ViewJsonV500]
+ updatedView.can_see_images should equal(true)
+ updatedView.can_delete_comment should equal(true)
+ updatedView.can_delete_physical_location should equal(false)
+ updatedView.can_edit_owner_comment should equal(false)
+ updatedView.description should equal(updatedViewDescription)
+ updatedView.hide_metadata_if_alias_used should equal(true)
+ updatedView.is_firehose should equal(Some(true))
+ }
+ }
+
+
+ feature(s"test $ApiEndpoint4 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint4, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint4")
+ val response400 = deleteSystemView("", None)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint4 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint4, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint4")
+ val response400 = deleteSystemView("", user1)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanDeleteSystemView)
+ }
+ }
+ feature(s"test $ApiEndpoint4 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint4, VersionOfApi) {
+ val viewId = APIUtil.generateUUID()
+ createSystemView(viewId)
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteSystemView.toString)
+ When(s"We make a request $ApiEndpoint4")
+ val response400 = deleteSystemView(viewId, user1)
+ Then("We should get a 200")
+ response400.code should equal(200)
+ }
+ }
+ feature(s"test $ApiEndpoint4 version $VersionOfApi - Authorized access with proper Role in order to delete owner view") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint4, VersionOfApi) {
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteSystemView.toString)
+ When(s"We make a request $ApiEndpoint4")
+ AccountAccess.findAll(
+ By(AccountAccess.view_id, SYSTEM_OWNER_VIEW_ID),
+ By(AccountAccess.user_fk, resourceUser1.id.get)
+ ).forall(_.delete_!) // Remove all rows assigned to the system owner view in order to delete it
+ val response400 = deleteSystemView(SYSTEM_OWNER_VIEW_ID, user1)
+ Then("We should get a 200")
+ response400.code should equal(200)
+ }
+ }
+
+
+ feature(s"test $ApiEndpoint5 version $VersionOfApi - Unauthorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint5")
+ val response400 = getSystemViewsIds(None)
+ Then("We should get a 401")
+ response400.code should equal(401)
+ response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
+ }
+ }
+ feature(s"test $ApiEndpoint5 version $VersionOfApi - Authorized access") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint2")
+ val response400 = getSystemViewsIds(user1)
+ Then("We should get a 403")
+ response400.code should equal(403)
+ response400.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetSystemView)
+ }
+ }
+ feature(s"test $ApiEndpoint5 version $VersionOfApi - Authorized access with proper Role") {
+ scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
+ When(s"We make a request $ApiEndpoint2")
+ Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetSystemView.toString)
+ val response400 = getSystemViewsIds(user1)
+ Then("We should get a 200")
+ response400.code should equal(200)
+ response400.body.extract[ViewsIdsJsonV500]
+ }
+ }
+
+
+}
diff --git a/obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala b/obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala
index 7caba12fb..5b770b3b9 100644
--- a/obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala
+++ b/obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala
@@ -12,6 +12,7 @@ import code.setup.{APIResponse, DefaultUsers, ServerSetupWithTestData}
import com.openbankproject.commons.util.ApiShortVersions
import dispatch.Req
import code.api.util.APIUtil.OAuth._
+import code.api.v2_0_0.BasicAccountsJSON
import net.liftweb.json.Serialization.write
import scala.util.Random.nextInt
@@ -33,6 +34,16 @@ trait V500ServerSetup extends ServerSetupWithTestData with DefaultUsers {
bank.id
}
+ def getPrivateAccounts(bankId : String, consumerAndToken: Option[(Consumer, Token)]) : APIResponse = {
+ val request = v5_0_0_Request / "banks" / bankId / "accounts" / "private" <@(consumerAndToken) //TODO, how can we know which endpoint it called? Although it is V300, but this endpoint called V200-privateAccountsAtOneBank
+ makeGetRequest(request)
+ }
+ def randomPrivateAccountId(bankId : String) : String = {
+ val accountsJson = getPrivateAccounts(bankId, user1).body.extract[BasicAccountsJSON].accounts //TODO, how to make this map automatically.
+ val randomPosition = nextInt(accountsJson.size)
+ accountsJson(randomPosition).id
+ }
+
// This will call create customer ,then return the customerId
def createAndGetCustomerIdViaEndpoint(bankId:String, consumerAndToken: Option[(Consumer, Token)]) = {
val postCustomerJson = SwaggerDefinitionsJSON.postCustomerJsonV310
diff --git a/obp-api/src/test/scala/code/api/v5_0_0/ViewsTests.scala b/obp-api/src/test/scala/code/api/v5_0_0/ViewsTests.scala
new file mode 100644
index 000000000..c2adc72c6
--- /dev/null
+++ b/obp-api/src/test/scala/code/api/v5_0_0/ViewsTests.scala
@@ -0,0 +1,93 @@
+/**
+Open Bank Project - API
+Copyright (C) 2011-2019, TESOBE GmbH.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+Email: contact@tesobe.com
+TESOBE GmbH.
+Osloer Strasse 16/17
+Berlin 13359, Germany
+
+This product includes software developed at
+TESOBE (http://www.tesobe.com/)
+
+ */
+package code.api.v5_0_0
+
+import code.api.Constant._
+import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
+import code.api.util.APIUtil.OAuth._
+import code.api.v1_2_1.{PermissionJSON, PermissionsJSON}
+import code.api.v3_0_0.OBPAPI3_0_0.Implementations3_0_0
+import code.setup.APIResponse
+import com.github.dwickern.macros.NameOf.nameOf
+import com.openbankproject.commons.util.ApiVersion
+import org.scalatest.Tag
+
+import scala.util.Random.nextInt
+
+class ViewsTests extends V500ServerSetup {
+
+ object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString)
+ object ApiEndpoint1 extends Tag(nameOf(Implementations3_0_0.getPermissionForUserForBankAccount))
+
+
+ //Custom view, name starts from `_`
+ val postBodyViewJson = createViewJsonV300
+ //System view, owner
+ val postBodySystemViewJson = createViewJsonV300.copy(name=SYSTEM_OWNER_VIEW_ID).copy(metadata_view = SYSTEM_OWNER_VIEW_ID)
+
+
+ def getAccountAccessForUser(bankId: String, accountId: String, provider : String, providerId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = (v5_0_0_Request / "banks" / bankId / "accounts" / accountId / "permissions" / provider / providerId).GET <@(consumerAndToken)
+ makeGetRequest(request)
+ }
+
+ //This will call v1_2_1Request and we need it here to prepare the data for further tests
+ //BK need to check this endpoint....
+ def getAccountPermissions(bankId : String, accountId : String, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
+ val request = v5_0_0_Request / "banks" / bankId / "accounts" / accountId / "permissions" <@(consumerAndToken)
+ makeGetRequest(request)
+ }
+ //This is a helper method, used to prepare the test parameters
+ def randomAccountPermission(bankId : String, accountId : String) : PermissionJSON = {
+ val persmissionsInfo = getAccountPermissions(bankId, accountId, user1).body.extract[PermissionsJSON]
+ val randomPermission = nextInt(persmissionsInfo.permissions.size)
+ persmissionsInfo.permissions(randomPermission)
+ }
+
+ feature(s"$ApiEndpoint1 - Get Account access for User. - $VersionOfApi") {
+ scenario("we will Get Account access for User.") {
+ Given("Prepare all the parameters:")
+ val bankId = randomBankId
+ val bankAccountId = randomPrivateAccountId(bankId)
+ val provider = defaultProvider
+ val permission = randomAccountPermission(bankId, bankAccountId)
+ val providerId = permission.user.id
+
+ When("We use a valid access token and valid put json")
+ val reply = getAccountAccessForUser(bankId, bankAccountId, provider, providerId, user1)
+ Then("We should get back the updated view")
+ reply.code should equal(200)
+ val response = reply.body.extract[ViewsJsonV500]
+ response.views.length should not equal (0)
+
+ //Note: as to new system view stuff, now the default account should both have some system view accesses and custom view accesses.
+ response.views.filter(_.is_system).length > 0 should be (true)
+ response.views.filter(!_.is_system).length > 0 should be (true)
+ }
+ }
+
+}
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala
index b8da25b20..113de64f9 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/BankingModel.scala
@@ -393,16 +393,19 @@ case class FirehoseAccountUser(
displayName : String
)
+case class FastFirehoseOwners(user_id: String, provider: String, user_name: String)
+case class FastFirehoseRoutings(bank_id: String, account_id: String)
+case class FastFirehoseAttributes(`type`: String, code: String, value: String)
case class FastFirehoseAccount(
id: String,
bankId: String,
label: String,
number: String,
- owners: String,
+ owners: List[FastFirehoseOwners],
productCode: String,
balance: AmountOfMoney,
- accountRoutings: String,
- accountAttributes: String
+ accountRoutings: List[FastFirehoseRoutings],
+ accountAttributes: List[FastFirehoseAttributes],
)
case class FastFirehoseAccounts(
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/UserModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/UserModel.scala
index 1839a356f..20fd1e898 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/model/UserModel.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/UserModel.scala
@@ -69,6 +69,7 @@ trait User {
def isConsentUser = createdByConsentId.nonEmpty
def isDeleted: Option[Boolean]
def lastMarketingAgreementSignedDate: Option[Date]
+ def lastUsedLocale: Option[String] = None
}
case class UserPrimaryKey(val value : Long) {
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala
index f84ccde23..057b97bb5 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala
@@ -52,6 +52,8 @@ trait ViewSpecification {
def which_alias_to_use: String
def hide_metadata_if_alias_used: Boolean
def allowed_actions : List[String]
+ def can_grant_access_to_views : Option[List[String]] = None
+ def can_revoke_access_to_views : Option[List[String]] = None
}
/*
@@ -64,7 +66,9 @@ case class CreateViewJson(
is_public: Boolean,
which_alias_to_use: String,
hide_metadata_if_alias_used: Boolean,
- allowed_actions : List[String]
+ allowed_actions : List[String],
+ override val can_grant_access_to_views : Option[List[String]] = None,
+ override val can_revoke_access_to_views : Option[List[String]] = None
) extends ViewSpecification
@@ -78,7 +82,9 @@ case class UpdateViewJSON(
override val is_firehose: Option[Boolean] = None,
which_alias_to_use: String,
hide_metadata_if_alias_used: Boolean,
- allowed_actions: List[String]) extends ViewSpecification
+ allowed_actions: List[String],
+ override val can_grant_access_to_views : Option[List[String]] = None,
+ override val can_revoke_access_to_views : Option[List[String]] = None) extends ViewSpecification
@@ -245,6 +251,10 @@ trait View {
def hideOtherAccountMetadataIfAlias: Boolean
+ // Introduced in version 5.0.0
+ def canGrantAccessToViews : Option[List[String]] = None
+ def canRevokeAccessToViews : Option[List[String]] = None
+
//reading access
//transaction fields