From c823ebcaa059713d3631bc3cf03c3592ddc0abb3 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Tue, 25 Feb 2025 12:59:33 +0100 Subject: [PATCH] feature/added HelperInfoJson to JWT --- .../SwaggerDefinitionsJSON.scala | 8 ++-- .../scala/code/api/util/ConsentUtil.scala | 39 ++++++++++++------- .../scala/code/api/v3_1_0/APIMethods310.scala | 3 +- .../code/api/v3_1_0/JSONFactory3.1.0.scala | 4 +- .../scala/code/api/v5_0_0/APIMethods500.scala | 17 +++++--- .../code/api/v5_0_0/JSONFactory5.0.0.scala | 2 +- .../scala/code/api/v5_1_0/APIMethods510.scala | 3 +- .../scala/code/api/v3_1_0/ConsentTest.scala | 6 +-- .../code/api/v5_1_0/ConsentObpTest.scala | 4 +- .../api/v5_1_0/VRPConsentRequestTest.scala | 8 ++-- 10 files changed, 57 insertions(+), 37 deletions(-) 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 89b127e0c..948abbdac 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 @@ -4238,7 +4238,7 @@ object SwaggerDefinitionsJSON { val postConsentEmailJsonV310 = PostConsentEmailJsonV310( everything = false, - views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value)), + views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value, None)), entitlements = List(PostConsentEntitlementJsonV310(bankIdExample.value, "CanGetCustomer")), consumer_id = Some(consumerIdExample.value), email = emailExample.value, @@ -4248,7 +4248,7 @@ object SwaggerDefinitionsJSON { val postConsentPhoneJsonV310 = PostConsentPhoneJsonV310( everything = false, - views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value)), + views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value, None)), entitlements = List(PostConsentEntitlementJsonV310(bankIdExample.value, "CanGetCustomer")), consumer_id = Some(consumerIdExample.value), phone_number = mobileNumberExample.value, @@ -4258,7 +4258,7 @@ object SwaggerDefinitionsJSON { val postConsentImplicitJsonV310 = PostConsentImplicitJsonV310( everything = false, - views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value)), + views = List(PostConsentViewJsonV310(bankIdExample.value, accountIdExample.value, viewIdExample.value, None)), entitlements = List(PostConsentEntitlementJsonV310(bankIdExample.value, "CanGetCustomer")), consumer_id = Some(consumerIdExample.value), valid_from = Some(new Date()), @@ -5223,7 +5223,7 @@ object SwaggerDefinitionsJSON { ) val helperInfoJson = HelperInfoJson( - counterparty_id = List(counterpartyIdExample.value) + counterparty_ids = List(counterpartyIdExample.value) ) val consentAccountAccessJson= ConsentAccountAccessJson( diff --git a/obp-api/src/main/scala/code/api/util/ConsentUtil.scala b/obp-api/src/main/scala/code/api/util/ConsentUtil.scala index 20e423cba..d74809194 100644 --- a/obp-api/src/main/scala/code/api/util/ConsentUtil.scala +++ b/obp-api/src/main/scala/code/api/util/ConsentUtil.scala @@ -4,8 +4,9 @@ import java.text.SimpleDateFormat import java.util.{Date, UUID} import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{ConsentAccessJson, PostConsentJson} import code.api.util.ApiRole.{canCreateEntitlementAtAnyBank, canCreateEntitlementAtOneBank} -import code.api.util.ErrorMessages.{InvalidConnectorResponse, NoViewReadAccountsBerlinGroup, CouldNotAssignAccountAccess} +import code.api.util.ErrorMessages.{CouldNotAssignAccountAccess, InvalidConnectorResponse, NoViewReadAccountsBerlinGroup} import code.api.v3_1_0.{PostConsentBodyCommonJson, PostConsentEntitlementJsonV310, PostConsentViewJsonV310} +import code.api.v5_0_0.HelperInfoJson import code.api.{APIFailure, Constant, RequestHeader} import code.bankconnectors.Connector import code.consent @@ -71,7 +72,8 @@ case class Role(role_name: String, ) case class ConsentView(bank_id: String, account_id: String, - view_id : String + view_id : String, + helper_info: Option[HelperInfoJson] ) case class Consent(createdByUserId: String, @@ -593,7 +595,9 @@ object Consent extends MdcLoggable { consentId: String, consumerId: Option[String], validFrom: Option[Date], - timeToLive: Long): String = { + timeToLive: Long, + helperInfo: Option[HelperInfoJson] + ): String = { lazy val currentConsumerId = Consumer.findAll(By(Consumer.createdByUserId, user.userId)).map(_.consumerId.get).headOption.getOrElse("") val currentTimeInSeconds = System.currentTimeMillis / 1000 @@ -621,12 +625,13 @@ object Consent extends MdcLoggable { val viewsToAdd: Seq[ConsentView] = for { view <- views - if consent.everything || consent.views.exists(_ == PostConsentViewJsonV310(view.bankId.value,view.accountId.value, view.viewId.value)) + if consent.everything || consent.views.exists(_ == PostConsentViewJsonV310(view.bankId.value,view.accountId.value, view.viewId.value, helperInfo)) } yield { ConsentView( bank_id = view.bankId.value, account_id = view.accountId.value, - view_id = view.viewId.value + view_id = view.viewId.value, + helper_info = helperInfo ) } // 2. Add Roles @@ -701,7 +706,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -712,7 +718,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -723,7 +730,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -767,7 +775,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -778,7 +787,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -789,7 +799,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""), account_id = bankAccount._1.map(_.accountId.value).openOrThrowException(error), - view_id = Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID + view_id = Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID, + None ) } } @@ -853,7 +864,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = bankId.getOrElse(null), account_id = accountId, - view_id = permission + view_id = permission, + None )) }.flatten } else { @@ -862,7 +874,8 @@ object Consent extends MdcLoggable { ConsentView( bank_id = null, account_id = null, - view_id = permission + view_id = permission, + None ) } } 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 ef3b22944..c49557fdd 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 @@ -3582,7 +3582,8 @@ trait APIMethods310 { createdConsent.consentId, consumerId, consentJson.valid_from, - consentJson.time_to_live.getOrElse(3600) + consentJson.time_to_live.getOrElse(3600), + None ) _ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map { i => connectorEmptyResponse(i, callContext) diff --git a/obp-api/src/main/scala/code/api/v3_1_0/JSONFactory3.1.0.scala b/obp-api/src/main/scala/code/api/v3_1_0/JSONFactory3.1.0.scala index 41b66593f..f198ebfd9 100644 --- a/obp-api/src/main/scala/code/api/v3_1_0/JSONFactory3.1.0.scala +++ b/obp-api/src/main/scala/code/api/v3_1_0/JSONFactory3.1.0.scala @@ -28,7 +28,6 @@ package code.api.v3_1_0 import java.lang import java.util.Date - import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.util.APIUtil.{stringOptionOrNull, stringOrNull} import code.api.util.RateLimitingPeriod.LimitCallPeriod @@ -44,6 +43,7 @@ import code.api.v2_1_0.{CounterpartyIdJson, CustomerCreditRatingJSON, ResourceUs import code.api.v2_2_0._ import code.api.v3_0_0.{AccountRuleJsonV300, CustomerAttributeResponseJsonV300, JSONFactory300, ViewBasicV300, ViewJsonV300} import code.api.v3_0_0.JSONFactory300.{createAccountRoutingsJSON, createAccountRulesJSON} +import code.api.v5_0_0.HelperInfoJson import code.consent.MappedConsent import code.entitlement.Entitlement import code.loginattempts.BadLoginAttempt @@ -518,7 +518,7 @@ case class MeetingsJsonV310( meetings: List[MeetingJsonV310] ) case class PostConsentEntitlementJsonV310(bank_id: String, role_name: String) -case class PostConsentViewJsonV310(bank_id: String, account_id: String, view_id: String) +case class PostConsentViewJsonV310(bank_id: String, account_id: String, view_id: String, helper_info: Option[HelperInfoJson]) trait PostConsentCommonBody{ val everything: Boolean val views: List[PostConsentViewJsonV310] 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 51ff0b6f7..8d9d3ef8f 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 @@ -936,8 +936,10 @@ trait APIMethods500 { _ <- Helper.booleanToFuture(ConsentAllowedScaMethods, cc=callContext){ List(StrongCustomerAuthentication.SMS.toString(), StrongCustomerAuthentication.EMAIL.toString(), StrongCustomerAuthentication.IMPLICIT.toString()).exists(_ == scaMethod) } + // If the payload contains "to_account` , it mean it is a VRP consent. + isVrpConsent = createdConsentRequest.payload.contains("to_account") (consentRequestJson, isVRPConsentRequest) <- - if(createdConsentRequest.payload.contains("to_account")) { + if(isVrpConsent) { val failMsg = s"$InvalidJsonFormat The vrp consent request json body should be the $PostVRPConsentRequestJsonV510 " NewStyle.function.tryons(failMsg, 400, callContext) { json.parse(createdConsentRequest.payload).extract[code.api.v5_1_0.PostVRPConsentRequestJsonInternalV510] @@ -1123,11 +1125,12 @@ trait APIMethods500 { ) ) } - postConsentViewJsons <- if(createdConsentRequest.payload.contains("to_account")) { + postConsentViewJsons <- if(isVrpConsent) { Future.successful(List(PostConsentViewJsonV310( bankId.value, accountId.value, - viewId.value + viewId.value, + Some(HelperInfoJson(List(counterpartyId.value))) ))) }else{ Future.sequence( @@ -1137,7 +1140,8 @@ trait APIMethods500 { .map(result =>PostConsentViewJsonV310( result._1.bankId.value, result._1.accountId.value, - access.view_id + access.view_id, + None, )) ) ) @@ -1198,7 +1202,8 @@ trait APIMethods500 { createdConsent.consentId, consumerId, postConsentBodyCommonJson.valid_from, - postConsentBodyCommonJson.time_to_live.getOrElse(3600) + postConsentBodyCommonJson.time_to_live.getOrElse(3600), + Some(HelperInfoJson(List(counterpartyId.value))) ) _ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map { i => connectorEmptyResponse(i, callContext) @@ -2148,7 +2153,7 @@ trait APIMethods500 { _ <- 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)) + (createViewJsonV500(updatedView), HttpCode.`200`(cc.callContext)) } } } 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 3b2c111bd..db7157f34 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 @@ -232,7 +232,7 @@ case class PostConsentRequestJsonV500( time_to_live: Option[Long] ) case class HelperInfoJson( - counterparty_id:List[String] + counterparty_ids:List[String] ) case class ConsentAccountAccessJson( diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index f70cfb458..219b988e5 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -2045,7 +2045,8 @@ trait APIMethods510 { createdConsent.consentId, consumerId, consentJson.valid_from, - consentJson.time_to_live.getOrElse(3600) + consentJson.time_to_live.getOrElse(3600), + None, ) _ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map { i => connectorEmptyResponse(i, callContext) diff --git a/obp-api/src/test/scala/code/api/v3_1_0/ConsentTest.scala b/obp-api/src/test/scala/code/api/v3_1_0/ConsentTest.scala index cc23dc8d9..cb24a310b 100644 --- a/obp-api/src/test/scala/code/api/v3_1_0/ConsentTest.scala +++ b/obp-api/src/test/scala/code/api/v3_1_0/ConsentTest.scala @@ -60,7 +60,7 @@ class ConsentTest extends V310ServerSetup { lazy val bankId = randomBankId lazy val bankAccount = randomPrivateAccount(bankId) lazy val entitlements = List(PostConsentEntitlementJsonV310("", CanGetAnyUser.toString())) - lazy val views = List(PostConsentViewJsonV310(bankId, bankAccount.id, Constant.SYSTEM_OWNER_VIEW_ID)) + lazy val views = List(PostConsentViewJsonV310(bankId, bankAccount.id, Constant.SYSTEM_OWNER_VIEW_ID, None)) lazy val postConsentEmailJsonV310 = SwaggerDefinitionsJSON.postConsentEmailJsonV310 .copy(entitlements=entitlements) .copy(consumer_id=Some(testConsumer.consumerId.get)) @@ -198,7 +198,7 @@ class ConsentTest extends V310ServerSetup { // Check we have all views from the consent val assignedViews = user.views.map(_.list).toSeq.flatten - assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id)).distinct should equal(views) + assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id, None)).distinct should equal(views) case false => // Due to missing props at the instance the request must fail @@ -277,7 +277,7 @@ class ConsentTest extends V310ServerSetup { // Check we have all views from the consent val assignedViews = user.views.map(_.list).toSeq.flatten - assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id)).distinct should equal(views) + assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id, None)).distinct should equal(views) case false => // Due to missing props at the instance the request must fail diff --git a/obp-api/src/test/scala/code/api/v5_1_0/ConsentObpTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/ConsentObpTest.scala index f32313162..ca2435d31 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/ConsentObpTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/ConsentObpTest.scala @@ -61,7 +61,7 @@ class ConsentObpTest extends V510ServerSetup { lazy val bankId = randomBankId lazy val bankAccount = randomPrivateAccount(bankId) lazy val entitlements = List(PostConsentEntitlementJsonV310("", CanGetAnyUser.toString())) - lazy val views = List(PostConsentViewJsonV310(bankId, bankAccount.id, Constant.SYSTEM_OWNER_VIEW_ID)) + lazy val views = List(PostConsentViewJsonV310(bankId, bankAccount.id, Constant.SYSTEM_OWNER_VIEW_ID, None)) lazy val postConsentEmailJsonV310 = SwaggerDefinitionsJSON.postConsentEmailJsonV310 .copy(entitlements=entitlements) .copy(consumer_id=Some(testConsumer.consumerId.get)) @@ -169,7 +169,7 @@ class ConsentObpTest extends V510ServerSetup { // Check we have all views from the consent val assignedViews = user.views.map(_.list).toSeq.flatten - assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id)).distinct should equal(views) + assignedViews.map(e => PostConsentViewJsonV310(e.bank_id, e.account_id, e.view_id, None)).distinct should equal(views) case false => // Due to missing props at the instance the request must fail diff --git a/obp-api/src/test/scala/code/api/v5_1_0/VRPConsentRequestTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/VRPConsentRequestTest.scala index da0234898..ad26841e8 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/VRPConsentRequestTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/VRPConsentRequestTest.scala @@ -215,7 +215,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{ val consentRequestBankId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.bank_id val consentRequestAccountId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.account_id val consentRequestViewId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.view_id - val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_id + val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_ids val createTransReqRequest = (v4_0_0_Request / "banks" / consentRequestBankId / "accounts" / consentRequestAccountId / consentRequestViewId / "transaction-request-types" / "COUNTERPARTY" / "transaction-requests").POST @@ -326,7 +326,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{ val consentRequestBankId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.bank_id val consentRequestAccountId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.account_id val consentRequestViewId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.view_id - val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_id + val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_ids val createTransReqRequest = (v4_0_0_Request / "banks" / consentRequestBankId / "accounts" / consentRequestAccountId / consentRequestViewId / "transaction-request-types" / "COUNTERPARTY" / "transaction-requests").POST @@ -421,7 +421,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{ val consentRequestBankId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.bank_id val consentRequestAccountId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.account_id val consentRequestViewId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.view_id - val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_id + val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_ids val createTransReqRequest = (v4_0_0_Request / "banks" / consentRequestBankId / "accounts" / consentRequestAccountId / consentRequestViewId / "transaction-request-types" / "COUNTERPARTY" / "transaction-requests").POST @@ -509,7 +509,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{ val consentRequestBankId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.bank_id val consentRequestAccountId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.account_id val consentRequestViewId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.view_id - val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_id + val consentRequestCounterpartyId = createConsentByRequestResponse.body.extract[ConsentJsonV500].account_access.get.helper_info.counterparty_ids val createTransReqRequest = (v4_0_0_Request / "banks" / consentRequestBankId / "accounts" / consentRequestAccountId / consentRequestViewId / "transaction-request-types" / "COUNTERPARTY" / "transaction-requests").POST