From cbba66298c76eb55e34cd550d571ac84579cefd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 20 Mar 2025 13:28:38 +0100 Subject: [PATCH 1/6] bugfix/Error of Mandatory headers of Berlin Group is 400 --- .../src/main/scala/code/api/util/BerlinGroupCheck.scala | 7 ++++--- obp-api/src/main/scala/code/api/util/ErrorMessages.scala | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/obp-api/src/main/scala/code/api/util/BerlinGroupCheck.scala b/obp-api/src/main/scala/code/api/util/BerlinGroupCheck.scala index 0d01a58cc1..b4ba2998e7 100644 --- a/obp-api/src/main/scala/code/api/util/BerlinGroupCheck.scala +++ b/obp-api/src/main/scala/code/api/util/BerlinGroupCheck.scala @@ -1,8 +1,9 @@ package code.api.util -import code.api.RequestHeader +import code.api.APIFailureNewStyle +import code.api.util.APIUtil.fullBoxOrException import com.openbankproject.commons.model.User -import net.liftweb.common.{Box, Empty, Failure} +import net.liftweb.common.{Box, Empty} import net.liftweb.http.provider.HTTPParam object BerlinGroupCheck { @@ -27,7 +28,7 @@ object BerlinGroupCheck { if (missingHeaders.isEmpty) { forwardResult // All mandatory headers are present } else { - (Failure(s"Missing mandatory headers: ${missingHeaders.mkString(", ")}"), forwardResult._2) + (fullBoxOrException(Empty ~> APIFailureNewStyle(s"${ErrorMessages.MissingMandatoryBerlinGroupHeaders}(${missingHeaders.mkString(", ")})", 400, forwardResult._2.map(_.toLight))), forwardResult._2) } } 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 e26922d345..a253d61850 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -266,6 +266,7 @@ object ErrorMessages { val Oauth2ValidateAccessTokenError = "OBP-20215: There was a problem validating the OAuth2 access token. " val AuthorizationHeaderAmbiguity = "OBP-20250: Request headers used for authorization are ambiguous. " + val MissingMandatoryBerlinGroupHeaders= "OBP-20251: Missing mandatory request headers. " // X.509 val X509GeneralError = "OBP-20300: PEM Encoded Certificate issue." From b813547add241e6c474dafb8d24aace3bdf19ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 21 Mar 2025 07:15:33 +0100 Subject: [PATCH 2/6] refactor/Remove unused function --- .../group/v1_3/AccountInformationServiceAISApi.scala | 9 --------- 1 file changed, 9 deletions(-) diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala index 4ab4828c27..5e9d72f76c 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala @@ -704,15 +704,6 @@ where the consent was directly managed between ASPSP and PSU e.g. in a re-direct } - - def tweakStatusNames(status: String) = { - val scaStatus = status - .replace(ConsentStatus.INITIATED.toString, "started") - .replace(ConsentStatus.ACCEPTED.toString, "finalised") - .replace(ConsentStatus.REJECTED.toString, "failed") - scaStatus - } - resourceDocs += ResourceDoc( getConsentScaStatus, apiVersion, From dea9f372585f175ba4555302773af63ffdc9f03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 21 Mar 2025 09:42:27 +0100 Subject: [PATCH 3/6] feature/Function getBankAccountCommon can get account by UUID value --- .../main/scala/code/api/util/APIUtil.scala | 2 +- .../scala/code/api/util/ConsentUtil.scala | 2 +- .../bankconnectors/LocalMappedConnector.scala | 29 ++++++++++++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) 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 682c2c4b52..405486d37a 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -3783,7 +3783,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ *A Version 1 UUID is a universally unique identifier that is generated using * a timestamp and the MAC address of the computer on which it was generated. */ - def checkIfStringIsUUIDVersion1(value: String): Boolean = { + def checkIfStringIsUUID(value: String): Boolean = { Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") .matcher(value).matches() } 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 e94ba0c737..6a05bebe8c 100644 --- a/obp-api/src/main/scala/code/api/util/ConsentUtil.scala +++ b/obp-api/src/main/scala/code/api/util/ConsentUtil.scala @@ -440,7 +440,7 @@ object Consent extends MdcLoggable { } def getConsentJwtValueByConsentId(consentId: String): Option[MappedConsent] = { - APIUtil.checkIfStringIsUUIDVersion1(consentId) match { + APIUtil.checkIfStringIsUUID(consentId) match { case true => // String is a UUID Consents.consentProvider.vend.getConsentByConsentId(consentId) match { case Full(consent) => Some(consent) diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index caffed20b4..b9e27ab9a9 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -897,10 +897,31 @@ object LocalMappedConnector extends Connector with MdcLoggable { } } - def getBankAccountCommon(bankId: BankId, accountId: AccountId, callContext: Option[CallContext]) = { - MappedBankAccount - .find(By(MappedBankAccount.bank, bankId.value), By(MappedBankAccount.theAccountId, accountId.value)) - .map(bankAccount => (bankAccount, callContext)) + def getBankAccountCommon(bankId: BankId, accountId: AccountId, callContext: Option[CallContext]): Box[(MappedBankAccount, Option[CallContext])] = { + + def getByBankAndAccount(): Box[(MappedBankAccount, Option[CallContext])] = { + MappedBankAccount + .find(By(MappedBankAccount.bank, bankId.value), By(MappedBankAccount.theAccountId, accountId.value)) + .map(bankAccount => (bankAccount, callContext)) + } + + if(APIUtil.checkIfStringIsUUID(accountId.value)) { + // Find bank accounts by accountId first + val bankAccounts = MappedBankAccount.findAll(By(MappedBankAccount.theAccountId, accountId.value)) + + // If exactly one account is found, return it, else filter by bankId + bankAccounts match { + case account :: Nil => + // If exactly one account is found, return it + Some(account, callContext) + case _ => + // If multiple or no accounts are found, filter by bankId + getByBankAndAccount() + } + } else { + getByBankAndAccount() + } + } override def getBankAccounts(bankIdAccountIds: List[BankIdAccountId], callContext: Option[CallContext]): OBPReturnType[Box[List[BankAccount]]] = { From 69d6f5e68d255f5879e30db052aa94989cded331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 21 Mar 2025 14:01:38 +0100 Subject: [PATCH 4/6] feature/New Endpoint - Get All My Consents Info --- .../scala/code/api/v4_0_0/APIMethods400.scala | 44 ++++++++++++++++-- .../scala/code/api/v5_1_0/APIMethods510.scala | 46 +++++++++++++++++-- .../scala/code/api/v5_1_0/ConsentsTest.scala | 28 +++++++++-- 3 files changed, 106 insertions(+), 12 deletions(-) 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 d4e0518d4f..b7bf2973a1 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 @@ -8188,12 +8188,12 @@ trait APIMethods400 extends MdcLoggable { } } staticResourceDocs += ResourceDoc( - getConsentInfos, + getConsentInfosByBank, implementedInApiVersion, - nameOf(getConsentInfos), + nameOf(getConsentInfosByBank), "GET", "/banks/BANK_ID/my/consent-infos", - "Get My Consents Info", + "Get My Consents Info By Bank", s""" | |This endpoint gets the Consents that the current User created. @@ -8210,7 +8210,7 @@ trait APIMethods400 extends MdcLoggable { ), List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2)) - lazy val getConsentInfos: OBPEndpoint = { + lazy val getConsentInfosByBank: OBPEndpoint = { case "banks" :: BankId(bankId) :: "my" :: "consent-infos" :: Nil JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) for { @@ -8224,6 +8224,42 @@ trait APIMethods400 extends MdcLoggable { } } + staticResourceDocs += ResourceDoc( + getConsentInfos, + implementedInApiVersion, + nameOf(getConsentInfos), + "GET", + "/my/consent-infos", + "Get My Consents Info", + s""" + | + |This endpoint gets the Consents that the current User created. + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, + consentInfosJsonV400, + List( + $UserNotLoggedIn, + $BankNotFound, + UnknownError + ), + List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2)) + + lazy val getConsentInfos: OBPEndpoint = { + case "my" :: "consent-infos" :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + consents <- Future { Consents.consentProvider.vend.getConsentsByUser(cc.userId) + .sortBy(i => (i.creationDateTime, i.apiStandard)).reverse + } + } yield { + (JSONFactory400.createConsentInfosJsonV400(consents), HttpCode.`200`(cc)) + } + } + } + staticResourceDocs += ResourceDoc( getMyPersonalUserAttributes, implementedInApiVersion, 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 eb7805c7a0..c6edae3f65 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 @@ -1518,12 +1518,12 @@ trait APIMethods510 { staticResourceDocs += ResourceDoc( - getMyConsents, + getMyConsentsByBank, implementedInApiVersion, - nameOf(getMyConsents), + nameOf(getMyConsentsByBank), "GET", "/banks/BANK_ID/my/consents", - "Get My Consents", + "Get My Consents at Bank", s""" | |This endpoint gets the Consents created by a current User. @@ -1540,7 +1540,7 @@ trait APIMethods510 { ), List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2)) - lazy val getMyConsents: OBPEndpoint = { + lazy val getMyConsentsByBank: OBPEndpoint = { case "banks" :: BankId(bankId) :: "my" :: "consents" :: Nil JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) @@ -1556,6 +1556,44 @@ trait APIMethods510 { } } + staticResourceDocs += ResourceDoc( + getMyConsents, + implementedInApiVersion, + nameOf(getMyConsents), + "GET", + "/my/consents", + "Get My Consents", + s""" + | + |This endpoint gets the Consents created by a current User. + | + |${userAuthenticationMessage(true)} + | + """.stripMargin, + EmptyBody, + consentsJsonV400, + List( + $UserNotLoggedIn, + $BankNotFound, + UnknownError + ), + List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2)) + + lazy val getMyConsents: OBPEndpoint = { + case "my" :: "consents" :: Nil JsonGet _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + consents <- Future { + Consents.consentProvider.vend.getConsentsByUser(cc.userId) + .sortBy(i => (i.creationDateTime, i.apiStandard)).reverse + } + } yield { + (createConsentsInfoJsonV510(consents), HttpCode.`200`(cc)) + } + } + } + staticResourceDocs += ResourceDoc( getConsentsAtBank, diff --git a/obp-api/src/test/scala/code/api/v5_1_0/ConsentsTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/ConsentsTest.scala index c8f7750258..01bd74e7f3 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/ConsentsTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/ConsentsTest.scala @@ -65,7 +65,8 @@ class ConsentsTest extends V510ServerSetup with PropsReset{ object ApiEndpoint5 extends Tag(nameOf(Implementations4_0_0.getUsers)) object ApiEndpoint6 extends Tag(nameOf(Implementations5_1_0.revokeConsentAtBank)) object ApiEndpoint7 extends Tag(nameOf(Implementations5_1_0.getConsentByConsentId)) - object ApiEndpoint8 extends Tag(nameOf(Implementations5_1_0.getMyConsents)) + object ApiEndpoint8 extends Tag(nameOf(Implementations5_1_0.getMyConsentsByBank)) + object getMyConsents extends Tag(nameOf(Implementations5_1_0.getMyConsents)) object ApiEndpoint9 extends Tag(nameOf(Implementations5_1_0.getConsentsAtBank)) object GetConsents extends Tag(nameOf(Implementations5_1_0.getConsents)) object UpdateConsentStatusByConsent extends Tag(nameOf(Implementations5_1_0.updateConsentStatusByConsent)) @@ -92,7 +93,8 @@ class ConsentsTest extends V510ServerSetup with PropsReset{ def getConsentByRequestIdUrl(requestId:String) = (v5_1_0_Request / "consumer"/ "consent-requests"/requestId/"consents").GET<@(user1) def getConsentByIdUrl(requestId:String) = (v5_1_0_Request / "consumer" / "current" / "consents" / requestId ).GET<@(user1) def revokeConsentUrl(consentId: String) = (v5_1_0_Request / "banks" / bankId / "consents" / consentId).DELETE - def getMyConsents(consentId: String) = (v5_1_0_Request / "banks" / bankId / "my" / "consents").GET + def getMyConsentAtBank(consentId: String) = (v5_1_0_Request / "banks" / bankId / "my" / "consents").GET + def getMyConsent(consentId: String) = (v5_1_0_Request / "my" / "consents").GET def getConsentsAtBAnk(consentId: String) = (v5_1_0_Request / "management"/ "consents" / "banks" / bankId).GET def getConsents(consentId: String) = (v5_1_0_Request / "management"/ "consents").GET def updateConsentStatusByConsent(consentId: String) = (v5_1_0_Request / "management" / "banks" / bankId / "consents" / consentId).PUT @@ -120,7 +122,7 @@ class ConsentsTest extends V510ServerSetup with PropsReset{ feature(s"test $ApiEndpoint8 version $VersionOfApi - Unautenticated access") { scenario("We will call the endpoint without user credentials", ApiEndpoint8, VersionOfApi) { When(s"We make a request $ApiEndpoint8") - val response510 = makeGetRequest(getMyConsents("whatever")) + val response510 = makeGetRequest(getMyConsentAtBank("whatever")) Then("We should get a 401") response510.code should equal(401) response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) @@ -129,7 +131,25 @@ class ConsentsTest extends V510ServerSetup with PropsReset{ feature(s"test $ApiEndpoint8 version $VersionOfApi - Autenticated access") { scenario("We will call the endpoint with user credentials", ApiEndpoint8, VersionOfApi) { When(s"We make a request $ApiEndpoint1") - val response510 = makeGetRequest(getMyConsents("whatever")<@(user1)) + val response510 = makeGetRequest(getMyConsentAtBank("whatever")<@(user1)) + Then("We should get a 200") + response510.code should equal(200) + } + } + + feature(s"test $getMyConsents version $VersionOfApi - Unautenticated access") { + scenario("We will call the endpoint without user credentials", getMyConsents, VersionOfApi) { + When(s"We make a request $getMyConsents") + val response510 = makeGetRequest(getMyConsent("whatever")) + Then("We should get a 401") + response510.code should equal(401) + response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + } + } + feature(s"test $getMyConsents version $VersionOfApi - Autenticated access") { + scenario("We will call the endpoint with user credentials", getMyConsents, VersionOfApi) { + When(s"We make a request $ApiEndpoint1") + val response510 = makeGetRequest(getMyConsent("whatever")<@(user1)) Then("We should get a 200") response510.code should equal(200) } From d295e2de0f5b51a68c76ab6898b804b306885074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Sun, 23 Mar 2025 10:48:27 +0100 Subject: [PATCH 5/6] test/Update frozen class tests --- .../src/test/resources/frozen_type_meta_data | Bin 136189 -> 136213 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/obp-api/src/test/resources/frozen_type_meta_data b/obp-api/src/test/resources/frozen_type_meta_data index 74b0167d2ce5d66dc29f27be0e7853dcdb32a306..eb1e8a02f70da46266bbf40e57461bb3a971a8b4 100644 GIT binary patch delta 8987 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 Cwje_Q delta 9025 zcmaJ{d0>oJ*Uxz*lV!3^mPsZOiHSWVVqX%3eo81IwU;bo5Ry!miO>>M5ftIRaa53? z)wgy=jn>|J+gg*hszs?fJW1!93O;bnx8YYY$1?p3{ z?QIV?MKq0#Qe5VWKC!JmW8|_{R+lKTxNfMZ3HG7}@`-<}OWq!Gtew@xh%W}QCDtb# zn)1sSJ-SCm!RW%CmI8+c>SyE@7GvkrR|Pl9&Nk;_S1!R0xnIW43o}gCEKBaolk?1y z-axBMxJs`w%1!(d8&TKl;$4(CTI$oOCQlG>Jd4P<#21~1Q&ecRK);ghph9zjBxR77 z9C@)=T|BUApe5T}=y;TK@TkF8D9`HBRBVk27QemYCf39SQi))%*3qjS>MM42adC-* zt}!>&WXUtDpZz6Woe0r3pa5Hfc7Q{x$PMF4Wg1>0!*ILs?J_d+U zelgTt%=2S?U-_ZGybO?+AgfCguw)%kpcv?%;`*}HrLoBHiwx+Ulb4-k%CgE?gXLw2 z_}YI2rHj_OF}g7M!6Gl=R+k9qpQpDYy*QvV(rodauC@QQ-^C$Ut4pZpRzFB|3V6@` zZL3Q?FchDMMu-CqU4=GqC&h@50%xdu@e^4=FHoG=9P}-<5{rWyXeEyYARyOl3l9=M z1rMd;qK|%&I)9;{kRkMrZCFSHq5x46x|li&e?xuhWNT&UPPD;R6qZYxO_IuH+l{)j zh_>1+5idGUW3f0>Z>()tWK+@v$r(bdiAtay;$qZGD)nGnV*PBQ;kNb09LEa1t!;y0 zj>k~3w&6_oF;|hH|gNM5*m`yFK!%ed)#C_ zQH1T?X1@}BD%Ld5rCCDPBC$?^OLMW2>WWiwsuEipbup$8(X^<4LA)y6bp z-=uh3vo=i>ZzIfYeDQ?Bw4#D6KB%QYj?$4v6t{bUjABo_Y+ReRF9NB`_Ip8UWQR}4 z%R$7$>JlydJBQnPcj`wNTGrVMH;%7><7$@#h|>upNnbvILPWpBXeVPm-`PY4d)?vm zl_JJ;%g6l9GiZY7ku)6wZoD2TzDqKLW$*5TajohO_B{PK1@ZD`q!rD3M1oJ>9>H~R z%j{`VoK(HU<;)=4rCxoBN=1w09E?^Z2NEc3=`$I|)U>Z18@Sx}A)e2^RF3cY{f6L6 z%H&Y4{F*{Is|h9Yxn9&>WcPmotGD(459##q-@F2NVS#lr&Q#HhZLNbu#en8yERUyP zaehEM(C|3%Q23-y2ID!YFJtMs)ZP^E!0O_fn~`Id%SzR?oV}c)MA-ySkv^ycc6~RW zqHTKyb%MsE7{YJJ2)|OGL@EG3cdUcmt?F+o~-Ff+60>n+lR+ z^V6Jj{Q1sZTFh~qDOC*JsONJXC`g$U0B zRqT9q3l@)gEyu~!o%fehBPffel=#46pP8Lr=(>lAbyFfhI%RUS*fXe+@R?eHxA&&L zS=aFVOvJrnbLOBdqyu?{y*Wdt1dGS3bz)*kBk)>T(g)kTQL+G%6i+LW>Und?E4*PK zX*sPgpu#jG6v~=1!-B~-XY{GHn8erR@y>l+x?AK-i6d{$%ms}{GwUfB2%A09AM&~* zSINmJa5~t9yD8%9+0kI}X!bA9)GD3Zx3q=ioG`ZmJS}7HP!RfX?px%XqjTEFBofKr zH4-=PjS&kcX~okb4gav60yQ#(VD;GrGqL})g=aN-spC@7ZBcKCGH=lcsCP;)3grWz zPzw=LHWN&?ly$}A+hsqi3RH)@fom`PhyMc%@?&%D-g(A!grOaL3mn!g+wTR9X)>%i zX<4I1%l)BZ=3D(dK+!cTGb5J=?89Dezf~8S)-KP+^Q7gwacxtP2@rkd8k}oXvb#7~ zk%S3h)51i=iUcPcjkH|eYNSZ9Y{kE^CTV36CfQdma41SIl2^S+`lUWfGj83GbiCD% z+_^HGJjJxl-VW{7!dN@ie1V3Q2;(aHSET!hZ!7gMqKB0yaXnG>2-hR47lOsGHTk$! zb&ue(S)}30XmS_#*R;jAn6*D)ht`q~zL;Rl(;sxNodT2S7VSGa=@=-oTn z<(b2Xg%k85<*PUdJN>J4>MbsRC4sr#Dd`~Tr$&O&zEf$?kEr*}JWP7;8;Nj+(^D|8 z^t4+Yc|37q#?v@);@lihxS@y1l9OZR{aPFt3{F&jpoLX}{ZEa-|7|23+wckj}h{97~+M`U3g0PEW0z!6oHd&u3@2Es&!4zCKj^11jDx)(F&kn_`MHgB%2~g}$boGS{{`WC{#v2R z{=D-?J&M+V3EZ7G-^I+dM^bmQ9#um2hL4dBidP^1F9_v6fkgsVRg-@S{x^l1#up&eL(raA5j+H}W9^ z_X|hVsk*A=$8OZ*nW5ZmPt!Oph#EK{KJt45-_%ejwpnet$1#JE5llD_VD$B%Fi6+b zgG_(6PQKwm^)aUPq(W>E#e$lG7qXWZ)#fzbs!ubDgim>t780tS`y5aj-AF8sLb$h=eA~XtQc1y!tDO;NLJO6b_T2gwi>9piyzH{ zdJp?i1_;IY(<@+A>Q93ue8}S9XC1-lxh8<%`rIv$#$zBczLD6S;LYa)=?FdG`ER3k zxEh2-dQJ$YUXJSE_xwl(HEmFGp(S^4o0cur2;r=sSoORgg6RwFY_FbfI&O8j@^yqT zO(>nf2iT(;(+)v^?FJf(n>LKbfLTEpO{NF-n_(0zK`LWG1V@I$j@08b{Y?!b$|}S7 zd^inuo@lU|)!LEO!WPfgqfedRJw--*3%+=ndUIqHtpclkQ8Wj1d)B8>P{4pIk$gx# zmU6U_P;E(jl64kLiF-w>rd%9NfKmP+n$ob|(0~TvO@?Bw+9z$+M6N6vP-{^Av;nPp z-o|c-Cg1z=Yv~kRYp%#cWj#PsBE>>;j5um;z=p;MNJj3|n9Sf`)tKH=tuW4xQm)id zfSJ%6f^S-7b3xH_on~~<$wns@C5{r|UlfS*UHt7EVqgW%k?w3MrM*0IEP3*%xs+hP zG=`44a#;_mZ{IM1y4T_Cb`bgjSGA*+*jShLlnI-GJ1>)G;JdCK5A8_VTKFk4Ta(FL zSg7V@e6=GXF=OgPC_L@MI#ER}%R!Q5xxFlb{;S0h($IP!#TC720&ecfR0KX#ld-_S zhCcKz-VXMG9jMV3_{t@H;T!51L^8cZ|8gG0moHIEh?JDni~IH?Bx5|YA0gY~`~7ex z)%HRCrJWmjV+s{u`TrNASv!!7m>N3}D;<`G^#AuP;NTU4Ee*ux)GALRmvn5IVTqKV zQ@QKQbSB{WlEYaOt1g;%3ii-%5JiGP?jUO8JP9}UUrjCf^dOpnjgJ^i>p>Mx;`ENp zA#})DX{gZ4lTMHi_a6#0GVr*e#E9qH76)?RFjew)!>BLN`|N_IoHzn!n|6`{*n2;E z3b~y%qUK`{zBCL6q$WDCbs$O1NSX+XO3Dc34@Xj$KW8sUZ0m^&75+ZbubpnK7`Xc= zn(ma}$3|~Nk=%M$kvr=R-k45_u0WzFp<5TkD?f!0UK!-8c}^9wJ-|?hmiuQ=*x!`Z z=s$4PZRDC!ue*w@N4_FW@5vu#0J4qzSqAk{n>i+Df0DP^k%zSG;?3PMsRL$A&LkA~ zd^{7r_<*BLFf0SVWumM<1lQG>O}Oo7(qX}iqiKS3H_s}B;c6I5;4CxcI>(a!#%G3m zfKz7+EUcQBSO_%*pPL1CTOL90WAX@D4KK+9b{LoD6FM%^{Pa8`pW6Rf)4V#L`r}}L zgZpFz*jh-(@mgY~UC3{^{X_tOfmcqXToCXsCRi$`6;r{pW2m|ODv1YUgHRa`BGk35*s^Q(*$RE26%v;Ge=S^T)^5A{&}tA3G&=lT9q)TRKkME{#M&fE;Tk zQh{oIR83L#%$cN>+s}Q2Hi2*WEJ81bO|w)kP;D9Ba%R(T+&-I)@L=S)In)gc^5)Pl z&{tL|#d+5{OwDx)7yDmw5;N(DQzE)0)F+F`IrY~AbZLr~_#2}t_0`Iq%k{ePf zX9b1Qz`mRb&DCl?zl<(9{q59S)afr)5V;%&r{^KdNp@zQPlcCO0OwS|L6Xjw_fiYK zQ2~rLa>NQ1?-s3~1dJS8fgoOOPgn`;#B2E~z%(%FS$y!Wqz`a#pH$N7KRATcLwYcZ zUao>3s_h%9fJh+FVhx#PIq$(;K0#|Qc6%@%T|*6}rq)pUGryVFBhp@s`U>3(nJNIC zIqDrG8b+S_4k6*RUwelpAq%yq{hKaIJnp(4U~S}y>tWbNJ|}MgmJK-QYWwaDc*EEF zn`okw13Ic`P01iGd%QeiD_wVvc#6d}UAS}`$QpUvb_6OTAKgwvoWov@%IVns1TL}B zPT)FPYL2w!rU6)*yMuIoFbPc|$`VH_Q|*BAnjKVE^T3foeY^wbVdSLu0Vc9O4&)>6 zBf=p@9Bje;ccL?;#=Ho%smxo$;QbqRB0;FOpVil<)br za{zyNm||;H=Y9mLGIIP8>WUjOGnq#rkJHQE@;ZF_*HN4)%p7Gmw>n0x@ae7>QtDUs z0h$&Zqq@#*xjQ}|J4QB4L9@QqvkIHLH2{U0;}k0E5VxX2&UlDSL2dPTo&YpdbC(lz z4Rab+BZo2a+-i7iwH=5DRU;$+oKoW_J{W43y8uxK&IlQ(`v3vpuI4ux{+DZr14KB2t%6q0>M z-j5#z?7#oY;po9|(KmDzLX9|0Y5$bWJS&a4g--Dlug%o5?-}xhY@uhc!3W|(D+8CG zQOz6KlB4S-BImku^CslMCO;)eR8H~}2d;W~KUXQZi8EKbI12c>YVD=x(`TtIT*dDk zRf77Kb0BHprsru1cC+U^eT!S=1zM^eg{+B0*?@2!c2Opw=o~iY6&C@D)qMIQ?QmAL z?_NT60}H#XR-RKX(-m;c_?C9oHcJtnIL(5*MXFw07^>lxYe^F@ILlnDRyS>Hs~bkO z*4e)5I|_%>*>_(7LD+NrcGz~pH8syeH*&-?7?M?x{lYb*94I*Md=KL{a2G@<=vpR- zV%{CCcvuin8<+b%p>BNkI>LdGBU4Zqn{TM7s}>h6cA@;-a)Ub78mG{`5oY)N0mTBQ zH~X)wUwH0+=@10!catVNr|JIEMT$Y^t1j`XAL%^gm~xv&LfdC<(|j1t-eI9!atC3= zfb$IFE+cSsGNBZUE@@eR7dkd@tGjCYzUr<73i}UtDIOT_sJlDgL#bZMDfd7O0DliM zAy>LjqiSV#)P)D`BiC0Ow-K@(#Pc6ed*=*qKDdFJil>$&d+VQJ2bh-i3t7Pkkk?Bp zyDA;Z?(!?V*1-9{QoeJc8&?McF@M^GK2OV}K+gRFxp({{8Vw16z-oRbQ^o7@lT+O6 z$29-B?$m(p;T-;i;;{lJQL8}pw-5gQ361`9wK&6jb(BVbN&TW8X+_KKo}4q9yd0_710L_HEQLnNO)=0v z`8)U4C=oIrsxxR{U)hog=V>DmJ0~9|??B}rDjw18j)tcz Date: Mon, 24 Mar 2025 09:08:43 +0100 Subject: [PATCH 6/6] feature/Add endpoint updateConsumerName v5.1.0 --- .../SwaggerDefinitionsJSON.scala | 3 ++ .../main/scala/code/api/util/ApiRole.scala | 2 + .../scala/code/api/v5_1_0/APIMethods510.scala | 47 +++++++++++++++++++ .../code/api/v5_1_0/JSONFactory5.1.0.scala | 1 + .../scala/code/api/v5_1_0/ConsumerTest.scala | 39 ++++++++++++--- 5 files changed, 85 insertions(+), 7 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 74b39d19bb..b4a96a6d40 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 @@ -5508,6 +5508,9 @@ object SwaggerDefinitionsJSON { val consumerLogoUrlJson = ConsumerLogoUrlJson( "http://localhost:8888" ) + val consumerNameJson = ConsumerNameJson( + "App name" + ) val consumersJsonV510 = ConsumersJsonV510( List(consumerJsonV510) 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 c2fe897264..1547f0bda8 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -243,6 +243,8 @@ object ApiRole extends MdcLoggable{ case class CanUpdateConsumerLogoUrl(requiresBankId: Boolean = false) extends ApiRole lazy val canUpdateConsumerLogoUrl = CanUpdateConsumerLogoUrl() + case class CanUpdateConsumerName(requiresBankId: Boolean = false) extends ApiRole + lazy val canUpdateConsumerName = CanUpdateConsumerName() case class CanCreateConsumer (requiresBankId: Boolean = false) extends ApiRole lazy val canCreateConsumer = CanCreateConsumer() 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 c6edae3f65..4dc6f7d08f 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 @@ -3198,6 +3198,53 @@ trait APIMethods510 { } } + staticResourceDocs += ResourceDoc( + updateConsumerName, + implementedInApiVersion, + nameOf(updateConsumerName), + "PUT", + "/management/consumers/CONSUMER_ID/consumer/name", + "Update Consumer Name", + s"""Update an existing name for a Consumer specified by CONSUMER_ID. + | + | ${consumerDisabledText()} + | + | CONSUMER_ID can be obtained after you register the application. + | + | Or use the endpoint 'Get Consumers' to get it + | + """.stripMargin, + consumerNameJson, + consumerJsonV510, + List( + $UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagConsumer), + Some(List(canUpdateConsumerName)) + ) + + lazy val updateConsumerName: OBPEndpoint = { + case "management" :: "consumers" :: consumerId :: "consumer" :: "name" :: Nil JsonPut json -> _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + postJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, cc.callContext) { + json.extract[ConsumerNameJson] + } + consumer <- NewStyle.function.getConsumerByConsumerId(consumerId, cc.callContext) + updatedConsumer <- NewStyle.function.updateConsumer( + id = consumer.id.get, + name = Some(postJson.app_name), + callContext = cc.callContext + ) + } yield { + (JSONFactory510.createConsumerJSON(updatedConsumer), HttpCode.`200`(cc.callContext)) + } + } + } + staticResourceDocs += ResourceDoc( getConsumer, diff --git a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala index 975ef6e811..4c29a54c69 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala @@ -559,6 +559,7 @@ case class APITags( case class ConsumerLogoUrlJson( logo_url: String ) +case class ConsumerNameJson(app_name: String) case class TransactionRequestJsonV510( transaction_request_id: String, diff --git a/obp-api/src/test/scala/code/api/v5_1_0/ConsumerTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/ConsumerTest.scala index 1cd92b42b1..4fa77c7954 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/ConsumerTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/ConsumerTest.scala @@ -27,7 +27,7 @@ package code.api.v5_1_0 import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.util.APIUtil.OAuth._ -import code.api.util.ApiRole.{canCreateConsumer, canGetConsumers, canUpdateConsumerLogoUrl, canUpdateConsumerRedirectUrl} +import code.api.util.ApiRole.{canCreateConsumer, canGetConsumers, canUpdateConsumerLogoUrl, canUpdateConsumerName, canUpdateConsumerRedirectUrl} import code.api.util.ErrorMessages.{InvalidJsonFormat, UserNotLoggedIn} import code.api.v3_1_0.ConsumerJsonV310 import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0 @@ -51,10 +51,11 @@ class ConsumerTest extends V510ServerSetup { object ApiEndpoint2 extends Tag(nameOf(Implementations5_1_0.getConsumers)) object ApiEndpoint3 extends Tag(nameOf(Implementations5_1_0.updateConsumerRedirectURL)) object ApiEndpoint4 extends Tag(nameOf(Implementations5_1_0.updateConsumerLogoURL)) + object UpdateConsumerName extends Tag(nameOf(Implementations5_1_0.updateConsumerName)) object GetConsumer extends Tag(nameOf(Implementations5_1_0.getConsumer)) feature("Test all error cases ") { - scenario("We test the authentication errors", GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { + scenario("We test the authentication errors", UpdateConsumerName, GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { When("We make a request v5.1.0") lazy val postApiCollectionJson = SwaggerDefinitionsJSON.postApiCollectionJson400 val requestApiEndpoint1 = (v5_1_0_Request / "management" / "consumers").POST @@ -69,6 +70,9 @@ class ConsumerTest extends V510ServerSetup { val requestApiEndpoint4 = (v5_1_0_Request /"management" / "consumers" / "CONSUMER_ID" / "consumer" / "logo_url").PUT val responseApiEndpoint4 = makePutRequest(requestApiEndpoint4, write(postApiCollectionJson)) + val requestApiUpdateConsumerName = (v5_1_0_Request /"management" / "consumers" / "CONSUMER_ID" / "consumer" / "name").PUT + val responseApiUpdateConsumerName = makePutRequest(requestApiUpdateConsumerName, write(postApiCollectionJson)) + Then(s"we should get the error messages") responseApiEndpoint1.code should equal(401) responseApiEndpoint2.code should equal(401) @@ -79,6 +83,9 @@ class ConsumerTest extends V510ServerSetup { responseApiEndpoint3.body.toString contains(s"$UserNotLoggedIn") should be (true) responseApiEndpoint4.body.toString contains(s"$UserNotLoggedIn") should be (true) + responseApiUpdateConsumerName.code should equal(401) + responseApiUpdateConsumerName.body.toString contains(s"$UserNotLoggedIn") should be (true) + // Endpoint GetConsumer val requestApiEndpoint5 = (v5_1_0_Request / "management" / "consumers" / "whatever").GET val responseApiEndpoint5 = makeGetRequest(requestApiEndpoint5) @@ -86,7 +93,7 @@ class ConsumerTest extends V510ServerSetup { responseApiEndpoint5.body.toString contains(s"$UserNotLoggedIn") should be (true) } - scenario("We test the missing roles errors", GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { + scenario("We test the missing roles errors", UpdateConsumerName, GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { When("We make a request v5.1.0") lazy val wrongJsonForTesting = SwaggerDefinitionsJSON.routing @@ -101,6 +108,9 @@ class ConsumerTest extends V510ServerSetup { val requestApiEndpoint4 = (v5_1_0_Request /"management" / "consumers" / "CONSUMER_ID" / "consumer" / "logo_url").PUT<@ (user1) val responseApiEndpoint4 = makePutRequest(requestApiEndpoint4, write(wrongJsonForTesting)) + + val requestApiUpdateConsumerName = (v5_1_0_Request /"management" / "consumers" / "CONSUMER_ID" / "consumer" / "name").PUT<@ (user1) + val responseApiUpdateConsumerName = makePutRequest(requestApiUpdateConsumerName, write(wrongJsonForTesting)) Then(s"we should get the error messages") responseApiEndpoint1.code should equal(403) @@ -111,6 +121,8 @@ class ConsumerTest extends V510ServerSetup { responseApiEndpoint3.body.toString contains(s"$canUpdateConsumerRedirectUrl") should be (true) responseApiEndpoint4.code should equal(403) responseApiEndpoint4.body.toString contains(s"$canUpdateConsumerLogoUrl") should be (true) + responseApiUpdateConsumerName.code should equal(403) + responseApiUpdateConsumerName.body.toString contains(s"$canUpdateConsumerName") should be (true) // Endpoint GetConsumer val requestApiEndpoint5 = (v5_1_0_Request / "management" / "consumers" / "whatever").GET <@ user1 @@ -119,12 +131,13 @@ class ConsumerTest extends V510ServerSetup { responseApiEndpoint5.body.toString contains (s"$canGetConsumers") should be(true) } - scenario("We added the proper roles, but wrong json", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { + scenario("We added the proper roles, but wrong json", UpdateConsumerName, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { When("we first grant the missing roles:") Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canCreateConsumer.toString) Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerLogoUrl.toString) Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerRedirectUrl.toString) - + Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerName.toString) + When("We make a request v5.1.0") lazy val wrongJsonForTesting = SwaggerDefinitionsJSON.postApiCollectionJson400 val requestApiEndpoint1 = (v5_1_0_Request / "management" / "consumers").POST<@ (user1) @@ -135,7 +148,10 @@ class ConsumerTest extends V510ServerSetup { val requestApiEndpoint4 = (v5_1_0_Request /"management" / "consumers" / "CONSUMER_ID" / "consumer" / "logo_url").PUT<@ (user1) val responseApiEndpoint4 = makePutRequest(requestApiEndpoint4, write(wrongJsonForTesting)) - + + val requestApiUpdateConsumerName = (v5_1_0_Request / "management" / "consumers" / "CONSUMER_ID" / "consumer" / "name").PUT <@ (user1) + val responseApiUpdateConsumerName = makePutRequest(requestApiUpdateConsumerName, write(wrongJsonForTesting)) + Then(s"we should get the error messages") responseApiEndpoint1.code should equal(400) responseApiEndpoint1.body.toString contains(s"$InvalidJsonFormat") should be (true) @@ -143,21 +159,25 @@ class ConsumerTest extends V510ServerSetup { responseApiEndpoint3.body.toString contains(s"$InvalidJsonFormat") should be (true) responseApiEndpoint4.code should equal(400) responseApiEndpoint4.body.toString contains(s"$InvalidJsonFormat") should be (true) + responseApiUpdateConsumerName.code should equal(400) + responseApiUpdateConsumerName.body.toString contains(s"$InvalidJsonFormat") should be (true) } } feature(s"test all successful cases") { - scenario("we create, update and get consumers", GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { + scenario("we create, update and get consumers", UpdateConsumerName, GetConsumer, ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) { When("we first grant the missing roles:") Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canCreateConsumer.toString) Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canGetConsumers.toString) Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerLogoUrl.toString) Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerRedirectUrl.toString) + Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canUpdateConsumerName.toString) lazy val createConsumerRequestJsonV510 = SwaggerDefinitionsJSON.createConsumerRequestJsonV510 lazy val consumerRedirectUrlJSON = SwaggerDefinitionsJSON.consumerRedirectUrlJSON lazy val consumerLogoUrlJson = SwaggerDefinitionsJSON.consumerLogoUrlJson + lazy val consumerNameJson = SwaggerDefinitionsJSON.consumerNameJson val requestApiEndpoint1 = (v5_1_0_Request / "management" / "consumers").POST<@ (user1) val responseApiEndpoint1 = makePostRequest(requestApiEndpoint1, write(createConsumerRequestJsonV510)) val consumerId = responseApiEndpoint1.body.extract[ConsumerJsonV510].consumer_id @@ -175,6 +195,11 @@ class ConsumerTest extends V510ServerSetup { val responseApiEndpoint4 = makePutRequest(requestApiEndpoint4, write(consumerLogoUrlJson)) val logoUrl = responseApiEndpoint4.body.extract[ConsumerJsonV510].logo_url logoUrl.head shouldBe(consumerLogoUrlJson.logo_url) + + val requestApiUpdateConsumerName = (v5_1_0_Request /"management" / "consumers" / consumerId / "consumer" / "name").PUT<@ (user1) + val responseApiUpdateConsumerName = makePutRequest(requestApiUpdateConsumerName, write(consumerNameJson)) + val name = responseApiUpdateConsumerName.body.extract[ConsumerJsonV510].app_name + name shouldBe(consumerNameJson.app_name) Then(s"we should get the error messages") responseApiEndpoint1.code should equal(201)