Merge pull request #2168 from hongwei1/develop

refactor/close two tickets
This commit is contained in:
Simon Redfern 2023-01-13 14:59:31 +01:00 committed by GitHub
commit 8b1f252d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 90 additions and 18 deletions

View File

@ -611,7 +611,7 @@ class Boot extends MdcLoggable {
// Check to see if the user explicitly requests a new locale
// In case it's true we use that value to set up a new cookie value
S.param("locale") match {
S.param(PARAM_LOCALE) match {
case Full(requestedLocale) if requestedLocale != null => {
val computedLocale: Locale = I18NUtil.computeLocale(requestedLocale)
val id: Long = AuthUser.getCurrentUser.map(_.user.userPrimaryKey.value).getOrElse(0)

View File

@ -1,5 +1,6 @@
package code.accountattribute
import code.api.Constant.{PARAM_LOCALE, PARAM_TIMESTAMP}
import code.api.attributedefinition.AttributeDefinition
import code.products.MappedProduct
import code.util.{AttributeQueryTrait, MappedUUID, UUIDString}
@ -154,11 +155,14 @@ object MappedAccountAttributeProvider extends AccountAttributeProvider {
}
override def getAccountIdsByParams(bankId: BankId, params: Map[String, List[String]]): Future[Box[List[String]]] = Future {
val paramFiltered = params.filterNot(_._1 == PARAM_TIMESTAMP) // ignore `_timestamp_` parameter, it is for invalid Browser caching
.filterNot(_._1 == PARAM_LOCALE)
Box !! {
if (params.isEmpty) {
if (paramFiltered.isEmpty) {
MappedAccountAttribute.findAll(By(MappedAccountAttribute.mBankIdId, bankId.value)).map(_.accountId.value)
} else {
val paramList = params.toList
val paramList = paramFiltered.toList.filterNot(_._1 == PARAM_TIMESTAMP).filterNot(_._1 == PARAM_LOCALE)
val parameters: List[String] = MappedAccountAttribute.getParameters(paramList)
val sqlParametersFilter = MappedAccountAttribute.getSqlParametersFilter(paramList)
val accountIdList = paramList.isEmpty match {

View File

@ -83,7 +83,7 @@ case class APIFailureNewStyle(failMsg: String,
val errorCode = extractErrorMessageCode(failMsg)
val errorBody = extractErrorMessageBody(failMsg)
val localeUrlParameter = getHttpRequestUrlParam(ccl.map(_.url).getOrElse(""),"locale")
val localeUrlParameter = getHttpRequestUrlParam(ccl.map(_.url).getOrElse(""),PARAM_LOCALE)
val localeFromUrl = I18NUtil.computeLocale(localeUrlParameter)

View File

@ -1,5 +1,7 @@
package code.api.ResourceDocs1_4_0
import code.api.Constant.PARAM_LOCALE
import java.util.UUID.randomUUID
import code.api.OBPRestHelper
import code.api.builder.OBP_APIBuilder
@ -989,7 +991,7 @@ object ResourceDocsAPIMethodsUtil extends MdcLoggable{
// So we can produce a reduced list of resource docs to prevent manual editing of swagger files.
val languageParam = for {
x <- S.param("language").or(S.param("locale"))
x <- S.param("language").or(S.param(PARAM_LOCALE))
y <- stringToLanguageParam(x)
} yield y
logger.info(s"languageParam is $languageParam")

View File

@ -45,6 +45,8 @@ object Constant extends MdcLoggable {
final val OUTGOING_SETTLEMENT_ACCOUNT_ID = "OBP-OUTGOING-SETTLEMENT-ACCOUNT"
final val ALL_CONSUMERS = "ALL_CONSUMERS"
final val PARAM_LOCALE = "locale"
final val PARAM_TIMESTAMP = "_timestamp_"
}

View File

@ -1,6 +1,7 @@
package code.api.dynamic.entity
import code.DynamicData.{DynamicData, DynamicDataProvider}
import code.api.Constant.PARAM_LOCALE
import code.api.dynamic.endpoint.helper.{DynamicEndpointHelper, MockResponseHolder}
import code.api.dynamic.endpoint.helper.DynamicEndpointHelper.DynamicReq
import code.api.dynamic.endpoint.helper.MockResponseHolder
@ -65,7 +66,7 @@ trait APIMethodsDynamicEntity {
case map if map.isEmpty => resultList
case params =>
val filteredWithFieldValue = resultList.arr.filter { jValue =>
params.filter(_._1!="locale").forall { kv =>
params.filter(_._1!=PARAM_LOCALE).forall { kv =>
val (path, values) = kv
values.exists(JsonUtils.isFieldEquals(jValue, path, _))
}

View File

@ -1,5 +1,6 @@
package code.api.util
import code.api.Constant.PARAM_LOCALE
import code.api.util.APIUtil.{getOAuth2ServerUrl, getObpApiRoot, getServerUrl}
import code.api.util.ExampleValue.{accountIdExample, bankIdExample, customerIdExample, userIdExample}
import code.util.Helper.MdcLoggable
@ -2126,7 +2127,7 @@ object Glossary extends MdcLoggable {
| "picture": "https://lh5.googleusercontent.com/-Xd44hnJ6TDo/AAAAAAAAAAI/AAAAAAAAAAA/AKxrwcadwzhm4N4tWk5E8Avxi-ZK6ks4qg/s96-c/photo.jpg",
| "given_name": "Marko",
| "family_name": "Milić",
| "locale": "en",
| $PARAM_LOCALE: "en",
| "iat": 1547705691,
| "exp": 1547709291
| }

View File

@ -1,5 +1,7 @@
package code.api.util
import code.api.Constant.PARAM_LOCALE
import java.util.{Date, Locale}
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
@ -25,7 +27,7 @@ object I18NUtil {
def currentLocale() : Locale = {
// Cookie name
val localeCookieName = "SELECTED_LOCALE"
S.param("locale") match {
S.param(PARAM_LOCALE) match {
// 1st choice: Use query parameter as a source of truth if any
case Full(requestedLocale) if requestedLocale != null => {
val computedLocale = I18NUtil.computeLocale(requestedLocale)

View File

@ -1,10 +1,10 @@
package code.api.v3_0_0
import java.util.regex.Pattern
import code.accountattribute.AccountAttributeX
import code.accountholders.AccountHolders
import code.api.APIFailureNewStyle
import code.api.Constant.{PARAM_LOCALE, PARAM_TIMESTAMP}
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{bankJSON, banksJSON, branchJsonV300, _}
import code.api.util.APIUtil.{getGlossaryItems, _}
@ -501,7 +501,8 @@ trait APIMethods300 {
availableBankIdAccountIdList <- Future {
Views.views.vend.getAllFirehoseAccounts(bank.bankId).map(a => BankIdAccountId(a.bankId,a.accountId))
}
params = req.params.filterNot(_._1 == "_timestamp_") // ignore `_timestamp_` parameter, it is for invalid Browser caching
params = req.params.filterNot(_._1 == PARAM_TIMESTAMP) // ignore `_timestamp_` parameter, it is for invalid Browser caching
.filterNot(_._1 == PARAM_LOCALE)
availableBankIdAccountIdList2 <- if(params.isEmpty) {
Future.successful(availableBankIdAccountIdList)
} else {
@ -571,18 +572,21 @@ trait APIMethods300 {
transactionsJsonV300,
List(UserNotLoggedIn, AccountFirehoseNotAllowedOnThisInstance, UserHasMissingRoles, UnknownError),
List(apiTagTransaction, apiTagAccountFirehose, apiTagTransactionFirehose, apiTagFirehoseData, apiTagNewStyle),
Some(List(canUseAccountFirehoseAtAnyBank)))
Some(List(canUseAccountFirehoseAtAnyBank, ApiRole.canUseAccountFirehose))
)
lazy val getFirehoseTransactionsForBankAccount : OBPEndpoint = {
//get private accounts for all banks
case "banks" :: BankId(bankId):: "firehose" :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) :: "transactions" :: Nil JsonGet req => {
cc =>
val allowedEntitlements = canUseAccountFirehoseAtAnyBank :: ApiRole.canUseAccountFirehose :: Nil
val allowedEntitlementsTxt = allowedEntitlements.mkString(" or ")
for {
(Full(u), callContext) <- authenticatedAccess(cc)
_ <- Helper.booleanToFuture(failMsg = AccountFirehoseNotAllowedOnThisInstance , cc=callContext) {
allowAccountFirehose
}
_ <- NewStyle.function.hasEntitlement("", u.userId, ApiRole.canUseAccountFirehoseAtAnyBank, callContext)
_ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = UserHasMissingRoles + allowedEntitlementsTxt)(bankId.value, u.userId, allowedEntitlements, callContext)
(bank, callContext) <- NewStyle.function.getBank(bankId, callContext)
(bankAccount, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext)
view <- NewStyle.function.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankAccount.bankId, bankAccount.accountId),Some(u), callContext)

View File

@ -4,10 +4,10 @@ import java.net.URLEncoder
import java.text.SimpleDateFormat
import java.util
import java.util.{Calendar, Date}
import code.DynamicData.{DynamicData, DynamicDataProvider}
import code.DynamicEndpoint.DynamicEndpointSwagger
import code.accountattribute.AccountAttributeX
import code.api.Constant.{PARAM_LOCALE, PARAM_TIMESTAMP}
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{jsonDynamicResourceDoc, _}
import code.api.UKOpenBanking.v2_0_0.OBP_UKOpenBanking_200
@ -3447,7 +3447,8 @@ trait APIMethods400 {
availableBankIdAccountIdList <- Future {
Views.views.vend.getAllFirehoseAccounts(bank.bankId).map(a => BankIdAccountId(a.bankId,a.accountId))
}
params = req.params.filterNot(_._1 == "_timestamp_") // ignore `_timestamp_` parameter, it is for invalid Browser caching
params = req.params.filterNot(_._1 == PARAM_TIMESTAMP) // ignore `_timestamp_` parameter, it is for invalid Browser caching
.filterNot(_._1 == PARAM_LOCALE)
availableBankIdAccountIdList2 <- if(params.isEmpty) {
Future.successful(availableBankIdAccountIdList)
} else {
@ -5156,13 +5157,14 @@ trait APIMethods400 {
for {
(Full(u), bank, callContext) <- SS.userBank
(privateViewsUserCanAccessAtOneBank, privateAccountAccess) = Views.views.vend.privateViewsUserCanAccessAtBank(u, bankId)
params = req.params
params = req.params.filterNot(_._1 == PARAM_TIMESTAMP) // ignore `_timestamp_` parameter, it is for invalid Browser caching
.filterNot(_._1 == PARAM_LOCALE)
privateAccountAccess2 <- if(params.isEmpty || privateAccountAccess.isEmpty) {
Future.successful(privateAccountAccess)
} else {
AccountAttributeX.accountAttributeProvider.vend
.getAccountIdsByParams(bankId, req.params)
.map { boxedAccountIds =>
.getAccountIdsByParams(bankId, params)
.map { boxedAccountIds =>
val accountIds = boxedAccountIds.getOrElse(Nil)
privateAccountAccess.filter(aa => accountIds.contains(aa.account_id.get))
}

View File

@ -2,7 +2,7 @@ package code.api.v3_0_0
import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole
import code.api.util.ApiRole.CanUseAccountFirehoseAtAnyBank
import code.api.util.ApiRole.{CanUseAccountFirehose, CanUseAccountFirehoseAtAnyBank}
import code.api.util.ErrorMessages.AccountFirehoseNotAllowedOnThisInstance
import code.api.v3_0_0.OBPAPI3_0_0.Implementations3_0_0
import code.entitlement.Entitlement
@ -83,6 +83,18 @@ class FirehoseTest extends V300ServerSetup with PropsReset{
response.code should equal(200)
response.body.extract[ModeratedCoreAccountsJsonV300]
}
scenario("We will call the endpoint with user credentials - bank level role", VersionOfApi, ApiEndpoint4) {
setPropsValues("allow_account_firehose" -> "true")
setPropsValues("enable.force_error" -> "true")
Entitlement.entitlement.vend.addEntitlement(testBankId1.value, resourceUser1.userId, ApiRole.CanUseAccountFirehose.toString)
When("We send the request")
val request = (v3_0Request / "banks" / testBankId1.value / "firehose" / "accounts" / testAccountId1.value / "views" / "owner" / "transactions").GET <@ (user1)
val response = makeGetRequest(request)
Then("We should get a 200 and check the response body")
response.code should equal(200)
response.body.extract[ModeratedCoreAccountsJsonV300]
}
scenario("We will call the endpoint with user credentials, props alias", VersionOfApi, ApiEndpoint4) {
setPropsValues("allow_firehose_views" -> "true")
@ -104,6 +116,7 @@ class FirehoseTest extends V300ServerSetup with PropsReset{
Then("We should get a 403 and check the response body")
response.code should equal(403)
response.body.toString contains (CanUseAccountFirehoseAtAnyBank.toString()) should be(true)
response.body.toString contains (CanUseAccountFirehose.toString()) should be(true)
}
scenario("We will call the endpoint missing props ", VersionOfApi, ApiEndpoint4) {

View File

@ -1,5 +1,6 @@
package code.api.v4_0_0
import code.api.Constant.{PARAM_LOCALE, PARAM_TIMESTAMP}
import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole
import code.api.util.ApiRole.CanUseAccountFirehoseAtAnyBank
@ -64,6 +65,46 @@ class FirehoseTest extends V400ServerSetup with PropsReset{
response.code should equal(400)
response.body.toString contains (AccountFirehoseNotAllowedOnThisInstance) should be (true)
}
scenario("We will test the endpoint URL Params", VersionOfApi, ApiEndpoint1) {
setPropsValues("allow_account_firehose" -> "true")
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanUseAccountFirehoseAtAnyBank.toString)
When("We send the request")
val request = (v4_0_0_Request / "banks" / testBankId1.value / "firehose" / "accounts" / "views" / "firehose").GET <@ (user1)
val response = makeGetRequest(request)
Then("We should get a 200 and check the response body")
response.code should equal(200)
val accounts = response.body.extract[ModeratedFirehoseAccountsJsonV400]
accounts.accounts.length > (0) shouldBe(true)
{
val request = (v4_0_0_Request / "banks" / testBankId1.value / "firehose" / "accounts" / "views" / "firehose").GET <@ (user1) <<? (List(("NoExistingFieldName", "xxxxxx")))
val response = makeGetRequest(request)
Then("We should get a 200 and check the response body")
response.code should equal(200)
val accounts = response.body.extract[ModeratedFirehoseAccountsJsonV400]
accounts.accounts.length shouldBe (0)
}
{
val request = (v4_0_0_Request / "banks" / testBankId1.value / "firehose" / "accounts" / "views" / "firehose").GET <@ (user1) <<? (List((PARAM_LOCALE, "en_GB")))
val response = makeGetRequest(request)
Then("We should get a 200 and check the response body")
response.code should equal(200)
val accounts = response.body.extract[ModeratedFirehoseAccountsJsonV400]
accounts.accounts.length > (0) shouldBe (true)
}
{
val request = (v4_0_0_Request / "banks" / testBankId1.value / "firehose" / "accounts" / "views" / "firehose").GET <@ (user1) <<? (List((PARAM_TIMESTAMP, "1596762180358")))
val response = makeGetRequest(request)
Then("We should get a 200 and check the response body")
response.code should equal(200)
val accounts = response.body.extract[ModeratedFirehoseAccountsJsonV400]
accounts.accounts.length > (0) shouldBe (true)
}
}
}
feature(s"test $ApiEndpoint2 version $VersionOfApi - Authorized access") {