diff --git a/.github/workflows/build_container_develop_branch.yml b/.github/workflows/build_container_develop_branch.yml
index 211cc9cb9..c9355f523 100644
--- a/.github/workflows/build_container_develop_branch.yml
+++ b/.github/workflows/build_container_develop_branch.yml
@@ -3,12 +3,9 @@ name: Build and publish container develop
# read-write repo token
# access to secrets
on:
- workflow_run:
- workflows: [build maven artifact]
+ push:
branches:
- develop
- types:
- - completed
env:
## Sets environment variable
@@ -19,35 +16,78 @@ env:
jobs:
build:
runs-on: ubuntu-latest
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
+ services:
+ # Label used to access the service container
+ redis:
+ # Docker Hub image
+ image: redis
+ ports:
+ # Opens tcp port 6379 on the host and service container
+ - 6379:6379
+ # Set health checks to wait until redis has started
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
steps:
- - uses: actions/checkout@v3
- - name: 'Download artifact'
- uses: actions/github-script@v7
+ - uses: actions/checkout@v4
+ - name: Set up JDK 11
+ uses: actions/setup-java@v4
with:
- script: |
- var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
- owner: context.repo.owner,
- repo: context.repo.repo,
- run_id: ${{github.event.workflow_run.id }},
- });
- var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
- return artifact.name == "push"
- })[0];
- var download = await github.rest.actions.downloadArtifact({
- owner: context.repo.owner,
- repo: context.repo.repo,
- artifact_id: matchArtifact.id,
- archive_format: 'zip',
- });
- var fs = require('fs');
- fs.writeFileSync('${{github.workspace}}/push.zip', Buffer.from(download.data));
- - run: unzip push.zip
-
- - name: prepare the artifact
+ java-version: '11'
+ distribution: 'adopt'
+ cache: maven
+ - name: Build with Maven
run: |
- mkdir -p obp-api/target/
- cp obp-api-1.10.1.war obp-api/target/obp-api-1.10.1.war
+ cp obp-api/src/main/resources/props/sample.props.template obp-api/src/main/resources/props/production.default.props
+ echo connector=star > obp-api/src/main/resources/props/test.default.props
+ echo starConnector_supported_types=mapped,internal >> obp-api/src/main/resources/props/test.default.props
+ echo hostname=http://localhost:8016 >> obp-api/src/main/resources/props/test.default.props
+ echo tests.port=8016 >> obp-api/src/main/resources/props/test.default.props
+ echo End of minimum settings >> obp-api/src/main/resources/props/test.default.props
+ echo payments_enabled=false >> obp-api/src/main/resources/props/test.default.props
+ echo importer_secret=change_me >> obp-api/src/main/resources/props/test.default.props
+ echo messageQueue.updateBankAccountsTransaction=false >> obp-api/src/main/resources/props/test.default.props
+ echo messageQueue.createBankAccounts=false >> obp-api/src/main/resources/props/test.default.props
+ echo allow_sandbox_account_creation=true >> obp-api/src/main/resources/props/test.default.props
+ echo allow_sandbox_data_import=true >> obp-api/src/main/resources/props/test.default.props
+ echo sandbox_data_import_secret=change_me >> obp-api/src/main/resources/props/test.default.props
+ echo allow_account_deletion=true >> obp-api/src/main/resources/props/test.default.props
+ echo allowed_internal_redirect_urls = /,/oauth/authorize >> obp-api/src/main/resources/props/test.default.props
+ echo transactionRequests_enabled=true >> obp-api/src/main/resources/props/test.default.props
+ echo transactionRequests_supported_types=SEPA,SANDBOX_TAN,FREE_FORM,COUNTERPARTY,ACCOUNT,SIMPLE >> obp-api/src/main/resources/props/test.default.props
+ echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo openredirects.hostname.whitlelist=http://127.0.0.1,http://localhost >> obp-api/src/main/resources/props/test.default.props
+ echo remotedata.secret = foobarbaz >> obp-api/src/main/resources/props/test.default.props
+ echo allow_public_views=true >> obp-api/src/main/resources/props/test.default.props
+
+ echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo ACCOUNT_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo SEPA_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo FREE_FORM_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo COUNTERPARTY_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo SEPA_CREDIT_TRANSFERS_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+
+ echo kafka.akka.timeout = 9 >> obp-api/src/main/resources/props/test.default.props
+ echo remotedata.timeout = 10 >> obp-api/src/main/resources/props/test.default.props
+
+ echo allow_oauth2_login=true >> obp-api/src/main/resources/props/test.default.props
+ echo oauth2.jwk_set.url=https://www.googleapis.com/oauth2/v3/certs >> obp-api/src/main/resources/props/test.default.props
+
+ echo ResetPasswordUrlEnabled=true >> obp-api/src/main/resources/props/test.default.props
+
+ echo consents.allowed=true >> obp-api/src/main/resources/props/test.default.props
+ MAVEN_OPTS="-Xmx3G -Xss2m" mvn clean package -Pprod
+
+ - name: Save .war artifact
+ run: |
+ mkdir -p ./push
+ cp obp-api/target/obp-api-1.*.war ./push/
+ - uses: actions/upload-artifact@v4
+ with:
+ name: ${{ github.sha }}
+ path: push/
- name: Build the Docker image
run: |
diff --git a/.github/workflows/build_container_non_develop_branch.yml b/.github/workflows/build_container_non_develop_branch.yml
index 7c8a0e695..0a3a1e608 100644
--- a/.github/workflows/build_container_non_develop_branch.yml
+++ b/.github/workflows/build_container_non_develop_branch.yml
@@ -1,54 +1,93 @@
name: Build and publish container non develop
-# read-write repo token
-# access to secrets
on:
- workflow_run:
- workflows: [build maven artifact]
+ push:
branches:
- '*'
- '!develop'
- types:
- - completed
env:
- ## Sets environment variable
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' }}
+ services:
+ # Label used to access the service container
+ redis:
+ # Docker Hub image
+ image: redis
+ ports:
+ # Opens tcp port 6379 on the host and service container
+ - 6379:6379
+ # Set health checks to wait until redis has started
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
steps:
- uses: actions/checkout@v3
- - name: 'Download artifact'
- uses: actions/github-script@v7
+ - name: Extract branch name
+ shell: bash
+ run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
+ - name: Set up JDK 11
+ uses: actions/setup-java@v2
with:
- script: |
- var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
- owner: context.repo.owner,
- repo: context.repo.repo,
- run_id: ${{github.event.workflow_run.id }},
- });
- var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
- return artifact.name == "push"
- })[0];
- var download = await github.rest.actions.downloadArtifact({
- owner: context.repo.owner,
- repo: context.repo.repo,
- artifact_id: matchArtifact.id,
- archive_format: 'zip',
- });
- var fs = require('fs');
- fs.writeFileSync('${{github.workspace}}/push.zip', Buffer.from(download.data));
- - run: unzip push.zip
-
- - name: prepare the artifact
+ java-version: '11'
+ distribution: 'adopt'
+ cache: maven
+ - name: Build with Maven
run: |
- mkdir -p obp-api/target/
- cp obp-api-1.10.1.war obp-api/target/obp-api-1.10.1.war
+ cp obp-api/src/main/resources/props/sample.props.template obp-api/src/main/resources/props/production.default.props
+ echo connector=star > obp-api/src/main/resources/props/test.default.props
+ echo starConnector_supported_types=mapped,internal >> obp-api/src/main/resources/props/test.default.props
+ echo hostname=http://localhost:8016 >> obp-api/src/main/resources/props/test.default.props
+ echo tests.port=8016 >> obp-api/src/main/resources/props/test.default.props
+ echo End of minimum settings >> obp-api/src/main/resources/props/test.default.props
+ echo payments_enabled=false >> obp-api/src/main/resources/props/test.default.props
+ echo importer_secret=change_me >> obp-api/src/main/resources/props/test.default.props
+ echo messageQueue.updateBankAccountsTransaction=false >> obp-api/src/main/resources/props/test.default.props
+ echo messageQueue.createBankAccounts=false >> obp-api/src/main/resources/props/test.default.props
+ echo allow_sandbox_account_creation=true >> obp-api/src/main/resources/props/test.default.props
+ echo allow_sandbox_data_import=true >> obp-api/src/main/resources/props/test.default.props
+ echo sandbox_data_import_secret=change_me >> obp-api/src/main/resources/props/test.default.props
+ echo allow_account_deletion=true >> obp-api/src/main/resources/props/test.default.props
+ echo allowed_internal_redirect_urls = /,/oauth/authorize >> obp-api/src/main/resources/props/test.default.props
+ echo transactionRequests_enabled=true >> obp-api/src/main/resources/props/test.default.props
+ echo transactionRequests_supported_types=SEPA,SANDBOX_TAN,FREE_FORM,COUNTERPARTY,ACCOUNT,SIMPLE >> obp-api/src/main/resources/props/test.default.props
+ echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo openredirects.hostname.whitlelist=http://127.0.0.1,http://localhost >> obp-api/src/main/resources/props/test.default.props
+ echo remotedata.secret = foobarbaz >> obp-api/src/main/resources/props/test.default.props
+ echo allow_public_views=true >> obp-api/src/main/resources/props/test.default.props
+
+ echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo ACCOUNT_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo SEPA_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo FREE_FORM_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo COUNTERPARTY_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+ echo SEPA_CREDIT_TRANSFERS_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
+
+ echo kafka.akka.timeout = 9 >> obp-api/src/main/resources/props/test.default.props
+ echo remotedata.timeout = 10 >> obp-api/src/main/resources/props/test.default.props
+
+ echo allow_oauth2_login=true >> obp-api/src/main/resources/props/test.default.props
+ echo oauth2.jwk_set.url=https://www.googleapis.com/oauth2/v3/certs >> obp-api/src/main/resources/props/test.default.props
+
+ echo ResetPasswordUrlEnabled=true >> obp-api/src/main/resources/props/test.default.props
+
+ echo consents.allowed=true >> obp-api/src/main/resources/props/test.default.props
+ MAVEN_OPTS="-Xmx3G -Xss2m" mvn clean package -Pprod
+
+ - name: Save .war artifact
+ run: |
+ mkdir -p ./push
+ cp obp-api/target/obp-api-1.*.war ./push/
+ - uses: actions/upload-artifact@v4
+ with:
+ name: ${{ github.sha }}
+ path: push/
- name: Build the Docker image
run: |
diff --git a/.github/workflows/build_contributer_container.yml b/.github/workflows/build_contributer_container.yml
deleted file mode 100644
index 5700bbdb2..000000000
--- a/.github/workflows/build_contributer_container.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: Build and publish commiter container
-
-# read-write repo token
-# access to secrets
-on:
- workflow_run:
- workflows: [Build on Pull Request]
- types:
- - completed
-
-env:
- ## Sets environment variable
- DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION }}
-
-jobs:
- upload:
- runs-on: ubuntu-latest
- if: >
- github.event.workflow_run.event == 'pull_request' &&
- github.event.workflow_run.conclusion == 'success'
- steps:
- - uses: actions/checkout@v3
- - name: 'Download artifact'
- uses: actions/github-script@v7
- with:
- script: |
- var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
- owner: context.repo.owner,
- repo: context.repo.repo,
- run_id: ${{github.event.workflow_run.id }},
- });
- var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
- return artifact.name == "pr"
- })[0];
- var download = await github.rest.actions.downloadArtifact({
- owner: context.repo.owner,
- repo: context.repo.repo,
- artifact_id: matchArtifact.id,
- archive_format: 'zip',
- });
- var fs = require('fs');
- fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));
- - run: unzip pr.zip
- - name: Get user from file
- run: echo "USER_NAME=$(cat UN)" >> $GITHUB_ENV
-
- - name: prepare the artifact
- run: |
- mkdir -p obp-api/target/
- cp obp-api-1.10.1.war obp-api/target/obp-api-1.10.1.war
-
- - name: Build the Docker image
- 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 }}/obp-api-${{ env.USER_NAME }}:${{ github.event.pull_request.head }} --tag docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/obp-api-${{ env.USER_NAME }}:latest
- docker push docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/obp-api-${{ env.USER_NAME }} --all-tags
- echo docker done
diff --git a/.github/workflows/build_package.yml b/.github/workflows/build_package.yml
deleted file mode 100644
index e1d246800..000000000
--- a/.github/workflows/build_package.yml
+++ /dev/null
@@ -1,82 +0,0 @@
-name: build maven artifact
-
-on: [push]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- services:
- # Label used to access the service container
- redis:
- # Docker Hub image
- image: redis
- ports:
- # Opens tcp port 6379 on the host and service container
- - 6379:6379
- # Set health checks to wait until redis has started
- options: >-
- --health-cmd "redis-cli ping"
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
- steps:
- - uses: actions/checkout@v3
- - name: Set up JDK 11
- uses: actions/setup-java@v2
- with:
- java-version: '11'
- distribution: 'adopt'
- cache: maven
- - name: Build with Maven
- run: |
- cp obp-api/src/main/resources/props/sample.props.template obp-api/src/main/resources/props/production.default.props
- echo connector=star > obp-api/src/main/resources/props/test.default.props
- echo starConnector_supported_types=mapped,internal >> obp-api/src/main/resources/props/test.default.props
- echo hostname=http://localhost:8016 >> obp-api/src/main/resources/props/test.default.props
- echo tests.port=8016 >> obp-api/src/main/resources/props/test.default.props
- echo End of minimum settings >> obp-api/src/main/resources/props/test.default.props
- echo payments_enabled=false >> obp-api/src/main/resources/props/test.default.props
- echo importer_secret=change_me >> obp-api/src/main/resources/props/test.default.props
- echo messageQueue.updateBankAccountsTransaction=false >> obp-api/src/main/resources/props/test.default.props
- echo messageQueue.createBankAccounts=false >> obp-api/src/main/resources/props/test.default.props
- echo allow_sandbox_account_creation=true >> obp-api/src/main/resources/props/test.default.props
- echo allow_sandbox_data_import=true >> obp-api/src/main/resources/props/test.default.props
- echo sandbox_data_import_secret=change_me >> obp-api/src/main/resources/props/test.default.props
- echo allow_account_deletion=true >> obp-api/src/main/resources/props/test.default.props
- echo allowed_internal_redirect_urls = /,/oauth/authorize >> obp-api/src/main/resources/props/test.default.props
- echo transactionRequests_enabled=true >> obp-api/src/main/resources/props/test.default.props
- echo transactionRequests_supported_types=SEPA,SANDBOX_TAN,FREE_FORM,COUNTERPARTY,ACCOUNT,SIMPLE >> obp-api/src/main/resources/props/test.default.props
- echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo openredirects.hostname.whitlelist=http://127.0.0.1,http://localhost >> obp-api/src/main/resources/props/test.default.props
- echo remotedata.secret = foobarbaz >> obp-api/src/main/resources/props/test.default.props
- echo allow_public_views=true >> obp-api/src/main/resources/props/test.default.props
-
- echo SIMPLE_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo ACCOUNT_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo SEPA_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo FREE_FORM_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo COUNTERPARTY_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
- echo SEPA_CREDIT_TRANSFERS_OTP_INSTRUCTION_TRANSPORT=dummy >> obp-api/src/main/resources/props/test.default.props
-
- echo allow_oauth2_login=true >> obp-api/src/main/resources/props/test.default.props
- echo oauth2.jwk_set.url=https://www.googleapis.com/oauth2/v3/certs >> obp-api/src/main/resources/props/test.default.props
-
- echo ResetPasswordUrlEnabled=true >> obp-api/src/main/resources/props/test.default.props
-
- echo consents.allowed=true >> obp-api/src/main/resources/props/test.default.props
- MAVEN_OPTS="-Xmx3G -Xss2m" mvn clean package -Pprod
-
- - name: Save .war artifact
- run: |
- mkdir -p ./push
- cp obp-api/target/obp-api-1.*.war ./push/
- - uses: actions/upload-artifact@v4
- with:
- name: push
- path: push/
-
-
-
-
-
-
diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml
index d47c47fcd..24500a23b 100644
--- a/.github/workflows/build_pull_request.yml
+++ b/.github/workflows/build_pull_request.yml
@@ -27,9 +27,9 @@ jobs:
--health-timeout 5s
--health-retries 5
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up JDK 11
- uses: actions/setup-java@v2
+ uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'
@@ -73,15 +73,12 @@ jobs:
echo consents.allowed=true >> obp-api/src/main/resources/props/test.default.props
MAVEN_OPTS="-Xmx3G -Xss2m" mvn clean package -Pprod
- - name: Save user name and .war artifact
+ - name: Build the Docker image
run: |
- mkdir -p ./pr
- echo ${{ github.event.pull_request.user.login }} > ./pr/UN
- cp obp-api/target/obp-api-1.10.1.war ./pr/obp-api-1.10.1.war
- - uses: actions/upload-artifact@v4
- with:
- name: pr
- path: pr/
+ 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 }}/obp-api-${{ env.USER_NAME }}:latest
+ docker push docker.io/${{ env.DOCKER_HUB_ORGANIZATION }}/obp-api-${{ env.USER_NAME }} --all-tags
+ echo docker done
diff --git a/.github/workflows/run_trivy.yml b/.github/workflows/run_trivy.yml
index 548cd92ad..4636bd311 100644
--- a/.github/workflows/run_trivy.yml
+++ b/.github/workflows/run_trivy.yml
@@ -19,7 +19,7 @@ jobs:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- id: trivy-db
name: Check trivy db sha
env:
@@ -31,7 +31,7 @@ jobs:
sha=$(gh api -H "${headers}" "${endpoint}" | jq --raw-output "${jqFilter}")
echo "Trivy DB sha256:${sha}"
echo "::set-output name=sha::${sha}"
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
with:
path: .trivy
key: ${{ runner.os }}-trivy-db-${{ steps.trivy-db.outputs.sha }}
@@ -49,6 +49,6 @@ jobs:
- 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@v1
+ uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
\ No newline at end of file
diff --git a/obp-api/src/main/resources/props/sample.props.template b/obp-api/src/main/resources/props/sample.props.template
index fd10c7472..a3ecc27fd 100644
--- a/obp-api/src/main/resources/props/sample.props.template
+++ b/obp-api/src/main/resources/props/sample.props.template
@@ -157,6 +157,12 @@ jwt.use.ssl=false
# truststore.password.redis = truststore-password
+## Trust stores is a list of trusted CA certificates
+## Public certificate for the CA (used by clients and servers to validate signatures)
+# truststore.path.tpp_signature = path/to/ca.p12
+# truststore.password.tpp_signature = truststore-password
+
+
## Enable writing API metrics (which APIs are called) to RDBMS
write_metrics=true
## Enable writing connector metrics (which methods are called)to RDBMS
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 5040e26b9..ccc0db137 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
@@ -311,6 +311,8 @@ of the PSU at this ASPSP.
(Full(u), callContext) <- authenticatedAccess(cc)
_ <- passesPsd2Aisp(callContext)
(availablePrivateAccounts, callContext) <- NewStyle.function.getAccountListOfBerlinGroup(u, callContext)
+ (canReadBalancesAccounts, callContext) <- NewStyle.function.getAccountCanReadBalancesOfBerlinGroup(u, callContext)
+ (canReadTransactionsAccounts, callContext) <- NewStyle.function.getAccountCanReadTransactionsOfBerlinGroup(u, callContext)
(accounts, callContext) <- NewStyle.function.getBankAccounts(availablePrivateAccounts, callContext)
bankAccountsFiltered = accounts.filter(bankAccount =>
bankAccount.attributes.toList.flatten.find(attribute =>
@@ -320,7 +322,12 @@ of the PSU at this ASPSP.
).isEmpty)
} yield {
- (JSONFactory_BERLIN_GROUP_1_3.createAccountListJson(bankAccountsFiltered, u), callContext)
+ (JSONFactory_BERLIN_GROUP_1_3.createAccountListJson(
+ bankAccountsFiltered,
+ canReadBalancesAccounts,
+ canReadTransactionsAccounts,
+ u
+ ), callContext)
}
}
}
diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala
index 7b59df4c9..8cefe014f 100644
--- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala
+++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala
@@ -49,8 +49,8 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
)
case class CoreAccountLinksJsonV13(
- balances: LinkHrefJson //,
-// trasactions: LinkHrefJson // These links are only supported, when the corresponding consent has been already granted.
+ balances: LinkHrefJson,
+ transactions: Option[LinkHrefJson] = None // These links are only supported, when the corresponding consent has been already granted.
)
case class CoreAccountBalancesJson(
@@ -69,7 +69,6 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
product: String,
cashAccountType: String,
// status: String="enabled",
- bic: String,
// linkedAccounts: String ="string",
// usage: String ="PRIV",
// details: String ="",
@@ -308,10 +307,17 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
)
- def createAccountListJson(bankAccounts: List[BankAccount], user: User): CoreAccountsJsonV13 = {
+ def createAccountListJson(bankAccounts: List[BankAccount],
+ canReadBalancesAccounts: List[BankIdAccountId],
+ canReadTransactionsAccounts: List[BankIdAccountId],
+ user: User): CoreAccountsJsonV13 = {
CoreAccountsJsonV13(bankAccounts.map {
x =>
val (iBan: String, bBan: String) = getIbanAndBban(x)
+ val commonPath = s"${OBP_BERLIN_GROUP_1_3.apiVersion.urlPrefix}/${OBP_BERLIN_GROUP_1_3.version}/accounts/${x.accountId.value}"
+ val balanceRef = LinkHrefJson(s"/$commonPath/accounts/${x.accountId.value}/balances")
+ val transactionRef = LinkHrefJson(s"/$commonPath/accounts/${x.accountId.value}/transactions")
+ val canReadTransactions = canReadTransactionsAccounts.map(_.accountId.value).contains(x.accountId.value)
CoreAccountJsonV13(
@@ -320,10 +326,12 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
bban = bBan,
currency = x.currency,
name = x.name,
- bic = getBicFromBankId(x.bankId.value),
cashAccountType = x.accountType,
product = x.accountType,
- _links = CoreAccountLinksJsonV13(LinkHrefJson(s"/${OBP_BERLIN_GROUP_1_3.apiVersion.urlPrefix}/${OBP_BERLIN_GROUP_1_3.version}/accounts/${x.accountId.value}/balances"))
+ _links = CoreAccountLinksJsonV13(
+ balances = balanceRef,
+ transactions = if(canReadTransactions) Some(transactionRef) else None,
+ )
)
}
)
@@ -340,7 +348,6 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
bban = bBan,
currency = x.currency,
name = x.name,
- bic = getBicFromBankId(x.bankId.value),
cashAccountType = x.accountType,
product = x.accountType,
_links = CoreAccountLinksJsonV13(LinkHrefJson(s"/${OBP_BERLIN_GROUP_1_3.apiVersion.urlPrefix}/${OBP_BERLIN_GROUP_1_3.version}/accounts/${x.accountId.value}/balances"))
diff --git a/obp-api/src/main/scala/code/api/cache/Redis.scala b/obp-api/src/main/scala/code/api/cache/Redis.scala
index 4c5412125..ed5d6856c 100644
--- a/obp-api/src/main/scala/code/api/cache/Redis.scala
+++ b/obp-api/src/main/scala/code/api/cache/Redis.scala
@@ -61,7 +61,7 @@ object Redis extends MdcLoggable {
// Load the CA certificate
val trustStore = KeyStore.getInstance(KeyStore.getDefaultType)
- val trustStorePassword = APIUtil.getPropsValue("keystore.password.redis")
+ val trustStorePassword = APIUtil.getPropsValue("truststore.password.redis")
.getOrElse(APIUtil.initPasswd).toCharArray
val truststorePath = APIUtil.getPropsValue("truststore.path.redis").getOrElse("")
val trustStoreStream = new FileInputStream(truststorePath)
diff --git a/obp-api/src/main/scala/code/api/sandbox/example_data/2016-04-28/example_import.json b/obp-api/src/main/scala/code/api/sandbox/example_data/2016-04-28/example_import.json
index 640c91a4d..f6ee011d8 100644
--- a/obp-api/src/main/scala/code/api/sandbox/example_data/2016-04-28/example_import.json
+++ b/obp-api/src/main/scala/code/api/sandbox/example_data/2016-04-28/example_import.json
@@ -12,47 +12,48 @@
"logo":"https://static.openbankproject.com/images/sandbox/bank_y.png",
"website":"https://www.example.com"
}],
- "users":[{
- "email":"robert.xuk.x@example.com",
- "user_name": "robert.xuk.x@example.com",
- "password":"5232e7",
- "display_name":"Robert XUk X"
- },{
- "email":"susan.xuk.x@example.com",
- "user_name": "susan.xuk.x@example.com",
- "password":"43ca4d",
- "display_name":"Susan XUk X"
- },{
- "email":"anil.xuk.x@example.com",
- "user_name": "anil.xuk.x@example.com",
- "password":"d8c716",
- "display_name":"Anil XUk X"
- },{
- "email":"ellie.xuk.x@example.com",
- "user_name": "ellie.xuk.x@example.com",
- "password":"6187b9",
- "display_name":"Ellie XUk X"
- },{
- "email":"robert.yuk.y@example.com",
- "user_name": "robert.yuk.y@example.com",
- "password":"e5046a",
- "display_name":"Robert YUk Y"
- },{
- "email":"susan.yuk.y@example.com",
- "user_name": "susan.yuk.y@example.com",
- "password":"5b38a6",
- "display_name":"Susan YUk Y"
- },{
- "email":"anil.yuk.y@example.com",
- "user_name": "anil.yuk.y@example.com",
- "password":"dcf03d",
- "display_name":"Anil YUk Y"
- },{
- "email":"ellie.yuk.y@example.com",
- "user_name": "ellie.yuk.y@example.com",
- "password":"4f9eaa",
- "display_name":"Ellie YUk Y"
- }],
+ "users": [
+ {
+ "email": "robert.x.0.gh@example.com",
+ "password": "V8%Ktssl(L",
+ "user_name": "Robert.X.0.GH"
+ },
+ {
+ "email": "susan.x.0.gh@example.com",
+ "password": "naW9u3C%bh",
+ "user_name": "Susan.X.0.GH"
+ },
+ {
+ "email": "anil.x.0.gh@example.com",
+ "password": "9W0RIrX-6f",
+ "user_name": "Anil.X.0.GH"
+ },
+ {
+ "email": "ellie.x.0.gh@example.com",
+ "password": "rMf_OHM0dW",
+ "user_name": "Ellie.X.0.GH"
+ },
+ {
+ "email": "robert.y.9.gh@example.com",
+ "password": "%1Z43kzt2L",
+ "user_name": "Robert.Y.9.GH"
+ },
+ {
+ "email": "susan.y.9.gh@example.com",
+ "password": "oITehM!B2V",
+ "user_name": "Susan.Y.9.GH"
+ },
+ {
+ "email": "anil.y.9.gh@example.com",
+ "password": "TuKaNO8oI-",
+ "user_name": "Anil.Y.9.GH"
+ },
+ {
+ "email": "ellie.y.9.gh@example.com",
+ "password": "SkJDH+ds2_",
+ "user_name": "Ellie.Y.9.GH"
+ }
+ ],
"accounts":[{
"id":"05237266-b334-4704-a087-5b460a2ecf04",
"bank":"psd201-bank-x--uk",
diff --git a/obp-api/src/main/scala/code/api/sandbox/example_data/example_import.json b/obp-api/src/main/scala/code/api/sandbox/example_data/example_import.json
index 91418c4d6..0126ddd05 100644
--- a/obp-api/src/main/scala/code/api/sandbox/example_data/example_import.json
+++ b/obp-api/src/main/scala/code/api/sandbox/example_data/example_import.json
@@ -12,39 +12,48 @@
"logo":"https://static.openbankproject.com/images/sandbox/bank_y.png",
"website":"https://www.example.com"
}],
- "users":[{
- "email":"robert.x.0.gh@example.com",
- "password":"X!d1edcafd",
- "user_name":"Robert.X.0.GH"
- },{
- "email":"susan.x.0.gh@example.com",
- "password":"X!90e4e3e4",
- "user_name":"Susan.X.0.GH"
- },{
- "email":"anil.x.0.gh@example.com",
- "password":"X!eb06b005",
- "user_name":"Anil.X.0.GH"
- },{
- "email":"ellie.x.0.gh@example.com",
- "password":"X!5bc94405",
- "user_name":"Ellie.X.0.GH"
- },{
- "email":"robert.y.9.gh@example.com",
- "password":"X!039941de",
- "user_name":"Robert.Y.9.GH"
- },{
- "email":"susan.y.9.gh@example.com",
- "password":"X!bb4efa3d",
- "user_name":"Susan.Y.9.GH"
- },{
- "email":"anil.y.9.gh@example.com",
- "password":"X!098915cd",
- "user_name":"Anil.Y.9.GH"
- },{
- "email":"ellie.y.9.gh@example.com",
- "password":"X!6170b37b",
- "user_name":"Ellie.Y.9.GH"
- }],
+ "users": [
+ {
+ "email": "robert.x.0.gh@example.com",
+ "password": "V8%Ktssl(L",
+ "user_name": "Robert.X.0.GH"
+ },
+ {
+ "email": "susan.x.0.gh@example.com",
+ "password": "naW9u3C%bh",
+ "user_name": "Susan.X.0.GH"
+ },
+ {
+ "email": "anil.x.0.gh@example.com",
+ "password": "9W0RIrX-6f",
+ "user_name": "Anil.X.0.GH"
+ },
+ {
+ "email": "ellie.x.0.gh@example.com",
+ "password": "rMf_OHM0dW",
+ "user_name": "Ellie.X.0.GH"
+ },
+ {
+ "email": "robert.y.9.gh@example.com",
+ "password": "%1Z43kzt2L",
+ "user_name": "Robert.Y.9.GH"
+ },
+ {
+ "email": "susan.y.9.gh@example.com",
+ "password": "oITehM!B2V",
+ "user_name": "Susan.Y.9.GH"
+ },
+ {
+ "email": "anil.y.9.gh@example.com",
+ "password": "TuKaNO8oI-",
+ "user_name": "Anil.Y.9.GH"
+ },
+ {
+ "email": "ellie.y.9.gh@example.com",
+ "password": "SkJDH+ds2_",
+ "user_name": "Ellie.Y.9.GH"
+ }
+ ],
"accounts":[{
"id":"f65e28a5-9abe-428f-85bb-6c3c38122adb",
"bank":"obp-bank-x-gh",
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 2e789f27d..4d7367dc9 100644
--- a/obp-api/src/main/scala/code/api/util/APIUtil.scala
+++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala
@@ -2353,15 +2353,6 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
}
}
- // Function checks does a consumer specified by a parameter consumerId has at least one role provided by a parameter roles at a bank specified by a parameter bankId
- // i.e. does consumer has assigned at least one role from the list
- def hasAtLeastOneScope(bankId: String, consumerId: String, roles: List[ApiRole]): Boolean = {
- val list: List[Boolean] = for (role <- roles) yield {
- !Scope.scope.vend.getScope(if (role.requiresBankId == true) bankId else "", consumerId, role.toString).isEmpty
- }
- list.exists(_ == true)
- }
-
def hasEntitlement(bankId: String, userId: String, apiRole: ApiRole): Boolean = apiRole match {
case RoleCombination(roles) => roles.forall(hasEntitlement(bankId, userId, _))
case role =>
@@ -3683,7 +3674,12 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
}
final def checkAuthorisationToCreateTransactionRequest(viewId: ViewId, bankAccountId: BankIdAccountId, user: User, callContext: Option[CallContext]): Box[Boolean] = {
- lazy val hasCanCreateAnyTransactionRequestRole = APIUtil.hasEntitlement(bankAccountId.bankId.value, user.userId, canCreateAnyTransactionRequest)
+ lazy val hasCanCreateAnyTransactionRequestRole = APIUtil.handleEntitlementsAndScopes(
+ bankAccountId.bankId.value,
+ user.userId,
+ APIUtil.getConsumerPrimaryKey(callContext),
+ List(canCreateAnyTransactionRequest)
+ )
lazy val view = APIUtil.checkViewAccessAndReturnView(viewId, bankAccountId, Some(user), callContext)
diff --git a/obp-api/src/main/scala/code/api/util/BerlinGroupSigning.scala b/obp-api/src/main/scala/code/api/util/BerlinGroupSigning.scala
index 3cb253db0..c63fc89cc 100644
--- a/obp-api/src/main/scala/code/api/util/BerlinGroupSigning.scala
+++ b/obp-api/src/main/scala/code/api/util/BerlinGroupSigning.scala
@@ -130,7 +130,12 @@ object BerlinGroupSigning {
val signatureHeaderValue = getHeaderValue(RequestHeader.Signature, requestHeaders)
val signature = parseSignatureHeader(signatureHeaderValue).getOrElse("signature", "NONE")
val isVerified = verifySignature(signingString, signature, certificatePem)
- if (isVerified) forwardResult else (Failure(ErrorMessages.X509PublicKeyCannotVerify), forwardResult._2)
+ val isValidated = CertificateVerifier.validateCertificate(certificatePem)
+ (isVerified, isValidated) match {
+ case (true, true) => forwardResult
+ case (true, false) => (Failure(ErrorMessages.X509PublicKeyCannotBeValidated), forwardResult._2)
+ case (false, _) => (Failure(ErrorMessages.X509PublicKeyCannotVerify), forwardResult._2)
+ }
case Failure(msg, t, c) => (Failure(msg, t, c), forwardResult._2) // PEM certificate is not valid
case _ => (Failure(ErrorMessages.X509GeneralError), forwardResult._2) // PEM certificate cannot be validated
}
diff --git a/obp-api/src/main/scala/code/api/util/CertificateVerifier.scala b/obp-api/src/main/scala/code/api/util/CertificateVerifier.scala
new file mode 100644
index 000000000..cefb24abe
--- /dev/null
+++ b/obp-api/src/main/scala/code/api/util/CertificateVerifier.scala
@@ -0,0 +1,153 @@
+package code.api.util
+
+import code.util.Helper.MdcLoggable
+
+import java.io.{ByteArrayInputStream, FileInputStream}
+import java.security.KeyStore
+import java.security.cert._
+import java.util.{Base64, Collections}
+import javax.net.ssl.TrustManagerFactory
+import scala.io.Source
+import scala.jdk.CollectionConverters._
+import scala.util.{Failure, Success, Try}
+
+object CertificateVerifier extends MdcLoggable {
+
+ /**
+ * Loads a trust store (`.p12` file) from a configured path.
+ *
+ * This function:
+ * - Reads the trust store password from the application properties (`truststore.path.tpp_signature`).
+ * - Uses Java's `KeyStore` class to load the certificates.
+ *
+ * @return An `Option[KeyStore]` containing the loaded trust store, or `None` if loading fails.
+ */
+ private def loadTrustStore(): Option[KeyStore] = {
+ val trustStorePath = APIUtil.getPropsValue("truststore.path.tpp_signature")
+ .or(APIUtil.getPropsValue("truststore.path")).getOrElse("")
+ val trustStorePassword = APIUtil.getPropsValue("truststore.password.tpp_signature", "").toCharArray
+
+ Try {
+ val trustStore = KeyStore.getInstance("PKCS12")
+ val trustStoreInputStream = new FileInputStream(trustStorePath)
+ try {
+ trustStore.load(trustStoreInputStream, trustStorePassword)
+ } finally {
+ trustStoreInputStream.close()
+ }
+ trustStore
+ } match {
+ case Success(store) =>
+ logger.info(s"Loaded trust store from: $trustStorePath")
+ Some(store)
+ case Failure(e) =>
+ logger.info(s"Failed to load trust store: ${e.getMessage}")
+ None
+ }
+ }
+
+ /**
+ * Verifies an X.509 certificate against the loaded trust store.
+ *
+ * This function:
+ * - Parses the PEM certificate into an `X509Certificate` using `parsePemToX509Certificate`.
+ * - Loads the trust store using `loadTrustStore()`.
+ * - Extracts trusted root CAs from the trust store.
+ * - Creates PKIX validation parameters and disables revocation checking.
+ * - Validates the certificate using Java's `CertPathValidator`.
+ *
+ * @param pemCertificate The X.509 certificate in PEM format.
+ * @return `true` if the certificate is valid and trusted, otherwise `false`.
+ */
+ def validateCertificate(pemCertificate: String): Boolean = {
+ Try {
+ val certificate = parsePemToX509Certificate(pemCertificate)
+
+ // Load trust store
+ val trustStore = loadTrustStore()
+ .getOrElse(throw new Exception("Trust store could not be loaded."))
+
+ val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
+ trustManagerFactory.init(trustStore)
+
+ // Get trusted CAs from the trust store
+ val trustAnchors = trustStore.aliases().asScala
+ .filter(trustStore.isCertificateEntry)
+ .map(alias => trustStore.getCertificate(alias).asInstanceOf[X509Certificate])
+ .map(cert => new TrustAnchor(cert, null))
+ .toSet
+ .asJava // Convert Scala Set to Java Set
+
+ if (trustAnchors.isEmpty) throw new Exception("No trusted certificates found in trust store.")
+
+ // Set up PKIX parameters for validation
+ val pkixParams = new PKIXParameters(trustAnchors)
+ pkixParams.setRevocationEnabled(false) // Disable CRL checks
+
+ // Validate certificate chain
+ val certPath = CertificateFactory.getInstance("X.509").generateCertPath(Collections.singletonList(certificate))
+ val validator = CertPathValidator.getInstance("PKIX")
+ validator.validate(certPath, pkixParams)
+
+ logger.info("Certificate is valid and trusted.")
+ true
+ } match {
+ case Success(_) => true
+ case Failure(e: CertPathValidatorException) =>
+ logger.info(s"Certificate validation failed: ${e.getMessage}")
+ false
+ case Failure(e) =>
+ logger.info(s"Error: ${e.getMessage}")
+ false
+ }
+ }
+
+ /**
+ * Converts a PEM certificate (Base64-encoded) into an `X509Certificate` object.
+ *
+ * This function:
+ * - Removes the PEM header and footer (`-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`).
+ * - Decodes the Base64-encoded certificate data.
+ * - Generates and returns an `X509Certificate` object.
+ *
+ * @param pem The X.509 certificate in PEM format.
+ * @return The parsed `X509Certificate` object.
+ */
+ private def parsePemToX509Certificate(pem: String): X509Certificate = {
+ val cleanedPem = pem.replaceAll("-----BEGIN CERTIFICATE-----", "")
+ .replaceAll("-----END CERTIFICATE-----", "")
+ .replaceAll("\\s", "")
+
+ val decoded = Base64.getDecoder.decode(cleanedPem)
+ val certFactory = CertificateFactory.getInstance("X.509")
+ certFactory.generateCertificate(new ByteArrayInputStream(decoded)).asInstanceOf[X509Certificate]
+ }
+
+ def loadPemCertificateFromFile(filePath: String): Option[String] = {
+ Try {
+ val source = Source.fromFile(filePath)
+ try source.getLines().mkString("\n") // Read entire file into a single string
+ finally source.close()
+ } match {
+ case Success(pem) => Some(pem)
+ case Failure(exception) =>
+ logger.error(s"Failed to load PEM certificate from file: ${exception.getMessage}")
+ None
+ }
+ }
+
+ def main(args: Array[String]): Unit = {
+ // change the following path if using this function to test on your localhost
+ val certificatePath = "/path/to/certificate.pem"
+ val pemCertificate = loadPemCertificateFromFile(certificatePath)
+
+ pemCertificate.foreach { pem =>
+ val isValid = validateCertificate(pem)
+ logger.info(s"Certificate verification result: $isValid")
+ }
+
+ loadTrustStore().foreach { trustStore =>
+ logger.info(s"Trust Store contains ${trustStore.size()} certificates.")
+ }
+ }
+}
diff --git a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
index 8e118129d..8e28a23ab 100644
--- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
+++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala
@@ -279,6 +279,7 @@ object ErrorMessages {
val X509ThereAreNoPsd2Roles = "OBP-20308: PEM Encoded Certificate does not contain PSD2 roles."
val X509CannotGetPublicKey = "OBP-20309: Public key cannot be found in the PEM Encoded Certificate."
val X509PublicKeyCannotVerify = "OBP-20310: Certificate's public key cannot be used to verify signed request."
+ val X509PublicKeyCannotBeValidated = "OBP-20312: Certificate's public key cannot be validated."
val X509RequestIsNotSigned = "OBP-20311: The Request is not signed."
// OpenID Connect
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 1618e33e2..cd749c3f9 100644
--- a/obp-api/src/main/scala/code/api/util/NewStyle.scala
+++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala
@@ -6,7 +6,7 @@ import java.util.UUID.randomUUID
import akka.http.scaladsl.model.HttpMethod
import code.DynamicEndpoint.{DynamicEndpointProvider, DynamicEndpointT}
import code.api.{APIFailureNewStyle, Constant, JsonResponseException}
-import code.api.Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID
+import code.api.Constant.{SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID, SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID}
import code.api.cache.Caching
import code.api.util.APIUtil._
import code.api.util.ApiRole.canCreateAnyTransactionRequest
@@ -73,11 +73,11 @@ import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo}
import code.atmattribute.AtmAttribute
import code.bankattribute.BankAttribute
import code.connectormethod.{ConnectorMethodProvider, JsonConnectorMethod}
-import code.counterpartylimit.{CounterpartyLimit}
+import code.counterpartylimit.CounterpartyLimit
import com.openbankproject.commons.model.CounterpartyLimitTrait
import code.crm.CrmEvent
import code.crm.CrmEvent.CrmEvent
-import com.openbankproject.commons.model.{CustomerAccountLinkTrait, AgentAccountLinkTrait}
+import com.openbankproject.commons.model.{AgentAccountLinkTrait, CustomerAccountLinkTrait}
import code.dynamicMessageDoc.{DynamicMessageDocProvider, JsonDynamicMessageDoc}
import code.dynamicResourceDoc.{DynamicResourceDocProvider, JsonDynamicResourceDoc}
import code.endpointMapping.{EndpointMappingProvider, EndpointMappingT}
@@ -364,6 +364,20 @@ object NewStyle extends MdcLoggable{
}
}
+ def getAccountCanReadBalancesOfBerlinGroup(user : User, callContext: Option[CallContext]): OBPReturnType[List[BankIdAccountId]] = {
+ val viewIds = List(ViewId(SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID))
+ Views.views.vend.getPrivateBankAccountsFuture(user, viewIds) map { i =>
+ (i, callContext )
+ }
+ }
+
+ def getAccountCanReadTransactionsOfBerlinGroup(user : User, callContext: Option[CallContext]): OBPReturnType[List[BankIdAccountId]] = {
+ val viewIds = List(ViewId(Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID))
+ Views.views.vend.getPrivateBankAccountsFuture(user, viewIds) map { i =>
+ (i, callContext )
+ }
+ }
+
def getAccountListOfBerlinGroup(user : User, callContext: Option[CallContext]): OBPReturnType[List[BankIdAccountId]] = {
val viewIds = List(ViewId(SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID))
Views.views.vend.getPrivateBankAccountsFuture(user, viewIds) map { i =>
diff --git a/obp-api/src/main/scala/code/sandbox/OBPDataImport.scala b/obp-api/src/main/scala/code/sandbox/OBPDataImport.scala
index 22e366afc..0024598c0 100644
--- a/obp-api/src/main/scala/code/sandbox/OBPDataImport.scala
+++ b/obp-api/src/main/scala/code/sandbox/OBPDataImport.scala
@@ -72,7 +72,9 @@ trait OBPDataImport extends MdcLoggable {
protected def dataOrFirstFailure[T](boxes : List[Box[T]]) = {
val firstFailure = boxes.collectFirst{case f: Failure => f}
firstFailure match {
- case Some(f) => f
+ case Some(f) =>
+ logger.debug(f)
+ f
case None => Full(boxes.flatten) //no failures, so we can return the results
}
}
diff --git a/obp-api/src/main/scala/code/snippet/BerlinGroupConsent.scala b/obp-api/src/main/scala/code/snippet/BerlinGroupConsent.scala
index 9b8956ef9..59bcbfb57 100644
--- a/obp-api/src/main/scala/code/snippet/BerlinGroupConsent.scala
+++ b/obp-api/src/main/scala/code/snippet/BerlinGroupConsent.scala
@@ -1,89 +1,302 @@
/**
-Open Bank Project - API
-Copyright (C) 2011-2019, TESOBE GmbH.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see
+ {formTextHtml} +
+Allowed actions:
+Read account details
+Read account balances
+Read transactions
+Accounts:
+This consent will end on date {json.validUntil}.
+I understand that I can revoke this consent at any time.
+