diff --git a/.github/workflows/auto_update_base_image.yml b/.github/workflows/auto_update_base_image.yml index 3048faf15..84cec8846 100644 --- a/.github/workflows/auto_update_base_image.yml +++ b/.github/workflows/auto_update_base_image.yml @@ -11,6 +11,7 @@ env: jobs: build: runs-on: ubuntu-latest + if: github.repository == 'OpenBankProject/OBP-API' steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/build_container_develop_branch.yml b/.github/workflows/build_container_develop_branch.yml index 3afc3d6ec..f2905252a 100644 --- a/.github/workflows/build_container_develop_branch.yml +++ b/.github/workflows/build_container_develop_branch.yml @@ -13,7 +13,6 @@ env: DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }} DOCKER_HUB_REPOSITORY: obp-api - jobs: build: runs-on: ubuntu-latest @@ -36,8 +35,8 @@ jobs: - name: Set up JDK 11 uses: actions/setup-java@v4 with: - java-version: '11' - distribution: 'adopt' + java-version: "11" + distribution: "adopt" cache: maven - name: Build with Maven run: | @@ -126,6 +125,7 @@ jobs: path: push/ - name: Build the Docker image + if: github.repository == 'OpenBankProject/OBP-API' run: | echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin docker.io docker build . --file .github/Dockerfile_PreBuild --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:$GITHUB_SHA --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:latest --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:develop @@ -136,9 +136,11 @@ jobs: - uses: sigstore/cosign-installer@4d14d7f17e7112af04ea6108fbb4bfc714c00390 - name: Write signing key to disk (only needed for `cosign sign --key`) + if: github.repository == 'OpenBankProject/OBP-API' run: echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > cosign.key - name: Sign container image + if: github.repository == 'OpenBankProject/OBP-API' run: | cosign sign -y --key cosign.key \ docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:develop @@ -152,5 +154,3 @@ jobs: docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:latest-OC env: COSIGN_PASSWORD: "${{secrets.COSIGN_PASSWORD}}" - - diff --git a/.github/workflows/build_container_non_develop_branch.yml b/.github/workflows/build_container_non_develop_branch.yml index fda13bb72..6fdd52bdd 100644 --- a/.github/workflows/build_container_non_develop_branch.yml +++ b/.github/workflows/build_container_non_develop_branch.yml @@ -3,8 +3,8 @@ name: Build and publish container non develop on: push: branches: - - '**' - - '!develop' + - "*" + - "!develop" env: DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }} @@ -35,8 +35,8 @@ jobs: - name: Set up JDK 11 uses: actions/setup-java@v4 with: - java-version: '11' - distribution: 'adopt' + java-version: "11" + distribution: "adopt" cache: maven - name: Build with Maven run: | @@ -125,6 +125,7 @@ jobs: path: push/ - name: Build the Docker image + if: github.repository == 'OpenBankProject/OBP-API' run: | echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin docker.io docker build . --file .github/Dockerfile_PreBuild --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:$GITHUB_SHA --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:${GITHUB_REF##*/} @@ -135,9 +136,11 @@ jobs: - uses: sigstore/cosign-installer@4d14d7f17e7112af04ea6108fbb4bfc714c00390 - name: Write signing key to disk (only needed for `cosign sign --key`) + if: github.repository == 'OpenBankProject/OBP-API' run: echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > cosign.key - name: Sign container image + if: github.repository == 'OpenBankProject/OBP-API' run: | cosign sign -y --key cosign.key \ docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:${GITHUB_REF##*/} @@ -147,5 +150,3 @@ jobs: docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:$GITHUB_SHA env: COSIGN_PASSWORD: "${{secrets.COSIGN_PASSWORD}}" - - diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml index 61d1e05a5..e0fc7a3d4 100644 --- a/.github/workflows/build_pull_request.yml +++ b/.github/workflows/build_pull_request.yml @@ -3,15 +3,15 @@ name: Build on Pull Request on: pull_request: branches: - - '**' + - "**" env: ## Sets environment variable DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }} - jobs: build: runs-on: ubuntu-latest + if: github.repository == 'OpenBankProject/OBP-API' services: # Label used to access the service container redis: @@ -31,8 +31,8 @@ jobs: - name: Set up JDK 11 uses: actions/setup-java@v4 with: - java-version: '11' - distribution: 'adopt' + java-version: "11" + distribution: "adopt" cache: maven - name: Build with Maven run: | @@ -119,6 +119,3 @@ jobs: with: name: ${{ github.sha }} path: pull/ - - - diff --git a/.github/workflows/run_trivy.yml b/.github/workflows/run_trivy.yml index 4636bd311..53213c031 100644 --- a/.github/workflows/run_trivy.yml +++ b/.github/workflows/run_trivy.yml @@ -12,11 +12,10 @@ env: DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }} DOCKER_HUB_REPOSITORY: obp-api - jobs: build: runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.conclusion == 'success' }} + if: github.repository == 'OpenBankProject/OBP-API' && github.event.workflow_run.conclusion == 'success' steps: - uses: actions/checkout@v4 @@ -38,17 +37,17 @@ jobs: - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: - image-ref: 'docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:${{ github.sha }}' - format: 'template' - template: '@/contrib/sarif.tpl' - output: 'trivy-results.sarif' - security-checks: 'vuln' - severity: 'CRITICAL,HIGH' - timeout: '30m' + image-ref: "docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.DOCKER_HUB_REPOSITORY }}:${{ github.sha }}" + format: "template" + template: "@/contrib/sarif.tpl" + output: "trivy-results.sarif" + security-checks: "vuln" + severity: "CRITICAL,HIGH" + timeout: "30m" cache-dir: .trivy - name: Fix .trivy permissions run: sudo chown -R $(stat . -c %u:%g) .trivy - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v3 with: - sarif_file: 'trivy-results.sarif' \ No newline at end of file + sarif_file: "trivy-results.sarif" diff --git a/.gitignore b/.gitignore index 1b8d28dff..53865fbdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.github/* *.class *.db .DS_Store diff --git a/obp-api/pom.xml b/obp-api/pom.xml index 7379ff566..7af24246b 100644 --- a/obp-api/pom.xml +++ b/obp-api/pom.xml @@ -586,15 +586,9 @@ once . WDF TestSuite.txt - - -Drun.mode=test -XX:MaxMetaspaceSize=1G -Xms2G -Xmx4G -XX:+UseG1GC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+UseStringDeduplication --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.jar=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED + -Drun.mode=test -XX:MaxMetaspaceSize=512m -Xms512m -Xmx512m --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.jar=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED code.external ${maven.test.failure.ignore} - - - - - false @@ -673,26 +667,15 @@ 4.8.1 true - incremental - true -Xms4G -Xmx12G - -Xss4m -XX:MaxMetaspaceSize=4G -XX:+UseG1GC - -XX:+TieredCompilation - -XX:TieredStopAtLevel=1 -deprecation -feature - - -language:implicitConversions - -language:reflectiveCalls - -language:postfixOps - - -Wconf:cat=deprecation&msg=auto-application:s diff --git a/obp-api/src/main/resources/props/sample.props.template b/obp-api/src/main/resources/props/sample.props.template index d181a5a1f..c0f151d83 100644 --- a/obp-api/src/main/resources/props/sample.props.template +++ b/obp-api/src/main/resources/props/sample.props.template @@ -624,6 +624,14 @@ webui_agree_terms_url = #webui_post_consumer_registration_more_info_text = Please tell us more your Application and / or Startup using this link. #webui_post_consumer_registration_submit_button_value=Register consumer +# OBP Portal URL - base URL for the OBP Portal service +webui_obp_portal_url = http://localhost:5174 + +# External Consumer Registration URL - used to redirect "Get API Key" links to an external service +# If not set, defaults to webui_obp_portal_url + "/consumer-registration" +# Set this to redirect to a custom URL for consumer registration +webui_external_consumer_registration_url = http://localhost:5174/consumer-registration + ## Display For Banks section webui_display_for_banks_section = true diff --git a/obp-api/src/main/scala/code/abacrule/AbacRuleEngine.scala b/obp-api/src/main/scala/code/abacrule/AbacRuleEngine.scala index 5b531af98..93fb81537 100644 --- a/obp-api/src/main/scala/code/abacrule/AbacRuleEngine.scala +++ b/obp-api/src/main/scala/code/abacrule/AbacRuleEngine.scala @@ -4,6 +4,7 @@ import code.api.util.{APIUtil, CallContext, DynamicUtil} import code.bankconnectors.Connector import code.model.dataAccess.ResourceUser import code.users.Users +import code.entitlement.Entitlement import com.openbankproject.commons.model._ import com.openbankproject.commons.ExecutionContext.Implicits.global import net.liftweb.common.{Box, Empty, Failure, Full} @@ -26,12 +27,12 @@ object AbacRuleEngine { /** * Type alias for compiled ABAC rule function - * Parameters: authenticatedUser (logged in), authenticatedUserAttributes (non-personal), authenticatedUserAuthContext (auth context), - * onBehalfOfUser (delegation), onBehalfOfUserAttributes, onBehalfOfUserAuthContext, + * Parameters: authenticatedUser (logged in), authenticatedUserAttributes (non-personal), authenticatedUserAuthContext (auth context), authenticatedUserEntitlements (roles), + * onBehalfOfUser (delegation), onBehalfOfUserAttributes, onBehalfOfUserAuthContext, onBehalfOfUserEntitlements, * user, userAttributes, bankOpt, bankAttributes, accountOpt, accountAttributes, transactionOpt, transactionAttributes, customerOpt, customerAttributes * Returns: Boolean (true = allow access, false = deny access) */ - type AbacRuleFunction = (User, List[UserAttributeTrait], List[UserAuthContext], Option[User], List[UserAttributeTrait], List[UserAuthContext], Option[User], List[UserAttributeTrait], Option[Bank], List[BankAttributeTrait], Option[BankAccount], List[AccountAttribute], Option[Transaction], List[TransactionAttribute], Option[TransactionRequest], List[TransactionRequestAttributeTrait], Option[Customer], List[CustomerAttribute], Option[CallContext]) => Boolean + type AbacRuleFunction = (User, List[UserAttributeTrait], List[UserAuthContext], List[Entitlement], Option[User], List[UserAttributeTrait], List[UserAuthContext], List[Entitlement], Option[User], List[UserAttributeTrait], Option[Bank], List[BankAttributeTrait], Option[BankAccount], List[AccountAttribute], Option[Transaction], List[TransactionAttribute], Option[TransactionRequest], List[TransactionRequestAttributeTrait], Option[Customer], List[CustomerAttribute], Option[CallContext]) => Boolean /** * Compile an ABAC rule from Scala code @@ -73,9 +74,11 @@ object AbacRuleEngine { |import com.openbankproject.commons.model._ |import code.model.dataAccess.ResourceUser |import net.liftweb.common._ + |import code.entitlement.Entitlement + |import code.api.util.CallContext | |// ABAC Rule Function - |(authenticatedUser: User, authenticatedUserAttributes: List[UserAttributeTrait], authenticatedUserAuthContext: List[UserAuthContext], onBehalfOfUserOpt: Option[User], onBehalfOfUserAttributes: List[UserAttributeTrait], onBehalfOfUserAuthContext: List[UserAuthContext], userOpt: Option[User], userAttributes: List[UserAttributeTrait], bankOpt: Option[Bank], bankAttributes: List[BankAttributeTrait], accountOpt: Option[BankAccount], accountAttributes: List[AccountAttribute], transactionOpt: Option[Transaction], transactionAttributes: List[TransactionAttribute], transactionRequestOpt: Option[TransactionRequest], transactionRequestAttributes: List[TransactionRequestAttributeTrait], customerOpt: Option[Customer], customerAttributes: List[CustomerAttribute], callContext: Option[code.api.util.CallContext]) => { + |(authenticatedUser: User, authenticatedUserAttributes: List[UserAttributeTrait], authenticatedUserAuthContext: List[UserAuthContext], authenticatedUserEntitlements: List[Entitlement], onBehalfOfUserOpt: Option[User], onBehalfOfUserAttributes: List[UserAttributeTrait], onBehalfOfUserAuthContext: List[UserAuthContext], onBehalfOfUserEntitlements: List[Entitlement], userOpt: Option[User], userAttributes: List[UserAttributeTrait], bankOpt: Option[Bank], bankAttributes: List[BankAttributeTrait], accountOpt: Option[BankAccount], accountAttributes: List[AccountAttribute], transactionOpt: Option[Transaction], transactionAttributes: List[TransactionAttribute], transactionRequestOpt: Option[TransactionRequest], transactionRequestAttributes: List[TransactionRequestAttributeTrait], customerOpt: Option[Customer], customerAttributes: List[CustomerAttribute], callContext: Option[code.api.util.CallContext]) => { | $ruleCode |} |""".stripMargin @@ -129,6 +132,12 @@ object AbacRuleEngine { 5.seconds ) + // Fetch entitlements for authenticated user + authenticatedUserEntitlements = Await.result( + code.api.util.NewStyle.function.getEntitlementsByUserId(authenticatedUserId, Some(callContext)), + 5.seconds + ) + // Fetch onBehalfOf user if provided (delegation scenario) onBehalfOfUserOpt <- onBehalfOfUserId match { case Some(obUserId) => Users.users.vend.getUserByUserId(obUserId).map(Some(_)) @@ -155,6 +164,16 @@ object AbacRuleEngine { case None => List.empty[UserAuthContext] } + // Fetch entitlements for onBehalfOf user if provided + onBehalfOfUserEntitlements = onBehalfOfUserId match { + case Some(obUserId) => + Await.result( + code.api.util.NewStyle.function.getEntitlementsByUserId(obUserId, Some(callContext)), + 5.seconds + ) + case None => List.empty[Entitlement] + } + // Fetch target user if userId is provided userOpt <- userId match { case Some(uId) => Users.users.vend.getUserByUserId(uId).map(Some(_)) @@ -274,13 +293,77 @@ object AbacRuleEngine { // Compile and execute the rule compiledFunc <- compileRule(ruleId, rule.ruleCode) result <- tryo { - compiledFunc(authenticatedUser, authenticatedUserAttributes, authenticatedUserAuthContext, onBehalfOfUserOpt, onBehalfOfUserAttributes, onBehalfOfUserAuthContext, userOpt, userAttributes, bankOpt, bankAttributes, accountOpt, accountAttributes, transactionOpt, transactionAttributes, transactionRequestOpt, transactionRequestAttributes, customerOpt, customerAttributes, Some(callContext)) + compiledFunc(authenticatedUser, authenticatedUserAttributes, authenticatedUserAuthContext, authenticatedUserEntitlements, onBehalfOfUserOpt, onBehalfOfUserAttributes, onBehalfOfUserAuthContext, onBehalfOfUserEntitlements, userOpt, userAttributes, bankOpt, bankAttributes, accountOpt, accountAttributes, transactionOpt, transactionAttributes, transactionRequestOpt, transactionRequestAttributes, customerOpt, customerAttributes, Some(callContext)) } } yield result } + /** + * Execute all active ABAC rules with a specific policy (OR logic - at least one must pass) + * @param logic The logic to apply: "AND" (all must pass), "OR" (any must pass), "XOR" (exactly one must pass) + * + * @param policy The policy to filter rules by + * @param authenticatedUserId The ID of the authenticated user + * @param onBehalfOfUserId Optional ID of user being acted on behalf of + * @param userId The ID of the target user to evaluate + * @param callContext Call context for fetching objects + * @param bankId Optional bank ID + * @param accountId Optional account ID + * @param viewId Optional view ID + * @param transactionId Optional transaction ID + * @param transactionRequestId Optional transaction request ID + * @param customerId Optional customer ID + * @return Box[Boolean] - Full(true) if at least one rule passes (OR logic), Full(false) if all fail + */ + def executeRulesByPolicy( + policy: String, + authenticatedUserId: String, + onBehalfOfUserId: Option[String] = None, + userId: Option[String] = None, + callContext: CallContext, + bankId: Option[String] = None, + accountId: Option[String] = None, + viewId: Option[String] = None, + transactionId: Option[String] = None, + transactionRequestId: Option[String] = None, + customerId: Option[String] = None + ): Box[Boolean] = { + val rules = MappedAbacRuleProvider.getActiveAbacRulesByPolicy(policy) + + if (rules.isEmpty) { + // No rules for this policy - default to allow + Full(true) + } else { + // Execute all rules and check if at least one passes + val results = rules.map { rule => + executeRule( + ruleId = rule.abacRuleId, + authenticatedUserId = authenticatedUserId, + onBehalfOfUserId = onBehalfOfUserId, + userId = userId, + callContext = callContext, + bankId = bankId, + accountId = accountId, + viewId = viewId, + transactionId = transactionId, + transactionRequestId = transactionRequestId, + customerId = customerId + ) + } + + // Count successes and failures + val successes = results.filter { + case Full(true) => true + case _ => false + } + + // At least one rule must pass (OR logic) + Full(successes.nonEmpty) + } + } + /** * Validate ABAC rule code by attempting to compile it * diff --git a/obp-api/src/main/scala/code/abacrule/AbacRuleTrait.scala b/obp-api/src/main/scala/code/abacrule/AbacRuleTrait.scala index e4309f342..9e9a22885 100644 --- a/obp-api/src/main/scala/code/abacrule/AbacRuleTrait.scala +++ b/obp-api/src/main/scala/code/abacrule/AbacRuleTrait.scala @@ -14,6 +14,7 @@ trait AbacRuleTrait { def ruleCode: String def isActive: Boolean def description: String + def policy: String def createdByUserId: String def updatedByUserId: String } @@ -30,6 +31,7 @@ class AbacRule extends AbacRuleTrait with LongKeyedMapper[AbacRule] with IdPK wi override def defaultValue = true } object Description extends MappedText(this) + object Policy extends MappedText(this) object CreatedByUserId extends MappedString(this, 255) object UpdatedByUserId extends MappedString(this, 255) @@ -38,6 +40,7 @@ class AbacRule extends AbacRuleTrait with LongKeyedMapper[AbacRule] with IdPK wi override def ruleCode: String = RuleCode.get override def isActive: Boolean = IsActive.get override def description: String = Description.get + override def policy: String = Policy.get override def createdByUserId: String = CreatedByUserId.get override def updatedByUserId: String = UpdatedByUserId.get } @@ -51,10 +54,13 @@ trait AbacRuleProvider { def getAbacRuleByName(ruleName: String): Box[AbacRuleTrait] def getAllAbacRules(): List[AbacRuleTrait] def getActiveAbacRules(): List[AbacRuleTrait] + def getAbacRulesByPolicy(policy: String): List[AbacRuleTrait] + def getActiveAbacRulesByPolicy(policy: String): List[AbacRuleTrait] def createAbacRule( ruleName: String, ruleCode: String, description: String, + policy: String, isActive: Boolean, createdBy: String ): Box[AbacRuleTrait] @@ -63,6 +69,7 @@ trait AbacRuleProvider { ruleName: String, ruleCode: String, description: String, + policy: String, isActive: Boolean, updatedBy: String ): Box[AbacRuleTrait] @@ -87,10 +94,23 @@ object MappedAbacRuleProvider extends AbacRuleProvider { AbacRule.findAll(By(AbacRule.IsActive, true)) } + override def getAbacRulesByPolicy(policy: String): List[AbacRuleTrait] = { + AbacRule.findAll().filter { rule => + rule.policy.split(",").map(_.trim).contains(policy) + } + } + + override def getActiveAbacRulesByPolicy(policy: String): List[AbacRuleTrait] = { + AbacRule.findAll(By(AbacRule.IsActive, true)).filter { rule => + rule.policy.split(",").map(_.trim).contains(policy) + } + } + override def createAbacRule( ruleName: String, ruleCode: String, description: String, + policy: String, isActive: Boolean, createdBy: String ): Box[AbacRuleTrait] = { @@ -99,6 +119,7 @@ object MappedAbacRuleProvider extends AbacRuleProvider { .RuleName(ruleName) .RuleCode(ruleCode) .Description(description) + .Policy(policy) .IsActive(isActive) .CreatedByUserId(createdBy) .UpdatedByUserId(createdBy) @@ -111,6 +132,7 @@ object MappedAbacRuleProvider extends AbacRuleProvider { ruleName: String, ruleCode: String, description: String, + policy: String, isActive: Boolean, updatedBy: String ): Box[AbacRuleTrait] = { @@ -121,6 +143,7 @@ object MappedAbacRuleProvider extends AbacRuleProvider { .RuleName(ruleName) .RuleCode(ruleCode) .Description(description) + .Policy(policy) .IsActive(isActive) .UpdatedByUserId(updatedBy) .saveMe() diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/AccountsApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/AccountsApi.scala index 30cf5ae5b..24935484d 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/AccountsApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/AccountsApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/BankingApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/BankingApi.scala index 65bcbea58..447383855 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/BankingApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/BankingApi.scala @@ -1,5 +1,6 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil.{defaultBankId, _} import code.api.util.ApiTag._ diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CommonApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CommonApi.scala index 0056a83bb..b649a0844 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CommonApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CommonApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CustomerApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CustomerApi.scala index b503872f4..5041a61af 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CustomerApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/CustomerApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DirectDebitsApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DirectDebitsApi.scala index 7ad501032..035ff3d34 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DirectDebitsApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DirectDebitsApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DiscoveryApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DiscoveryApi.scala index 3962e839a..70bafc161 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DiscoveryApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/DiscoveryApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/PayeesApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/PayeesApi.scala index 177ee2322..335b82fc8 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/PayeesApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/PayeesApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ProductsApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ProductsApi.scala index 66437f5ef..04d227672 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ProductsApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ProductsApi.scala @@ -1,5 +1,6 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ScheduledPaymentsApi.scala b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ScheduledPaymentsApi.scala index bbccbf617..037447e0c 100644 --- a/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ScheduledPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/AUOpenBanking/v1_0_0/ScheduledPaymentsApi.scala @@ -1,5 +1,7 @@ package code.api.AUOpenBanking.v1_0_0 +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountAccessConsentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountAccessConsentsApi.scala index 33cc3dedf..450c57c03 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountAccessConsentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountAccessConsentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountsApi.scala index 730721040..e48bafcf2 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/AccountsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BalancesApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BalancesApi.scala index 5dbc93c94..39bf856d3 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BalancesApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BalancesApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BeneficiariesApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BeneficiariesApi.scala index 6038285cb..9a0f9acee 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BeneficiariesApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/BeneficiariesApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DirectDebitsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DirectDebitsApi.scala index 9336905a0..5fdc57f2b 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DirectDebitsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DirectDebitsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentConsentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentConsentsApi.scala index 1721b088f..182976b65 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentConsentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentConsentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentsApi.scala index 0ecb2810a..24799c52a 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticFutureDatedPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsApi.scala index 6acfd8cb7..26b4ec4be 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsConsentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsConsentsApi.scala index faa898429..9a6c8dbe0 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsConsentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/DomesticPaymentsConsentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/EventNotificationApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/EventNotificationApi.scala index 9ba5594a7..3045884ef 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/EventNotificationApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/EventNotificationApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentConsentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentConsentsApi.scala index 9ba8f57ed..38e2ee641 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentConsentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentConsentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentsApi.scala index 3aeaa070a..1c2a026a0 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FilePaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FutureDatedPaymentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FutureDatedPaymentsApi.scala index 756b2072e..be891acd8 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FutureDatedPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/FutureDatedPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentConsentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentConsentsApi.scala index bdcb84f45..a194292b0 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentConsentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentConsentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentsApi.scala index 7dfd35463..b91652f7c 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/InternationalPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/OffersApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/OffersApi.scala index 2aa6139c6..38d21e864 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/OffersApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/OffersApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/PartiesApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/PartiesApi.scala index f4b078449..d2d4a1575 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/PartiesApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/PartiesApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StandingOrdersApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StandingOrdersApi.scala index a6083e487..e352843f1 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StandingOrdersApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StandingOrdersApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StatementsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StatementsApi.scala index 13afd37cd..0c18ccd47 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StatementsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/StatementsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/SupplementaryAccountInfoApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/SupplementaryAccountInfoApi.scala index d82cba8f7..534554f2b 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/SupplementaryAccountInfoApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/SupplementaryAccountInfoApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/TransactionsApi.scala b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/TransactionsApi.scala index a1bcb87f8..fbd6467cb 100644 --- a/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/TransactionsApi.scala +++ b/obp-api/src/main/scala/code/api/BahrainOBF/v1_0_0/TransactionsApi.scala @@ -1,5 +1,6 @@ package code.api.BahrainOBF.v1_0_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/MxOF/APIMethods_AtmsApi.scala b/obp-api/src/main/scala/code/api/MxOF/APIMethods_AtmsApi.scala index 6ede06c1e..65089ecf7 100644 --- a/obp-api/src/main/scala/code/api/MxOF/APIMethods_AtmsApi.scala +++ b/obp-api/src/main/scala/code/api/MxOF/APIMethods_AtmsApi.scala @@ -1,5 +1,7 @@ package code.api.MxOF +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.Constant import code.api.MxOF.JSONFactory_MXOF_0_0_1.createGetAtmsResponse import code.api.util.APIUtil._ diff --git a/obp-api/src/main/scala/code/api/OBPRestHelper.scala b/obp-api/src/main/scala/code/api/OBPRestHelper.scala index ea6adbdbb..78dc3bde3 100644 --- a/obp-api/src/main/scala/code/api/OBPRestHelper.scala +++ b/obp-api/src/main/scala/code/api/OBPRestHelper.scala @@ -27,6 +27,8 @@ TESOBE (http://www.tesobe.com/) package code.api +import scala.language.reflectiveCalls +import scala.language.implicitConversions import code.api.Constant._ import code.api.OAuthHandshake._ import code.api.util.APIUtil._ diff --git a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/AISApi.scala b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/AISApi.scala index 6977cb0c4..0cabab029 100644 --- a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/AISApi.scala +++ b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/AISApi.scala @@ -1,5 +1,6 @@ package code.api.Polish.v2_1_1_1 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/ASApi.scala b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/ASApi.scala index 6d2740406..e9af8fc1c 100644 --- a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/ASApi.scala +++ b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/ASApi.scala @@ -1,5 +1,6 @@ package code.api.Polish.v2_1_1_1 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/CAFApi.scala b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/CAFApi.scala index c90e96880..96792a58a 100644 --- a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/CAFApi.scala +++ b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/CAFApi.scala @@ -1,5 +1,6 @@ package code.api.Polish.v2_1_1_1 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/PISApi.scala b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/PISApi.scala index 9d3afe519..6a21cedf7 100644 --- a/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/PISApi.scala +++ b/obp-api/src/main/scala/code/api/Polish/v2_1_1_1/PISApi.scala @@ -1,5 +1,6 @@ package code.api.Polish.v2_1_1_1 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocs140.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocs140.scala index 70f4b4cd5..1a5d8bebc 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocs140.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocs140.scala @@ -1,5 +1,6 @@ package code.api.ResourceDocs1_4_0 +import scala.language.reflectiveCalls import code.api.Constant.HostName import code.api.OBPRestHelper import code.api.cache.Caching @@ -16,7 +17,7 @@ import net.liftweb.http.{GetRequest, InMemoryResponse, PlainTextResponse, Req, S object ResourceDocs140 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version = ApiVersion.v1_4_0 // "1.4.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, @@ -31,7 +32,7 @@ object ResourceDocs140 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs200 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version = ApiVersion.v2_0_0 // "2.0.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -46,7 +47,7 @@ object ResourceDocs200 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs210 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v2_1_0 // "2.1.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -60,7 +61,7 @@ object ResourceDocs210 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs220 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v2_2_0 // "2.2.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -74,7 +75,7 @@ object ResourceDocs220 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version : ApiVersion = ApiVersion.v3_0_0 // = "3.0.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -87,7 +88,7 @@ object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs310 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v3_1_0 // = "3.0.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObp, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -102,7 +103,7 @@ object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs400 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v4_0_0 // = "4.0.0" // We match other api versions so API explorer can easily use the path. val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObpV400, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -117,7 +118,7 @@ object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs500 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v5_0_0 val versionStatus = ApiVersionStatus.STABLE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObpV400, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -132,7 +133,7 @@ object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs510 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v5_1_0 val versionStatus = ApiVersionStatus.BLEEDING_EDGE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObpV400, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getBankLevelDynamicResourceDocsObp, @@ -148,7 +149,7 @@ object ResourceDocs300 extends OBPRestHelper with ResourceDocsAPIMethods with Md object ResourceDocs600 extends OBPRestHelper with ResourceDocsAPIMethods with MdcLoggable { val version: ApiVersion = ApiVersion.v6_0_0 val versionStatus = ApiVersionStatus.BLEEDING_EDGE.toString - val routes = List( + val routes: Seq[OBPEndpoint] = List( ImplementationsResourceDocs.getResourceDocsObpV400, ImplementationsResourceDocs.getResourceDocsSwagger, ImplementationsResourceDocs.getResourceDocsOpenAPI31, diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala index f7ef88d26..b355e782e 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala @@ -39,6 +39,7 @@ import net.liftweb.json.JsonAST.{JField, JString, JValue} import net.liftweb.json._ import java.util.concurrent.ConcurrentHashMap +import scala.collection.immutable import scala.collection.immutable.{List, Nil} import scala.concurrent.Future @@ -471,7 +472,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth case true => authenticatedAccess(cc) // If set resource_docs_requires_role=true, we need check the authentication } _ <- resourceDocsRequireRole match { - case false => Future() + case false => Future(()) case true => // If set resource_docs_requires_role=true, we need check the roles as well NewStyle.function.hasAtLeastOneEntitlement(failMsg = UserHasMissingRoles + canReadResourceDoc.toString)("", u.map(_.userId).getOrElse(""), ApiRole.canReadResourceDoc :: Nil, cc.callContext) } @@ -595,7 +596,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth } (_, callContext) <- NewStyle.function.getBank(BankId(bankId), Option(cc)) _ <- resourceDocsRequireRole match { - case false => Future() + case false => Future(()) case true => // If set resource_docs_requires_role=true, we need check the the roles as well NewStyle.function.hasAtLeastOneEntitlement(failMsg = UserHasMissingRoles + ApiRole.canReadDynamicResourceDocsAtOneBank.toString)( bankId, u.map(_.userId).getOrElse(""), ApiRole.canReadDynamicResourceDocsAtOneBank::Nil, cc.callContext @@ -1256,3 +1257,4 @@ so the caller must specify any required filtering by catalog explicitly. } + 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 bb62b8431..6e22b45cc 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 @@ -1,5 +1,6 @@ package code.api.ResourceDocs1_4_0 +import scala.language.implicitConversions import code.api.Constant import code.api.Constant._ import code.api.UKOpenBanking.v2_0_0.JSONFactory_UKOpenBanking_200 diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala index 28f11e297..2ac9c5782 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerJSONFactory.scala @@ -889,7 +889,7 @@ object SwaggerJSONFactory extends MdcLoggable { * @return a list of include original list and nested objects */ private def getAllEntities(entities: List[AnyRef]) = { - val notNullEntities = entities.filter(null !=) + val notNullEntities = entities.filter(null.!=) val notSupportYetEntity = entities.filter(_.getClass.getSimpleName.equals(NotSupportedYet.getClass.getSimpleName.replace("$",""))) val existsEntityTypes: Set[universe.Type] = notNullEntities.map(ReflectUtils.getType).toSet @@ -919,10 +919,10 @@ object SwaggerJSONFactory extends MdcLoggable { val entityType = ReflectUtils.getType(obj) val constructorParamList = ReflectUtils.getPrimaryConstructor(entityType).paramLists.headOption.getOrElse(Nil) // if exclude current obj, the result list tail will be Nil - val resultTail = if(excludeTypes.exists(entityType =:=)) Nil else List(obj) + val resultTail = if(excludeTypes.exists(entityType.=:=)) Nil else List(obj) val refValues: List[Any] = constructorParamList - .filter(it => isSwaggerRefType(it.info) && !excludeTypes.exists(_ =:= it.info)) + .filter(it => isSwaggerRefType(it.info) && !excludeTypes.exists(_.=:=(it.info))) .map(it => { val paramName = it.name.toString val value = ReflectUtils.invokeMethod(obj, paramName) @@ -1009,7 +1009,7 @@ object SwaggerJSONFactory extends MdcLoggable { val errorMessages: Set[AnyRef] = resourceDocList.flatMap(_.error_response_bodies).toSet val errorDefinitions = ErrorMessages.allFields - .filterNot(null ==) + .filterNot(null.==) .filter(it => errorMessages.contains(it._2)) .toList .map(it => { diff --git a/obp-api/src/main/scala/code/api/STET/v1_4/AISPApi.scala b/obp-api/src/main/scala/code/api/STET/v1_4/AISPApi.scala index 0b973c1a6..dbe075172 100644 --- a/obp-api/src/main/scala/code/api/STET/v1_4/AISPApi.scala +++ b/obp-api/src/main/scala/code/api/STET/v1_4/AISPApi.scala @@ -1,5 +1,6 @@ package code.api.STET.v1_4 +import scala.language.implicitConversions import code.api.APIFailureNewStyle import code.api.STET.v1_4.JSONFactory_STET_1_4._ import code.api.berlin.group.v1_3.JvalueCaseClass diff --git a/obp-api/src/main/scala/code/api/STET/v1_4/CBPIIApi.scala b/obp-api/src/main/scala/code/api/STET/v1_4/CBPIIApi.scala index 918c69166..5b8e4ffa4 100644 --- a/obp-api/src/main/scala/code/api/STET/v1_4/CBPIIApi.scala +++ b/obp-api/src/main/scala/code/api/STET/v1_4/CBPIIApi.scala @@ -1,5 +1,6 @@ package code.api.STET.v1_4 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/STET/v1_4/PISPApi.scala b/obp-api/src/main/scala/code/api/STET/v1_4/PISPApi.scala index 1d154ee29..64b7b9400 100644 --- a/obp-api/src/main/scala/code/api/STET/v1_4/PISPApi.scala +++ b/obp-api/src/main/scala/code/api/STET/v1_4/PISPApi.scala @@ -1,5 +1,6 @@ package code.api.STET.v1_4 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountAccessApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountAccessApi.scala index 56a607291..27a5047a4 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountAccessApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountAccessApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.Constant import code.api.UKOpenBanking.v3_1_0.JSONFactory_UKOpenBanking_310.ConsentPostBodyUKV310 import code.api.berlin.group.v1_3.JvalueCaseClass diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountsApi.scala index 90c263a44..2b2c3eddd 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/AccountsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.Constant import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BalancesApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BalancesApi.scala index e56fb6965..feb7956c6 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BalancesApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BalancesApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.Constant import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BeneficiariesApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BeneficiariesApi.scala index 6aae2cd97..07919dda5 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BeneficiariesApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/BeneficiariesApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DirectDebitsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DirectDebitsApi.scala index f78ccd5bc..6dd920ace 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DirectDebitsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DirectDebitsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticPaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticPaymentsApi.scala index da56928da..6d32805b5 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticScheduledPaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticScheduledPaymentsApi.scala index b76dc2043..1d3697e00 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticScheduledPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticScheduledPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticStandingOrdersApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticStandingOrdersApi.scala index fda823c9a..32f5f229e 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticStandingOrdersApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/DomesticStandingOrdersApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FilePaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FilePaymentsApi.scala index c5dc4260c..88e72483a 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FilePaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FilePaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FundsConfirmationsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FundsConfirmationsApi.scala index dd111892e..a97776eef 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FundsConfirmationsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/FundsConfirmationsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalPaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalPaymentsApi.scala index bd30cf661..dc2db414a 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalScheduledPaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalScheduledPaymentsApi.scala index 8631c141f..05070bb0d 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalScheduledPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalScheduledPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalStandingOrdersApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalStandingOrdersApi.scala index 74aac46fe..8735d6c6c 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalStandingOrdersApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/InternationalStandingOrdersApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/OffersApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/OffersApi.scala index a69e3c414..56b1ad408 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/OffersApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/OffersApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/PartysApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/PartysApi.scala index b562322a6..f5222be85 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/PartysApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/PartysApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ProductsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ProductsApi.scala index c3afc5da0..49f24147a 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ProductsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ProductsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ScheduledPaymentsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ScheduledPaymentsApi.scala index 8579fcb47..b5e0bf170 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ScheduledPaymentsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/ScheduledPaymentsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StandingOrdersApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StandingOrdersApi.scala index 3ac5e73de..4dc1409f0 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StandingOrdersApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StandingOrdersApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StatementsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StatementsApi.scala index a56431eff..0ec509d24 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StatementsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/StatementsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil._ import code.api.util.ApiTag diff --git a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/TransactionsApi.scala b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/TransactionsApi.scala index dfa918579..924cfa0b8 100644 --- a/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/TransactionsApi.scala +++ b/obp-api/src/main/scala/code/api/UKOpenBanking/v3_1_0/TransactionsApi.scala @@ -1,5 +1,6 @@ package code.api.UKOpenBanking.v3_1_0 +import scala.language.implicitConversions import code.api.berlin.group.v1_3.JvalueCaseClass import code.api.util.APIUtil.{defaultBankId, _} import code.api.util.ApiTag._ 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 9bd3357a0..bee7519aa 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 @@ -1,5 +1,6 @@ package code.api.builder.AccountInformationServiceAISApi +import scala.language.implicitConversions import code.api.APIFailureNewStyle import code.api.Constant.{SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID, SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID, SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID} import code.api.berlin.group.ConstantsBG diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/CommonServicesApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/CommonServicesApi.scala index 34b0f54f6..6a40112e9 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/CommonServicesApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/CommonServicesApi.scala @@ -1,5 +1,6 @@ package code.api.builder.CommonServicesApi +import scala.language.implicitConversions import code.api.berlin.group.ConstantsBG import code.api.berlin.group.v1_3.{JvalueCaseClass, OBP_BERLIN_GROUP_1_3} import code.api.builder.AccountInformationServiceAISApi.APIMethods_AccountInformationServiceAISApi diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/ConfirmationOfFundsServicePIISApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/ConfirmationOfFundsServicePIISApi.scala index 5a9aec935..6a2bf7f41 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/ConfirmationOfFundsServicePIISApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/ConfirmationOfFundsServicePIISApi.scala @@ -1,5 +1,6 @@ package code.api.builder.ConfirmationOfFundsServicePIISApi +import scala.language.implicitConversions import code.api.berlin.group.ConstantsBG import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3._ import code.api.berlin.group.v1_3.{JvalueCaseClass, OBP_BERLIN_GROUP_1_3} diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala index e10e811ff..f46477ee2 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala @@ -1,5 +1,6 @@ package code.api.builder.PaymentInitiationServicePISApi +import scala.language.implicitConversions import code.api.berlin.group.ConstantsBG import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{CancelPaymentResponseJson, CancelPaymentResponseLinks, LinkHrefJson, UpdatePaymentPsuDataJson, checkAuthorisationConfirmation, checkSelectPsuAuthenticationMethod, checkTransactionAuthorisation, checkUpdatePsuAuthentication, createCancellationTransactionRequestJson} import code.api.berlin.group.v1_3.model.TransactionStatus.mapTransactionStatus diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/SigningBasketsApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/SigningBasketsApi.scala index b620104de..2b02ec4ce 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/SigningBasketsApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/SigningBasketsApi.scala @@ -1,5 +1,6 @@ package code.api.builder.SigningBasketsApi +import scala.language.implicitConversions import code.api.berlin.group.ConstantsBG import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{PostSigningBasketJsonV13, UpdatePaymentPsuDataJson, createSigningBasketResponseJson, createStartSigningBasketAuthorisationJson, getSigningBasketResponseJson, getSigningBasketStatusResponseJson} import code.api.berlin.group.v1_3.{JSONFactory_BERLIN_GROUP_1_3, JvalueCaseClass} diff --git a/obp-api/src/main/scala/code/api/constant/constant.scala b/obp-api/src/main/scala/code/api/constant/constant.scala index 73cee00a6..9816ad4a2 100644 --- a/obp-api/src/main/scala/code/api/constant/constant.scala +++ b/obp-api/src/main/scala/code/api/constant/constant.scala @@ -266,6 +266,19 @@ object Constant extends MdcLoggable { // ABAC Cache Prefixes (with global namespace and versioning) def ABAC_RULE_PREFIX: String = getVersionedCachePrefix(ABAC_RULE_NAMESPACE) + // ABAC Policy Constants + final val ABAC_POLICY_ACCOUNT_ACCESS = "account-access" + + // List of all ABAC Policies + final val ABAC_POLICIES: List[String] = List( + ABAC_POLICY_ACCOUNT_ACCESS + ) + + // Map of ABAC Policies to their descriptions + final val ABAC_POLICY_DESCRIPTIONS: Map[String, String] = Map( + ABAC_POLICY_ACCOUNT_ACCESS -> "Rules for controlling access to account information and account-related operations" + ) + final val CAN_SEE_TRANSACTION_OTHER_BANK_ACCOUNT = "can_see_transaction_other_bank_account" final val CAN_SEE_TRANSACTION_METADATA = "can_see_transaction_metadata" final val CAN_SEE_TRANSACTION_DESCRIPTION = "can_see_transaction_description" diff --git a/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicCompileEndpoint.scala b/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicCompileEndpoint.scala index d052e2169..4022feacd 100644 --- a/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicCompileEndpoint.scala +++ b/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicCompileEndpoint.scala @@ -1,5 +1,6 @@ package code.api.dynamic.endpoint.helper +import scala.language.implicitConversions import code.api.util.APIUtil.{OBPEndpoint, OBPReturnType, futureToBoxedResponse, scalaFutureToLaFuture} import code.api.util.DynamicUtil.{Sandbox, Validation} import code.api.util.{CallContext, CustomJsonFormats, DynamicUtil} @@ -34,7 +35,7 @@ trait DynamicCompileEndpoint { } private def validateDependencies() = { - val dependencies = DynamicUtil.getDynamicCodeDependentMethods(this.getClass, "process" == ) + val dependencies = DynamicUtil.getDynamicCodeDependentMethods(this.getClass, "process".==) Validation.validateDependency(dependencies) } } diff --git a/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicEndpointHelper.scala b/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicEndpointHelper.scala index 13234abf6..0866e8e09 100644 --- a/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicEndpointHelper.scala +++ b/obp-api/src/main/scala/code/api/dynamic/endpoint/helper/DynamicEndpointHelper.scala @@ -1,5 +1,6 @@ package code.api.dynamic.endpoint.helper +import scala.language.existentials import org.apache.pekko.http.scaladsl.model.{HttpMethods, HttpMethod => PekkoHttpMethod} import code.DynamicData.{DynamicDataProvider, DynamicDataT} import code.DynamicEndpoint.{DynamicEndpointProvider, DynamicEndpointT} @@ -677,7 +678,7 @@ object DynamicEndpointHelper extends RestHelper { schemas += schema } // check whether this schema already recurse two times - if(schemas.count(schema ==) > 3) { + if(schemas.count(schema.==) > 3) { return JObject(Nil) } 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 de55797d7..bf4fbef93 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -26,6 +26,9 @@ TESOBE (http://www.tesobe.com/) */ package code.api.util + +import scala.language.implicitConversions +import scala.language.reflectiveCalls import bootstrap.liftweb.CustomDBVendor import cats.effect.IO import code.accountholders.AccountHolders @@ -1646,6 +1649,11 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ var errorResponseBodies: List[String], // Possible error responses tags: List[ResourceDocTag], var roles: Option[List[ApiRole]] = None, + // IMPORTANT: Roles declared here are AUTOMATICALLY CHECKED at runtime! + // When roles specified, framework automatically: 1) Validates user authentication, + // 2) Checks user has at least one of specified roles, 3) Performs checks in wrappedWithAuthCheck() + // No manual hasEntitlement() call needed in endpoint body - handled automatically! + // To disable: call .disableAutoValidateRoles() on ResourceDoc isFeatured: Boolean = false, specialInstructions: Option[String] = None, var specifiedUrl: Option[String] = None, // A derived value: Contains the called version (added at run time). See the resource doc for resource doc! @@ -1778,9 +1786,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ private val reversedRequestUrl = requestUrlPartPath.reverse def getPathParams(url: List[String]): Map[String, String] = - reversedRequestUrl.zip(url.reverse) collect { + reversedRequestUrl.zip(url.reverse).collect { case pair @(k, _) if isPathVariable(k) => pair - } toMap + }.toMap /** * According errorResponseBodies whether contains UserNotLoggedIn and UserHasMissingRoles do validation. @@ -4068,7 +4076,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ def parseDate(date: String): Option[Date] = { val currentSupportFormats = List(DateWithDayFormat, DateWithSecondsFormat, DateWithMsFormat, DateWithMsRollbackFormat) val parsePosition = new ParsePosition(0) - currentSupportFormats.toStream.map(_.parse(date, parsePosition)).find(null !=) + currentSupportFormats.toStream.map(_.parse(date, parsePosition)).find(null.!=) } private def passesPsd2ServiceProviderCommon(cc: Option[CallContext], serviceProvider: String) = { @@ -4464,7 +4472,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ private def getClassPool(classLoader: ClassLoader) = { import scala.concurrent.duration._ - Caching.memoizeSyncWithImMemory(Some(classLoader.toString()))(DurationInt(30) days) { + Caching.memoizeSyncWithImMemory(Some(classLoader.toString()))(DurationInt(30).days) { val classPool: ClassPool = ClassPool.getDefault classPool.appendClassPath(new LoaderClassPath(classLoader)) classPool @@ -4565,7 +4573,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ */ def getObpTrace(clazzName: String, methodName: String, signature: String, exclude: List[(String, String, String)] = Nil): List[(String, String, String)] = { import scala.concurrent.duration._ - Caching.memoizeSyncWithImMemory(Some(clazzName + methodName + signature))(DurationInt(30) days) { + Caching.memoizeSyncWithImMemory(Some(clazzName + methodName + signature))(DurationInt(30).days) { // List:: className->methodName->signature, find all the dependent methods for one val methods = getDependentMethods(clazzName, methodName, signature) diff --git a/obp-api/src/main/scala/code/api/util/AfterApiAuth.scala b/obp-api/src/main/scala/code/api/util/AfterApiAuth.scala index 0650d3990..860957127 100644 --- a/obp-api/src/main/scala/code/api/util/AfterApiAuth.scala +++ b/obp-api/src/main/scala/code/api/util/AfterApiAuth.scala @@ -32,11 +32,12 @@ object AfterApiAuth extends MdcLoggable{ */ def innerLoginUserInitAction(authUser: Box[AuthUser]) = { authUser.map { u => // Init actions - logger.info("AfterApiAuth.innerLoginUserInitAction started successfully") + logger.debug("AfterApiAuth.innerLoginUserInitAction started successfully") sofitInitAction(u) } match { - case Full(_) => logger.warn("AfterApiAuth.innerLoginUserInitAction completed successfully") - case userInitActionFailure => logger.warn("AfterApiAuth.innerLoginUserInitAction: " + userInitActionFailure) + case Full(_) => logger.debug("AfterApiAuth.innerLoginUserInitAction completed successfully") + case Empty => // Init actions are not started at all + case userInitActionFailure => logger.error("AfterApiAuth.innerLoginUserInitAction: " + userInitActionFailure) } } /** 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 9c7a990be..9e1f404b7 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -124,7 +124,7 @@ object ApiRole extends MdcLoggable{ // ALL case class CanGetSystemLogCacheAll(requiresBankId: Boolean = false) extends ApiRole lazy val canGetSystemLogCacheAll = CanGetSystemLogCacheAll() - + case class CanUpdateAgentStatusAtAnyBank(requiresBankId: Boolean = false) extends ApiRole lazy val canUpdateAgentStatusAtAnyBank = CanUpdateAgentStatusAtAnyBank() @@ -1003,6 +1003,9 @@ object ApiRole extends MdcLoggable{ case class CanGetAllConnectorMethods(requiresBankId: Boolean = false) extends ApiRole lazy val canGetAllConnectorMethods = CanGetAllConnectorMethods() + case class CanGetSystemConnectorMethodNames(requiresBankId: Boolean = false) extends ApiRole + lazy val canGetSystemConnectorMethodNames = CanGetSystemConnectorMethodNames() + case class CanCreateDynamicResourceDoc(requiresBankId: Boolean = false) extends ApiRole lazy val canCreateDynamicResourceDoc = CanCreateDynamicResourceDoc() diff --git a/obp-api/src/main/scala/code/api/util/ApiTag.scala b/obp-api/src/main/scala/code/api/util/ApiTag.scala index bd4c41f01..38208d32d 100644 --- a/obp-api/src/main/scala/code/api/util/ApiTag.scala +++ b/obp-api/src/main/scala/code/api/util/ApiTag.scala @@ -18,6 +18,8 @@ object ApiTag { val apiTagTransactionRequestAttribute = ResourceDocTag("Transaction-Request-Attribute") val apiTagVrp = ResourceDocTag("VRP") val apiTagApi = ResourceDocTag("API") + val apiTagOAuth = ResourceDocTag("OAuth") + val apiTagOIDC = ResourceDocTag("OIDC") val apiTagBank = ResourceDocTag("Bank") val apiTagBankAttribute = ResourceDocTag("Bank-Attribute") val apiTagAccount = ResourceDocTag("Account") 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 80394c0c5..2a684e516 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -3160,7 +3160,7 @@ object NewStyle extends MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(methodRoutingTTL second) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(methodRoutingTTL.second) { MethodRoutingProvider.connectorMethodProvider.vend.getMethodRoutings(methodName, isBankIdExactMatch, bankIdPattern) } } @@ -3213,7 +3213,7 @@ object NewStyle extends MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(endpointMappingTTL second) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(endpointMappingTTL.second) { {(EndpointMappingProvider.endpointMappingProvider.vend.getAllEndpointMappings(bankId), callContext)} } } @@ -3327,7 +3327,7 @@ object NewStyle extends MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(dynamicEntityTTL second) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(dynamicEntityTTL.second) { DynamicEntityProvider.connectorMethodProvider.vend.getDynamicEntities(bankId, returnBothBankAndSystemLevel) } } @@ -3338,7 +3338,7 @@ object NewStyle extends MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(dynamicEntityTTL second) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(dynamicEntityTTL.second) { DynamicEntityProvider.connectorMethodProvider.vend.getDynamicEntitiesByUserId(userId: String) } } diff --git a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala index 1c6db5a45..a8cbead5b 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala @@ -76,7 +76,7 @@ trait APIMethods121 { def checkIfLocationPossible(lat:Double,lon:Double) : Box[Unit] = { if(scala.math.abs(lat) <= 90 & scala.math.abs(lon) <= 180) - Full() + Full(()) else Failure("Coordinates not possible") } @@ -132,7 +132,7 @@ trait APIMethods121 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(apiVersion,apiVersionStatus), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala b/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala index 5c550e036..113d684b1 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala @@ -26,6 +26,8 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v1_2_1 +import scala.language.implicitConversions +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} @@ -40,7 +42,7 @@ object OBPAPI1_2_1 extends OBPRestHelper with APIMethods121 with MdcLoggable wit val version : ApiVersion = ApiVersion.v1_2_1 // "1.2.1" val versionStatus = ApiVersionStatus.DEPRECATED.toString - lazy val endpointsOf1_2_1 = List( + lazy val endpointsOf1_2_1: Seq[OBPEndpoint] = List( Implementations1_2_1.root, Implementations1_2_1.getBanks, Implementations1_2_1.bankById, diff --git a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala index 7c493aba1..f3abe43b1 100644 --- a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala +++ b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala @@ -50,7 +50,7 @@ trait APIMethods130 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI1_3_0.version, OBPAPI1_3_0.versionStatus), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala b/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala index 7dccdf33d..d5b6ce050 100644 --- a/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala +++ b/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala @@ -1,5 +1,6 @@ package code.api.v1_3_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} diff --git a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala index 36fb445f2..aa36e9243 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala @@ -1,5 +1,6 @@ package code.api.v1_4_0 +import scala.language.reflectiveCalls import code.api.Constant._ import code.api.util.ApiRole._ import code.api.util.ApiTag._ @@ -84,7 +85,7 @@ trait APIMethods140 extends MdcLoggable with APIMethods130 with APIMethods121{ cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI1_4_0.version, OBPAPI1_4_0.versionStatus), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala index bc2701364..db6f7ee9f 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala @@ -530,7 +530,7 @@ object JSONFactory1_4_0 extends MdcLoggable{ jsonResponseBodyFieldsI18n:String ): ResourceDocJson = { val cacheKey = LOCALISED_RESOURCE_DOC_PREFIX + s"operationId:${operationId}-locale:$locale- isVersion4OrHigher:$isVersion4OrHigher".intern() - Caching.memoizeSyncWithImMemory(Some(cacheKey))(CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL seconds) { + Caching.memoizeSyncWithImMemory(Some(cacheKey))(CREATE_LOCALISED_RESOURCE_DOC_JSON_TTL.seconds) { val fieldsDescription = if (resourceDocUpdatedTags.tags.toString.contains("Dynamic-Entity") || resourceDocUpdatedTags.tags.toString.contains("Dynamic-Endpoint") diff --git a/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala index 57d6d2180..86c282757 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala @@ -1,5 +1,6 @@ package code.api.v1_4_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} diff --git a/obp-api/src/main/scala/code/api/v2_0_0/APIMethods200.scala b/obp-api/src/main/scala/code/api/v2_0_0/APIMethods200.scala index 398792e9a..f2b2b532c 100644 --- a/obp-api/src/main/scala/code/api/v2_0_0/APIMethods200.scala +++ b/obp-api/src/main/scala/code/api/v2_0_0/APIMethods200.scala @@ -1,5 +1,6 @@ package code.api.v2_0_0 +import scala.language.reflectiveCalls import code.TransactionTypes.TransactionType import code.api.APIFailureNewStyle import code.api.Constant._ @@ -147,7 +148,7 @@ trait APIMethods200 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory121.getApiInfoJSON(OBPAPI2_0_0.version, OBPAPI2_0_0.versionStatus), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v2_0_0/OBPAPI2_0_0.scala b/obp-api/src/main/scala/code/api/v2_0_0/OBPAPI2_0_0.scala index 6e037559c..c642e154a 100644 --- a/obp-api/src/main/scala/code/api/v2_0_0/OBPAPI2_0_0.scala +++ b/obp-api/src/main/scala/code/api/v2_0_0/OBPAPI2_0_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v2_0_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} diff --git a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala index 8bf413554..798ff7613 100644 --- a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala +++ b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala @@ -1,5 +1,6 @@ package code.api.v2_1_0 +import scala.language.reflectiveCalls import code.TransactionTypes.TransactionType import code.api.Constant.CAN_SEE_TRANSACTION_REQUESTS import code.api.util.ApiTag._ @@ -91,7 +92,7 @@ trait APIMethods210 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI2_1_0.version, OBPAPI2_1_0.versionStatus), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala b/obp-api/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala index e796bbee5..eaab7b2d0 100644 --- a/obp-api/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala +++ b/obp-api/src/main/scala/code/api/v2_1_0/OBPAPI2_1_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v2_1_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.{APIUtil, VersionedOBPApis} diff --git a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala index d38f821f4..e795429d9 100644 --- a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala +++ b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala @@ -1,5 +1,6 @@ package code.api.v2_2_0 +import scala.language.reflectiveCalls import code.api.Constant._ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ import code.api.util.APIUtil._ @@ -79,7 +80,7 @@ trait APIMethods220 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI2_2_0.version, OBPAPI2_2_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -535,14 +536,14 @@ trait APIMethods220 { _ <- entitlementsByBank.filter(_.roleName == CanCreateEntitlementAtOneBank.toString()).size > 0 match { case true => // Already has entitlement - Full() + Full(()) case false => Full(Entitlement.entitlement.vend.addEntitlement(bank.id, u.userId, CanCreateEntitlementAtOneBank.toString())) } _ <- entitlementsByBank.filter(_.roleName == CanReadDynamicResourceDocsAtOneBank.toString()).size > 0 match { case true => // Already has entitlement - Full() + Full(()) case false => Full(Entitlement.entitlement.vend.addEntitlement(bank.id, u.userId, CanReadDynamicResourceDocsAtOneBank.toString())) } @@ -1246,7 +1247,7 @@ trait APIMethods220 { (account, callContext) } }else - Future{(Full(), Some(cc))} + Future{(Full(()), Some(cc))} otherAccountRoutingSchemeOBPFormat = if(postJson.other_account_routing_scheme.equalsIgnoreCase("AccountNo")) "ACCOUNT_NUMBER" else StringHelpers.snakify(postJson.other_account_routing_scheme).toUpperCase diff --git a/obp-api/src/main/scala/code/api/v2_2_0/OBPAPI2_2_0.scala b/obp-api/src/main/scala/code/api/v2_2_0/OBPAPI2_2_0.scala index d618322c2..eef388578 100644 --- a/obp-api/src/main/scala/code/api/v2_2_0/OBPAPI2_2_0.scala +++ b/obp-api/src/main/scala/code/api/v2_2_0/OBPAPI2_2_0.scala @@ -1,6 +1,7 @@ package code.api.v2_2_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.{APIUtil, VersionedOBPApis} 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 8513d89b6..aa81d1f8a 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 @@ -1,5 +1,6 @@ package code.api.v3_0_0 +import scala.language.reflectiveCalls import code.accountattribute.AccountAttributeX import code.api.Constant._ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON @@ -84,7 +85,7 @@ trait APIMethods300 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI3_0_0.version, OBPAPI3_0_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -2118,7 +2119,7 @@ trait APIMethods300 { hasCanReadGlossaryRole } } else { - Future{Full()} + Future{Full(())} } json = JSONFactory300.createGlossaryItemsJsonV300(getGlossaryItems) } yield { diff --git a/obp-api/src/main/scala/code/api/v3_0_0/OBPAPI3_0_0.scala b/obp-api/src/main/scala/code/api/v3_0_0/OBPAPI3_0_0.scala index fad91faae..d8bd8f86c 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/OBPAPI3_0_0.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/OBPAPI3_0_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v3_0_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} 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 b9e8671ae..31b1913ad 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 @@ -1,5 +1,6 @@ package code.api.v3_1_0 +import scala.language.reflectiveCalls import code.api.Constant import code.api.Constant._ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ @@ -101,7 +102,7 @@ trait APIMethods310 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory.getApiInfoJSON(OBPAPI3_1_0.version, OBPAPI3_1_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -1863,7 +1864,7 @@ trait APIMethods310 { List( UnknownError ), - List(apiTagApi)) + List(apiTagApi, apiTagOAuth, apiTagOIDC)) lazy val getObpConnectorLoopback : OBPEndpoint = { case "connector" :: "loopback" :: Nil JsonGet _ => { @@ -4111,7 +4112,7 @@ trait APIMethods310 { List( UnknownError ), - List(apiTagApi)) + List(apiTagApi, apiTagOAuth, apiTagOIDC)) lazy val getOAuth2ServerJWKsURIs: OBPEndpoint = { case "jwks-uris" :: Nil JsonGet _ => { 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 a640f7efa..0f25cb7c5 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 @@ -1075,7 +1075,7 @@ object JSONFactory310{ def createEntitlementJsonsV310(tr: List[Entitlement]) = { val idToUser: Map[String, Box[String]] = tr.map(_.userId).distinct.map { userId => (userId, UserX.findByUserId(userId).map(_.name)) - } toMap; + }.toMap; EntitlementJSonsV310( tr.map(e => diff --git a/obp-api/src/main/scala/code/api/v3_1_0/OBPAPI3_1_0.scala b/obp-api/src/main/scala/code/api/v3_1_0/OBPAPI3_1_0.scala index b581773be..fe1b43249 100644 --- a/obp-api/src/main/scala/code/api/v3_1_0/OBPAPI3_1_0.scala +++ b/obp-api/src/main/scala/code/api/v3_1_0/OBPAPI3_1_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v3_1_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} 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 5d4be5591..1e52b797a 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 @@ -1,5 +1,6 @@ package code.api.v4_0_0 +import scala.language.reflectiveCalls import code.DynamicData.DynamicData import code.DynamicEndpoint.DynamicEndpointSwagger import code.accountattribute.AccountAttributeX @@ -1546,7 +1547,7 @@ trait APIMethods400 extends MdcLoggable { value = rejectReasonCode, callContext = callContext ) - } else Future.successful() + } else Future.successful(()) rejectAdditionalInformation = challengeAnswerJson.additional_information.getOrElse("") _ <- @@ -1562,7 +1563,7 @@ trait APIMethods400 extends MdcLoggable { value = rejectAdditionalInformation, callContext = callContext ) - } else Future.successful() + } else Future.successful(()) _ <- NewStyle.function.notifyTransactionRequest( fromAccount, toAccount, @@ -3371,7 +3372,7 @@ trait APIMethods400 extends MdcLoggable { case (Nil | "root" :: Nil) JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { ( JSONFactory400.getApiInfoJSON( @@ -3405,7 +3406,7 @@ trait APIMethods400 extends MdcLoggable { case "development" :: "call_context" :: Nil JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (cc.callContext, HttpCode.`200`(cc.callContext)) } @@ -3434,7 +3435,7 @@ trait APIMethods400 extends MdcLoggable { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (cc.callContext, HttpCode.`200`(cc.callContext)) } @@ -10457,7 +10458,7 @@ trait APIMethods400 extends MdcLoggable { (account, callContext) } } else - Future { (Full(), Some(cc)) } + Future { (Full(()), Some(cc)) } otherAccountRoutingSchemeOBPFormat = if ( @@ -10810,7 +10811,7 @@ trait APIMethods400 extends MdcLoggable { (account, callContext) } } else - Future { (Full(), Some(cc)) } + Future { (Full(()), Some(cc)) } otherAccountRoutingSchemeOBPFormat = if ( @@ -12872,7 +12873,7 @@ trait APIMethods400 extends MdcLoggable { // auth type validation related endpoints private val allowedAuthTypes = - AuthenticationType.values.filterNot(AuthenticationType.Anonymous ==) + AuthenticationType.values.filterNot(AuthenticationType.Anonymous.==) staticResourceDocs += ResourceDoc( createAuthenticationTypeValidation, implementedInApiVersion, @@ -16724,7 +16725,7 @@ trait APIMethods400 extends MdcLoggable { s"$EntitlementAlreadyExists user_id($userId) ${duplicatedRoles.mkString(",")}" Helper.booleanToFuture(errorMessages, cc = callContext) { false } } else - Future.successful(Full()) + Future.successful(Full(())) } /** This method will check all the roles the loggedIn user already has and the @@ -16758,7 +16759,7 @@ trait APIMethods400 extends MdcLoggable { .mkString(",")}" Helper.booleanToFuture(errorMessages, cc = callContext) { false } } else - Future.successful(Full()) + Future.successful(Full(())) } private def checkRoleBankIdMapping( diff --git a/obp-api/src/main/scala/code/api/v4_0_0/OBPAPI4_0_0.scala b/obp-api/src/main/scala/code/api/v4_0_0/OBPAPI4_0_0.scala index 0d8c671fa..089a7bc14 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/OBPAPI4_0_0.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/OBPAPI4_0_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v4_0_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.VersionedOBPApis 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 d7af07e5a..e6ceaa94f 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala @@ -1,5 +1,6 @@ package code.api.v5_0_0 +import scala.language.reflectiveCalls import code.accountattribute.AccountAttributeX import code.api.Constant._ import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ @@ -104,7 +105,7 @@ trait APIMethods500 { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory400.getApiInfoJSON(OBPAPI5_0_0.version,OBPAPI5_0_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -220,14 +221,14 @@ trait APIMethods500 { _ <- entitlementsByBank.filter(_.roleName == CanCreateEntitlementAtOneBank.toString()).size > 0 match { case true => // Already has entitlement - Future() + Future(()) case false => Future(Entitlement.entitlement.vend.addEntitlement(postJson.id.getOrElse(""), cc.userId, CanCreateEntitlementAtOneBank.toString())) } _ <- entitlementsByBank.filter(_.roleName == CanReadDynamicResourceDocsAtOneBank.toString()).size > 0 match { case true => // Already has entitlement - Future() + Future(()) case false => Future(Entitlement.entitlement.vend.addEntitlement(postJson.id.getOrElse(""), cc.userId, CanReadDynamicResourceDocsAtOneBank.toString())) } diff --git a/obp-api/src/main/scala/code/api/v5_0_0/OBPAPI5_0_0.scala b/obp-api/src/main/scala/code/api/v5_0_0/OBPAPI5_0_0.scala index 24110ea73..ac3528d8d 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/OBPAPI5_0_0.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/OBPAPI5_0_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v5_0_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.{APIUtil, VersionedOBPApis} 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 8d56fe598..7021061a5 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 @@ -1,6 +1,7 @@ package code.api.v5_1_0 +import scala.language.reflectiveCalls import code.api.Constant import code.api.Constant._ import code.api.OAuth2Login.{Keycloak, OBPOIDC} @@ -107,7 +108,7 @@ trait APIMethods510 { case (Nil | "root" :: Nil) JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory510.getApiInfoJSON(OBPAPI5_1_0.version,OBPAPI5_1_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -4451,7 +4452,7 @@ trait APIMethods510 { case "tags" :: Nil JsonGet _ => cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future.successful() // Just start async call + _ <- Future.successful(()) // Just start async call } yield { (APITags(ApiTag.allDisplayTagNames.toList), HttpCode.`200`(cc.callContext)) } diff --git a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala index 804e2eb5e..3a7f94e39 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala @@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v5_1_0 +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.{APIUtil, VersionedOBPApis} diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index 7d1e733e0..f3c3d70c6 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -1,5 +1,6 @@ package code.api.v6_0_0 +import scala.language.reflectiveCalls import code.accountattribute.AccountAttributeX import code.api.Constant import code.api.{DirectLogin, ObpApiFailure} @@ -111,7 +112,7 @@ trait APIMethods600 { case (Nil | "root" :: Nil) JsonGet _ => { cc => implicit val ec = EndpointContext(Some(cc)) for { - _ <- Future() // Just start async call + _ <- Future(()) // Just start async call } yield { (JSONFactory510.getApiInfoJSON(OBPAPI6_0_0.version, OBPAPI6_0_0.versionStatus), HttpCode.`200`(cc.callContext)) } @@ -1074,7 +1075,24 @@ trait APIMethods600 { entitlements <- NewStyle.function.getEntitlementsByUserId(u.userId, callContext) } yield { val permissions: Option[Permission] = Views.views.vend.getPermissionForUser(u).toOption - val currentUser = UserV600(u, entitlements, permissions) + // Add SuperAdmin virtual entitlement if user is super admin + val finalEntitlements = if (APIUtil.isSuperAdmin(u.userId)) { + // Create a virtual SuperAdmin entitlement + val superAdminEntitlement: Entitlement = new Entitlement { + def entitlementId: String = "" + def bankId: String = "" + def userId: String = u.userId + def roleName: String = "SuperAdmin" + def createdByProcess: String = "System" + def entitlementRequestId: Option[String] = None + def groupId: Option[String] = None + def process: Option[String] = None + } + entitlements ::: List(superAdminEntitlement) + } else { + entitlements + } + val currentUser = UserV600(u, finalEntitlements, permissions) val onBehalfOfUser = if(cc.onBehalfOfUser.isDefined) { val user = cc.onBehalfOfUser.toOption.get val entitlements = Entitlement.entitlement.vend.getEntitlementsByUserId(user.userId).headOption.toList.flatten @@ -1539,14 +1557,14 @@ trait APIMethods600 { _ <- entitlementsByBank.exists(_.roleName == CanCreateEntitlementAtOneBank.toString()) match { case true => // Already has entitlement - Future() + Future(()) case false => Future(Entitlement.entitlement.vend.addEntitlement(postJson.bank_id, cc.userId, CanCreateEntitlementAtOneBank.toString())) } _ <- entitlementsByBank.exists(_.roleName == CanReadDynamicResourceDocsAtOneBank.toString()) match { case true => // Already has entitlement - Future() + Future(()) case false => Future(Entitlement.entitlement.vend.addEntitlement(postJson.bank_id, cc.userId, CanReadDynamicResourceDocsAtOneBank.toString())) } @@ -1648,7 +1666,7 @@ trait APIMethods600 { | |${userAuthenticationMessage(true)} | - |CanGetMethodRoutings entitlement is required. + |CanGetSystemConnectorMethodNames entitlement is required. | """.stripMargin, EmptyBody, @@ -1658,8 +1676,8 @@ trait APIMethods600 { UserHasMissingRoles, UnknownError ), - List(apiTagSystem, apiTagMethodRouting, apiTagApi), - Some(List(canGetMethodRoutings)) + List(apiTagConnectorMethod, apiTagSystem, apiTagMethodRouting, apiTagApi), + Some(List(canGetSystemConnectorMethodNames)) ) lazy val getConnectorMethodNames: OBPEndpoint = { @@ -1667,7 +1685,6 @@ trait APIMethods600 { cc => implicit val ec = EndpointContext(Some(cc)) for { (Full(u), callContext) <- authenticatedAccess(cc) - _ <- NewStyle.function.hasEntitlement("", u.userId, canGetMethodRoutings, callContext) // Fetch connector method names with caching methodNames <- Future { /** @@ -1675,7 +1692,7 @@ trait APIMethods600 { */ val cacheKey = "getConnectorMethodNames" val cacheTTL = APIUtil.getPropsAsIntValue("getConnectorMethodNames.cache.ttl.seconds", 3600) - Caching.memoizeSyncWithProvider(Some(cacheKey))(cacheTTL seconds) { + Caching.memoizeSyncWithProvider(Some(cacheKey))(cacheTTL.seconds) { val connectorName = APIUtil.getPropsValue("connector", "mapped") val connector = code.bankconnectors.Connector.getConnectorInstance(connectorName) connector.callableMethods.keys.toList @@ -4733,6 +4750,7 @@ trait APIMethods600 { rule_name = "admin_only", rule_code = """user.emailAddress.contains("admin")""", description = "Only allow access to users with admin email", + policy = "user-access,admin", is_active = true ), AbacRuleJsonV600( @@ -4741,6 +4759,7 @@ trait APIMethods600 { rule_code = """user.emailAddress.contains("admin")""", is_active = true, description = "Only allow access to users with admin email", + policy = "user-access,admin", created_by_user_id = "user123", updated_by_user_id = "user123" ), @@ -4780,6 +4799,7 @@ trait APIMethods600 { ruleName = createJson.rule_name, ruleCode = createJson.rule_code, description = createJson.description, + policy = createJson.policy, isActive = createJson.is_active, createdBy = user.userId ) @@ -4816,6 +4836,7 @@ trait APIMethods600 { rule_code = """user.emailAddress.contains("admin")""", is_active = true, description = "Only allow access to users with admin email", + policy = "user-access,admin", created_by_user_id = "user123", updated_by_user_id = "user123" ), @@ -4871,6 +4892,7 @@ trait APIMethods600 { rule_code = """user.emailAddress.contains("admin")""", is_active = true, description = "Only allow access to users with admin email", + policy = "user-access,admin", created_by_user_id = "user123", updated_by_user_id = "user123" ) @@ -4900,6 +4922,75 @@ trait APIMethods600 { } } + staticResourceDocs += ResourceDoc( + getAbacRulesByPolicy, + implementedInApiVersion, + nameOf(getAbacRulesByPolicy), + "GET", + "/management/abac-rules/policy/POLICY", + "Get ABAC Rules by Policy", + s"""Get all ABAC rules that belong to a specific policy. + | + |Multiple rules can share the same policy. Rules with multiple policies (comma-separated) + |will be returned if any of their policies match the requested policy. + | + |**Documentation:** + |- ${Glossary.getGlossaryItemLink("ABAC_Simple_Guide")} - Getting started with ABAC rules + |- ${Glossary.getGlossaryItemLink("ABAC_Parameters_Summary")} - Complete list of all 18 parameters + |- ${Glossary.getGlossaryItemLink("ABAC_Object_Properties_Reference")} - Detailed property reference + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + AbacRulesJsonV600( + abac_rules = List( + AbacRuleJsonV600( + abac_rule_id = "abc123", + rule_name = "admin_only", + rule_code = """user.emailAddress.contains("admin")""", + is_active = true, + description = "Only allow access to users with admin email", + policy = "user-access,admin", + created_by_user_id = "user123", + updated_by_user_id = "user123" + ), + AbacRuleJsonV600( + abac_rule_id = "def456", + rule_name = "admin_department_check", + rule_code = """user.department == "admin"""", + is_active = true, + description = "Check if user is in admin department", + policy = "admin", + created_by_user_id = "user123", + updated_by_user_id = "user123" + ) + ) + ), + List( + UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagABAC), + Some(List(canGetAbacRule)) + ) + + lazy val getAbacRulesByPolicy: OBPEndpoint = { + case "management" :: "abac-rules" :: "policy" :: policy :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (Full(user), callContext) <- authenticatedAccess(cc) + _ <- NewStyle.function.hasEntitlement("", user.userId, canGetAbacRule, callContext) + rules <- Future { + MappedAbacRuleProvider.getAbacRulesByPolicy(policy) + } + } yield { + (createAbacRulesJsonV600(rules), HttpCode.`200`(callContext)) + } + } + } + staticResourceDocs += ResourceDoc( updateAbacRule, implementedInApiVersion, @@ -4921,6 +5012,7 @@ trait APIMethods600 { rule_name = "admin_only_updated", rule_code = """user.emailAddress.contains("admin") && user.provider == "obp"""", description = "Only allow access to OBP admin users", + policy = "user-access,admin,obp", is_active = true ), AbacRuleJsonV600( @@ -4929,6 +5021,7 @@ trait APIMethods600 { rule_code = """user.emailAddress.contains("admin") && user.provider == "obp"""", is_active = true, description = "Only allow access to OBP admin users", + policy = "user-access,admin,obp", created_by_user_id = "user123", updated_by_user_id = "user456" ), @@ -4963,6 +5056,7 @@ trait APIMethods600 { ruleName = updateJson.rule_name, ruleCode = updateJson.rule_code, description = updateJson.description, + policy = updateJson.policy, isActive = updateJson.is_active, updatedBy = user.userId ) @@ -5077,16 +5171,18 @@ trait APIMethods600 { ), examples = List( AbacRuleExampleJsonV600( - category = "User Access", - title = "Check User Identity", - code = "authenticatedUser.userId == user.userId", - description = "Verify that the authenticated user matches the target user" + rule_name = "Check User Identity", + rule_code = "authenticatedUser.userId == user.userId", + description = "Verify that the authenticated user matches the target user", + policy = "user-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "Bank Access", - title = "Check Specific Bank", - code = "bankOpt.isDefined && bankOpt.get.bankId.value == \"gh.29.uk\"", - description = "Verify that the bank context is defined and matches a specific bank ID" + rule_name = "Check Specific Bank", + rule_code = "bankOpt.isDefined && bankOpt.get.bankId.value == \"gh.29.uk\"", + policy = "bank-access", + description = "Verify that the bank context is defined and matches a specific bank ID", + is_active = true ) ), available_operators = List("==", "!=", "&&", "||", "!", ">", "<", ">=", "<=", "contains", "isDefined"), @@ -5117,9 +5213,11 @@ trait APIMethods600 { AbacParameterJsonV600("authenticatedUser", "User", "The logged-in user (always present)", required = true, "User"), AbacParameterJsonV600("authenticatedUserAttributes", "List[UserAttributeTrait]", "Non-personal attributes of authenticated user", required = true, "User"), AbacParameterJsonV600("authenticatedUserAuthContext", "List[UserAuthContext]", "Auth context of authenticated user", required = true, "User"), + AbacParameterJsonV600("authenticatedUserEntitlements", "List[Entitlement]", "Entitlements (roles) of authenticated user", required = true, "User"), AbacParameterJsonV600("onBehalfOfUserOpt", "Option[User]", "User being acted on behalf of (delegation)", required = false, "User"), AbacParameterJsonV600("onBehalfOfUserAttributes", "List[UserAttributeTrait]", "Attributes of delegation user", required = false, "User"), AbacParameterJsonV600("onBehalfOfUserAuthContext", "List[UserAuthContext]", "Auth context of delegation user", required = false, "User"), + AbacParameterJsonV600("onBehalfOfUserEntitlements", "List[Entitlement]", "Entitlements (roles) of delegation user", required = false, "User"), AbacParameterJsonV600("userOpt", "Option[User]", "Target user being evaluated", required = false, "User"), AbacParameterJsonV600("userAttributes", "List[UserAttributeTrait]", "Attributes of target user", required = false, "User"), AbacParameterJsonV600("bankOpt", "Option[Bank]", "Bank context", required = false, "Bank"), @@ -5224,6 +5322,12 @@ trait APIMethods600 { AbacObjectPropertyJsonV600("value", "String", "Attribute value"), AbacObjectPropertyJsonV600("attributeType", "AttributeType", "Attribute type") )), + AbacObjectTypeJsonV600("Entitlement", "User entitlement (role)", List( + AbacObjectPropertyJsonV600("entitlementId", "String", "Entitlement ID"), + AbacObjectPropertyJsonV600("roleName", "String", "Role name (e.g., CanCreateAccount, CanReadTransactions)"), + AbacObjectPropertyJsonV600("bankId", "String", "Bank ID (empty string for system-wide roles)"), + AbacObjectPropertyJsonV600("userId", "String", "User ID this entitlement belongs to") + )), AbacObjectTypeJsonV600("CallContext", "Request context with metadata", List( AbacObjectPropertyJsonV600("correlationId", "String", "Correlation ID for request tracking"), AbacObjectPropertyJsonV600("url", "Option[String]", "Request URL"), @@ -5237,538 +5341,60 @@ trait APIMethods600 { ), examples = List( AbacRuleExampleJsonV600( - category = "User - Authenticated User", - title = "Check Email Domain", - code = "authenticatedUser.emailAddress.contains(\"@example.com\")", - description = "Verify that the authenticated user's email belongs to a specific domain" + rule_name = "Branch Manager Internal Account Access", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanReadAccountsAtOneBank\") && authenticatedUserAttributes.exists(a => a.name == \"branch\" && accountAttributes.exists(aa => aa.name == \"branch\" && a.value == aa.value)) && callContext.exists(_.verb.exists(_ == \"GET\")) && accountOpt.exists(_.accountType == \"CURRENT\")", + description = "Allow GET access to current accounts when user has CanReadAccountsAtOneBank role and branch matches account's branch", + policy = "account-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User - Authenticated User", - title = "Check Authentication Provider", - code = "authenticatedUser.provider == \"obp\"", - description = "Verify the authentication provider is OBP" + rule_name = "Internal Network High-Value Transaction Review", + rule_code = "callContext.exists(_.ipAddress.exists(_.startsWith(\"10.\"))) && authenticatedUserEntitlements.exists(e => e.roleName == \"CanReadTransactionsAtOneBank\") && transactionOpt.exists(_.amount > 10000)", + description = "Allow users with CanReadTransactionsAtOneBank role on internal network to review high-value transactions over 10,000", + policy = "transaction-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User - Authenticated User", - title = "Compare Authenticated to Target User", - code = "authenticatedUser.userId == userOpt.get.userId", - description = "Check if authenticated user matches the target user (unsafe - use exists instead)" + rule_name = "Department Head Same-Department Account Read where overdrawn", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanReadAccountsAtOneBank\") && authenticatedUserAttributes.exists(ua => ua.name == \"department\" && accountAttributes.exists(aa => aa.name == \"department\" && ua.value == aa.value)) && callContext.exists(_.url.exists(_.contains(\"/accounts/\"))) && accountOpt.exists(_.balance < 0)", + description = "Allow users with CanReadAccountsAtOneBank role to read overdrawn accounts in their department", + policy = "account-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User - Authenticated User", - title = "Check User Not Deleted", - code = "!authenticatedUser.isDeleted.getOrElse(false)", - description = "Verify the authenticated user is not marked as deleted" + rule_name = "Manager Internal Network Transaction Approval", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanCreateTransactionRequest\") && callContext.exists(_.ipAddress.exists(ip => ip.startsWith(\"10.\") || ip.startsWith(\"192.168.\"))) && transactionRequestOpt.exists(tr => tr.status == \"PENDING\" && tr.charge.value.toDouble < 50000)", + description = "Allow users with CanCreateTransactionRequest role on internal network to approve pending transaction requests under 50,000", + policy = "transaction-request", + is_active = true ), AbacRuleExampleJsonV600( - category = "User Attributes - Authenticated User", - title = "Check Admin Role", - code = "authenticatedUserAttributes.exists(attr => attr.name == \"role\" && attr.value == \"admin\")", - description = "Check if authenticated user has admin role attribute" + rule_name = "KYC Officer Customer Creation from Branch", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanCreateCustomer\") && authenticatedUserAttributes.exists(a => a.name == \"certification\" && a.value == \"kyc_certified\") && callContext.exists(_.verb.exists(_ == \"POST\")) && callContext.exists(_.ipAddress.exists(_.startsWith(\"10.20.\"))) && customerAttributes.exists(ca => ca.name == \"onboarding_status\" && ca.value == \"pending\")", + description = "Allow users with CanCreateCustomer role and KYC certification to create customers via POST from branch network (10.20.x.x) when status is pending", + policy = "customer-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User Attributes - Authenticated User", - title = "Check Department", - code = "authenticatedUserAttributes.find(_.name == \"department\").exists(_.value == \"finance\")", - description = "Check if authenticated user belongs to finance department" + rule_name = "International Team Foreign Currency Transaction", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanReadTransactionsAtOneBank\") && authenticatedUserAttributes.exists(a => a.name == \"team\" && a.value == \"international\") && callContext.exists(_.url.exists(_.contains(\"/transactions/\"))) && transactionOpt.exists(t => t.currency != \"USD\" && t.amount < 100000) && accountOpt.exists(a => accountAttributes.exists(aa => aa.name == \"international_enabled\" && aa.value == \"true\"))", + description = "Allow international team users with CanReadTransactionsAtOneBank role to access foreign currency transactions under 100k on international-enabled accounts", + policy = "transaction-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User Attributes - Authenticated User", - title = "Check Multiple Roles", - code = "authenticatedUserAttributes.exists(attr => attr.name == \"role\" && List(\"admin\", \"manager\").contains(attr.value))", - description = "Check if authenticated user has admin or manager role" + rule_name = "Assistant with Limited Delegation Account View", + rule_code = "onBehalfOfUserOpt.isDefined && onBehalfOfUserEntitlements.exists(e => e.roleName == \"CanReadAccountsAtOneBank\") && authenticatedUserAttributes.exists(a => a.name == \"assistant_of\" && onBehalfOfUserOpt.exists(u => a.value == u.userId)) && callContext.exists(_.verb.exists(_ == \"GET\")) && accountOpt.exists(a => accountAttributes.exists(aa => aa.name == \"tier\" && List(\"gold\", \"platinum\").contains(aa.value)))", + description = "Allow assistants to view gold/platinum accounts via GET when acting on behalf of a user with CanReadAccountsAtOneBank role", + policy = "account-access", + is_active = true ), AbacRuleExampleJsonV600( - category = "User Auth Context", - title = "Check Session Type", - code = "authenticatedUserAuthContext.exists(_.key == \"session_type\" && _.value == \"secure\")", - description = "Verify the session type is secure" - ), - AbacRuleExampleJsonV600( - category = "User Auth Context", - title = "Check Auth Method", - code = "authenticatedUserAuthContext.exists(_.key == \"auth_method\" && _.value == \"certificate\")", - description = "Verify authentication was done via certificate" - ), - AbacRuleExampleJsonV600( - category = "User - Delegation", - title = "Check Delegated User Email Domain", - code = "onBehalfOfUserOpt.exists(_.emailAddress.endsWith(\"@company.com\"))", - description = "Check if delegation user belongs to specific company domain" - ), - AbacRuleExampleJsonV600( - category = "User - Delegation", - title = "Check No Delegation or Self Delegation", - code = "onBehalfOfUserOpt.isEmpty || onBehalfOfUserOpt.get.userId == authenticatedUser.userId", - description = "Allow if no delegation or user delegating to themselves" - ), - AbacRuleExampleJsonV600( - category = "User - Delegation", - title = "Check Different User Delegation", - code = "onBehalfOfUserOpt.forall(_.userId != authenticatedUser.userId)", - description = "Check that delegation is to a different user (if present)" - ), - AbacRuleExampleJsonV600( - category = "User Attributes - Delegation", - title = "Check Delegation Level", - code = "onBehalfOfUserAttributes.exists(attr => attr.name == \"delegation_level\" && attr.value == \"full\")", - description = "Check if delegation has full permission level" - ), - AbacRuleExampleJsonV600( - category = "User Attributes - Delegation", - title = "Check Authorized Delegation", - code = "onBehalfOfUserAttributes.isEmpty || onBehalfOfUserAttributes.exists(_.name == \"authorized\")", - description = "Allow if no delegation attributes or has authorized attribute" - ), - AbacRuleExampleJsonV600( - category = "User - Target User", - title = "Check Self Access", - code = "userOpt.isDefined && userOpt.get.userId == authenticatedUser.userId", - description = "Check if target user is the authenticated user (self-access)" - ), - AbacRuleExampleJsonV600( - category = "User - Target User", - title = "Check Target User Provider", - code = "userOpt.exists(_.provider == \"obp\")", - description = "Check if target user is authenticated via OBP provider" - ), - AbacRuleExampleJsonV600( - category = "User - Target User", - title = "Check Target User Email Domain", - code = "userOpt.exists(_.emailAddress.endsWith(\"@trusted.com\"))", - description = "Check if target user belongs to trusted domain" - ), - AbacRuleExampleJsonV600( - category = "User - Target User", - title = "Check Target User Active", - code = "userOpt.forall(!_.isDeleted.getOrElse(false))", - description = "Ensure target user is not deleted (if present)" - ), - AbacRuleExampleJsonV600( - category = "User Attributes - Target User", - title = "Check Premium Account", - code = "userAttributes.exists(attr => attr.name == \"account_type\" && attr.value == \"premium\")", - description = "Check if target user has premium account type" - ), - AbacRuleExampleJsonV600( - category = "User Attributes - Target User", - title = "Check KYC Status", - code = "userAttributes.exists(attr => attr.name == \"kyc_status\" && attr.value == \"verified\")", - description = "Check if target user has verified KYC status" - ), - AbacRuleExampleJsonV600( - category = "User Attributes - Target User", - title = "Check User Tier Level", - code = "userAttributes.find(_.name == \"tier\").exists(_.value.toInt >= 2)", - description = "Check if user tier is 2 or higher" - ), - AbacRuleExampleJsonV600( - category = "Bank", - title = "Check Specific Bank ID", - code = "bankOpt.isDefined && bankOpt.get.bankId.value == \"gh.29.uk\"", - description = "Check if bank context is defined and matches specific bank ID" - ), - AbacRuleExampleJsonV600( - category = "Bank", - title = "Check Bank Name Contains Text", - code = "bankOpt.exists(_.fullName.contains(\"Community\"))", - description = "Check if bank full name contains specific text" - ), - AbacRuleExampleJsonV600( - category = "Bank", - title = "Check Bank Has HTTPS Website", - code = "bankOpt.exists(_.websiteUrl.contains(\"https://\"))", - description = "Check if bank website uses HTTPS" - ), - AbacRuleExampleJsonV600( - category = "Bank Attributes", - title = "Check Bank Region", - code = "bankAttributes.exists(attr => attr.name == \"region\" && attr.value == \"EU\")", - description = "Check if bank is in EU region" - ), - AbacRuleExampleJsonV600( - category = "Bank Attributes", - title = "Check Bank Certification", - code = "bankAttributes.exists(attr => attr.name == \"certified\" && attr.value == \"true\")", - description = "Check if bank has certification attribute" - ), - AbacRuleExampleJsonV600( - category = "Account", - title = "Check Minimum Balance", - code = "accountOpt.isDefined && accountOpt.get.balance > 1000", - description = "Check if account balance is above threshold" - ), - AbacRuleExampleJsonV600( - category = "Account", - title = "Check USD Account Balance", - code = "accountOpt.exists(acc => acc.currency == \"USD\" && acc.balance > 5000)", - description = "Check if USD account has balance above $5000" - ), - AbacRuleExampleJsonV600( - category = "Account", - title = "Check Account Type", - code = "accountOpt.exists(_.accountType == \"SAVINGS\")", - description = "Check if account is a savings account" - ), - AbacRuleExampleJsonV600( - category = "Account", - title = "Check Account Number Length", - code = "accountOpt.exists(_.number.length >= 10)", - description = "Check if account number has minimum length" - ), - AbacRuleExampleJsonV600( - category = "Account Attributes", - title = "Check Account Status", - code = "accountAttributes.exists(attr => attr.name == \"status\" && attr.value == \"active\")", - description = "Check if account has active status" - ), - AbacRuleExampleJsonV600( - category = "Account Attributes", - title = "Check Account Tier", - code = "accountAttributes.exists(attr => attr.name == \"account_tier\" && attr.value == \"gold\")", - description = "Check if account has gold tier" - ), - AbacRuleExampleJsonV600( - category = "Transaction", - title = "Check Transaction Amount Limit", - code = "transactionOpt.isDefined && transactionOpt.get.amount < 10000", - description = "Check if transaction amount is below limit" - ), - AbacRuleExampleJsonV600( - category = "Transaction", - title = "Check Transaction Type", - code = "transactionOpt.exists(_.transactionType.contains(\"TRANSFER\"))", - description = "Check if transaction is a transfer type" - ), - AbacRuleExampleJsonV600( - category = "Transaction", - title = "Check EUR Transaction Amount", - code = "transactionOpt.exists(t => t.currency == \"EUR\" && t.amount > 100)", - description = "Check if EUR transaction exceeds €100" - ), - AbacRuleExampleJsonV600( - category = "Transaction", - title = "Check Positive Balance After Transaction", - code = "transactionOpt.exists(_.balance > 0)", - description = "Check if balance remains positive after transaction" - ), - AbacRuleExampleJsonV600( - category = "Transaction Attributes", - title = "Check Transaction Category", - code = "transactionAttributes.exists(attr => attr.name == \"category\" && attr.value == \"business\")", - description = "Check if transaction is categorized as business" - ), - AbacRuleExampleJsonV600( - category = "Transaction Attributes", - title = "Check Transaction Not Flagged", - code = "!transactionAttributes.exists(attr => attr.name == \"flagged\" && attr.value == \"true\")", - description = "Check that transaction is not flagged" - ), - AbacRuleExampleJsonV600( - category = "Transaction Request", - title = "Check Pending Status", - code = "transactionRequestOpt.exists(_.status == \"PENDING\")", - description = "Check if transaction request is pending" - ), - AbacRuleExampleJsonV600( - category = "Transaction Request", - title = "Check SEPA Type", - code = "transactionRequestOpt.exists(_.type == \"SEPA\")", - description = "Check if transaction request is SEPA type" - ), - AbacRuleExampleJsonV600( - category = "Transaction Request", - title = "Check Same Bank", - code = "transactionRequestOpt.exists(_.this_bank_id.value == bankOpt.get.bankId.value)", - description = "Check if transaction request is for the same bank (unsafe - use exists)" - ), - AbacRuleExampleJsonV600( - category = "Transaction Request Attributes", - title = "Check High Priority", - code = "transactionRequestAttributes.exists(attr => attr.name == \"priority\" && attr.value == \"high\")", - description = "Check if transaction request has high priority" - ), - AbacRuleExampleJsonV600( - category = "Transaction Request Attributes", - title = "Check Mobile App Source", - code = "transactionRequestAttributes.exists(attr => attr.name == \"source\" && attr.value == \"mobile_app\")", - description = "Check if transaction request originated from mobile app" - ), - AbacRuleExampleJsonV600( - category = "Customer", - title = "Check Corporate Customer", - code = "customerOpt.exists(_.legalName.contains(\"Corp\"))", - description = "Check if customer legal name contains Corp" - ), - AbacRuleExampleJsonV600( - category = "Customer", - title = "Check Customer Email Matches User", - code = "customerOpt.isDefined && customerOpt.get.email == authenticatedUser.emailAddress", - description = "Check if customer email matches authenticated user" - ), - AbacRuleExampleJsonV600( - category = "Customer", - title = "Check Active Customer Relationship", - code = "customerOpt.exists(_.relationshipStatus == \"ACTIVE\")", - description = "Check if customer relationship is active" - ), - AbacRuleExampleJsonV600( - category = "Customer", - title = "Check Customer Has Mobile", - code = "customerOpt.exists(_.mobileNumber.nonEmpty)", - description = "Check if customer has mobile number on file" - ), - AbacRuleExampleJsonV600( - category = "Customer Attributes", - title = "Check Low Risk Customer", - code = "customerAttributes.exists(attr => attr.name == \"risk_level\" && attr.value == \"low\")", - description = "Check if customer has low risk level" - ), - AbacRuleExampleJsonV600( - category = "Customer Attributes", - title = "Check VIP Status", - code = "customerAttributes.exists(attr => attr.name == \"vip_status\" && attr.value == \"true\")", - description = "Check if customer has VIP status" - ), - AbacRuleExampleJsonV600( - category = "Call Context", - title = "Check Internal Network", - code = "callContext.exists(_.ipAddress.exists(_.startsWith(\"192.168\")))", - description = "Check if request comes from internal network" - ), - AbacRuleExampleJsonV600( - category = "Call Context", - title = "Check GET Request", - code = "callContext.exists(_.verb.exists(_ == \"GET\"))", - description = "Check if request is GET method" - ), - AbacRuleExampleJsonV600( - category = "Call Context", - title = "Check URL Contains Pattern", - code = "callContext.exists(_.url.exists(_.contains(\"/accounts/\")))", - description = "Check if request URL contains accounts path" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - User Comparisons", - title = "Self Access Check", - code = "userOpt.exists(_.userId == authenticatedUser.userId)", - description = "Check if target user is the authenticated user" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - User Comparisons", - title = "Same Email Check", - code = "userOpt.exists(_.emailAddress == authenticatedUser.emailAddress)", - description = "Check if target user has same email as authenticated user" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - User Comparisons", - title = "Same Email Domain", - code = "userOpt.exists(u => authenticatedUser.emailAddress.split(\"@\")(1) == u.emailAddress.split(\"@\")(1))", - description = "Check if both users belong to same email domain" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - User Comparisons", - title = "Delegation Match", - code = "onBehalfOfUserOpt.isDefined && userOpt.isDefined && onBehalfOfUserOpt.get.userId == userOpt.get.userId", - description = "Check if delegation user matches target user" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - User Comparisons", - title = "Different User Access", - code = "userOpt.exists(_.userId != authenticatedUser.userId)", - description = "Check if accessing a different user's data" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Customer Comparisons", - title = "Customer Email Matches Auth User", - code = "customerOpt.exists(_.email == authenticatedUser.emailAddress)", - description = "Check if customer email matches authenticated user" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Customer Comparisons", - title = "Customer Email Matches Target User", - code = "customerOpt.isDefined && userOpt.isDefined && customerOpt.get.email == userOpt.get.emailAddress", - description = "Check if customer email matches target user email" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Customer Comparisons", - title = "Customer Name Contains User Name", - code = "customerOpt.exists(c => userOpt.exists(u => c.legalName.contains(u.name)))", - description = "Check if customer legal name contains user name" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Account/Transaction", - title = "Transaction Within Balance", - code = "transactionOpt.isDefined && accountOpt.isDefined && transactionOpt.get.amount < accountOpt.get.balance", - description = "Check if transaction amount is less than account balance" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Account/Transaction", - title = "Transaction Within 50% Balance", - code = "transactionOpt.exists(t => accountOpt.exists(a => t.amount <= a.balance * 0.5))", - description = "Check if transaction is within 50% of account balance" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Account/Transaction", - title = "Same Currency Check", - code = "transactionOpt.exists(t => accountOpt.exists(a => t.currency == a.currency))", - description = "Check if transaction and account have same currency" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Account/Transaction", - title = "Sufficient Funds After Transaction", - code = "transactionOpt.exists(t => accountOpt.exists(a => a.balance - t.amount >= 0))", - description = "Check if account will have sufficient funds after transaction" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Account/Transaction", - title = "Debit from Checking", - code = "transactionOpt.exists(t => accountOpt.exists(a => (a.accountType == \"CHECKING\" && t.transactionType.exists(_.contains(\"DEBIT\")))))", - description = "Check if debit transaction from checking account" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Bank/Account", - title = "Account Belongs to Bank", - code = "accountOpt.isDefined && bankOpt.isDefined && accountOpt.get.bankId == bankOpt.get.bankId.value", - description = "Check if account belongs to the bank" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Bank/Account", - title = "Account Currency Matches Bank Currency", - code = "accountOpt.exists(a => bankAttributes.exists(attr => attr.name == \"primary_currency\" && attr.value == a.currency))", - description = "Check if account currency matches bank's primary currency" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Transaction Request", - title = "Transaction Request for Account", - code = "transactionRequestOpt.exists(tr => accountOpt.exists(a => tr.this_account_id.value == a.accountId.value))", - description = "Check if transaction request is for this account" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Transaction Request", - title = "Transaction Request for Bank", - code = "transactionRequestOpt.exists(tr => bankOpt.exists(b => tr.this_bank_id.value == b.bankId.value))", - description = "Check if transaction request is for this bank" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Transaction Request", - title = "Transaction Amount Matches Charge", - code = "transactionOpt.isDefined && transactionRequestOpt.isDefined && transactionOpt.get.amount == transactionRequestOpt.get.charge.value.toDouble", - description = "Check if transaction amount matches request charge" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Attribute Comparisons", - title = "User and Account Same Tier", - code = "userAttributes.exists(ua => ua.name == \"tier\" && accountAttributes.exists(aa => aa.name == \"tier\" && ua.value == aa.value))", - description = "Check if user tier matches account tier" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Attribute Comparisons", - title = "Customer and Account Same Segment", - code = "customerAttributes.exists(ca => ca.name == \"segment\" && accountAttributes.exists(aa => aa.name == \"segment\" && ca.value == aa.value))", - description = "Check if customer segment matches account segment" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Attribute Comparisons", - title = "Auth User and Account Same Department", - code = "authenticatedUserAttributes.exists(ua => ua.name == \"department\" && accountAttributes.exists(aa => aa.name == \"department\" && ua.value == aa.value))", - description = "Check if authenticated user department matches account department" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Attribute Comparisons", - title = "Transaction Risk Within User Tolerance", - code = "transactionAttributes.exists(ta => ta.name == \"risk_score\" && userAttributes.exists(ua => ua.name == \"risk_tolerance\" && ta.value.toInt <= ua.value.toInt))", - description = "Check if transaction risk is within user's tolerance" - ), - AbacRuleExampleJsonV600( - category = "Cross-Object - Attribute Comparisons", - title = "Bank and Customer Same Region", - code = "bankAttributes.exists(ba => ba.name == \"region\" && customerAttributes.exists(ca => ca.name == \"region\" && ba.value == ca.value))", - description = "Check if bank and customer are in same region" - ), - AbacRuleExampleJsonV600( - category = "Complex - Multi-Object", - title = "Bank Employee with Active Account", - code = "authenticatedUser.emailAddress.endsWith(\"@bank.com\") && accountOpt.exists(_.balance > 0) && bankOpt.exists(_.bankId.value == \"gh.29.uk\")", - description = "Check if bank employee accessing active account at specific bank" - ), - AbacRuleExampleJsonV600( - category = "Complex - Multi-Object", - title = "Manager Accessing Other User", - code = "authenticatedUserAttributes.exists(_.name == \"role\" && _.value == \"manager\") && userOpt.exists(_.userId != authenticatedUser.userId)", - description = "Check if manager is accessing another user's data" - ), - AbacRuleExampleJsonV600( - category = "Complex - Multi-Object", - title = "Self or Authorized Delegation with Balance", - code = "(onBehalfOfUserOpt.isEmpty || onBehalfOfUserOpt.get.userId == authenticatedUser.userId) && accountOpt.exists(_.balance > 1000)", - description = "Check if self-access or authorized delegation with minimum balance" - ), - AbacRuleExampleJsonV600( - category = "Complex - Multi-Object", - title = "Verified User with Optional Delegation", - code = "userAttributes.exists(_.name == \"kyc_status\" && _.value == \"verified\") && (onBehalfOfUserOpt.isEmpty || onBehalfOfUserAttributes.exists(_.name == \"authorized\"))", - description = "Check if user is KYC verified and delegation is authorized (if present)" - ), - AbacRuleExampleJsonV600( - category = "Complex - Multi-Object", - title = "VIP Customer with Premium Account", - code = "customerAttributes.exists(_.name == \"vip_status\" && _.value == \"true\") && accountAttributes.exists(_.name == \"account_tier\" && _.value == \"premium\")", - description = "Check if VIP customer has premium account" - ), - AbacRuleExampleJsonV600( - category = "Complex - Chained Validation", - title = "User-Customer-Account-Transaction Chain", - code = "userOpt.exists(u => customerOpt.exists(c => c.email == u.emailAddress && accountOpt.exists(a => transactionOpt.exists(t => t.accountId.value == a.accountId.value))))", - description = "Validate complete chain from user to customer to account to transaction" - ), - AbacRuleExampleJsonV600( - category = "Complex - Chained Validation", - title = "Bank-Account-Transaction Request Chain", - code = "bankOpt.exists(b => accountOpt.exists(a => a.bankId == b.bankId.value && transactionRequestOpt.exists(tr => tr.this_account_id.value == a.accountId.value)))", - description = "Validate bank owns account and transaction request is for that account" - ), - AbacRuleExampleJsonV600( - category = "Complex - Aggregation", - title = "Matching Attributes", - code = "authenticatedUserAttributes.exists(aua => userAttributes.exists(ua => aua.name == ua.name && aua.value == ua.value))", - description = "Check if authenticated user and target user share any matching attributes" - ), - AbacRuleExampleJsonV600( - category = "Complex - Aggregation", - title = "Allowed Transaction Attributes", - code = "transactionAttributes.forall(ta => accountAttributes.exists(aa => aa.name == \"allowed_transaction_\" + ta.name))", - description = "Check if all transaction attributes are allowed for this account" - ), - AbacRuleExampleJsonV600( - category = "Business Logic - Loan Approval", - title = "Credit Score and Balance Check", - code = "customerAttributes.exists(ca => ca.name == \"credit_score\" && ca.value.toInt > 650) && accountOpt.exists(_.balance > 5000)", - description = "Check if customer has good credit score and sufficient balance for loan" - ), - AbacRuleExampleJsonV600( - category = "Business Logic - Wire Transfer", - title = "Wire Transfer Authorization", - code = "transactionOpt.exists(t => t.amount < 100000 && t.transactionType.exists(_.contains(\"WIRE\"))) && authenticatedUserAttributes.exists(_.name == \"wire_authorized\")", - description = "Check if wire transfer is under limit and user is authorized" - ), - AbacRuleExampleJsonV600( - category = "Business Logic - Account Closure", - title = "Self-Service or Manager Account Closure", - code = "accountOpt.exists(a => (a.balance == 0 && userOpt.exists(_.userId == authenticatedUser.userId)) || authenticatedUserAttributes.exists(_.name == \"role\" && _.value == \"manager\"))", - description = "Allow account closure if zero balance self-service or manager override" - ), - AbacRuleExampleJsonV600( - category = "Business Logic - VIP Processing", - title = "VIP Priority Check", - code = "(customerAttributes.exists(_.name == \"vip_status\" && _.value == \"true\") || accountAttributes.exists(_.name == \"account_tier\" && _.value == \"platinum\"))", - description = "Check if customer or account qualifies for VIP priority processing" - ), - AbacRuleExampleJsonV600( - category = "Business Logic - Joint Account", - title = "Joint Account Access", - code = "accountOpt.exists(a => a.accountHolders.exists(h => h.userId == authenticatedUser.userId || h.emailAddress == authenticatedUser.emailAddress))", - description = "Check if authenticated user is one of the account holders" + rule_name = "Fraud Analyst High-Risk Transaction Access", + rule_code = "authenticatedUserEntitlements.exists(e => e.roleName == \"CanReadTransactionsAtOneBank\") && callContext.exists(c => c.verb.exists(_ == \"GET\") && c.implementedByPartialFunction.exists(_.contains(\"Transaction\"))) && transactionAttributes.exists(ta => ta.name == \"risk_score\" && ta.value.toInt >= 75) && transactionOpt.exists(_.status.exists(_ != \"COMPLETED\"))", + description = "Allow users with CanReadTransactionsAtOneBank role to GET high-risk (score ≥75) non-completed transactions", + policy = "transaction-access", + is_active = true ) ), available_operators = List( @@ -5794,6 +5420,59 @@ trait APIMethods600 { } } + staticResourceDocs += ResourceDoc( + getAbacPolicies, + implementedInApiVersion, + nameOf(getAbacPolicies), + "GET", + "/management/abac-policies", + "Get ABAC Policies", + s"""Get the list of allowed ABAC policy names. + | + |ABAC rules are organized by policies. Each rule must have at least one policy assigned. + |Rules can have multiple policies (comma-separated). This endpoint returns the list of + |standardized policy names that should be used when creating or updating rules. + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + AbacPoliciesJsonV600( + policies = List( + AbacPolicyJsonV600( + policy = "account-access", + description = "Rules for controlling access to account information" + ) + ) + ), + List( + UserNotLoggedIn, + UserHasMissingRoles, + UnknownError + ), + List(apiTagABAC), + Some(List(canGetAbacRule)) + ) + + lazy val getAbacPolicies: OBPEndpoint = { + case "management" :: "abac-policies" :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (Full(user), callContext) <- authenticatedAccess(cc) + _ <- NewStyle.function.hasEntitlement("", user.userId, canGetAbacRule, callContext) + } yield { + val policies = Constant.ABAC_POLICIES.map { policy => + AbacPolicyJsonV600( + policy = policy, + description = Constant.ABAC_POLICY_DESCRIPTIONS.getOrElse(policy, "No description available") + ) + } + + (AbacPoliciesJsonV600(policies), HttpCode.`200`(callContext)) + } + } + } + staticResourceDocs += ResourceDoc( validateAbacRule, implementedInApiVersion, @@ -5991,6 +5670,112 @@ trait APIMethods600 { } } + staticResourceDocs += ResourceDoc( + executeAbacPolicy, + implementedInApiVersion, + nameOf(executeAbacPolicy), + "POST", + "/management/abac-policies/POLICY/execute", + "Execute ABAC Policy", + s"""Execute all ABAC rules in a policy to test access control. + | + |This endpoint executes all active rules that belong to the specified policy. + |The policy uses OR logic - access is granted if at least one rule passes. + | + |This allows you to test a complete policy with specific context (authenticated user, bank, account, transaction, customer, etc.). + | + |**Documentation:** + |- ${Glossary.getGlossaryItemLink("ABAC_Simple_Guide")} - Getting started with ABAC rules + |- ${Glossary.getGlossaryItemLink("ABAC_Parameters_Summary")} - Complete list of all 18 parameters + |- ${Glossary.getGlossaryItemLink("ABAC_Object_Properties_Reference")} - Detailed property reference + |- ${Glossary.getGlossaryItemLink("ABAC_Testing_Examples")} - Testing examples and patterns + | + |You can provide optional IDs in the request body to test the policy with specific context. + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + ExecuteAbacRuleJsonV600( + authenticated_user_id = Some("c7b6cb47-cb96-4441-8801-35b57456753a"), + on_behalf_of_user_id = Some("a3b5c123-1234-5678-9012-fedcba987654"), + user_id = Some("c7b6cb47-cb96-4441-8801-35b57456753a"), + bank_id = Some("gh.29.uk"), + account_id = Some("8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0"), + view_id = Some("owner"), + transaction_request_id = Some("123456"), + transaction_id = Some("abc123"), + customer_id = Some("customer-id-123") + ), + AbacRuleResultJsonV600( + result = true + ), + List( + UserNotLoggedIn, + UserHasMissingRoles, + InvalidJsonFormat, + UnknownError + ), + List(apiTagABAC), + Some(List(canExecuteAbacRule)) + ) + + lazy val executeAbacPolicy: OBPEndpoint = { + case "management" :: "abac-policies" :: policy :: "execute" :: Nil JsonPost json -> _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (Full(user), callContext) <- authenticatedAccess(cc) + _ <- NewStyle.function.hasEntitlement("", user.userId, canExecuteAbacRule, callContext) + execJson <- NewStyle.function.tryons(s"$InvalidJsonFormat", 400, callContext) { + json.extract[ExecuteAbacRuleJsonV600] + } + + // Verify the policy exists + _ <- Future { + if (Constant.ABAC_POLICIES.contains(policy)) { + Full(true) + } else { + Failure(s"Policy not found: $policy. Available policies: ${Constant.ABAC_POLICIES.mkString(", ")}") + } + } map { + unboxFullOrFail(_, callContext, s"Invalid ABAC Policy: $policy", 404) + } + + // Execute the policy with IDs - object fetching happens internally + // authenticatedUserId: can be provided in request (for testing) or defaults to actual authenticated user + // onBehalfOfUserId: optional delegation - acting on behalf of another user + // userId: the target user being evaluated (defaults to authenticated user) + effectiveAuthenticatedUserId = execJson.authenticated_user_id.getOrElse(user.userId) + + result <- Future { + val resultBox = AbacRuleEngine.executeRulesByPolicy( + policy = policy, + authenticatedUserId = effectiveAuthenticatedUserId, + onBehalfOfUserId = execJson.on_behalf_of_user_id, + userId = execJson.user_id, + callContext = callContext.getOrElse(cc), + bankId = execJson.bank_id, + accountId = execJson.account_id, + viewId = execJson.view_id, + transactionId = execJson.transaction_id, + transactionRequestId = execJson.transaction_request_id, + customerId = execJson.customer_id + ) + + resultBox match { + case Full(allowed) => + AbacRuleResultJsonV600(result = allowed) + case Failure(msg, _, _) => + AbacRuleResultJsonV600(result = false) + case Empty => + AbacRuleResultJsonV600(result = false) + } + } + } yield { + (result, HttpCode.`200`(callContext)) + } + } + } + // ============================================================================================================ // USER ATTRIBUTES v6.0.0 - Consistent with other entity attributes // ============================================================================================================ diff --git a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala index 36ab2d96b..55a92ef0f 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala @@ -380,6 +380,7 @@ case class CreateAbacRuleJsonV600( rule_name: String, rule_code: String, description: String, + policy: String, is_active: Boolean ) @@ -387,6 +388,7 @@ case class UpdateAbacRuleJsonV600( rule_name: String, rule_code: String, description: String, + policy: String, is_active: Boolean ) @@ -396,6 +398,7 @@ case class AbacRuleJsonV600( rule_code: String, is_active: Boolean, description: String, + policy: String, created_by_user_id: String, updated_by_user_id: String ) @@ -459,10 +462,11 @@ case class AbacObjectTypeJsonV600( ) case class AbacRuleExampleJsonV600( - category: String, - title: String, - code: String, - description: String + rule_name: String, + rule_code: String, + description: String, + policy: String, + is_active: Boolean ) case class AbacRuleSchemaJsonV600( @@ -473,6 +477,15 @@ case class AbacRuleSchemaJsonV600( notes: List[String] ) +case class AbacPolicyJsonV600( + policy: String, + description: String +) + +case class AbacPoliciesJsonV600( + policies: List[AbacPolicyJsonV600] +) + object JSONFactory600 extends CustomJsonFormats with MdcLoggable { def createRedisCallCountersJson( @@ -1086,6 +1099,7 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable { rule_code = rule.ruleCode, is_active = rule.isActive, description = rule.description, + policy = rule.policy, created_by_user_id = rule.createdByUserId, updated_by_user_id = rule.updatedByUserId ) diff --git a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala index 6b1868e7d..b6a30baf5 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala @@ -26,6 +26,8 @@ TESOBE (http://www.tesobe.com/) */ package code.api.v6_0_0 + +import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} import code.api.util.VersionedOBPApis diff --git a/obp-api/src/main/scala/code/authtypevalidation/MappedAuthTypeValidationProvider.scala b/obp-api/src/main/scala/code/authtypevalidation/MappedAuthTypeValidationProvider.scala index 19e7cffd6..6f7d12219 100644 --- a/obp-api/src/main/scala/code/authtypevalidation/MappedAuthTypeValidationProvider.scala +++ b/obp-api/src/main/scala/code/authtypevalidation/MappedAuthTypeValidationProvider.scala @@ -22,7 +22,7 @@ object MappedAuthTypeValidationProvider extends AuthenticationTypeValidationProv override def getByOperationId(operationId: String): Box[JsonAuthTypeValidation] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getValidationByOperationIdTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getValidationByOperationIdTTL.second) { AuthenticationTypeValidation.find(By(AuthenticationTypeValidation.OperationId, operationId)) .map(it => JsonAuthTypeValidation(it.operationId, it.allowedAuthTypes)) }} diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 4fe2e3b84..8ef5483e3 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -1,5 +1,6 @@ package code.bankconnectors +import scala.language.implicitConversions import org.apache.pekko.http.scaladsl.model.HttpMethod import code.api.attributedefinition.AttributeDefinition import code.api.util.APIUtil.{OBPReturnType, _} @@ -220,7 +221,7 @@ trait Connector extends MdcLoggable { protected implicit def OBPReturnTypeToFutureReturnType[T](value: OBPReturnType[Box[T]]): Future[Box[(T, Option[CallContext])]] = value map tupleToBoxTuple - private val futureTimeOut: Duration = 20 seconds + private val futureTimeOut: Duration = 20.seconds /** * convert OBPReturnType return type to Tuple type * @@ -240,7 +241,7 @@ trait Connector extends MdcLoggable { */ protected implicit def OBPReturnTypeToBoxTuple[T](value: OBPReturnType[Box[T]]): Box[(T, Option[CallContext])] = Await.result( - OBPReturnTypeToFutureReturnType(value), 30 seconds + OBPReturnTypeToFutureReturnType(value), 30.seconds ) /** @@ -253,7 +254,7 @@ trait Connector extends MdcLoggable { protected implicit def OBPReturnTypeToBox[T](value: OBPReturnType[Box[T]]): Box[T] = Await.result( value.map(_._1), - 30 seconds + 30.seconds ) protected def convertToTuple[T](callContext: Option[CallContext])(inbound: Box[InBoundTrait[T]]): (Box[T], Option[CallContext]) = { diff --git a/obp-api/src/main/scala/code/bankconnectors/InternalConnector.scala b/obp-api/src/main/scala/code/bankconnectors/InternalConnector.scala index b9d1464a4..d5fac02b5 100644 --- a/obp-api/src/main/scala/code/bankconnectors/InternalConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/InternalConnector.scala @@ -241,19 +241,19 @@ object InternalConnector { val dynamicMethods: Map[String, MethodSymbol] = ConnectorMethodProvider.provider.vend.getAll().map { case JsonConnectorMethod(_, methodName, _, _) => methodName -> Box(methodNameToSymbols.get(methodName)).openOrThrowException(s"method name $methodName does not exist in the Connector") - } toMap + }.toMap dynamicMethods } - private lazy val methodNameToSymbols: Map[String, MethodSymbol] = typeOf[Connector].decls collect { + private lazy val methodNameToSymbols: Map[String, MethodSymbol] = typeOf[Connector].decls.collect { case t: TermSymbol if t.isMethod && t.isPublic && !t.isConstructor && !t.isVal && !t.isVar => val methodName = t.name.decodedName.toString.trim val method = t.asMethod methodName -> method - } toMap + }.toMap - lazy val methodNameToSignature: Map[String, String] = methodNameToSymbols map { + lazy val methodNameToSignature: Map[String, String] = methodNameToSymbols.map { case (methodName, methodSymbol) => val signature = methodSymbol.typeSignature.toString val returnType = methodSymbol.returnType.toString diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnectorInternal.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnectorInternal.scala index 25e48a15f..5313b8926 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnectorInternal.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnectorInternal.scala @@ -947,7 +947,7 @@ object LocalMappedConnectorInternal extends MdcLoggable { attributeType = TransactionRequestAttributeType.withName("STRING"), value = refundReasonCode, callContext = callContext) - } else Future.successful() + } else Future.successful(()) (newTransactionRequestStatus, callContext) <- NewStyle.function.notifyTransactionRequest(refundFromAccount, refundToAccount, createdTransactionRequest, callContext) _ <- NewStyle.function.saveTransactionRequestStatusImpl(createdTransactionRequest.id, newTransactionRequestStatus.toString, callContext) diff --git a/obp-api/src/main/scala/code/bankconnectors/akka/actor/AkkaConnectorActorInit.scala b/obp-api/src/main/scala/code/bankconnectors/akka/actor/AkkaConnectorActorInit.scala index 2170bf622..ec718d31d 100644 --- a/obp-api/src/main/scala/code/bankconnectors/akka/actor/AkkaConnectorActorInit.scala +++ b/obp-api/src/main/scala/code/bankconnectors/akka/actor/AkkaConnectorActorInit.scala @@ -9,5 +9,5 @@ import scala.concurrent.duration._ trait AkkaConnectorActorInit extends MdcLoggable{ // Default is 3 seconds, which should be more than enough for slower systems val ACTOR_TIMEOUT: Long = APIUtil.getPropsAsLongValue("akka_connector.timeout").openOr(3) - implicit val timeout = Timeout(ACTOR_TIMEOUT * (1000 milliseconds)) + implicit val timeout = Timeout(ACTOR_TIMEOUT * (1000.milliseconds)) } \ No newline at end of file diff --git a/obp-api/src/main/scala/code/bankconnectors/rest/RestConnector_vMar2019.scala b/obp-api/src/main/scala/code/bankconnectors/rest/RestConnector_vMar2019.scala index 26304d01f..c5bd84c1b 100644 --- a/obp-api/src/main/scala/code/bankconnectors/rest/RestConnector_vMar2019.scala +++ b/obp-api/src/main/scala/code/bankconnectors/rest/RestConnector_vMar2019.scala @@ -23,6 +23,7 @@ Osloerstrasse 16/17 Berlin 13359, Germany */ +import scala.language.implicitConversions import _root_.org.apache.pekko.stream.StreamTcpException import org.apache.pekko.http.scaladsl.model._ import org.apache.pekko.http.scaladsl.model.headers.RawHeader diff --git a/obp-api/src/main/scala/code/connectormethod/MappedConnectorMethodProvider.scala b/obp-api/src/main/scala/code/connectormethod/MappedConnectorMethodProvider.scala index caf7cfa0e..426f9b047 100644 --- a/obp-api/src/main/scala/code/connectormethod/MappedConnectorMethodProvider.scala +++ b/obp-api/src/main/scala/code/connectormethod/MappedConnectorMethodProvider.scala @@ -31,14 +31,14 @@ object MappedConnectorMethodProvider extends ConnectorMethodProvider { override def getByMethodNameWithCache(methodName: String): Box[JsonConnectorMethod] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getConnectorMethodTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getConnectorMethodTTL.second) { getByMethodNameWithoutCache(methodName) }} } override def getAll(): List[JsonConnectorMethod] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getConnectorMethodTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getConnectorMethodTTL.second) { ConnectorMethod.findAll() .map(it => JsonConnectorMethod(Some(it.ConnectorMethodId.get), it.MethodName.get, it.MethodBody.get, getLang(it))) }} diff --git a/obp-api/src/main/scala/code/dynamicEndpoint/MapppedDynamicEndpointProvider.scala b/obp-api/src/main/scala/code/dynamicEndpoint/MapppedDynamicEndpointProvider.scala index 3ae9f9cc0..d4660d7b5 100644 --- a/obp-api/src/main/scala/code/dynamicEndpoint/MapppedDynamicEndpointProvider.scala +++ b/obp-api/src/main/scala/code/dynamicEndpoint/MapppedDynamicEndpointProvider.scala @@ -71,7 +71,7 @@ object MappedDynamicEndpointProvider extends DynamicEndpointProvider with Custom override def getAll(bankId: Option[String]): List[DynamicEndpointT] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (dynamicEndpointTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (dynamicEndpointTTL.second) { if (bankId.isEmpty) DynamicEndpoint.findAll() else diff --git a/obp-api/src/main/scala/code/dynamicMessageDoc/MappedDynamicMessageDocProvider.scala b/obp-api/src/main/scala/code/dynamicMessageDoc/MappedDynamicMessageDocProvider.scala index 81b420b27..81240419f 100644 --- a/obp-api/src/main/scala/code/dynamicMessageDoc/MappedDynamicMessageDocProvider.scala +++ b/obp-api/src/main/scala/code/dynamicMessageDoc/MappedDynamicMessageDocProvider.scala @@ -44,7 +44,7 @@ object MappedDynamicMessageDocProvider extends DynamicMessageDocProvider { override def getAll(bankId: Option[String]): List[JsonDynamicMessageDoc] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getDynamicMessageDocTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getDynamicMessageDocTTL.second) { if(bankId.isEmpty){ DynamicMessageDoc.findAll().map(DynamicMessageDoc.getJsonDynamicMessageDoc) } else { diff --git a/obp-api/src/main/scala/code/dynamicResourceDoc/MappedDynamicResourceDocProvider.scala b/obp-api/src/main/scala/code/dynamicResourceDoc/MappedDynamicResourceDocProvider.scala index 2b545f336..142e64b2e 100644 --- a/obp-api/src/main/scala/code/dynamicResourceDoc/MappedDynamicResourceDocProvider.scala +++ b/obp-api/src/main/scala/code/dynamicResourceDoc/MappedDynamicResourceDocProvider.scala @@ -50,7 +50,7 @@ object MappedDynamicResourceDocProvider extends DynamicResourceDocProvider { override def getAllAndConvert[T: Manifest](bankId: Option[String], transform: JsonDynamicResourceDoc => T): List[T] = { val cacheKey = (bankId.toString+transform.toString()).intern() - Caching.memoizeSyncWithImMemory(Some(cacheKey))(getDynamicResourceDocTTL seconds){ + Caching.memoizeSyncWithImMemory(Some(cacheKey))(getDynamicResourceDocTTL.seconds){ if(bankId.isEmpty){ DynamicResourceDoc.findAll() .map(doc => transform(DynamicResourceDoc.getJsonDynamicResourceDoc(doc))) diff --git a/obp-api/src/main/scala/code/fx/fx.scala b/obp-api/src/main/scala/code/fx/fx.scala index f5a6ec948..9abf2e2f9 100644 --- a/obp-api/src/main/scala/code/fx/fx.scala +++ b/obp-api/src/main/scala/code/fx/fx.scala @@ -66,7 +66,7 @@ object fx extends MdcLoggable { */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(TTL seconds) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(TTL.seconds) { getFallbackExchangeRate(fromCurrency, toCurrency) } } diff --git a/obp-api/src/main/scala/code/management/ImporterAPI.scala b/obp-api/src/main/scala/code/management/ImporterAPI.scala index 3a0fa9e28..0a65a03e0 100644 --- a/obp-api/src/main/scala/code/management/ImporterAPI.scala +++ b/obp-api/src/main/scala/code/management/ImporterAPI.scala @@ -160,7 +160,7 @@ object ImporterAPI extends RestHelper with MdcLoggable { * per "Account". */ // TODO: this duration limit should be fixed - val createdEnvelopes = TransactionInserter !? (3 minutes, toInsert) + val createdEnvelopes = TransactionInserter !? (3.minutes, toInsert) createdEnvelopes match { case Full(inserted : InsertedTransactions) => diff --git a/obp-api/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala b/obp-api/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala index 08c244a22..44d6b5cf4 100644 --- a/obp-api/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala +++ b/obp-api/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala @@ -35,7 +35,7 @@ object MapperCounterparties extends Counterparties with MdcLoggable { */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(MetadataTTL second) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(MetadataTTL.second) { /** * Generates a new alias name that is guaranteed not to collide with any existing public alias names diff --git a/obp-api/src/main/scala/code/metrics/ConnectorMetrics.scala b/obp-api/src/main/scala/code/metrics/ConnectorMetrics.scala index edc8a1de1..9267e18c6 100644 --- a/obp-api/src/main/scala/code/metrics/ConnectorMetrics.scala +++ b/obp-api/src/main/scala/code/metrics/ConnectorMetrics.scala @@ -33,7 +33,7 @@ object ConnectorMetrics extends ConnectorMetricsProvider { */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cachedAllConnectorMetrics days){ + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cachedAllConnectorMetrics.days){ val limit = queryParams.collect { case OBPLimit(value) => MaxRows[MappedConnectorMetric](value) }.headOption val offset = queryParams.collect { case OBPOffset(value) => StartAt[MappedConnectorMetric](value) }.headOption val fromDate = queryParams.collect { case OBPFromDate(date) => By_>=(MappedConnectorMetric.date, date) }.headOption diff --git a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala index c62a4dc6e..6ccdefb8a 100644 --- a/obp-api/src/main/scala/code/metrics/MappedMetrics.scala +++ b/obp-api/src/main/scala/code/metrics/MappedMetrics.scala @@ -284,7 +284,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) val cacheTTL = determineMetricsCacheTTL(queryParams) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL seconds){ + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL.seconds){ val optionalParams = getQueryParams(queryParams) MappedMetric.findAll(optionalParams: _*) } @@ -339,7 +339,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) val cacheTTL = determineMetricsCacheTTL(queryParams) logger.debug(s"getAllAggregateMetricsBox cache key: $cacheKey, TTL: $cacheTTL seconds") - CacheKeyFromArguments.buildCacheKey { Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL seconds){ + CacheKeyFromArguments.buildCacheKey { Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL.seconds){ logger.info(s"getAllAggregateMetricsBox - CACHE MISS - Executing database query for aggregate metrics") val startTime = System.currentTimeMillis() val fromDate = queryParams.collect { case OBPFromDate(value) => value }.headOption @@ -457,7 +457,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) val cacheTTL = determineMetricsCacheTTL(queryParams) - CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL seconds){ + CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL.seconds){ { val fromDate = queryParams.collect { case OBPFromDate(value) => value }.headOption val toDate = queryParams.collect { case OBPToDate(value) => value }.headOption @@ -540,7 +540,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{ */ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) val cacheTTL = determineMetricsCacheTTL(queryParams) - CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL seconds){ + CacheKeyFromArguments.buildCacheKey {Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL.seconds){ val fromDate = queryParams.collect { case OBPFromDate(value) => value }.headOption val toDate = queryParams.collect { case OBPToDate(value) => value }.headOption diff --git a/obp-api/src/main/scala/code/model/ModeratedBankingData.scala b/obp-api/src/main/scala/code/model/ModeratedBankingData.scala index cf0a5aa35..cbe1eeb62 100644 --- a/obp-api/src/main/scala/code/model/ModeratedBankingData.scala +++ b/obp-api/src/main/scala/code/model/ModeratedBankingData.scala @@ -26,6 +26,8 @@ TESOBE (http://www.tesobe.com/) */ package code.model + +import scala.language.implicitConversions import code.api.Constant._ import code.api.util.ErrorMessages._ import code.api.util.{APIUtil, CallContext} @@ -182,6 +184,7 @@ class ModeratedTransactionMetadata( object ModeratedTransactionMetadata { + import scala.language.implicitConversions @deprecated(Helper.deprecatedJsonGenerationMessage) implicit def moderatedTransactionMetadata2Json(mTransactionMeta: ModeratedTransactionMetadata) : JObject = { JObject(JField("blah", JString("test")) :: Nil) @@ -256,6 +259,7 @@ object ModeratedBankAccount { ("name" -> bankName)) } + import scala.language.implicitConversions @deprecated(Helper.deprecatedJsonGenerationMessage) implicit def moderatedBankAccount2Json(mBankAccount: ModeratedBankAccount) : JObject = { val holderName = mBankAccount.owners match{ @@ -318,6 +322,7 @@ case class ModeratedOtherBankAccountCore( } object ModeratedOtherBankAccount { + import scala.language.implicitConversions @deprecated(Helper.deprecatedJsonGenerationMessage) implicit def moderatedOtherBankAccount2Json(mOtherBank: ModeratedOtherBankAccount) : JObject = { val holderName = mOtherBank.label.display @@ -353,6 +358,7 @@ class ModeratedOtherBankAccountMetadata( ) object ModeratedOtherBankAccountMetadata { + import scala.language.implicitConversions @deprecated(Helper.deprecatedJsonGenerationMessage) implicit def moderatedOtherBankAccountMetadata2Json(mOtherBankMeta: ModeratedOtherBankAccountMetadata) : JObject = { JObject(JField("blah", JString("test")) :: Nil) diff --git a/obp-api/src/main/scala/code/model/OAuth.scala b/obp-api/src/main/scala/code/model/OAuth.scala index c59f63a9c..6a93dceef 100644 --- a/obp-api/src/main/scala/code/model/OAuth.scala +++ b/obp-api/src/main/scala/code/model/OAuth.scala @@ -299,7 +299,7 @@ object MappedConsumersProvider extends ConsumersProvider with MdcLoggable { if(integrateWithHydra && isActive.isDefined) { val clientId = c.key.get val existsOAuth2Client = Box.tryo(hydraAdmin.getOAuth2Client(clientId)) - .filter(null !=) + .filter(null.!=) // TODO Involve Hydra ORY version with working update mechanism if (isActive == Some(false) && existsOAuth2Client.isDefined) { existsOAuth2Client @@ -956,7 +956,7 @@ class Token extends LongKeyedMapper[Token]{ } def generateThirdPartyApplicationSecret: String = { - if(thirdPartyApplicationSecret.get isEmpty){ + if(thirdPartyApplicationSecret.get.isEmpty){ def r() = randomInt(9).toString //from zero to 9 val generatedSecret = (1 to 10).map(x => r()).foldLeft("")(_ + _) thirdPartyApplicationSecret(generatedSecret).save diff --git a/obp-api/src/main/scala/code/model/View.scala b/obp-api/src/main/scala/code/model/View.scala index b7d9d4ebd..bbb44d32a 100644 --- a/obp-api/src/main/scala/code/model/View.scala +++ b/obp-api/src/main/scala/code/model/View.scala @@ -505,6 +505,7 @@ case class ViewExtended(val view: View) extends MdcLoggable { None } + import scala.language.implicitConversions implicit def optionStringToString(x : Option[String]) : String = x.getOrElse("") val otherAccountNationalIdentifier = if(viewPermissions.exists(_ == CAN_SEE_OTHER_ACCOUNT_NATIONAL_IDENTIFIER)) Some(otherBankAccount.nationalIdentifier) else None val otherAccountSWIFT_BIC = if(viewPermissions.exists(_ == CAN_SEE_OTHER_ACCOUNT_SWIFT_BIC)) otherBankAccount.otherBankRoutingAddress else None @@ -607,6 +608,7 @@ case class ViewExtended(val view: View) extends MdcLoggable { None } + import scala.language.implicitConversions implicit def optionStringToString(x : Option[String]) : String = x.getOrElse("") val otherAccountSWIFT_BIC = if(viewPermissions.exists(_ == CAN_SEE_OTHER_ACCOUNT_SWIFT_BIC)) counterpartyCore.otherBankRoutingAddress else None val otherAccountIBAN = if(viewPermissions.exists(_ == CAN_SEE_OTHER_ACCOUNT_IBAN)) counterpartyCore.otherAccountRoutingAddress else None diff --git a/obp-api/src/main/scala/code/model/dataAccess/AuthUser.scala b/obp-api/src/main/scala/code/model/dataAccess/AuthUser.scala index 0d8a462f9..de1989065 100644 --- a/obp-api/src/main/scala/code/model/dataAccess/AuthUser.scala +++ b/obp-api/src/main/scala/code/model/dataAccess/AuthUser.scala @@ -352,7 +352,7 @@ class AuthUser extends MegaProtoUser[AuthUser] with CreatedUpdated with MdcLogga } override def save(): Boolean = { - if(! (user defined_?)){ + if(! (user.defined_?)){ logger.info("user reference is null. We will create a ResourceUser") val resourceUser = createUnsavedResourceUser() val savedUser = Users.users.vend.saveResourceUser(resourceUser) diff --git a/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala b/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala index 5b0174c21..810d1bc6c 100644 --- a/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala +++ b/obp-api/src/main/scala/code/model/dataAccess/ResourceUser.scala @@ -139,7 +139,7 @@ object ResourceUser extends ResourceUser with LongKeyedMetaMapper[ResourceUser]{ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) val cacheTTL = APIUtil.getPropsAsIntValue("getDistinctProviders.cache.ttl.seconds", 3600) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL seconds) { + Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(cacheTTL.seconds) { val sql = "SELECT DISTINCT provider_ FROM resourceuser ORDER BY provider_" val (_, rows) = DB.runQuery(sql, List()) rows.flatten diff --git a/obp-api/src/main/scala/code/model/package.scala b/obp-api/src/main/scala/code/model/package.scala index 2f79aed10..4f2626c13 100644 --- a/obp-api/src/main/scala/code/model/package.scala +++ b/obp-api/src/main/scala/code/model/package.scala @@ -1,5 +1,6 @@ package code +import scala.language.implicitConversions import code.metadata.comments.Comments import code.metadata.counterparties.Counterparties import code.metadata.narrative.Narrative @@ -16,6 +17,7 @@ import com.openbankproject.commons.model._ * Bank -> Bank + BankEx */ package object model { + import scala.language.implicitConversions implicit def toBankExtended(bank: Bank) = BankExtended(bank) diff --git a/obp-api/src/main/scala/code/obp/grpc/Client.scala b/obp-api/src/main/scala/code/obp/grpc/Client.scala index 9d81a57bd..c8209f6c1 100644 --- a/obp-api/src/main/scala/code/obp/grpc/Client.scala +++ b/obp-api/src/main/scala/code/obp/grpc/Client.scala @@ -1,5 +1,6 @@ package code.obp.grpc +import scala.language.existentials import code.obp.grpc.api._ import com.google.protobuf.empty.Empty import io.grpc.{ManagedChannel, ManagedChannelBuilder} diff --git a/obp-api/src/main/scala/code/obp/grpc/HelloWorldServer.scala b/obp-api/src/main/scala/code/obp/grpc/HelloWorldServer.scala index 773b60f60..c77752fc5 100644 --- a/obp-api/src/main/scala/code/obp/grpc/HelloWorldServer.scala +++ b/obp-api/src/main/scala/code/obp/grpc/HelloWorldServer.scala @@ -1,5 +1,7 @@ package code.obp.grpc +import scala.language.existentials +import scala.language.reflectiveCalls import code.api.util.newstyle.ViewNewStyle import code.api.util.{APIUtil, CallContext, NewStyle} import code.api.v3_0_0.{CoreTransactionsJsonV300, ModeratedTransactionCoreWithAttributes} diff --git a/obp-api/src/main/scala/code/search/search.scala b/obp-api/src/main/scala/code/search/search.scala index 5c37eeaa9..e99dddf3d 100644 --- a/obp-api/src/main/scala/code/search/search.scala +++ b/obp-api/src/main/scala/code/search/search.scala @@ -185,13 +185,13 @@ class elasticsearch extends MdcLoggable { } private def getParameters(queryString: String): Map[String, String] = { - val res = queryString.split('&') map { str => + val res = queryString.split('&').map { str => val pair = str.split('=') if (pair.length > 1) (pair(0) -> pair(1)) else (pair(0) -> "") - } toMap + }.toMap res } diff --git a/obp-api/src/main/scala/code/snippet/GetHtmlFromUrl.scala b/obp-api/src/main/scala/code/snippet/GetHtmlFromUrl.scala index b1016ffa1..2d4b82f5e 100644 --- a/obp-api/src/main/scala/code/snippet/GetHtmlFromUrl.scala +++ b/obp-api/src/main/scala/code/snippet/GetHtmlFromUrl.scala @@ -55,7 +55,7 @@ object GetHtmlFromUrl extends MdcLoggable { logger.debug("jsVendorSupportHtml: " + jsVendorSupportHtml) // sleep for up to 5 seconds at development environment - if (Props.mode == Props.RunModes.Development) Thread.sleep(randomLong(3 seconds)) + if (Props.mode == Props.RunModes.Development) Thread.sleep(randomLong(3.seconds)) jsVendorSupportHtml } diff --git a/obp-api/src/main/scala/code/snippet/WebUI.scala b/obp-api/src/main/scala/code/snippet/WebUI.scala index 1d9e744ef..7973f6ced 100644 --- a/obp-api/src/main/scala/code/snippet/WebUI.scala +++ b/obp-api/src/main/scala/code/snippet/WebUI.scala @@ -312,11 +312,11 @@ class WebUI extends MdcLoggable{ // External Consumer Registration Link // This replaces the internal Lift-based consumer registration functionality // with a link to an external consumer registration service. - // Uses webui_api_explorer_url + /consumers/register as default. + // Uses OBP-Portal (webui_obp_portal_url) for consumer registration by default. // Configure webui_external_consumer_registration_url to override with a custom URL. def externalConsumerRegistrationLink: CssSel = { - val apiExplorerUrl = getWebUiPropsValue("webui_api_explorer_url", "http://localhost:5174") - val defaultConsumerRegisterUrl = s"$apiExplorerUrl/consumers/register" + val portalUrl = getWebUiPropsValue("webui_obp_portal_url", "http://localhost:5174") + val defaultConsumerRegisterUrl = s"$portalUrl/consumer-registration" val externalUrl = getWebUiPropsValue("webui_external_consumer_registration_url", defaultConsumerRegisterUrl) ".get-api-key-link a [href]" #> scala.xml.Unparsed(externalUrl) & ".get-api-key-link a [target]" #> "_blank" & @@ -641,7 +641,7 @@ class WebUI extends MdcLoggable{ val html = XML.loadString(htmlString) // Sleep if in development environment so can see the effects of content loading slowly - if (Props.mode == Props.RunModes.Development) Thread.sleep(10 seconds) + if (Props.mode == Props.RunModes.Development) Thread.sleep(10.seconds) // Return the HTML html diff --git a/obp-api/src/main/scala/code/util/AkkaHttpClient.scala b/obp-api/src/main/scala/code/util/AkkaHttpClient.scala index 946c1a92b..46d229784 100644 --- a/obp-api/src/main/scala/code/util/AkkaHttpClient.scala +++ b/obp-api/src/main/scala/code/util/AkkaHttpClient.scala @@ -52,7 +52,7 @@ object AkkaHttpClient extends MdcLoggable with CustomJsonFormats { private lazy val connectionPoolSettings: ConnectionPoolSettings = { val systemConfig = ConnectionPoolSettings(system.settings.config) //Note: get the timeout setting from here: https://github.com/akka/akka-http/issues/742 - val clientSettings = systemConfig.connectionSettings.withIdleTimeout(httpRequestTimeout seconds) + val clientSettings = systemConfig.connectionSettings.withIdleTimeout(httpRequestTimeout.seconds) // reset some settings value systemConfig.copy( /* diff --git a/obp-api/src/main/scala/code/util/Helper.scala b/obp-api/src/main/scala/code/util/Helper.scala index e2dd61562..51802a0ac 100644 --- a/obp-api/src/main/scala/code/util/Helper.scala +++ b/obp-api/src/main/scala/code/util/Helper.scala @@ -89,14 +89,14 @@ object Helper extends Loggable { */ def booleanToBox(statement: => Boolean, msg: String): Box[Unit] = { if(statement) - Full() + Full(()) else Failure(msg) } def booleanToBox(statement: => Boolean): Box[Unit] = { if(statement) - Full() + Full(()) else Empty } @@ -450,7 +450,7 @@ object Helper extends Loggable { def getRequiredFieldInfo(tpe: Type): RequiredInfo = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - code.api.cache.Caching.memoizeSyncWithImMemory (Some(cacheKey.toString())) (100000 days) { + code.api.cache.Caching.memoizeSyncWithImMemory (Some(cacheKey.toString())) (100000.days) { RequiredFieldValidation.getRequiredInfo(tpe) diff --git a/obp-api/src/main/scala/code/validation/MappedJsonSchemaValidationProvider.scala b/obp-api/src/main/scala/code/validation/MappedJsonSchemaValidationProvider.scala index 53538d152..17f7a663e 100644 --- a/obp-api/src/main/scala/code/validation/MappedJsonSchemaValidationProvider.scala +++ b/obp-api/src/main/scala/code/validation/MappedJsonSchemaValidationProvider.scala @@ -20,7 +20,7 @@ object MappedJsonSchemaValidationProvider extends JsonSchemaValidationProvider { override def getByOperationId(operationId: String): Box[JsonValidation] = { var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getValidationByOperationIdTTL second) { + Caching.memoizeSyncWithProvider (Some(cacheKey.toString())) (getValidationByOperationIdTTL.second) { JsonSchemaValidation.find(By(JsonSchemaValidation.OperationId, operationId)) .map(it => JsonValidation(it.operationId, it.jsonSchema)) }} diff --git a/obp-api/src/main/scala/code/views/MapperViews.scala b/obp-api/src/main/scala/code/views/MapperViews.scala index 19e7d1c4e..01cacb7d6 100644 --- a/obp-api/src/main/scala/code/views/MapperViews.scala +++ b/obp-api/src/main/scala/code/views/MapperViews.scala @@ -469,7 +469,7 @@ object MapperViews extends Views with MdcLoggable { viewId ).length > 0 match { case true => Failure("Account Access record uses this View.") // We want to prevent account access orphans - case false => Full() + case false => Full(()) } } yield { customView.deleteViewPermissions @@ -481,7 +481,7 @@ object MapperViews extends Views with MdcLoggable { view <- ViewDefinition.findSystemView(viewId.value) _ <- AccountAccess.findAllBySystemViewId(viewId).length > 0 match { case true => Failure("Account Access record uses this View.") // We want to prevent account access orphans - case false => Full() + case false => Full(()) } } yield { view.deleteViewPermissions diff --git a/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala b/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala index cec35e7c0..93b7516be 100644 --- a/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala +++ b/obp-api/src/main/scala/code/webuiprops/MappedWebUiPropsProvider.scala @@ -42,7 +42,7 @@ object MappedWebUiPropsProvider extends WebUiPropsProvider { import scala.concurrent.duration._ var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithImMemory(Some(cacheKey.toString()))(webUiPropsTTL second) { + Caching.memoizeSyncWithImMemory(Some(cacheKey.toString()))(webUiPropsTTL.second) { // If we have an active brand, construct a target property name to look for. val brandSpecificPropertyName = activeBrand() match { case Some(brand) => s"${requestedPropertyName}_FOR_BRAND_${brand}" diff --git a/obp-commons/pom.xml b/obp-commons/pom.xml index a41f81a4e..be3797110 100644 --- a/obp-commons/pom.xml +++ b/obp-commons/pom.xml @@ -113,14 +113,9 @@ once . WDF TestSuite.txt - - -Drun.mode=test -XX:MaxMetaspaceSize=1G -Xms2G -Xmx4G -XX:+UseG1GC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+UseStringDeduplication + -Drun.mode=test -XX:MaxMetaspaceSize=512m -Xms512m -Xmx512m code.external ${maven.test.failure.ignore} - - - - false diff --git a/pom.xml b/pom.xml index af0637b25..9969b8a19 100644 --- a/pom.xml +++ b/pom.xml @@ -134,14 +134,10 @@ ${scala.compiler} ${project.build.sourceEncoding} true - incremental - true -DpackageLinkDefs=file://${project.build.directory}/packageLinkDefs.properties - -Xms512m - -Xmx2G - -XX:+TieredCompilation - -XX:TieredStopAtLevel=1 + -Xms64m + -Xmx1024m -unchecked @@ -151,12 +147,6 @@ -deprecation --> -Ypartial-unification - - -language:implicitConversions - -language:reflectiveCalls - -language:postfixOps - - -Wconf:cat=deprecation&msg=auto-application:s