From 66aa36bf1a3f0f66e203b4b28a2a772f3c906e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 20 Sep 2024 10:46:35 +0200 Subject: [PATCH 01/11] docfix/Add comments regarding user invitation GUI flow --- .../api/v4_0_0/UserInvitationApiAndGuiTest.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/obp-api/src/test/scala/code/api/v4_0_0/UserInvitationApiAndGuiTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/UserInvitationApiAndGuiTest.scala index 5a093b9827..d2c71f26ed 100644 --- a/obp-api/src/test/scala/code/api/v4_0_0/UserInvitationApiAndGuiTest.scala +++ b/obp-api/src/test/scala/code/api/v4_0_0/UserInvitationApiAndGuiTest.scala @@ -19,6 +19,15 @@ import net.liftweb.util.Helpers.tryo import org.scalatest.Tag import org.scalatestplus.selenium.HtmlUnit +// This tests cover User Invitation Flow regarding APIs and GUI pages +// Tests for GUI flow cover: +// 1) fulfilling user invitation form and submitting +// the link for a form is something like this: (http://localhost:8016/user-invitation?id=7847276804754111643) +// and it is received via email +// use the props "user_invitation_link_base_URL" as a reference to a related code +// 2) set a new password at password form and submit +// the link for a form is something like this: (http://localhost:8016/user_mgt/reset_password/IXIU0TVDUCKOH3RWEJF0XSSHNKSEFTQT?action=set) +// 3) redirect to a home page and check the user is logged in class UserInvitationApiAndGuiTest extends V400ServerSetup { /** * Test tags @@ -107,7 +116,7 @@ class UserInvitationApiAndGuiTest extends V400ServerSetup { button.isEnabled } } - def submitForm(loginPage: String, invitation: UserInvitation): Box[Boolean]= { + def checkUserInvitationGuiFlow(loginPage: String, invitation: UserInvitation): Box[Boolean]= { tryo { go.to(loginPage) checkbox("consent_for_collecting_checkbox").select @@ -142,7 +151,7 @@ class UserInvitationApiAndGuiTest extends V400ServerSetup { } - + feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") { scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) { @@ -204,7 +213,7 @@ class UserInvitationApiAndGuiTest extends V400ServerSetup { b.checkSubmitButtonEnabled(pageUrl) should equal(true) // Submit form - b.submitForm(pageUrl, invitation) should equal(true) + b.checkUserInvitationGuiFlow(pageUrl, invitation) should equal(true) // Clean the resources b.closeAndQuit() From df65166f5f61e291a7b26665e09f143a2ec3f18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 20 Sep 2024 14:13:54 +0200 Subject: [PATCH 02/11] feature/Add endpoint Get Customer by Legal Name v5.1.0 --- .../SwaggerDefinitionsJSON.scala | 1 + .../main/scala/code/api/util/NewStyle.scala | 5 ++ .../scala/code/api/v5_1_0/APIMethods510.scala | 46 ++++++++++++++++++- .../code/api/v5_1_0/JSONFactory5.1.0.scala | 2 + .../scala/code/bankconnectors/Connector.scala | 1 + .../bankconnectors/LocalMappedConnector.scala | 4 ++ .../code/customer/CustomerProvider.scala | 3 +- .../customer/MappedCustomerProvider.scala | 7 +++ .../scala/code/api/v5_1_0/CustomerTest.scala | 40 +++++++++++++++- 9 files changed, 105 insertions(+), 4 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 d4fc1a8dbd..7b42e0e228 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 @@ -2656,6 +2656,7 @@ object SwaggerDefinitionsJSON { val putCustomerBranchJsonV310 = PutUpdateCustomerBranchJsonV310(branch_id = "123") val postCustomerNumberJsonV310 = PostCustomerNumberJsonV310(customer_number = ExampleValue.customerNumberExample.value) + val postCustomerLegalNameJsonV510 = PostCustomerLegalNameJsonV510(legal_name = ExampleValue.legalNameExample.value) val postCustomerPhoneNumberJsonV400 = PostCustomerPhoneNumberJsonV400(mobile_phone_number = ExampleValue.mobileNumberExample.value) val putUpdateCustomerEmailJsonV310 = PutUpdateCustomerEmailJsonV310("marko@tesobe.com") val putUpdateCustomerNumberJsonV310 = PutUpdateCustomerNumberJsonV310(customerNumberExample.value) 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 b73b9a2e43..b302148da5 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -728,6 +728,11 @@ object NewStyle extends MdcLoggable{ i => (connectorEmptyResponse(i._1, callContext), i._2) } } + def getCustomersByCustomerLegalName(bankId : BankId, legalName: String, callContext: Option[CallContext]): OBPReturnType[List[Customer]] = { + Connector.connector.vend.getCustomersByCustomerLegalName(bankId, legalName, callContext) map { + i => (connectorEmptyResponse(i._1, callContext), i._2) + } + } def getCustomerByCustomerId(customerId : String, callContext: Option[CallContext]): OBPReturnType[Customer] = { Connector.connector.vend.getCustomerByCustomerId(customerId, callContext) map { unboxFullOrFail(_, callContext, s"$CustomerNotFoundByCustomerId. Current CustomerId($customerId)", 404) 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 ab1aa17571..a18dde7aee 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 @@ -21,7 +21,7 @@ import code.api.v2_1_0.{ConsumerRedirectUrlJSON, JSONFactory210} import code.api.v2_2_0.JSONFactory220 import code.api.v3_0_0.JSONFactory300 import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson -import code.api.v3_1_0.{ConsentJsonV310, PostConsentBodyCommonJson} +import code.api.v3_1_0.{ConsentJsonV310, JSONFactory310, PostConsentBodyCommonJson} import code.api.v3_1_0.JSONFactory310.createBadLoginStatusJson import code.api.v4_0_0.JSONFactory400.{createAccountBalancesJson, createBalancesJson, createNewCoreBankAccountJson} import code.api.v4_0_0.{JSONFactory400, PostAccountAccessJsonV400, PostApiCollectionJson400, RevokedJsonV400} @@ -1599,6 +1599,50 @@ trait APIMethods510 { } } } + + + resourceDocs += ResourceDoc( + getCustomersByLegalName, + implementedInApiVersion, + nameOf(getCustomersByLegalName), + "POST", + "/banks/BANK_ID/customers/legal-name", + "Get Customer by Legal Name", + s"""Gets the Customer specified by Legal Name. + | + | + |${authenticationRequiredMessage(true)} + | + |""", + postCustomerLegalNameJsonV510, + customerJsonV310, + List( + UserNotLoggedIn, + UserCustomerLinksNotFoundForUser, + UnknownError + ), + List(apiTagCustomer, apiTagKyc), + Some(List(canGetCustomer)) + ) + + lazy val getCustomersByLegalName: OBPEndpoint = { + case "banks" :: BankId(bankId) :: "customers" :: "legal-name" :: Nil JsonPost json -> _ => { + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- authenticatedAccess(cc) + (bank, callContext) <- NewStyle.function.getBank(bankId, callContext) + _ <- NewStyle.function.hasEntitlement(bankId.value, u.userId, canGetCustomer, callContext) + failMsg = s"$InvalidJsonFormat The Json body should be the $PostCustomerLegalNameJsonV510 " + postedData <- NewStyle.function.tryons(failMsg, 400, callContext) { + json.extract[PostCustomerLegalNameJsonV510] + } + (customer, callContext) <- NewStyle.function.getCustomersByCustomerLegalName(bank.bankId, postedData.legal_name, callContext) + } yield { + (JSONFactory300.createCustomersJson(customer), HttpCode.`200`(callContext)) + } + } + } staticResourceDocs += ResourceDoc( 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 428be9ab19..0b175cc552 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 @@ -290,6 +290,8 @@ case class UserAttributesResponseJsonV510( case class CustomerIdJson(id: String) case class CustomersIdsJsonV510(customers: List[CustomerIdJson]) +case class PostCustomerLegalNameJsonV510(legal_name: String) + case class MetricJsonV510( user_id: String, url: String, diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index e119115106..4bc96a738a 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -2076,6 +2076,7 @@ trait Connector extends MdcLoggable { def getCustomers(bankId : BankId, callContext: Option[CallContext], queryParams: List[OBPQueryParam] = Nil): Future[Box[List[Customer]]] = Future{Failure(setUnimplementedError)} def getCustomersByCustomerPhoneNumber(bankId : BankId, phoneNumber: String, callContext: Option[CallContext]): OBPReturnType[Box[List[Customer]]] = Future{(Failure(setUnimplementedError), callContext)} + def getCustomersByCustomerLegalName(bankId: BankId, legalName: String, callContext: Option[CallContext]): OBPReturnType[Box[List[Customer]]] = Future{(Failure(setUnimplementedError), callContext)} def getCheckbookOrders( diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 8f1b649bea..8172a41d1a 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -3782,6 +3782,10 @@ object LocalMappedConnector extends Connector with MdcLoggable { CustomerX.customerProvider.vend.getCustomersByCustomerPhoneNumber(bankId, phoneNumber) map { (_, callContext) } + override def getCustomersByCustomerLegalName(bankId: BankId, legalName: String, callContext: Option[CallContext]): OBPReturnType[Box[List[Customer]]] = + CustomerX.customerProvider.vend.getCustomersByCustomerLegalName(bankId, legalName) map { + (_, callContext) + } override def getCustomerAddress(customerId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[CustomerAddress]]] = CustomerAddressX.address.vend.getAddress(customerId) map { diff --git a/obp-api/src/main/scala/code/customer/CustomerProvider.scala b/obp-api/src/main/scala/code/customer/CustomerProvider.scala index cbe22885e4..7c4bd205de 100644 --- a/obp-api/src/main/scala/code/customer/CustomerProvider.scala +++ b/obp-api/src/main/scala/code/customer/CustomerProvider.scala @@ -26,7 +26,8 @@ trait CustomerProvider { def getCustomersFuture(bankId : BankId, queryParams: List[OBPQueryParam]): Future[Box[List[Customer]]] def getCustomersByCustomerPhoneNumber(bankId: BankId, phoneNumber: String): Future[Box[List[Customer]]] - + def getCustomersByCustomerLegalName(bankId: BankId, legalName: String): Future[Box[List[Customer]]] + def getCustomerByUserId(bankId: BankId, userId: String): Box[Customer] def getCustomersByUserId(userId: String): List[Customer] diff --git a/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala b/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala index 45d73a3cfc..630b2f66e7 100644 --- a/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala +++ b/obp-api/src/main/scala/code/customer/MappedCustomerProvider.scala @@ -55,6 +55,13 @@ object MappedCustomerProvider extends CustomerProvider with MdcLoggable { ) Full(result) } + override def getCustomersByCustomerLegalName(bankId: BankId, legalName: String): Future[Box[List[Customer]]] = Future { + val result = MappedCustomer.findAll( + By(MappedCustomer.mBank, bankId.value), + Like(MappedCustomer.mLegalName, legalName) + ) + Full(result) + } override def checkCustomerNumberAvailable(bankId : BankId, customerNumber : String) : Boolean = { diff --git a/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala index 3ca4931d94..095dd0bdd6 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala @@ -25,20 +25,21 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v5_1_0 -import java.util.Date - import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.util.APIUtil.OAuth._ +import code.api.util.ApiRole.CanGetCustomer import code.api.util.ErrorMessages._ import code.api.v3_1_0.CustomerJsonV310 import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0 import code.customer.CustomerX +import code.entitlement.Entitlement import code.usercustomerlinks.UserCustomerLink import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.model.ErrorMessage import com.openbankproject.commons.util.ApiVersion import org.scalatest.Tag +import java.util.Date import scala.language.postfixOps class CustomerTest extends V510ServerSetup { @@ -62,6 +63,7 @@ class CustomerTest extends V510ServerSetup { */ object VersionOfApi extends Tag(ApiVersion.v5_1_0.toString) object ApiEndpoint1 extends Tag(nameOf(Implementations5_1_0.getCustomersForUserIdsOnly)) + object ApiEndpoint2 extends Tag(nameOf(Implementations5_1_0.getCustomersByLegalName)) lazy val bankId = testBankId1.value val getCustomerJson = SwaggerDefinitionsJSON.postCustomerOverviewJsonV500 @@ -93,6 +95,40 @@ class CustomerTest extends V510ServerSetup { ids.customers.map(_.id).filter(_ == customer.customer_id).length should equal(1) } } + + feature(s"$ApiEndpoint2 $VersionOfApi - Unauthorized access") { + scenario("We will call the endpoint without user credentials", ApiEndpoint2, VersionOfApi) { + When(s"We make a request $VersionOfApi") + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET + val response = makeGetRequest(request) + Then("We should get a 401") + response.code should equal(401) + And("error should be " + UserNotLoggedIn) + response.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + } + } + feature(s"$ApiEndpoint2 $VersionOfApi - Authorized access without proper role") { + scenario("We will call the endpoint with user credentials", ApiEndpoint2, VersionOfApi) { + When(s"We make a request $VersionOfApi") + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET <@(user1) + val response = makeGetRequest(request) + Then("We should get a 403") + Then("error should be " + UserHasMissingRoles + CanGetCustomer) + response.code should equal(403) + response.body.extract[ErrorMessage].message should be(UserHasMissingRoles + CanGetCustomer) + } + } + feature(s"$ApiEndpoint2 $VersionOfApi - Authorized access with proper role") { + scenario("We will call the endpoint with user credentials", ApiEndpoint2, VersionOfApi) { + When(s"We make a request $VersionOfApi") + Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString) + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET <@(user1) + val response = makeGetRequest(request) + Then("We should get a 200") + response.code should equal(200) + val customers = response.body.extract[CustomerJsonV310] + } + } } From a539c45f08099efebb96b12c2042a228b0b093b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 23 Sep 2024 11:18:40 +0200 Subject: [PATCH 03/11] tests/Fix failed Customer tests --- .../scala/code/api/v5_1_0/CustomerTest.scala | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala index 095dd0bdd6..0639de6c79 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/CustomerTest.scala @@ -26,9 +26,11 @@ TESOBE (http://www.tesobe.com/) package code.api.v5_1_0 import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.postCustomerLegalNameJsonV510 import code.api.util.APIUtil.OAuth._ import code.api.util.ApiRole.CanGetCustomer import code.api.util.ErrorMessages._ +import code.api.v3_0_0.CustomerJSONsV300 import code.api.v3_1_0.CustomerJsonV310 import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0 import code.customer.CustomerX @@ -37,6 +39,7 @@ import code.usercustomerlinks.UserCustomerLink import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.model.ErrorMessage import com.openbankproject.commons.util.ApiVersion +import net.liftweb.json.Serialization.write import org.scalatest.Tag import java.util.Date @@ -99,8 +102,8 @@ class CustomerTest extends V510ServerSetup { feature(s"$ApiEndpoint2 $VersionOfApi - Unauthorized access") { scenario("We will call the endpoint without user credentials", ApiEndpoint2, VersionOfApi) { When(s"We make a request $VersionOfApi") - val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET - val response = makeGetRequest(request) + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").POST + val response = makePostRequest(request, write(postCustomerLegalNameJsonV510)) Then("We should get a 401") response.code should equal(401) And("error should be " + UserNotLoggedIn) @@ -110,23 +113,23 @@ class CustomerTest extends V510ServerSetup { feature(s"$ApiEndpoint2 $VersionOfApi - Authorized access without proper role") { scenario("We will call the endpoint with user credentials", ApiEndpoint2, VersionOfApi) { When(s"We make a request $VersionOfApi") - val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET <@(user1) - val response = makeGetRequest(request) + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").POST <@(user1) + val response = makePostRequest(request, write(postCustomerLegalNameJsonV510)) Then("We should get a 403") Then("error should be " + UserHasMissingRoles + CanGetCustomer) response.code should equal(403) - response.body.extract[ErrorMessage].message should be(UserHasMissingRoles + CanGetCustomer) + response.body.extract[ErrorMessage].message should startWith(UserHasMissingRoles + CanGetCustomer) } } feature(s"$ApiEndpoint2 $VersionOfApi - Authorized access with proper role") { scenario("We will call the endpoint with user credentials", ApiEndpoint2, VersionOfApi) { When(s"We make a request $VersionOfApi") Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString) - val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").GET <@(user1) - val response = makeGetRequest(request) + val request = (v5_1_0_Request / "banks" / bankId / "customers" / "legal-name").POST <@(user1) + val response = makePostRequest(request, write(postCustomerLegalNameJsonV510)) Then("We should get a 200") response.code should equal(200) - val customers = response.body.extract[CustomerJsonV310] + val customers = response.body.extract[CustomerJSONsV300] } } From 40c73900c15740bf8543e0585743378395969535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 23 Sep 2024 13:27:14 +0200 Subject: [PATCH 04/11] test/Add tests for endpoint getCustomersByCustomerPhoneNumber --- .../scala/code/api/v4_0_0/APIMethods400.scala | 6 ++- .../scala/code/api/v4_0_0/CustomerTest.scala | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 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 bfdc3711a5..75d477334b 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 @@ -3573,7 +3573,9 @@ trait APIMethods400 extends MdcLoggable { UserCustomerLinksNotFoundForUser, UnknownError ), - List(apiTagCustomer, apiTagKyc)) + List(apiTagCustomer, apiTagKyc), + Some(List(canGetCustomer)) + ) lazy val getCustomersByCustomerPhoneNumber : OBPEndpoint = { case "banks" :: BankId(bankId) :: "search" :: "customers" :: "mobile-phone-number" :: Nil JsonPost json -> _ => { @@ -3585,7 +3587,7 @@ trait APIMethods400 extends MdcLoggable { } (customers, callContext) <- NewStyle.function.getCustomersByCustomerPhoneNumber(bankId, postedData.mobile_phone_number , cc.callContext) } yield { - (JSONFactory300.createCustomersJson(customers), HttpCode.`201`(callContext)) + (JSONFactory300.createCustomersJson(customers), HttpCode.`200`(callContext)) } } } diff --git a/obp-api/src/test/scala/code/api/v4_0_0/CustomerTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/CustomerTest.scala index 80958810d0..93df91f6a9 100644 --- a/obp-api/src/test/scala/code/api/v4_0_0/CustomerTest.scala +++ b/obp-api/src/test/scala/code/api/v4_0_0/CustomerTest.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) package code.api.v4_0_0 import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.postCustomerPhoneNumberJsonV400 import code.api.util.APIUtil.OAuth._ import code.api.util.ApiRole._ import code.api.util.ErrorMessages._ @@ -65,6 +66,7 @@ class CustomerTest extends V400ServerSetup with PropsReset{ object ApiEndpoint1 extends Tag(nameOf(Implementations4_0_0.getCustomersAtAnyBank)) object ApiEndpoint2 extends Tag(nameOf(Implementations4_0_0.getCustomersMinimalAtAnyBank)) object ApiEndpoint3 extends Tag(nameOf(Implementations4_0_0.createCustomer)) + object ApiEndpoint4 extends Tag(nameOf(Implementations4_0_0.getCustomersByCustomerPhoneNumber)) val customerNumberJson = PostCustomerNumberJsonV310(customer_number = "123") val postCustomerJson = SwaggerDefinitionsJSON.postCustomerJsonV310 @@ -190,4 +192,39 @@ class CustomerTest extends V400ServerSetup with PropsReset{ } + feature(s"$ApiEndpoint4 $VersionOfApi - Unauthorized access") { + scenario("We will call the endpoint without user credentials", ApiEndpoint4, VersionOfApi) { + When(s"We make a request $VersionOfApi") + val request = (v4_0_0_Request / "banks" / bankId / "search" / "customers" / "mobile-phone-number").POST + val response = makePostRequest(request, write(postCustomerPhoneNumberJsonV400)) + Then("We should get a 401") + response.code should equal(401) + And("error should be " + UserNotLoggedIn) + response.body.extract[ErrorMessage].message should equal(UserNotLoggedIn) + } + } + feature(s"$ApiEndpoint4 $VersionOfApi - Authorized access without proper role") { + scenario("We will call the endpoint with user credentials", ApiEndpoint4, VersionOfApi) { + When(s"We make a request $VersionOfApi") + val request = (v4_0_0_Request / "banks" / bankId / "search" /"customers" / "mobile-phone-number").POST <@ (user1) + val response = makePostRequest(request, write(postCustomerPhoneNumberJsonV400)) + Then("We should get a 403") + Then("error should be " + UserHasMissingRoles + CanGetCustomer) + response.code should equal(403) + response.body.extract[ErrorMessage].message should startWith(UserHasMissingRoles + CanGetCustomer) + } + } + feature(s"$ApiEndpoint4 $VersionOfApi - Authorized access with proper role") { + scenario("We will call the endpoint with user credentials", ApiEndpoint4, VersionOfApi) { + When(s"We make a request $VersionOfApi") + Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString) + val request = (v4_0_0_Request / "banks" / bankId / "search" / "customers" / "mobile-phone-number").POST <@ (user1) + val response = makePostRequest(request, write(postCustomerPhoneNumberJsonV400)) + Then("We should get a 200") + response.code should equal(200) + val customers = response.body.extract[CustomerJSONsV300] + } + } + + } From a652222aaba8ac2c0d5456c6dcbab312bbd152b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 23 Sep 2024 14:17:37 +0200 Subject: [PATCH 05/11] docfix/Tweak endpoint getCustomersByLegalName --- obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 a18dde7aee..9824bfc303 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 @@ -1607,8 +1607,8 @@ trait APIMethods510 { nameOf(getCustomersByLegalName), "POST", "/banks/BANK_ID/customers/legal-name", - "Get Customer by Legal Name", - s"""Gets the Customer specified by Legal Name. + "Get Customers by Legal Name", + s"""Gets the Customers specified by Legal Name. | | |${authenticationRequiredMessage(true)} From 3f5cd7c21fc5fe9bc22f7396e257a4333482cc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Wed, 9 Oct 2024 14:02:13 +0200 Subject: [PATCH 06/11] docfix/Clean up resource doc ?manager=John&count=8 --- .../src/main/scala/code/api/v3_0_0/APIMethods300.scala | 4 ++-- .../src/main/scala/code/api/v3_1_0/APIMethods310.scala | 2 +- .../src/main/scala/code/api/v4_0_0/APIMethods400.scala | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) 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 c1cc6b1994..6cea10a757 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 @@ -528,11 +528,11 @@ trait APIMethods300 { | |optional request parameters for filter with attributes |URL params example: - | /banks/some-bank-id/firehose/accounts/views/owner?manager=John&count=8 + | /banks/some-bank-id/firehose/accounts/views/owner?&limit=50&offset=1 | |to invalid Browser cache, add timestamp query parameter as follow, the parameter name must be `_timestamp_` |URL params example: - | `/banks/some-bank-id/firehose/accounts/views/owner?manager=John&count=8&_timestamp_=1596762180358` + | `/banks/some-bank-id/firehose/accounts/views/owner?&limit=50&offset=1&_timestamp_=1596762180358` | |${authenticationRequiredMessage(true)} | 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 a4f827843b..f041d321b4 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 @@ -2612,7 +2612,7 @@ trait APIMethods310 { |* License the data under this endpoint is released under | |Can filter with attributes name and values. - |URL params example: /banks/some-bank-id/products?manager=John&count=8 + |URL params example: /banks/some-bank-id/products?&limit=50&offset=1 | |${authenticationRequiredMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, 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 329d1a3bbf..144befb4e8 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 @@ -3417,11 +3417,11 @@ trait APIMethods400 extends MdcLoggable { | |optional request parameters for filter with attributes |URL params example: - | /banks/some-bank-id/firehose/accounts/views/owner?manager=John&count=8 + | /banks/some-bank-id/firehose/accounts/views/owner?&limit=50&offset=1 | |to invalid Browser cache, add timestamp query parameter as follow, the parameter name must be `_timestamp_` |URL params example: - | `/banks/some-bank-id/firehose/accounts/views/owner?manager=John&count=8&_timestamp_=1596762180358` + | `/banks/some-bank-id/firehose/accounts/views/owner?&limit=50&offset=1&_timestamp_=1596762180358` | |${authenticationRequiredMessage(true)} | @@ -4790,7 +4790,7 @@ trait APIMethods400 extends MdcLoggable { s"""Gets the Customers specified by attributes | |URL params example: /banks/some-bank-id/customers?name=John&age=8 - |URL params example: /banks/some-bank-id/customers?manager=John&count=8 + |URL params example: /banks/some-bank-id/customers?&limit=50&offset=1 | | |""", @@ -5209,7 +5209,7 @@ trait APIMethods400 extends MdcLoggable { |Each account must have at least one private View. | |optional request parameters for filter with attributes - |URL params example: /banks/some-bank-id/accounts?manager=John&count=8 + |URL params example: /banks/some-bank-id/accounts?&limit=50&offset=1 | | """.stripMargin, @@ -12187,7 +12187,7 @@ trait APIMethods400 extends MdcLoggable { |* License the data under this endpoint is released under | |Can filter with attributes name and values. - |URL params example: /banks/some-bank-id/products?manager=John&count=8 + |URL params example: /banks/some-bank-id/products?&limit=50&offset=1 | |${authenticationRequiredMessage(!getProductsIsPublic)}""".stripMargin, EmptyBody, From 8a0e3a9f17d6690459bb147dcf28e4909b43dba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 14 Oct 2024 14:50:07 +0200 Subject: [PATCH 07/11] feature/Add a new language - ro_RO --- obp-api/src/main/resources/props/sample.props.template | 2 +- obp-api/src/main/scala/code/api/util/APIUtil.scala | 2 +- obp-api/src/main/scala/code/api/util/ErrorMessages.scala | 2 +- obp-api/src/main/scala/code/snippet/WebUI.scala | 2 ++ obp-api/src/main/webapp/templates-hidden/default.html | 2 ++ 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/obp-api/src/main/resources/props/sample.props.template b/obp-api/src/main/resources/props/sample.props.template index 2e8d973669..2d318e1044 100644 --- a/obp-api/src/main/resources/props/sample.props.template +++ b/obp-api/src/main/resources/props/sample.props.template @@ -560,7 +560,7 @@ webui_register_consumer_success_message_email = Thank you for registering to use # Please note that depricated name ot this props is: language_tag default_locale = en_GB -supported_locales = en_GB,es_ES +supported_locales = en_GB,es_ES,ro_RO ## API Options 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 86c1842d82..cea13966ef 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -840,7 +840,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ /** only support en_GB, es_ES at the moment, will support more later*/ def obpLocaleValidation(value:String): String ={ - if(value.equalsIgnoreCase("es_Es")|| value.equalsIgnoreCase("en_GB")) + if(value.equalsIgnoreCase("es_Es") || value.equalsIgnoreCase("ro_RO") || value.equalsIgnoreCase("en_GB")) SILENCE_IS_GOLDEN else ErrorMessages.InvalidLocale 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 a27ef4248a..f34d034a35 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -112,7 +112,7 @@ object ErrorMessages { val InvalidHttpMethod = "OBP-10037: Incorrect http_method." val InvalidHttpProtocol = "OBP-10038: Incorrect http_protocol." val ServiceIsTooBusy = "OBP-10040: The Service is too busy, please try it later." - val InvalidLocale = "OBP-10041: This locale is not supported. Only the following can be used: en_GB , es_ES." + val InvalidLocale = "OBP-10041: This locale is not supported. Only the following can be used: en_GB, es_ES, ro_RO." // General Sort and Paging val FilterSortDirectionError = "OBP-10023: obp_sort_direction parameter can only take two values: DESC or ASC!" // was OBP-20023 diff --git a/obp-api/src/main/scala/code/snippet/WebUI.scala b/obp-api/src/main/scala/code/snippet/WebUI.scala index 1d2acb2528..ce261776ae 100644 --- a/obp-api/src/main/scala/code/snippet/WebUI.scala +++ b/obp-api/src/main/scala/code/snippet/WebUI.scala @@ -73,6 +73,8 @@ class WebUI extends MdcLoggable{ "#es a [style]" #> s"display: ${displayLanguage("es_ES")}" & "#locale_separator [style]" #> {if(supportedLocales.size == 1) "display: none" else ""} & "#en a [style]" #> s"display: ${displayLanguage("en_GB")}" & + "#locale_separator_ro_RO [style]" #> {if (supportedLocales.size < 3) "display: none" else ""} & + "#ro a [style]" #> s"display: ${displayLanguage("ro_RO")}" & s"#${language.toLowerCase()} *" #> scala.xml.Unparsed(s"${language.toUpperCase()}") } diff --git a/obp-api/src/main/webapp/templates-hidden/default.html b/obp-api/src/main/webapp/templates-hidden/default.html index 2b2c36cc0f..a5b4ff87fb 100644 --- a/obp-api/src/main/webapp/templates-hidden/default.html +++ b/obp-api/src/main/webapp/templates-hidden/default.html @@ -253,6 +253,8 @@ EN | ES + | + RO