diff --git a/.azuredevops/pipelines/build-v2.yml b/.azuredevops/pipelines/build-v2.yml
index 4c1c3f8..139a9e2 100644
--- a/.azuredevops/pipelines/build-v2.yml
+++ b/.azuredevops/pipelines/build-v2.yml
@@ -6,15 +6,53 @@ schedules:
include:
- develop
+resources:
+ repositories:
+ - repository: shared-code-scanning
+ type: git
+ name: Common/shared-code-scanning
+ ref: refs/heads/main
+ trigger: none
+
trigger:
- develop
- main
- releases/*
-
+
+variables:
+- group: PT-Pipeline-Common
+
pool:
- vmImage: ubuntu-latest
+ name: mdp-mgmt-shared
+ demands:
+ - ImageOverride -equals $(PipelineHostLinuxImage)
steps:
+- script: |
+ echo "Cleaning mock-register folder in temp"
+ ls $(Agent.BuildDirectory)/s/Source/_temp/mock-register-* 2>/dev/null || "No matching folders found"
+ sudo rm -rf $(Agent.BuildDirectory)/s/Source/_temp/mock-register-* 2> /dev/null
+ displayName: Clean temp mock-register folders
+ condition: always()
+
+- checkout: self
+ clean: true
+
+- task: UseDotNet@2
+ displayName: 'Use .NET 8 sdk'
+ condition: always()
+ inputs:
+ packageType: sdk
+ version: '8.0.x'
+ performMultiLevelLookup: true
+
+ # Restore dotnet tooling
+- task: CmdLine@2
+ displayName: 'Restore dotnet tooling'
+ condition: always()
+ inputs:
+ script: 'dotnet tool restore'
+
# Build mock-register
- task: Docker@2
displayName: Build mock-register image
@@ -25,6 +63,11 @@ steps:
repository: mock-register
tags: latest
+- template: templates/scan-image.yml@shared-code-scanning
+ parameters:
+ Repository: mock-register
+ Tag: latest
+
# Build mock-register-unit-tests
- task: Docker@2
displayName: Build mock-register-unit-tests image
@@ -83,23 +126,22 @@ steps:
# Remove integration tests
- script: |
- docker compose --file $(Build.SourcesDirectory)/Source/docker-compose.IntegrationTests.yml down
+ docker compose --file $(Build.SourcesDirectory)/Source/docker-compose.IntegrationTests.yml down
displayName: 'Integration Tests - Down'
condition: always()
-# Run trx formatter to output .MD and .CSV
+# Generate Extent Report from Test Results
- script: |
- docker run \
- -v=$(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx:/app/results.trx:ro \
- -v=$(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/formatted/:/app/out/:rw \
- $(SharedAcrBaseUrl).azurecr.io/trx-formatter -i results.trx -t "MR" --outputprefix "MR" -o out/
- displayName: 'Run trx-formatter'
- condition: always()
- env:
- TEST_FILTER: "Category!=CTSONLY"
+ dotnet TrxToExtentReport \
+ --output $(Build.ArtifactStagingDirectory)/test-results/mock-register-integration-tests/MR-$(Build.BuildNumber).html \
+ --trx $(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx \
+ --verbose
+ cp $(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx $(Build.ArtifactStagingDirectory)/test-results/mock-register-integration-tests/MR-$(Build.BuildNumber).trx
+ displayName: 'Format Test Results'
+ condition: always()
# Publish mock-register integration tests results
-- publish: Source/_temp/mock-register-integration-tests/testresults
+- publish: $(Build.ArtifactStagingDirectory)/test-results/mock-register-integration-tests
displayName: Publish MockRegister Integration tests
condition: always()
artifact: Mock-Register - Integration tests
@@ -117,7 +159,7 @@ steps:
# Run integration tests For CTS Only tests
#****************************************************************************************************************
- script: |
- docker compose --file $(Build.SourcesDirectory)/Source/docker-compose.IntegrationTests.yml up --abort-on-container-exit --exit-code-from mock-register-integration-tests
+ docker compose --file $(Build.SourcesDirectory)/Source/docker-compose.IntegrationTests.yml up --abort-on-container-exit --exit-code-from mock-register-integration-tests
displayName: 'Integration Tests Tests For CTS Only - Up'
condition: always()
env:
@@ -142,11 +184,12 @@ steps:
# Run trx formatter to output .MD and .CSV
- script: |
- docker run \
- -v=$(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx:/app/results.trx:ro \
- -v=$(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/formatted/:/app/out/:rw \
- $(SharedAcrBaseUrl).azurecr.io/trx-formatter -i results.trx -t "MR-CTS" --outputprefix "MR-CTS" -o out/
- displayName: 'Run trx-formatter'
+ dotnet TrxToExtentReport \
+ --output $(Build.ArtifactStagingDirectory)/test-results/mock-register-cts-integration-tests/MR-CTS-$(Build.BuildNumber).html \
+ --trx $(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx \
+ --verbose
+ cp $(Build.SourcesDirectory)/Source/_temp/mock-register-integration-tests/testresults/results.trx $(Build.ArtifactStagingDirectory)/test-results/mock-register-cts-integration-tests/MR-CTS-$(Build.BuildNumber).trx
+ displayName: 'Format Test Results'
condition: always()
# Remove integration tests For CTS Only tests
@@ -156,7 +199,7 @@ steps:
condition: always()
# Publish mock-register integration tests results
-- publish: Source/_temp/mock-register-integration-tests/testresults
+- publish: $(Build.ArtifactStagingDirectory)/test-results/mock-register-cts-integration-tests
displayName: Publish MockRegister CTS Integration tests
condition: always()
artifact: Mock-Register - CTS Integration tests
@@ -185,36 +228,15 @@ steps:
displayName: Publish container images
# condition: always()
inputs:
- path: $(build.artifactstagingdirectory)
+ path: $(build.artifactstagingdirectory)/mock-register.image.tar
artifact: Container Images
-# FIXME - MJS - See dockercompose, volume no longer mapped as 1001:121 (vsts:docker) in build pipeline and causes issue with chown in dockerfile (appuser:appgroup), ie stops register from starting because of different user
-# # Publish mock-register logs
-# - publish: Source/_temp/mock-register/tmp
-# displayName: Publish MockRegister logs
-# condition: always()
-# artifact: Mock-Register - Logs
-
# Publish mock-register unit tests results
- publish: Source/_temp/mock-register-unit-tests/testresults
displayName: Publish unit tests
condition: always()
artifact: Mock-Register - Unit tests
-- task: UseDotNet@2
- displayName: 'Use .NET 8 sdk'
- condition: always()
- inputs:
- packageType: sdk
- version: '8.0.x'
- performMultiLevelLookup: true
-
-- task: CmdLine@2
- displayName: 'Restore dotnet tooling'
- condition: always()
- inputs:
- script: 'dotnet tool restore'
-
- script: |
cd Source/CDR.Register.Repository
dotnet ef migrations bundle --context RegisterDatabaseContext --verbose --self-contained
diff --git a/.azuredevops/pipelines/code-scanning.yml b/.azuredevops/pipelines/code-scanning.yml
index ea3fe11..1fb2be5 100644
--- a/.azuredevops/pipelines/code-scanning.yml
+++ b/.azuredevops/pipelines/code-scanning.yml
@@ -17,8 +17,13 @@ schedules:
# Disable standard CI build
trigger: none
+variables:
+- group: PT-Pipeline-Common
+
pool:
- vmImage: 'ubuntu-latest'
+ name: mdp-mgmt-shared
+ demands:
+ - ImageOverride -equals $(PipelineHostLinuxImage)
extends:
template: pipeline-templates/code-scanning.yml@shared-code-scanning
\ No newline at end of file
diff --git a/.azuredevops/pipelines/dependabot.yml b/.azuredevops/pipelines/dependabot.yml
index b3268e3..415e259 100644
--- a/.azuredevops/pipelines/dependabot.yml
+++ b/.azuredevops/pipelines/dependabot.yml
@@ -6,11 +6,17 @@ schedules:
- refs/heads/develop
always: true
+variables:
+- group: PT-Pipeline-Common
+
+
jobs:
- job: dependabot
displayName: Dependabot
pool:
- vmImage: ubuntu-latest
+ name: mdp-mgmt-shared
+ demands:
+ - ImageOverride -equals $(PipelineHostLinuxImage)
steps:
- task: CmdLine@2
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 3173bfc..3e156dd 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,10 +3,18 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
- "version": "8.0.20",
+ "version": "8.0.25",
"commands": [
"dotnet-ef"
- ]
+ ],
+ "rollForward": false
+ },
+ "trxtoextentreport": {
+ "version": "0.0.4",
+ "commands": [
+ "TrxToExtentReport"
+ ],
+ "rollForward": false
}
}
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9584d1..0a9ee53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [2.2.6] - 2026-05-13
+### Changed
+- Support for "Non Bank Lending" industry added to the Mock Register
+- Updated Integration Tests inline with NBL updates
+- Migrate solution from Microsoft.AspNetCore.Mvc.Versioning to Asp.Versioning.Mvc package
+
+## [2.2.5] - 2026-03-18
+# Fixed
+- Patched vulnerabilities
+
+## [2.2.4] - 2026-02-25
+# Fixed
+- Fixed JWKS endpoint response to conform CDR Data Standard
+
## [2.2.3] - 2025-12-03
### Added
- Added health check endpoints for APIs
diff --git a/Help/notebooks/mock-register.ipynb b/Help/notebooks/mock-register.ipynb
index 8760d50..200f83c 100644
--- a/Help/notebooks/mock-register.ipynb
+++ b/Help/notebooks/mock-register.ipynb
@@ -38,7 +38,7 @@
"\n",
"Set the required configuration variables which are reused by all the PowerShell cells in this notebook. \n",
"\n",
- "**Note:** This cell must be executed prior to executing any PowerShell cells in this notebook."
+ "> **Note:** This cell must be executed prior to executing any PowerShell cells in this notebook."
]
},
{
@@ -50,9 +50,6 @@
},
"polyglot_notebook": {
"kernelName": "pwsh"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -61,16 +58,17 @@
"$hostname = \"localhost\"\n",
"$mockRegisterBaseUrl = \"https://${hostname}:7000\"\n",
"$mockRegisterSecureBaseUrl = \"https://${hostname}:7001\"\n",
+ "$mockRegisterAdminBaseUrl = \"https://${hostname}:7006\"\n",
"\n",
- "# Set Data Reciepient variables\n",
+ "# Set Data Recipient variables\n",
"$mockDataRecipientCertificatePath = \"..\\\\..\\\\CertificateManagement\\\\mtls\\\\client.pfx\"\n",
"$mockDataRecipientCertificatePassword = \"#M0ckDataRecipient#\"\n",
- "$industry = \"Banking\"\n",
- "$dataRecipientBrandId = \"F3F0C40B-9DF8-491A-AF1D-81CB9AB5F021\"\n",
- "$softwareProductId = \"6F7A1B8E-8799-48A8-9011-E3920391F713\"\n",
+ "$industry = \"Non-Bank-Lending\" # banking, energy, non-bank-lending, all\n",
+ "$dataRecipientBrandId = \"F3F0C40B-9DF8-491A-AF1D-81CB9AB5F021\" # YoYo\n",
+ "$softwareProductId = \"6F7A1B8E-8799-48A8-9011-E3920391F713\" # ThatBudgetHelper\n",
"$mdrClientAssertionUri = \"https://${hostname}:7006/loopback/MockDataRecipientClientAssertion?iss=$softwareProductId\"\n",
"\n",
- "# Load the Data Reciepient certificate with password\n",
+ "# Load the Data Recipient certificate with password\n",
"$certPassword = ConvertTo-SecureString -String $mockDataRecipientCertificatePassword -Force -AsPlainText\n",
"$mockDataRecipientCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $mockDataRecipientCertificatePath, $certPassword"
]
@@ -82,7 +80,7 @@
"\n",
"Set the required variables from above PowerShell cell to make them available for HTTP Request cells.\n",
"\n",
- "**Note:** This cell must be executed prior to executing any HTTP Request cells in this notebook."
+ "> **Note:** This cell must be executed prior to executing any HTTP Request cells in this notebook."
]
},
{
@@ -94,15 +92,13 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"#!set --value @pwsh:hostname --name hostname\n",
"#!set --value @pwsh:mockRegisterBaseUrl --name mockRegisterBaseUrl\n",
+ "#!set --value @pwsh:mockRegisterAdminBaseUrl --name mockRegisterAdminBaseUrl\n",
"#!set --value @pwsh:softwareProductId --name softwareProductId\n",
"#!set --value @pwsh:industry --name industry"
]
@@ -137,9 +133,6 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -155,7 +148,8 @@
"\n",
"`GET /cdr-register/v1/{industry}/data-recipients`\n",
"\n",
- "Endpoint used by participants to discover data recipients and associated brands and software products, available in the CDR ecosystem."
+ "Endpoint used by participants to discover data recipients and associated brands and software products, available in the CDR ecosystem. \n",
+ "> Data recipients are not industry specific."
]
},
{
@@ -167,15 +161,12 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
- "GET {{mockRegisterBaseUrl}}/cdr-register/v1/{{industry}}/data-recipients\n",
- "x-v:3"
+ "GET {{mockRegisterBaseUrl}}/cdr-register/v1/all/data-recipients\n",
+ "x-v: 4"
]
},
{
@@ -186,7 +177,8 @@
"\n",
"`GET /cdr-register/v1/{industry}/data-recipients/status`\n",
"\n",
- "Endpoint used by participants to discover the statuses for Data Recipients from the CDR Register."
+ "Endpoint used by participants to discover the statuses for Data Recipients from the CDR Register.\n",
+ "> Data recipients are not industry specific."
]
},
{
@@ -198,15 +190,12 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
- "GET {{mockRegisterBaseUrl}}/cdr-register/v1/{{industry}}/data-recipients/status\n",
- "x-v: 2"
+ "GET {{mockRegisterBaseUrl}}/cdr-register/v1/all/data-recipients/status\n",
+ "x-v: 3"
]
},
{
@@ -217,7 +206,8 @@
"\n",
"`GET /cdr-register/v1/{industry}/data-recipients/brands/software-products/status`\n",
"\n",
- "Endpoint used by participants to discover the statuses for software products from the CDR Register."
+ "Endpoint used by participants to discover the statuses for Software Products from the CDR Register.\n",
+ "> Software Products are not industry specific."
]
},
{
@@ -229,15 +219,12 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
- "GET {{mockRegisterBaseUrl}}/cdr-register/v1/{{industry}}/data-recipients/brands/software-products/status\n",
- "x-v: 2"
+ "GET {{mockRegisterBaseUrl}}/cdr-register/v1/all/data-recipients/brands/software-products/status\n",
+ "x-v: 3"
]
},
{
@@ -260,15 +247,12 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"GET {{mockRegisterBaseUrl}}/cdr-register/v1/{{industry}}/data-holders/status\n",
- "x-v: 1"
+ "x-v: 2"
]
},
{
@@ -300,9 +284,6 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -330,9 +311,6 @@
},
"polyglot_notebook": {
"kernelName": "pwsh"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -351,7 +329,7 @@
"}\n",
"\n",
"# Make the request\n",
- "$response = Invoke-RestMethod -Uri \"${mockRegisterSecureBaseUrl}/idp/connect/token\" `\n",
+ "$response = Invoke-RestMethod -Uri \"${mockRegisterSecureBaseUrl}/idp/connect/token\" `\n",
" -Method Post -StatusCodeVariable responseCode `\n",
" -Body $parameters -ContentType \"application/x-www-form-urlencoded\" `\n",
" -Certificate $mockDataRecipientCert\n",
@@ -378,7 +356,7 @@
"\n",
"Allows Data Recipients to discover Data Holder Brands available in the CDR ecosystem.\n",
"\n",
- "**Note:** This API requires an access token. The Get Access Token cell must be executed prior to executing this cell."
+ "> **Note:** This API requires an access token. The Get Access Token cell must be executed prior to executing this cell."
]
},
{
@@ -390,26 +368,24 @@
},
"polyglot_notebook": {
"kernelName": "pwsh"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"# Set the API version and Authorization headers\n",
"$headers = @{\n",
- " \"x-v\" = \"2\"\n",
+ " \"x-v\" = \"3\"\n",
" \"Authorization\" = \"Bearer $accessToken\"\n",
"}\n",
"\n",
"# Make the request\n",
- "$res = Invoke-RestMethod -Uri \"${mockRegisterSecureBaseUrl}/cdr-register/v1/all/data-holders/brands\" `\n",
+ "$res = Invoke-RestMethod -Uri \"${mockRegisterSecureBaseUrl}/cdr-register/v1/${industry}/data-holders/brands\" `\n",
" -Method Get -StatusCodeVariable resCode -Headers $headers -Certificate $mockDataRecipientCert `\n",
- " | ConvertTo-Json -Depth 10\n",
+ " -ResponseHeadersVariable resHeaders | ConvertTo-Json -Depth 10\n",
"\n",
"# Write the response status code and content to the console\n",
"Write-Host \"Response Code: $resCode\"\n",
+ "Write-Host \"Response x-v: $($resHeaders[\"x-v\"])\"\n",
"Write-Host \"Response Content: $($res)\""
]
},
@@ -423,7 +399,7 @@
"\n",
"Get a Software Statement Assertion (SSA) for a software product on the CDR Register to be used for Dynamic Client Registration with a Data Holder Brand.\n",
"\n",
- "**Note:** This API requires an access token. The Get Access Token cell must be executed prior to executing this cell."
+ "> **Note:** This API requires an access token. The Get Access Token cell must be executed prior to executing this cell."
]
},
{
@@ -435,26 +411,24 @@
},
"polyglot_notebook": {
"kernelName": "pwsh"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
"# Set the API version and Authorization headers\n",
"$headers = @{\n",
- " \"x-v\" = \"3\"\n",
+ " \"x-v\" = \"4\"\n",
" \"Authorization\" = \"Bearer $accessToken\"\n",
"}\n",
"\n",
"# Make the request\n",
"$r = Invoke-RestMethod -Uri \"${mockRegisterSecureBaseUrl}/cdr-register/v1/all/data-recipients/brands/${dataRecipientBrandId}/software-products/${softwareProductId}/ssa\" `\n",
- " -Method Get -StatusCodeVariable rCode -Headers $headers -Certificate $mockDataRecipientCert `\n",
+ " -Method Get -StatusCodeVariable rCode -Headers $headers -Certificate $mockDataRecipientCert -ResponseHeadersVariable resHeaders`\n",
" | ConvertTo-Json -Depth 10\n",
"\n",
"# Write the response status code and content to the console\n",
"Write-Host \"Response Code: $rCode\"\n",
+ "Write-Host \"Response x-v: $($resHeaders[\"x-v\"])\"\n",
"Write-Host \"Response Content: $($r)\""
]
},
@@ -487,9 +461,6 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -517,9 +488,6 @@
},
"polyglot_notebook": {
"kernelName": "pwsh"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -529,7 +497,7 @@
"$metadataPayload = Get-Content -path .\\payloads\\metadataPayload.json -raw\n",
"\n",
"# Make the request\n",
- "$response = Invoke-RestMethod -Uri \"https://${hostname}:7006/admin/metadata\" `\n",
+ "$response = Invoke-RestMethod -Uri \"${mockRegisterAdminBaseUrl}/admin/metadata\" `\n",
" -Method Post -StatusCodeVariable responseCode `\n",
" -Body $metadataPayload `\n",
" -ContentType \"application/json\" `\n",
@@ -559,14 +527,11 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
- "POST https://{{hostname}}:7006/admin/metadata/data-recipients \n",
+ "POST {{mockRegisterAdminBaseUrl}}/admin/metadata/data-recipients \n",
"x-v: 1\n",
"Content-Type: application/json\n",
"{\n",
@@ -642,19 +607,17 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
"source": [
- "POST https://{{hostname}}:7006/admin/metadata/data-holders HTTP/1.1\n",
+ "POST {{mockRegisterAdminBaseUrl}}/admin/metadata/data-holders HTTP/1.1\n",
"Content-Type: application/json\n",
"x-v: 1\n",
"{\n",
" \"dataHolderBrandId\": \"bb03be60-5c46-422e-a27e-aefa0015078d\",\n",
" \"brandName\": \"Luna\",\n",
+ " \"brandGroup\": \"Luna Banking Group\",\n",
" \"industries\": [\n",
" \"banking\"\n",
" ],\n",
@@ -663,6 +626,7 @@
" \"endpointDetail\": {\n",
" \"version\": \"v1\",\n",
" \"publicBaseUri\": \"https://publicapi.lunabank\",\n",
+ " \"productBaseUri\": \"https://productapi.lunabank\",\n",
" \"resourceBaseUri\": \"https://rb-api.lunabank\",\n",
" \"infosecBaseUri\": \"https://isb-api.lunabank\",\n",
" \"extensionBaseUri\": \"https://eb-api.lunabank\",\n",
@@ -710,9 +674,6 @@
},
"polyglot_notebook": {
"kernelName": "http"
- },
- "vscode": {
- "languageId": "polyglot-notebook"
}
},
"outputs": [],
@@ -728,7 +689,7 @@
"name": ".net-csharp"
},
"language_info": {
- "name": "python"
+ "name": "polyglot-notebook"
},
"polyglot_notebook": {
"kernelInfo": {
diff --git a/Help/notebooks/payloads/metadataPayload.json b/Help/notebooks/payloads/metadataPayload.json
index dfbbafa..2a986f2 100644
--- a/Help/notebooks/payloads/metadataPayload.json
+++ b/Help/notebooks/payloads/metadataPayload.json
@@ -1,1971 +1,2093 @@
{
- "legalEntities": [
- {
- "legalEntityId": "2f596416-53bc-42ad-bd5a-65537a2d5c42",
- "legalEntityName": "Very Smart Energy Company",
- "logoUri": "https://verysmarterenergy/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12345678901",
- "acn": "123456789",
- "arbn": null,
- "anzsicDivision": "2640",
- "organisationTypeId": 2,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 2,
- "statusId": 1,
- "brands": [
- {
- "brandId": "cfcaf0df-401b-47f2-98af-94787289eca8",
- "brandName": "Mock Data Holder (Energy)",
- "logoUri": "https://smarterenergy/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-12-01T10:00:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.smarterenergy/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://mock-data-holder-energy:8100",
- "resourceBaseUri": "https://mock-data-holder-energy:8102",
- "infoSecBaseUri": "https://mock-data-holder-energy:8101",
- "extensionBaseUri": "",
- "websiteUri": "https://smarterenergy/"
+ "legalEntities": [
+ {
+ "legalEntityId": "2f596416-53bc-42ad-bd5a-65537a2d5c42",
+ "legalEntityName": "Very Smart Energy Company",
+ "logoUri": "https://verysmarterenergy/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12345678901",
+ "acn": "123456789",
+ "arbn": null,
+ "anzsicDivision": "2640",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 2,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "cfcaf0df-401b-47f2-98af-94787289eca8",
+ "brandName": "Mock Data Holder (Energy)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://smarterenergy/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-12-01T10:00:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.smarterenergy/jwks"
}
- },
- {
- "brandId": "6859d9f9-9cf9-486d-bc85-5d43a7e116de",
- "brandName": "Cut Price Energy -- dummy data holder -- do not use",
- "logoUri": "https://cutpriceenergy/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-12-01T11:00:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.cutpriceenergy/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://api.cutpriceenergy:8100",
- "resourceBaseUri": "https://api.cutpriceenergy:8102",
- "infoSecBaseUri": "https://api.cutpriceenergy:8101",
- "extensionBaseUri": "",
- "websiteUri": "https://cutpriceenergy/"
- }
- }
- ]
- }
- ]
- },
- {
- "legalEntityId": "f9bde9a1-9fef-4bd9-b7ef-877369e076e3",
- "legalEntityName": "Mock Energy Company",
- "logoUri": "https://mocksoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "34241177887",
- "acn": "005249981",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000001",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "d50b74cf-e992-42fd-86d4-582ac9d72dbb",
- "brandName": "Mock Energy Tool",
- "logoUri": "https://mocksoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-12-01T09:00:00",
- "softwareProducts": [
- {
- "softwareProductId": "4754cf30-6cc2-4a9a-a9e1-4fb8f6d42120",
- "softwareProductName": "MyEnergyHelper",
- "softwareProductDescription": "A product to help you manage your energy costs",
- "logoUri": "https://mocksoftware/myenergyapp/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://mocksoftware/myenergyapp",
- "tosUri": "https://mocksoftware/myenergyapp/terms",
- "policyUri": "https://mocksoftware/myenergyapp/policy",
- "recipientBaseUri": "https://mock-data-recipient:9001",
- "revocationUri": "https://mock-data-recipient:9001/revocation",
- "redirectUris": "https://mock-data-recipient:9001/consent/callback",
- "jwksUri": "https://mock-data-recipient:9001/jwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://mock-data-holder-energy:8100",
+ "productBaseUri": "https://mock-data-holder-energy:8100",
+ "resourceBaseUri": "https://mock-data-holder-energy:8102",
+ "infoSecBaseUri": "https://mock-data-holder-energy:8101",
+ "extensionBaseUri": "",
+ "websiteUri": "https://smarterenergy/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "0d332caa-8cd8-4ac9-8898-20641c54bc8c",
- "legalEntityName": "Bank Legal Entity 1",
- "logoUri": "https://bank/logo.png",
- "registrationNumber": "12345",
- "registrationDate": "2021-12-01T10:00:00",
- "registeredCountry": "AUSTRALIA",
- "abn": "11111111111",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": "6221",
- "organisationTypeId": 2,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "804fc2fb-18a7-4235-9a49-2af393d18bc7",
- "brandName": "Mock Data Holder (Banking)",
- "logoUri": "https://bank1/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.bank1/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://mock-data-holder:8000",
- "resourceBaseUri": "https://mock-data-holder:8002",
- "infoSecBaseUri": "https://mock-data-holder:8001",
- "extensionBaseUri": "",
- "websiteUri": "https://bank1/"
+ },
+ {
+ "brandId": "6859d9f9-9cf9-486d-bc85-5d43a7e116de",
+ "brandName": "Cut Price Energy -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://cutpriceenergy/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-12-01T11:00:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.cutpriceenergy/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://api.cutpriceenergy:8100",
+ "productBaseUri": "https://api.cutpriceenergy:8100",
+ "resourceBaseUri": "https://api.cutpriceenergy:8102",
+ "infoSecBaseUri": "https://api.cutpriceenergy:8101",
+ "extensionBaseUri": "",
+ "websiteUri": "https://cutpriceenergy/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "18b75a76-5821-4c9e-b465-4709291cf0f4",
- "legalEntityName": "Mock Software Company",
- "logoUri": "https://mocksoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "11222333444",
- "acn": "222333444",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000099",
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "ffb1c8ba-279e-44d8-96f0-1bc34a6b436f",
- "brandName": "Mock Finance Tools",
- "logoUri": "https://mocksoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "c6327f87-687a-4369-99a4-eaacd3bb8210",
- "softwareProductName": "MyBudgetHelper",
- "softwareProductDescription": "A product to help you manage your budget",
- "logoUri": "https://mocksoftware/mybudgetapp/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://mocksoftware/mybudgetapp",
- "tosUri": "https://mocksoftware/mybudgetapp/terms",
- "policyUri": "https://mocksoftware/mybudgetapp/policy",
- "recipientBaseUri": "https://mock-data-recipient:9001",
- "revocationUri": "https://mock-data-recipient:9001/revocation",
- "redirectUris": "https://mock-data-recipient:9001/consent/callback",
- "jwksUri": "https://mock-data-recipient:9001/jwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "legalEntityId": "93ef5f28-7f30-43f2-8e5c-b1e3cb39ce90",
- "legalEntityName": "New Bank",
- "logoUri": "https://newbank/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "99888777666",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55",
- "brandName": "New Bank -- dummy data holder -- do not use",
- "logoUri": "https://newbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.newbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.newbank",
- "resourceBaseUri": "https://api.newbank",
- "infoSecBaseUri": "https://idp.newbank",
- "extensionBaseUri": "",
- "websiteUri": "https://newbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "f9bde9a1-9fef-4bd9-b7ef-877369e076e3",
+ "legalEntityName": "Mock Energy Company",
+ "logoUri": "https://mocksoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "34241177887",
+ "acn": "005249981",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000001",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "d50b74cf-e992-42fd-86d4-582ac9d72dbb",
+ "brandName": "Mock Energy Tool",
+ "brandGroup": null,
+ "logoUri": "https://mocksoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-12-01T09:00:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "4754cf30-6cc2-4a9a-a9e1-4fb8f6d42120",
+ "softwareProductName": "MyEnergyHelper",
+ "softwareProductDescription": "A product to help you manage your energy costs",
+ "logoUri": "https://mocksoftware/myenergyapp/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://mocksoftware/myenergyapp",
+ "tosUri": "https://mocksoftware/myenergyapp/terms",
+ "policyUri": "https://mocksoftware/myenergyapp/policy",
+ "recipientBaseUri": "https://mock-data-recipient:9001",
+ "revocationUri": "https://mock-data-recipient:9001/revocation",
+ "redirectUris": "https://mock-data-recipient:9001/consent/callback",
+ "jwksUri": "https://mock-data-recipient:9001/jwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
}
- }
- ]
- }
- ]
- },
- {
- "legalEntityId": "aeca53ab-2a90-4737-938d-987ce195ca14",
- "legalEntityName": "Sun Bank",
- "logoUri": "https://sunbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "94477558899",
- "acn": "99000099",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": 2,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d",
- "brandName": "Sun -- dummy data holder -- do not use",
- "logoUri": "https://sunbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-01T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.sunbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.sunbank",
- "resourceBaseUri": "https://api.sunbank",
- "infoSecBaseUri": "https://idp.sunbank",
- "extensionBaseUri": "",
- "websiteUri": "https://sunbank/"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "0d332caa-8cd8-4ac9-8898-20641c54bc8c",
+ "legalEntityName": "Bank Legal Entity 1",
+ "logoUri": "https://bank/logo.png",
+ "registrationNumber": "12345",
+ "registrationDate": "2021-12-01T10:00:00",
+ "registeredCountry": "AUSTRALIA",
+ "abn": "11111111111",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": "6221",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "804fc2fb-18a7-4235-9a49-2af393d18bc7",
+ "brandName": "Mock Data Holder (Banking)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://bank1/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.bank1/jwks"
}
- },
- {
- "brandId": "a2cd9cd1-e3c7-493b-86d8-f9f319ca0732",
- "brandName": "Brighter Bank -- dummy data holder -- do not use",
- "logoUri": "https://brighterbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-01-01T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.brighterbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.brighterbank",
- "resourceBaseUri": "https://api.brighterbank",
- "infoSecBaseUri": "https://idp.brighterbank",
- "extensionBaseUri": "",
- "websiteUri": "https://brighterbank/"
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://mock-data-holder:8000",
+ "productBaseUri": "https://mock-data-holder:8000",
+ "resourceBaseUri": "https://mock-data-holder:8002",
+ "infoSecBaseUri": "https://mock-data-holder:8001",
+ "extensionBaseUri": "",
+ "websiteUri": "https://bank1/"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "07568be9-ed72-4268-8a8f-83cf60608dff",
+ "legalEntityName": "Non Bank Legal Entity 1",
+ "logoUri": "https://non-bank/logo.png",
+ "registrationNumber": "48219",
+ "registrationDate": "2021-12-01T10:00:00",
+ "registeredCountry": "AUSTRALIA",
+ "abn": "58392017462",
+ "acn": "473915802",
+ "arbn": null,
+ "anzsicDivision": "6221",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 3,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "7f3c2a41-9b8e-4e6c-9df1-12c4b8f0a6e3",
+ "brandName": "Mock Data Holder (Non-Bank Lending)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://non-bank1/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.non.bank1/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://mock-data-holder:8200",
+ "productBaseUri": "https://mock-data-holder:8200",
+ "resourceBaseUri": "https://mock-data-holder:8202",
+ "infoSecBaseUri": "https://mock-data-holder:8201",
+ "extensionBaseUri": "",
+ "websiteUri": "https://non-bank1/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "ba1311fb-5cea-4c5c-b4ed-f2a98a0915e0",
- "legalEntityName": "Hot Bank",
- "logoUri": "https://hotbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12345678901",
- "acn": "123456789",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "62f4a113-defe-4f99-bd9c-625277bc0e36",
- "brandName": "mildBank -- dummy data holder -- do not use",
- "logoUri": "https://mildbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-11T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://mildbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.mildbank",
- "resourceBaseUri": "https://api.mildbank",
- "infoSecBaseUri": "https://idp.mildbank",
- "extensionBaseUri": "",
- "websiteUri": "https://mildbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "18b75a76-5821-4c9e-b465-4709291cf0f4",
+ "legalEntityName": "Mock Software Company",
+ "logoUri": "https://mocksoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "11222333444",
+ "acn": "222333444",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000099",
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "ffb1c8ba-279e-44d8-96f0-1bc34a6b436f",
+ "brandName": "Mock Finance Tools",
+ "brandGroup": null,
+ "logoUri": "https://mocksoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "c6327f87-687a-4369-99a4-eaacd3bb8210",
+ "softwareProductName": "MyBudgetHelper",
+ "softwareProductDescription": "A product to help you manage your budget",
+ "logoUri": "https://mocksoftware/mybudgetapp/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://mocksoftware/mybudgetapp",
+ "tosUri": "https://mocksoftware/mybudgetapp/terms",
+ "policyUri": "https://mocksoftware/mybudgetapp/policy",
+ "recipientBaseUri": "https://mock-data-recipient:9001",
+ "revocationUri": "https://mock-data-recipient:9001/revocation",
+ "redirectUris": "https://mock-data-recipient:9001/consent/callback",
+ "jwksUri": "https://mock-data-recipient:9001/jwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
}
- },
- {
- "brandId": "81d3d5cc-cdb6-4253-a78b-b17155dde7fd",
- "brandName": "extrahotBank -- dummy data holder -- do not use",
- "logoUri": "https://extrahotbank/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-16T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://extrahotbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.extrahotbank",
- "resourceBaseUri": "https://api.extrahotbank",
- "infoSecBaseUri": "https://idp.extrahotbank",
- "extensionBaseUri": "",
- "websiteUri": "https://extrahotbank/"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "93ef5f28-7f30-43f2-8e5c-b1e3cb39ce90",
+ "legalEntityName": "New Bank",
+ "logoUri": "https://newbank/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "99888777666",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55",
+ "brandName": "New Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://newbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.newbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.newbank",
+ "productBaseUri": null, // intentionally not provided
+ "resourceBaseUri": "https://api.newbank",
+ "infoSecBaseUri": "https://idp.newbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://newbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "725c6e62-bfa7-4719-94af-415ae64d4bcd",
- "legalEntityName": "Ive Bank",
- "logoUri": "https://ivebank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12312312393",
- "acn": "099800998",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "9928cf0f-70c7-40ea-b7ad-cad190232f68",
- "brandName": "Ive Bank -- dummy data holder -- do not use",
- "logoUri": "https://ivebank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-03T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.ivebank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.ivebank",
- "resourceBaseUri": "https://api.ivebank",
- "infoSecBaseUri": "https://idp.ivebank",
- "extensionBaseUri": "",
- "websiteUri": "https://ivebank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "aeca53ab-2a90-4737-938d-987ce195ca14",
+ "legalEntityName": "Sun Bank",
+ "logoUri": "https://sunbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "94477558899",
+ "acn": "99000099",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d",
+ "brandName": "Sun -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://sunbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-01T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.sunbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.sunbank",
+ "productBaseUri": "https://publicapi.sunbank",
+ "resourceBaseUri": "https://api.sunbank",
+ "infoSecBaseUri": "https://idp.sunbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://sunbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "2f1c327f-56b6-40c5-8e2e-b2130867329c",
- "legalEntityName": "Eva Bank",
- "logoUri": "https://evabank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "98765456765",
- "acn": "22121232",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "7c97c3b5-fe64-4b35-8ae0-17fa5d4aa0a8",
- "brandName": "Eva Bank corp -- dummy data holder -- do not use",
- "logoUri": "https://evabankcorp/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-26T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.evabank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.evabank",
- "resourceBaseUri": "https://api.evabank",
- "infoSecBaseUri": "https://idp.evabank",
- "extensionBaseUri": "",
- "websiteUri": "https://evabank/"
+ },
+ {
+ "brandId": "a2cd9cd1-e3c7-493b-86d8-f9f319ca0732",
+ "brandName": "Brighter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://brighterbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-01-01T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.brighterbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.brighterbank",
+ "productBaseUri": "https://publicapi.brighterbank",
+ "resourceBaseUri": "https://api.brighterbank",
+ "infoSecBaseUri": "https://idp.brighterbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://brighterbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "e81ab637-b3b7-4403-82b8-a43077a569d6",
- "legalEntityName": "Royal Bank",
- "logoUri": "https://royalbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "94477558833",
- "acn": "99000033",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "a5252bde-d1a6-413f-8f53-f7e2f6ab3f77",
- "brandName": "Royal Bank -- dummy data holder -- do not use",
- "logoUri": "https://royalbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-01T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.royalbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.royalbank",
- "resourceBaseUri": "https://api.royalbank",
- "infoSecBaseUri": "https://idp.royalbank",
- "extensionBaseUri": "",
- "websiteUri": "https://royalbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "ba1311fb-5cea-4c5c-b4ed-f2a98a0915e0",
+ "legalEntityName": "Hot Bank",
+ "logoUri": "https://hotbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12345678901",
+ "acn": "123456789",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "62f4a113-defe-4f99-bd9c-625277bc0e36",
+ "brandName": "mildBank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://mildbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-11T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://mildbank/idp/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.mildbank",
+ "productBaseUri": "https://publicapi.mildbank",
+ "resourceBaseUri": "https://api.mildbank",
+ "infoSecBaseUri": "https://idp.mildbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://mildbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "e81ab636-b3b7-4403-82b8-a43077a569d6",
- "legalEntityName": "Central Bank",
- "logoUri": "https://centralbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12398122412",
- "acn": "44123312",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": 2,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "c1ff7731-5843-4384-88d8-6062afde7c5b",
- "brandName": "central bank -- dummy data holder -- do not use",
- "logoUri": "https://centralbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-03-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.centralbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.centralbank",
- "resourceBaseUri": "https://api.centralbank",
- "infoSecBaseUri": "https://idp.centralbank",
- "extensionBaseUri": "",
- "websiteUri": "https://centralbank/"
+ },
+ {
+ "brandId": "81d3d5cc-cdb6-4253-a78b-b17155dde7fd",
+ "brandName": "extrahotBank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://extrahotbank/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-16T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://extrahotbank/idp/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.extrahotbank",
+ "productBaseUri": "https://publicapi.extrahotbank",
+ "resourceBaseUri": "https://api.extrahotbank",
+ "infoSecBaseUri": "https://idp.extrahotbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://extrahotbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "ae4af466-54c6-4ce4-ad2d-580bc6496943",
- "legalEntityName": "Fox Bank",
- "logoUri": "https://foxbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "31234212475",
- "acn": "122341213",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "2192a459-5ef5-4493-afe1-56c3d03fc1ba",
- "brandName": "Fox Bank -- dummy data holder -- do not use",
- "logoUri": "https://foxbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-21T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.foxbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.foxbank",
- "resourceBaseUri": "https://api.foxbank",
- "infoSecBaseUri": "https://idp.foxbank",
- "extensionBaseUri": "",
- "websiteUri": "https://foxbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "725c6e62-bfa7-4719-94af-415ae64d4bcd",
+ "legalEntityName": "Ive Bank",
+ "logoUri": "https://ivebank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12312312393",
+ "acn": "099800998",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "9928cf0f-70c7-40ea-b7ad-cad190232f68",
+ "brandName": "Ive Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://ivebank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-03T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.ivebank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.ivebank",
+ "productBaseUri": "https://publicapi.ivebank",
+ "resourceBaseUri": "https://api.ivebank",
+ "infoSecBaseUri": "https://idp.ivebank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://ivebank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "017fcfc8-1fd3-4ef4-8f08-b697c4c681ee",
- "legalEntityName": "Grand Bank",
- "logoUri": "https://grandbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "99888777666",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "8aa8e9a6-1dc7-4428-baea-d1f4533428b9",
- "brandName": "Grand Bank -- dummy data holder -- do not use",
- "logoUri": "https://grandbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-29T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.grandbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.grandbank",
- "resourceBaseUri": "https://api.grandbank",
- "infoSecBaseUri": "https://idp.grandbank",
- "extensionBaseUri": "",
- "websiteUri": "https://grandbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "2f1c327f-56b6-40c5-8e2e-b2130867329c",
+ "legalEntityName": "Eva Bank",
+ "logoUri": "https://evabank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "98765456765",
+ "acn": "22121232",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "7c97c3b5-fe64-4b35-8ae0-17fa5d4aa0a8",
+ "brandName": "Eva Bank corp -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://evabankcorp/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-26T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.evabank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.evabank",
+ "productBaseUri": "https://publicapi.evabank",
+ "resourceBaseUri": "https://api.evabank",
+ "infoSecBaseUri": "https://idp.evabank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://evabank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "7b1a7566-e113-411b-94b7-d3b9fb0da98a",
- "legalEntityName": "Kiss Bank",
- "logoUri": "https://kissbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12593477455",
- "acn": "112122235",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "85168ace-9211-45e3-bb75-f85c54e66f10",
- "brandName": "Kiss Bank -- dummy data holder -- do not use",
- "logoUri": "https://kissbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-12T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.kissbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.kissbank",
- "resourceBaseUri": "https://api.kissbank",
- "infoSecBaseUri": "https://idp.kissbank",
- "extensionBaseUri": "",
- "websiteUri": "https://kissbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "e81ab637-b3b7-4403-82b8-a43077a569d6",
+ "legalEntityName": "Royal Bank",
+ "logoUri": "https://royalbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "94477558833",
+ "acn": "99000033",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "a5252bde-d1a6-413f-8f53-f7e2f6ab3f77",
+ "brandName": "Royal Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://royalbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-01T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.royalbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.royalbank",
+ "productBaseUri": "https://publicapi.royalbank",
+ "resourceBaseUri": "https://api.royalbank",
+ "infoSecBaseUri": "https://idp.royalbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://royalbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "667407fc-dc7e-4be5-8795-5189240bcbca",
- "legalEntityName": "Luna Bank",
- "logoUri": "https://lunabank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12334412233",
- "acn": "747553322",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "bb03be60-5c46-422e-a27e-aefa0015078d",
- "brandName": "Luna -- dummy data holder -- do not use",
- "logoUri": "https://lunabank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-12T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.lunabank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.lunabank",
- "resourceBaseUri": "https://api.lunabank",
- "infoSecBaseUri": "https://idp.lunabank",
- "extensionBaseUri": "",
- "websiteUri": "https://lunabank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "e81ab636-b3b7-4403-82b8-a43077a569d6",
+ "legalEntityName": "Central Bank",
+ "logoUri": "https://centralbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12398122412",
+ "acn": "44123312",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "c1ff7731-5843-4384-88d8-6062afde7c5b",
+ "brandName": "central bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://centralbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-03-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.centralbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.centralbank",
+ "productBaseUri": "https://publicapi.centralbank",
+ "resourceBaseUri": "https://api.centralbank",
+ "infoSecBaseUri": "https://idp.centralbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://centralbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "7993c227-9252-432b-9b2f-a8666e2fd2f2",
- "legalEntityName": "Mu Bank",
- "logoUri": "https://mubank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12352345345",
- "acn": "112123121",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "52d23611-4493-4a21-9095-44ae9eb85841",
- "brandName": "Mu Bank -- dummy data holder -- do not use",
- "logoUri": "https://mubank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.mubank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.mubank",
- "resourceBaseUri": "https://api.mubank",
- "infoSecBaseUri": "https://idp.mubank",
- "extensionBaseUri": "",
- "websiteUri": "https://mubank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "ae4af466-54c6-4ce4-ad2d-580bc6496943",
+ "legalEntityName": "Fox Bank",
+ "logoUri": "https://foxbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "31234212475",
+ "acn": "122341213",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "2192a459-5ef5-4493-afe1-56c3d03fc1ba",
+ "brandName": "Fox Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://foxbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-21T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.foxbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.foxbank",
+ "productBaseUri": "https://publicapi.foxbank",
+ "resourceBaseUri": "https://api.foxbank",
+ "infoSecBaseUri": "https://idp.foxbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://foxbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "9c7dec6d-2e46-4b53-8430-5337c7eb93e9",
- "legalEntityName": "Noon Bank",
- "logoUri": "https://noonbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "11123599749",
- "acn": "224435522",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "557f42e8-4e00-4b03-a9c9-d97796b6418b",
- "brandName": "Noon Bank -- dummy data holder -- do not use",
- "logoUri": "https://noonbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.noonbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.noonbank",
- "resourceBaseUri": "https://api.noonbank",
- "infoSecBaseUri": "https://idp.noonbank",
- "extensionBaseUri": "",
- "websiteUri": "https://noonbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "017fcfc8-1fd3-4ef4-8f08-b697c4c681ee",
+ "legalEntityName": "Grand Bank",
+ "logoUri": "https://grandbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "99888777666",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "8aa8e9a6-1dc7-4428-baea-d1f4533428b9",
+ "brandName": "Grand Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://grandbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-29T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.grandbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.grandbank",
+ "productBaseUri": "https://publicapi.grandbank",
+ "resourceBaseUri": "https://api.grandbank",
+ "infoSecBaseUri": "https://idp.grandbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://grandbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "b9b45c14-3346-47f7-ad78-3416762cf1d8",
- "legalEntityName": "Oppo Bank",
- "logoUri": "https://oppobank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12412412426",
- "acn": "995543336",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "a5e45351-d13c-4690-93d1-3da515e71a92",
- "brandName": "Oppo Bank -- dummy data holder -- do not use",
- "logoUri": "https://oppobank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.oppobank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.oppobank",
- "resourceBaseUri": "https://api.oppobank",
- "infoSecBaseUri": "https://idp.oppobank",
- "extensionBaseUri": "",
- "websiteUri": "https://oppobank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "7b1a7566-e113-411b-94b7-d3b9fb0da98a",
+ "legalEntityName": "Kiss Bank",
+ "logoUri": "https://kissbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12593477455",
+ "acn": "112122235",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "85168ace-9211-45e3-bb75-f85c54e66f10",
+ "brandName": "Kiss Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://kissbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-12T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.kissbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.kissbank",
+ "productBaseUri": "https://publicapi.kissbank",
+ "resourceBaseUri": "https://api.kissbank",
+ "infoSecBaseUri": "https://idp.kissbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://kissbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "b7a18659-eb9b-4130-a0df-402c85f1f216",
- "legalEntityName": "Pepper Bank",
- "logoUri": "https://pepperbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "87356524315",
- "acn": "322342343",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "97e53112-73b2-482a-b352-39d389d67916",
- "brandName": "Pepper Bank -- dummy data holder -- do not use",
- "logoUri": "https://pepperbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.pepperbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.pepperbank",
- "resourceBaseUri": "https://api.pepperbank",
- "infoSecBaseUri": "https://idp.pepperbank",
- "extensionBaseUri": "",
- "websiteUri": "https://pepperbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "667407fc-dc7e-4be5-8795-5189240bcbca",
+ "legalEntityName": "Luna Bank",
+ "logoUri": "https://lunabank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12334412233",
+ "acn": "747553322",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "bb03be60-5c46-422e-a27e-aefa0015078d",
+ "brandName": "Luna -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://lunabank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-12T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.lunabank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.lunabank",
+ "productBaseUri": "https://publicapi.lunabank",
+ "resourceBaseUri": "https://api.lunabank",
+ "infoSecBaseUri": "https://idp.lunabank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://lunabank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "fe75814c-99ee-4922-a6b0-71913e60984c",
- "legalEntityName": "QQ Bank",
- "logoUri": "https://qqbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "21111244638",
- "acn": "317373231",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "895e54c5-93e0-405f-8072-0a9871bac8b5",
- "brandName": "QQ Bank -- dummy data holder -- do not use",
- "logoUri": "https://qqbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.qqbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.qqbank",
- "resourceBaseUri": "https://api.qqbank",
- "infoSecBaseUri": "https://idp.qqbank",
- "extensionBaseUri": "",
- "websiteUri": "https://qqbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "7993c227-9252-432b-9b2f-a8666e2fd2f2",
+ "legalEntityName": "Mu Bank",
+ "logoUri": "https://mubank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12352345345",
+ "acn": "112123121",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "52d23611-4493-4a21-9095-44ae9eb85841",
+ "brandName": "Mu Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://mubank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.mubank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.mubank",
+ "productBaseUri": "https://publicapi.mubank",
+ "resourceBaseUri": "https://api.mubank",
+ "infoSecBaseUri": "https://idp.mubank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://mubank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "06c595f2-f0b2-4684-90e1-6905e4537304",
- "legalEntityName": "Run Bank",
- "logoUri": "https://runbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "99888777666",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "975375f7-2bd9-44b5-a188-43d65ca8eaae",
- "brandName": "Run Bank -- dummy data holder -- do not use",
- "logoUri": "https://runbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.runbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.runbank",
- "resourceBaseUri": "https://api.runbank",
- "infoSecBaseUri": "https://idp.runbank",
- "extensionBaseUri": "",
- "websiteUri": "https://runbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "9c7dec6d-2e46-4b53-8430-5337c7eb93e9",
+ "legalEntityName": "Noon Bank",
+ "logoUri": "https://noonbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "11123599749",
+ "acn": "224435522",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "557f42e8-4e00-4b03-a9c9-d97796b6418b",
+ "brandName": "Noon Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://noonbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.noonbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.noonbank",
+ "productBaseUri": "https://publicapi.noonbank",
+ "resourceBaseUri": "https://api.noonbank",
+ "infoSecBaseUri": "https://idp.noonbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://noonbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "350c4b28-132c-4248-a962-1434e00e7046",
- "legalEntityName": "SaS Bank",
- "logoUri": "https://sasbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "99888777666",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "b648f694-0dee-4f5e-bd2c-9837ac08fb7b",
- "brandName": "SaS Bank -- dummy data holder -- do not use",
- "logoUri": "https://sasbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.sasbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.sasbank",
- "resourceBaseUri": "https://api.sasbank",
- "infoSecBaseUri": "https://idp.sasbank",
- "extensionBaseUri": "",
- "websiteUri": "https://sasbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "b9b45c14-3346-47f7-ad78-3416762cf1d8",
+ "legalEntityName": "Oppo Bank",
+ "logoUri": "https://oppobank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12412412426",
+ "acn": "995543336",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "a5e45351-d13c-4690-93d1-3da515e71a92",
+ "brandName": "Oppo Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://oppobank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.oppobank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.oppobank",
+ "productBaseUri": "https://publicapi.oppobank",
+ "resourceBaseUri": "https://api.oppobank",
+ "infoSecBaseUri": "https://idp.oppobank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://oppobank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "a1349224-adf3-4678-ba9b-f9ec800b5dc5",
- "legalEntityName": "TnT Bank",
- "logoUri": "https://tntbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "13123412473",
- "acn": "533284211",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "f8bce914-ac8d-436a-b265-19baca6d1df2",
- "brandName": "TnT Bank -- dummy data holder -- do not use",
- "logoUri": "https://tntbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-09T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.tntbank/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.tntbank",
- "resourceBaseUri": "https://api.tntbank",
- "infoSecBaseUri": "https://idp.tntbank",
- "extensionBaseUri": "",
- "websiteUri": "https://tntbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "b7a18659-eb9b-4130-a0df-402c85f1f216",
+ "legalEntityName": "Pepper Bank",
+ "logoUri": "https://pepperbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "87356524315",
+ "acn": "322342343",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "97e53112-73b2-482a-b352-39d389d67916",
+ "brandName": "Pepper Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://pepperbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.pepperbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.pepperbank",
+ "productBaseUri": "https://publicapi.pepperbank",
+ "resourceBaseUri": "https://api.pepperbank",
+ "infoSecBaseUri": "https://idp.pepperbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://pepperbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "bc9d68f2-74c4-43d5-9a9c-93e72a2e84c9",
- "legalEntityName": "Bank Legal Entity 2",
- "logoUri": "https://bank2/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "11111111111",
- "acn": "888777666",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": 2,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "e748eadf-4aa4-4e2f-b3da-fb4a9d511994",
- "brandName": "Bank Brand 2 -- dummy data holder -- do not use",
- "logoUri": "https://bank2/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://idp.bank2/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.bank2",
- "resourceBaseUri": "https://api.bank2",
- "infoSecBaseUri": "https://idp.bank2",
- "extensionBaseUri": "",
- "websiteUri": "https://bank2/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "fe75814c-99ee-4922-a6b0-71913e60984c",
+ "legalEntityName": "QQ Bank",
+ "logoUri": "https://qqbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "21111244638",
+ "acn": "317373231",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "895e54c5-93e0-405f-8072-0a9871bac8b5",
+ "brandName": "QQ Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://qqbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.qqbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.qqbank",
+ "productBaseUri": "https://publicapi.qqbank",
+ "resourceBaseUri": "https://api.qqbank",
+ "infoSecBaseUri": "https://idp.qqbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://qqbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "3d974478-afa6-4ce4-80bc-6f93e8e92e19",
- "legalEntityName": "Smarter Bank",
- "logoUri": "https://smarterbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12345678901",
- "acn": "123456789",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "9f8df3e2-6866-42af-91d4-5faa3204f0b8",
- "brandName": "Smarter Bank -- dummy data holder -- do not use",
- "logoUri": "https://smarterbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://smarterbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.smarterbank",
- "resourceBaseUri": "https://api.smarterbank",
- "infoSecBaseUri": "https://idp.smarterbank",
- "extensionBaseUri": "",
- "websiteUri": "https://smarterbank/"
- }
- },
- {
- "brandId": "81d3d5cb-cdb6-4253-a78b-b17155dde7fd",
- "brandName": "MyBank -- dummy data holder -- do not use",
- "logoUri": "https://mybank/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://mybank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.mybank",
- "resourceBaseUri": "https://api.mybank",
- "infoSecBaseUri": "https://idp.mybank",
- "extensionBaseUri": "",
- "websiteUri": "https://mybank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "06c595f2-f0b2-4684-90e1-6905e4537304",
+ "legalEntityName": "Run Bank",
+ "logoUri": "https://runbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "99888777666",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "975375f7-2bd9-44b5-a188-43d65ca8eaae",
+ "brandName": "Run Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://runbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.runbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.runbank",
+ "productBaseUri": "https://publicapi.runbank",
+ "resourceBaseUri": "https://api.runbank",
+ "infoSecBaseUri": "https://idp.runbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://runbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "924ca498-0f19-402d-ae07-2cb61088f8aa",
- "legalEntityName": "Hall Bank",
- "logoUri": "https://hallbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "12345678901",
- "acn": "123456789",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "cf217aba-e00d-48d5-9c3d-03af0b91cb80",
- "brandName": "Hall Bank -- dummy data holder -- do not use",
- "logoUri": "https://hallardbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-19T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://hallbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.hallbank",
- "resourceBaseUri": "https://api.hallbank",
- "infoSecBaseUri": "https://idp.hallbank",
- "extensionBaseUri": "",
- "websiteUri": "https://hallbank/"
- }
- },
- {
- "brandId": "920f296d-5f2f-49de-876c-15a4aa1b4a79",
- "brandName": "Hallway -- dummy data holder -- do not use",
- "logoUri": "https://hallwaybank/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-18T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://hallwaybank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.hallwaybank",
- "resourceBaseUri": "https://api.hallwaybank",
- "infoSecBaseUri": "https://idp.hallwaybank",
- "extensionBaseUri": "",
- "websiteUri": "https://hallwaybank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "350c4b28-132c-4248-a962-1434e00e7046",
+ "legalEntityName": "SaS Bank",
+ "logoUri": "https://sasbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "99888777666",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "b648f694-0dee-4f5e-bd2c-9837ac08fb7b",
+ "brandName": "SaS Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://sasbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.sasbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.sasbank",
+ "productBaseUri": "https://publicapi.sasbank",
+ "resourceBaseUri": "https://api.sasbank",
+ "infoSecBaseUri": "https://idp.sasbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://sasbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "04361651-f485-421a-8e3e-d01dd7ab2706",
- "legalEntityName": "Job Bank",
- "logoUri": "https://jobbank/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "13254365476",
- "acn": "264284352",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": null,
- "accreditationLevelId": null,
- "participations": [
- {
- "participationTypeId": 1,
- "industryId": 1,
- "statusId": 1,
- "brands": [
- {
- "brandId": "bc144967-d6f8-47a6-8590-07caf522141b",
- "brandName": "Jobs Bank -- dummy data holder -- do not use",
- "logoUri": "https://jobsbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://jobsbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.jobsbank",
- "resourceBaseUri": "https://api.jobsbank",
- "infoSecBaseUri": "https://idp.jobsbank",
- "extensionBaseUri": "",
- "websiteUri": "https://jobsbank/"
- }
- },
- {
- "brandId": "7b47ecf8-a991-4dd3-adef-b89564005e8e",
- "brandName": "offer bank -- dummy data holder -- do not use",
- "logoUri": "https://offerbank/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://offerbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.offerbank",
- "resourceBaseUri": "https://api.offerbank",
- "infoSecBaseUri": "https://idp.offerbank",
- "extensionBaseUri": "",
- "websiteUri": "https://offerbank/"
- }
- },
- {
- "brandId": "c3176245-4258-4383-b945-cd2f7c828d3c",
- "brandName": "J bank -- dummy data holder -- do not use",
- "logoUri": "https://jbank/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-18T11:58:00",
- "authDetails": [
- {
- "registerUTypeId": 1,
- "jwksEndpoint": "https://jbank/idp/jwks"
- }
- ],
- "endpoint": {
- "version": 1,
- "publicBaseUri": "https://publicapi.jbank",
- "resourceBaseUri": "https://api.jbank",
- "infoSecBaseUri": "https://idp.jbank",
- "extensionBaseUri": "",
- "websiteUri": "https://jbank/"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "a1349224-adf3-4678-ba9b-f9ec800b5dc5",
+ "legalEntityName": "TnT Bank",
+ "logoUri": "https://tntbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "13123412473",
+ "acn": "533284211",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "f8bce914-ac8d-436a-b265-19baca6d1df2",
+ "brandName": "TnT Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://tntbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-09T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.tntbank/jwks"
}
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.tntbank",
+ "productBaseUri": "https://publicapi.tntbank",
+ "resourceBaseUri": "https://api.tntbank",
+ "infoSecBaseUri": "https://idp.tntbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://tntbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "9d34ede4-2c76-4ecc-a31e-ea8392d31cc9",
- "legalEntityName": "FintechX",
- "logoUri": "https://fintechx/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "98765987654",
- "acn": "987659876",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR001001",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "20c0864b-ceef-4de0-8944-eb0962f825eb",
- "brandName": "Finance X",
- "logoUri": "https://fintechx/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "d3c44426-e003-4604-aa45-4137e45dfbc4",
- "softwareProductName": "Loan Calculator X",
- "softwareProductDescription": "Loan affordability application",
- "logoUri": "https://fintechx/products/loancalculator/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://fintechx/products/loancalculator",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://fintechx/products/loancalculator",
- "revocationUri": "https://fintechx/products/loancalculator/revocation",
- "redirectUris": "https://fintechx/products/loancalculator/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- },
- {
- "softwareProductId": "9381dad2-6b68-4879-b496-c1319d7dfbc9",
- "softwareProductName": "Track Xpense",
- "softwareProductDescription": "Application to allow you to track your expenses",
- "logoUri": "https://fintechx/products/trackxpense/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://fintechx/products/trackxpense",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://fintechx/products/trackxpense",
- "revocationUri": "https://fintechx/products/trackxpense/revoke",
- "redirectUris": "https://fintechx/products/trackxpense/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- },
- {
- "softwareProductId": "63bc22ac-6fd2-4e85-a979-c2fc7c4db9da",
- "softwareProductName": "TestProductCert",
- "softwareProductDescription": "Application to allow you to track your expenses",
- "logoUri": "https://fintechx/products/trackxpense/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://fintechx/products/trackxpense",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://fintechx/products/trackxpense",
- "revocationUri": "https://fintechx/products/trackxpense/revoke",
- "redirectUris": "https://fintechx/products/trackxpense/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- },
- {
- "softwareProductId": "86ecb655-9eba-409c-9be3-59e7adf7080d",
- "softwareProductName": "MockDataRecepient",
- "softwareProductDescription": "Mock Data Recepient",
- "logoUri": "https://fintechx/products/trackxpense/logo.png",
- "sectorIdentifierUri": "https://fintechx/products/trackxpense/sectoridentifieruri",
- "clientUri": "https://fintechx/products/trackxpense",
- "tosUri": "https://fintechx/products/trackxpense/tos",
- "policyUri": "https://fintechx/products/trackxpense/policy",
- "recipientBaseUri": "https://fintechx/products/trackxpense",
- "revocationUri": "https://fintechx/products/trackxpense/revoke",
- "redirectUris": "https://fintechx/products/trackxpense/cb https://fintechx/products/trackxpense/cb2",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "bc9d68f2-74c4-43d5-9a9c-93e72a2e84c9",
+ "legalEntityName": "Bank Legal Entity 2",
+ "logoUri": "https://bank2/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "11111111111",
+ "acn": "888777666",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "e748eadf-4aa4-4e2f-b3da-fb4a9d511994",
+ "brandName": "Bank Brand 2 -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://bank2/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.bank2/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.bank2",
+ "productBaseUri": "https://publicapi.bank2",
+ "resourceBaseUri": "https://api.bank2",
+ "infoSecBaseUri": "https://idp.bank2",
+ "extensionBaseUri": "",
+ "websiteUri": "https://bank2/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "a1ca85da-7be8-4020-9c27-c9623eca582b",
- "legalEntityName": "Xray Software Pty Ltd",
- "logoUri": "https://xraysoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "112341234",
- "acn": "12341243",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000006",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "fe123396-4eba-4518-aade-b245ceea78af",
- "brandName": "XRay Financial",
- "logoUri": "https://xraysoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "6a25c22b-0810-4f41-8e41-f48d162c517d",
- "softwareProductName": "Budget direct",
- "softwareProductDescription": "A product to help you manage your budget",
- "logoUri": "https://xraysoftware/budgetdirect/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://xraysoftware/budgetdirect",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://api.xrayoftware/budgetdirect",
- "revocationUri": "https://api.xraysoftware/budgetdirect/revoke",
- "redirectUris": "https://api.xraysoftware/budgetdirect/callback",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "3d974478-afa6-4ce4-80bc-6f93e8e92e19",
+ "legalEntityName": "Smarter Bank",
+ "logoUri": "https://smarterbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12345678901",
+ "acn": "123456789",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "9f8df3e2-6866-42af-91d4-5faa3204f0b8",
+ "brandName": "Smarter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://smarterbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://smarterbank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.smarterbank",
+ "productBaseUri": "https://publicapi.smarterbank",
+ "resourceBaseUri": "https://api.smarterbank",
+ "infoSecBaseUri": "https://idp.smarterbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://smarterbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "8ff78c90-74c2-4c51-9c04-9d829476687a",
- "legalEntityName": "WOW Software Company",
- "logoUri": "https://wowsoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "88778877",
- "acn": "99889988",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000007",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "8fe9791a-e4a8-4104-b1cb-e0df41189520",
- "brandName": "WOW",
- "logoUri": "https://wowsoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-02-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "9788e6d3-75a1-47eb-a891-dd752ced0f61",
- "softwareProductName": "MyBudgetHelper",
- "softwareProductDescription": "A product to help you manage your budget",
- "logoUri": "https://wowsoftware/mybudgetapp/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://wowsoftware/mybudgetapp",
- "tosUri": "https://wowsoftware/mybudgetapp/terms",
- "policyUri": "https://wowsoftware/mybudgetapp/policy",
- "recipientBaseUri": "https://api.wowsoftware/mybudgetapp",
- "revocationUri": "https://api.wowsoftware/mybudgetapp/revoke",
- "redirectUris": "https://api.wowsoftware/mybudgetapp/callback https://api.mocksoftware/mybudgetapp/return",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ },
+ {
+ "brandId": "81d3d5cb-cdb6-4253-a78b-b17155dde7fd",
+ "brandName": "MyBank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://mybank/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://mybank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.mybank",
+ "productBaseUri": "https://publicapi.mybank",
+ "resourceBaseUri": "https://api.mybank",
+ "infoSecBaseUri": "https://idp.mybank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://mybank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "4a29856c-2634-4fea-bf9b-74c99c337e2f",
- "legalEntityName": "olm Software Company",
- "logoUri": "https://olmsoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "88778877",
- "acn": "99889988",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000008",
- "accreditationLevelId": 0,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "a7171ba3-fd05-456f-a859-be4e1cbcc17d",
- "brandName": "OLM Software",
- "logoUri": "https://olmsoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "05d7dfd7-1d8f-4abf-b987-cf56c9115e8d",
- "softwareProductName": "Budgeter",
- "softwareProductDescription": "A product to help you manage your budget",
- "logoUri": "https://olmsoftware/mybudgetapp/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://olmsoftware/mybudgetapp",
- "tosUri": "https://olmsoftware/mybudgetapp/terms",
- "policyUri": "https://olmsoftware/mybudgetapp/policy",
- "recipientBaseUri": "https://api.olmsoftware/mybudgetapp",
- "revocationUri": "https://api.olmsoftware/mybudgetapp/revoke",
- "redirectUris": "https://api.olmsoftware/mybudgetapp/redirect",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "924ca498-0f19-402d-ae07-2cb61088f8aa",
+ "legalEntityName": "Hall Bank",
+ "logoUri": "https://hallbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "12345678901",
+ "acn": "123456789",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "cf217aba-e00d-48d5-9c3d-03af0b91cb80",
+ "brandName": "Hall Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://hallardbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-19T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://hallbank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.hallbank",
+ "productBaseUri": "https://publicapi.hallbank",
+ "resourceBaseUri": "https://api.hallbank",
+ "infoSecBaseUri": "https://idp.hallbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://hallbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "f138d974-0d12-4150-ad0f-c77af745c60b",
- "legalEntityName": "xlogical Software Company",
- "logoUri": "https://xlogical/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": null,
- "acn": null,
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR001009",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "8a3441aa-1242-493a-b466-dcbfffe5a441",
- "brandName": "xlogical",
- "logoUri": "https://xlogical/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "25ee528f-35ac-4a66-a67c-6166602c9322",
- "softwareProductName": "Loan Calculator ",
- "softwareProductDescription": "Loan applications",
- "logoUri": "https://xlogical/products/loancalculator/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://xlogical/products/loancalculator",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://xlogical/products/loancalculator",
- "revocationUri": "https://xlogical/products/loancalculator/revocation",
- "redirectUris": "https://xlogical/products/loancalculator/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:payees:read bank:regular_payments:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ },
+ {
+ "brandId": "920f296d-5f2f-49de-876c-15a4aa1b4a79",
+ "brandName": "Hallway -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://hallwaybank/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-18T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://hallwaybank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.hallwaybank",
+ "productBaseUri": "https://publicapi.hallwaybank",
+ "resourceBaseUri": "https://api.hallwaybank",
+ "infoSecBaseUri": "https://idp.hallwaybank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://hallwaybank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "f72ab707-a619-4dc1-a90b-177d61bcf574",
- "legalEntityName": "HotFinTech",
- "logoUri": "https://hotfintech/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "01944123445",
- "acn": "123412345",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR001002",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "46b33515-b4a5-4b1c-b5b4-25654d675be6",
- "brandName": "HotFinTech",
- "logoUri": "https://hotfintech/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-05T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "d3c44425-e003-4604-aa45-4137e45dfbc4",
- "softwareProductName": "Pay advance",
- "softwareProductDescription": "Buy first and pay later product",
- "logoUri": "https://hotfintech/products/payadvance/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://hotfintech/products/payadvance ",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://hotfintech/products/payadvance",
- "revocationUri": "https://hotfintech/products/payadvance/revocation",
- "redirectUris": "https://hotfintech/products/payadvance/redirect",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- },
- {
- "softwareProductId": "9926a894-cc29-4d63-b3b4-e404066ae6f2",
- "softwareProductName": "Track sheet",
- "softwareProductDescription": "Application to allow you to track your expenses",
- "logoUri": "https://hotfintech/products/tracksheet/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://hotfintech/products/tracksheet/",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://hotfintech/products/tracksheet",
- "revocationUri": "https://hotfintech/products/tracksheet/revoke",
- "redirectUris": "https://hotfintech/products/tracksheet/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "04361651-f485-421a-8e3e-d01dd7ab2706",
+ "legalEntityName": "Job Bank",
+ "logoUri": "https://jobbank/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "13254365476",
+ "acn": "264284352",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 1,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "bc144967-d6f8-47a6-8590-07caf522141b",
+ "brandName": "Jobs Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://jobsbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://jobsbank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.jobsbank",
+ "productBaseUri": "https://publicapi.jobsbank",
+ "resourceBaseUri": "https://api.jobsbank",
+ "infoSecBaseUri": "https://idp.jobsbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://jobsbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "c70456f3-843f-4407-a988-577c108a7816",
- "legalEntityName": "ZeroFintech",
- "logoUri": "https://zerofintech/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "98765987654",
- "acn": "987659876",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR001004",
- "accreditationLevelId": 1,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "ebbcc2f2-817e-42b8-8a28-cd45902159e0",
- "brandName": "ZeroFintech",
- "logoUri": "https://zerofintech/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-05T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "5d03d1a6-b83b-4176-a2f4-d0074a205695",
- "softwareProductName": "Mortgage",
- "softwareProductDescription": "calculate the mortgage value",
- "logoUri": "https://zerofintech/products/mortgage/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://zerofintech/products/mortgage",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://zerofintech/products/mortgage",
- "revocationUri": "https://zerofintech/products/mortgage/revocation",
- "redirectUris": "https://zerofintech/products/mortgage/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- },
- {
- "softwareProductId": "dafa09db-4433-4203-907a-bdf797c8cd21",
- "softwareProductName": "Reward program",
- "softwareProductDescription": "Application to allow you to track your expenses",
- "logoUri": "https://zerofintech//products/rewards/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://zerofintech/products/rewards",
- "tosUri": null,
- "policyUri": null,
- "recipientBaseUri": "https://zerofintech/products/rewards",
- "revocationUri": "https://hotfintech/products/rewards/revoke",
- "redirectUris": "https://zerofintech/products/rewards/cb",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ },
+ {
+ "brandId": "7b47ecf8-a991-4dd3-adef-b89564005e8e",
+ "brandName": "offer bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://offerbank/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://offerbank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.offerbank",
+ "productBaseUri": "https://publicapi.offerbank",
+ "resourceBaseUri": "https://api.offerbank",
+ "infoSecBaseUri": "https://idp.offerbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://offerbank/"
}
- ]
- }
- ]
- },
- {
- "legalEntityId": "de815a93-85b3-4fe8-9513-33ad8f4359d0",
- "legalEntityName": "yoyo Software Company",
- "logoUri": "https://yoyosoftware/img/logo.png",
- "registrationNumber": null,
- "registrationDate": null,
- "registeredCountry": null,
- "abn": "11222333444",
- "acn": "222333444",
- "arbn": null,
- "anzsicDivision": null,
- "organisationTypeId": null,
- "legalEntityStatusId": 1,
- "accreditationNumber": "ADR000005",
- "accreditationLevelId": 0,
- "participations": [
- {
- "participationTypeId": 2,
- "industryId": null,
- "statusId": 1,
- "brands": [
- {
- "brandId": "f3f0c40b-9df8-491a-af1d-81cb9ab5f021",
- "brandName": "YoYo",
- "logoUri": "https://yoyosoftware/img/logo.png",
- "brandStatusId": 1,
- "lastUpdated": "2021-04-06T11:58:00",
- "softwareProducts": [
- {
- "softwareProductId": "6f7a1b8e-8799-48a8-9011-e3920391f713",
- "softwareProductName": "MyBudgetHelper",
- "softwareProductDescription": "A product to help you manage your budget",
- "logoUri": "https://yoyosoftware/mybudgetapp/img/logo.png",
- "sectorIdentifierUri": null,
- "clientUri": "https://yoyosoftware/mybudgetapp",
- "tosUri": "https://yoyosoftware/mybudgetapp/terms",
- "policyUri": "https://yoyosoftware/mybudgetapp/policy",
- "recipientBaseUri": "https://api.yoyosoftware/mybudgetapp",
- "revocationUri": "https://api.yoyosoftware/mybudgetapp/revoke",
- "redirectUris": "https://api.yoyosoftware/mybudgetapp/callback https://api.yoyosoftware/mybudgetapp/return",
- "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
- "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
- "statusId": 1,
- "certificates": [
- {
- "commonName": "MockDataRecipient",
- "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
- }
- ]
- }
- ]
+ },
+ {
+ "brandId": "c3176245-4258-4383-b945-cd2f7c828d3c",
+ "brandName": "J bank -- dummy data holder -- do not use",
+ "brandGroup": null,
+ "logoUri": "https://jbank/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-18T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://jbank/idp/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://publicapi.jbank",
+ "productBaseUri": "https://publicapi.jbank",
+ "resourceBaseUri": "https://api.jbank",
+ "infoSecBaseUri": "https://idp.jbank",
+ "extensionBaseUri": "",
+ "websiteUri": "https://jbank/"
}
- ]
- }
- ]
- }
- ]
- }
\ No newline at end of file
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "9d34ede4-2c76-4ecc-a31e-ea8392d31cc9",
+ "legalEntityName": "FintechX",
+ "logoUri": "https://fintechx/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "98765987654",
+ "acn": "987659876",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR001001",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "20c0864b-ceef-4de0-8944-eb0962f825eb",
+ "brandName": "Finance X",
+ "brandGroup": null,
+ "logoUri": "https://fintechx/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "d3c44426-e003-4604-aa45-4137e45dfbc4",
+ "softwareProductName": "Loan Calculator X",
+ "softwareProductDescription": "Loan affordability application",
+ "logoUri": "https://fintechx/products/loancalculator/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://fintechx/products/loancalculator",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://fintechx/products/loancalculator",
+ "revocationUri": "https://fintechx/products/loancalculator/revocation",
+ "redirectUris": "https://fintechx/products/loancalculator/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ },
+ {
+ "softwareProductId": "9381dad2-6b68-4879-b496-c1319d7dfbc9",
+ "softwareProductName": "Track Xpense",
+ "softwareProductDescription": "Application to allow you to track your expenses",
+ "logoUri": "https://fintechx/products/trackxpense/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://fintechx/products/trackxpense",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://fintechx/products/trackxpense",
+ "revocationUri": "https://fintechx/products/trackxpense/revoke",
+ "redirectUris": "https://fintechx/products/trackxpense/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ },
+ {
+ "softwareProductId": "63bc22ac-6fd2-4e85-a979-c2fc7c4db9da",
+ "softwareProductName": "TestProductCert",
+ "softwareProductDescription": "Application to allow you to track your expenses",
+ "logoUri": "https://fintechx/products/trackxpense/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://fintechx/products/trackxpense",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://fintechx/products/trackxpense",
+ "revocationUri": "https://fintechx/products/trackxpense/revoke",
+ "redirectUris": "https://fintechx/products/trackxpense/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ },
+ {
+ "softwareProductId": "86ecb655-9eba-409c-9be3-59e7adf7080d",
+ "softwareProductName": "MockDataRecepient",
+ "softwareProductDescription": "Mock Data Recepient",
+ "logoUri": "https://fintechx/products/trackxpense/logo.png",
+ "sectorIdentifierUri": "https://fintechx/products/trackxpense/sectoridentifieruri",
+ "clientUri": "https://fintechx/products/trackxpense",
+ "tosUri": "https://fintechx/products/trackxpense/tos",
+ "policyUri": "https://fintechx/products/trackxpense/policy",
+ "recipientBaseUri": "https://fintechx/products/trackxpense",
+ "revocationUri": "https://fintechx/products/trackxpense/revoke",
+ "redirectUris": "https://fintechx/products/trackxpense/cb https://fintechx/products/trackxpense/cb2",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "a1ca85da-7be8-4020-9c27-c9623eca582b",
+ "legalEntityName": "Xray Software Pty Ltd",
+ "logoUri": "https://xraysoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "112341234",
+ "acn": "12341243",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000006",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "fe123396-4eba-4518-aade-b245ceea78af",
+ "brandName": "XRay Financial",
+ "brandGroup": null,
+ "logoUri": "https://xraysoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "6a25c22b-0810-4f41-8e41-f48d162c517d",
+ "softwareProductName": "Budget direct",
+ "softwareProductDescription": "A product to help you manage your budget",
+ "logoUri": "https://xraysoftware/budgetdirect/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://xraysoftware/budgetdirect",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://api.xrayoftware/budgetdirect",
+ "revocationUri": "https://api.xraysoftware/budgetdirect/revoke",
+ "redirectUris": "https://api.xraysoftware/budgetdirect/callback",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "8ff78c90-74c2-4c51-9c04-9d829476687a",
+ "legalEntityName": "WOW Software Company",
+ "logoUri": "https://wowsoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "88778877",
+ "acn": "99889988",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000007",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "8fe9791a-e4a8-4104-b1cb-e0df41189520",
+ "brandName": "WOW",
+ "brandGroup": null,
+ "logoUri": "https://wowsoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-02-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "9788e6d3-75a1-47eb-a891-dd752ced0f61",
+ "softwareProductName": "MyBudgetHelper",
+ "softwareProductDescription": "A product to help you manage your budget",
+ "logoUri": "https://wowsoftware/mybudgetapp/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://wowsoftware/mybudgetapp",
+ "tosUri": "https://wowsoftware/mybudgetapp/terms",
+ "policyUri": "https://wowsoftware/mybudgetapp/policy",
+ "recipientBaseUri": "https://api.wowsoftware/mybudgetapp",
+ "revocationUri": "https://api.wowsoftware/mybudgetapp/revoke",
+ "redirectUris": "https://api.wowsoftware/mybudgetapp/callback https://api.mocksoftware/mybudgetapp/return",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "4a29856c-2634-4fea-bf9b-74c99c337e2f",
+ "legalEntityName": "olm Software Company",
+ "logoUri": "https://olmsoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "88778877",
+ "acn": "99889988",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000008",
+ "accreditationLevelId": 0,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "a7171ba3-fd05-456f-a859-be4e1cbcc17d",
+ "brandName": "OLM Software",
+ "brandGroup": null,
+ "logoUri": "https://olmsoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "05d7dfd7-1d8f-4abf-b987-cf56c9115e8d",
+ "softwareProductName": "Budgeter",
+ "softwareProductDescription": "A product to help you manage your budget",
+ "logoUri": "https://olmsoftware/mybudgetapp/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://olmsoftware/mybudgetapp",
+ "tosUri": "https://olmsoftware/mybudgetapp/terms",
+ "policyUri": "https://olmsoftware/mybudgetapp/policy",
+ "recipientBaseUri": "https://api.olmsoftware/mybudgetapp",
+ "revocationUri": "https://api.olmsoftware/mybudgetapp/revoke",
+ "redirectUris": "https://api.olmsoftware/mybudgetapp/redirect",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "f138d974-0d12-4150-ad0f-c77af745c60b",
+ "legalEntityName": "xlogical Software Company",
+ "logoUri": "https://xlogical/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": null,
+ "acn": null,
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR001009",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "8a3441aa-1242-493a-b466-dcbfffe5a441",
+ "brandName": "xlogical",
+ "brandGroup": null,
+ "logoUri": "https://xlogical/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "25ee528f-35ac-4a66-a67c-6166602c9322",
+ "softwareProductName": "Loan Calculator ",
+ "softwareProductDescription": "Loan applications",
+ "logoUri": "https://xlogical/products/loancalculator/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://xlogical/products/loancalculator",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://xlogical/products/loancalculator",
+ "revocationUri": "https://xlogical/products/loancalculator/revocation",
+ "redirectUris": "https://xlogical/products/loancalculator/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:payees:read bank:regular_payments:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "f72ab707-a619-4dc1-a90b-177d61bcf574",
+ "legalEntityName": "HotFinTech",
+ "logoUri": "https://hotfintech/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "01944123445",
+ "acn": "123412345",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR001002",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "46b33515-b4a5-4b1c-b5b4-25654d675be6",
+ "brandName": "HotFinTech",
+ "brandGroup": null,
+ "logoUri": "https://hotfintech/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-05T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "d3c44425-e003-4604-aa45-4137e45dfbc4",
+ "softwareProductName": "Pay advance",
+ "softwareProductDescription": "Buy first and pay later product",
+ "logoUri": "https://hotfintech/products/payadvance/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://hotfintech/products/payadvance ",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://hotfintech/products/payadvance",
+ "revocationUri": "https://hotfintech/products/payadvance/revocation",
+ "redirectUris": "https://hotfintech/products/payadvance/redirect",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ },
+ {
+ "softwareProductId": "9926a894-cc29-4d63-b3b4-e404066ae6f2",
+ "softwareProductName": "Track sheet",
+ "softwareProductDescription": "Application to allow you to track your expenses",
+ "logoUri": "https://hotfintech/products/tracksheet/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://hotfintech/products/tracksheet/",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://hotfintech/products/tracksheet",
+ "revocationUri": "https://hotfintech/products/tracksheet/revoke",
+ "redirectUris": "https://hotfintech/products/tracksheet/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "c70456f3-843f-4407-a988-577c108a7816",
+ "legalEntityName": "ZeroFintech",
+ "logoUri": "https://zerofintech/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "98765987654",
+ "acn": "987659876",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR001004",
+ "accreditationLevelId": 1,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "ebbcc2f2-817e-42b8-8a28-cd45902159e0",
+ "brandName": "ZeroFintech",
+ "brandGroup": null,
+ "logoUri": "https://zerofintech/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-05T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "5d03d1a6-b83b-4176-a2f4-d0074a205695",
+ "softwareProductName": "Mortgage",
+ "softwareProductDescription": "calculate the mortgage value",
+ "logoUri": "https://zerofintech/products/mortgage/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://zerofintech/products/mortgage",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://zerofintech/products/mortgage",
+ "revocationUri": "https://zerofintech/products/mortgage/revocation",
+ "redirectUris": "https://zerofintech/products/mortgage/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ },
+ {
+ "softwareProductId": "dafa09db-4433-4203-907a-bdf797c8cd21",
+ "softwareProductName": "Reward program",
+ "softwareProductDescription": "Application to allow you to track your expenses",
+ "logoUri": "https://zerofintech//products/rewards/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://zerofintech/products/rewards",
+ "tosUri": null,
+ "policyUri": null,
+ "recipientBaseUri": "https://zerofintech/products/rewards",
+ "revocationUri": "https://hotfintech/products/rewards/revoke",
+ "redirectUris": "https://zerofintech/products/rewards/cb",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "legalEntityId": "de815a93-85b3-4fe8-9513-33ad8f4359d0",
+ "legalEntityName": "yoyo Software Company",
+ "logoUri": "https://yoyosoftware/img/logo.png",
+ "registrationNumber": null,
+ "registrationDate": null,
+ "registeredCountry": null,
+ "abn": "11222333444",
+ "acn": "222333444",
+ "arbn": null,
+ "anzsicDivision": null,
+ "organisationTypeId": null,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": "ADR000005",
+ "accreditationLevelId": 0,
+ "participations": [
+ {
+ "participationTypeId": 2,
+ "industryId": null,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "f3f0c40b-9df8-491a-af1d-81cb9ab5f021",
+ "brandName": "YoYo",
+ "brandGroup": null,
+ "logoUri": "https://yoyosoftware/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "softwareProducts": [
+ {
+ "softwareProductId": "6f7a1b8e-8799-48a8-9011-e3920391f713",
+ "softwareProductName": "MyBudgetHelper",
+ "softwareProductDescription": "A product to help you manage your budget",
+ "logoUri": "https://yoyosoftware/mybudgetapp/img/logo.png",
+ "sectorIdentifierUri": null,
+ "clientUri": "https://yoyosoftware/mybudgetapp",
+ "tosUri": "https://yoyosoftware/mybudgetapp/terms",
+ "policyUri": "https://yoyosoftware/mybudgetapp/policy",
+ "recipientBaseUri": "https://api.yoyosoftware/mybudgetapp",
+ "revocationUri": "https://api.yoyosoftware/mybudgetapp/revoke",
+ "redirectUris": "https://api.yoyosoftware/mybudgetapp/callback https://api.yoyosoftware/mybudgetapp/return",
+ "jwksUri": "https://localhost:7006/loopback/MockDataRecipientJwks",
+ "scope": "openid profile common:customer.basic:read common:customer.detail:read bank:accounts.basic:read bank:accounts.detail:read bank:transactions:read bank:regular_payments:read bank:payees:read energy:accounts.basic:read energy:accounts.detail:read energy:accounts.concessions:read energy:accounts.paymentschedule:read energy:billing:read energy:electricity.servicepoints.basic:read energy:electricity.servicepoints.detail:read energy:electricity.der:read energy:electricity.usage:read cdr:registration",
+ "statusId": 1,
+ "certificates": [
+ {
+ "commonName": "MockDataRecipient",
+ "thumbprint": "f0e5146a51f16e236844cf0353d791f11865e405"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 42b3174..b5b63fd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@

-[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.34.0/#introduction)
+[](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.36.0/#introduction)
[](https://dotnet.microsoft.com/)
[](https://docs.microsoft.com/en-us/dotnet/csharp/)
[](./LICENSE)
@@ -12,7 +12,7 @@ This project includes source code, documentation and instructions for the Consum
The ACCC operates the CDR Register within the CDR ecosystem. This repository contains a mock implementation of the CDR Register and is offered to help the community in the development and testing of their CDR solutions.
## Mock Register - Alignment
-The Mock Register aligns to [v1.34.0](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.34.0/#introduction) of the [Consumer Data Standards](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.34.0/#introduction).
+The Mock Register aligns to [v1.36.0](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.36.0/#introduction) of the [Consumer Data Standards](https://consumerdatastandardsaustralia.github.io/standards-archives/standards-1.36.0/#introduction).
## Getting Started
There are a number of ways that the artefacts within this project can be used:
diff --git a/Source/.editorconfig b/Source/.editorconfig
index 33cd81c..0d14e5e 100644
--- a/Source/.editorconfig
+++ b/Source/.editorconfig
@@ -169,7 +169,22 @@ dotnet_diagnostic.SA1601.severity = none
dotnet_diagnostic.S6960.severity = none
# In the context of ASP.NET Core MVC web applications, both model binding and model validation are processes that take place prior to the execution of a controller action.
dotnet_diagnostic.S6967.severity = none
+csharp_style_prefer_null_check_over_type_check = true:suggestion
+
+# Allow endpoint versions to be marked as obsolete to hint they need to be cleaned up eventually without blocking the build as we need to maintain parity with the real register
+# S1133: Deprecated code should be removed
+dotnet_diagnostic.S1133.severity = suggestion
[Program.cs]
# Using platform dependent API on a component makes the code no longer work across all platforms.
dotnet_diagnostic.CA1416.severity = none
+
+
+# Allow model / mapping classes to be marked as obsolete to hint they need to be cleaned up
+# but not block the build as we will need to maintain this obsolete functionality to match the real register
+[**/Business/**.cs]
+# S1133: Deprecated code should be removed
+dotnet_diagnostic.S1133.severity = suggestion
+
+# CS0618: Type or member is obsolete
+dotnet_diagnostic.CS0618.severity = suggestion
\ No newline at end of file
diff --git a/Source/.trivyignore b/Source/.trivyignore
new file mode 100644
index 0000000..ba80870
--- /dev/null
+++ b/Source/.trivyignore
@@ -0,0 +1,3 @@
+# AutoMapper Vulnerable to Denial of Service (DoS) via Uncontrolled Recursion
+CVE-2026-32933 # (workaround applied, licensing for new version underway)
+GHSA-rvv3-g6hj-g44x # same as above
\ No newline at end of file
diff --git a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Models/CdrApiOptionsTests.cs b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Models/CdrApiOptionsTests.cs
new file mode 100644
index 0000000..4fb80f7
--- /dev/null
+++ b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Models/CdrApiOptionsTests.cs
@@ -0,0 +1,82 @@
+using CDR.Register.API.Infrastructure.Models;
+using Xunit;
+
+namespace CDR.Register.API.Infrastructure.Tests.UnitTests.Models
+{
+ [Trait("Category", "UnitTests")]
+ public partial class CdrApiOptionsTests
+ {
+ // DH Brands Endpoint Versions
+ public const int DhBrandsVersionMin = 2;
+ public const int DhBrandsVersionMax = 3;
+
+ // DH Status Endpoint Versions
+ public const int DhStatusVersionMin = 1;
+ public const int DhStatusVersionMax = 2;
+
+ // ADR Endpoint Versions
+ public const int AdrVersionMin = 3;
+ public const int AdrVersionMax = 4;
+
+ // ADR Status Endpoint Versions
+ public const int AdrStatusVersionMin = 2;
+ public const int AdrStatusVersionMax = 3;
+
+ // ADR Software Product Status Endpoint Versions
+ public const int AdrSoftwareProductStatusVersionMin = 2;
+ public const int AdrSoftwareProductStatusVersionMax = 3;
+
+ // ADR SSA
+ public const int AdrSsaVersionMin = 3;
+ public const int AdrSsaVersionMax = 4;
+
+ private readonly CdrApiOptions _underTest = new();
+
+#pragma warning disable SA1515 // Single-line comment should be preceded by blank line
+ [Theory]
+ // DH Brands
+ [InlineData("/cdr-Register/v1/all/data-holders/brands", DhBrandsVersionMin, DhBrandsVersionMax)]
+ [InlineData("/cdr-register/v1/Banking/data-holders/brands", DhBrandsVersionMin, DhBrandsVersionMax)]
+ [InlineData("/cdr-register/v1/energy/Data-Holders/brands", DhBrandsVersionMin, DhBrandsVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-holders/Brands", DhBrandsVersionMin, DhBrandsVersionMax)]
+ [InlineData("/cdr-register/v1/telco/data-holders/brands", DhBrandsVersionMin, DhBrandsVersionMax)]
+ // DH Status
+ [InlineData("/CDR-register/v1/all/data-holders/status", DhStatusVersionMin, DhStatusVersionMax)]
+ [InlineData("/cdr-register/v1/banking/Data-Holders/status", DhStatusVersionMin, DhStatusVersionMax)]
+ [InlineData("/cdr-register/v1/Energy/data-holders/status", DhStatusVersionMin, DhStatusVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-holders/Status", DhStatusVersionMin, DhStatusVersionMax)]
+ [InlineData("/cdr-register/V1/telco/data-holders/status", DhStatusVersionMin, DhStatusVersionMax)]
+ // Adr
+ [InlineData("/CDR-register/v1/all/data-recipients", AdrVersionMin, AdrVersionMax)]
+ [InlineData("/cdr-register/v1/banking/Data-Recipients", AdrVersionMin, AdrVersionMax)]
+ [InlineData("/cdr-register/v1/Energy/data-recipients", AdrVersionMin, AdrVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-recipients", AdrVersionMin, AdrVersionMax)]
+ [InlineData("/cdr-register/V1/telco/data-recipients", AdrVersionMin, AdrVersionMax)]
+ // ADR Status
+ [InlineData("/CDR-register/v1/all/data-recipients/status", AdrStatusVersionMin, AdrStatusVersionMax)]
+ [InlineData("/cdr-register/v1/banking/Data-Recipients/status", AdrStatusVersionMin, AdrStatusVersionMax)]
+ [InlineData("/cdr-register/v1/Energy/data-recipients/status", AdrStatusVersionMin, AdrStatusVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-recipients/Status", AdrStatusVersionMin, AdrStatusVersionMax)]
+ [InlineData("/cdr-register/V1/telco/data-recipients/status", AdrStatusVersionMin, AdrStatusVersionMax)]
+ // ADR Software Product Status
+ [InlineData("/CDR-register/v1/all/data-recipients/brands/software-products/status", AdrSoftwareProductStatusVersionMin, AdrSoftwareProductStatusVersionMax)]
+ [InlineData("/cdr-register/v1/banking/Data-Recipients/brands/software-products/status", AdrSoftwareProductStatusVersionMin, AdrSoftwareProductStatusVersionMax)]
+ [InlineData("/cdr-register/v1/Energy/data-recipients/brands/software-products/status", AdrSoftwareProductStatusVersionMin, AdrSoftwareProductStatusVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-recipients/Brands/software-products/Status", AdrSoftwareProductStatusVersionMin, AdrSoftwareProductStatusVersionMax)]
+ [InlineData("/cdr-register/V1/telco/data-recipients/brands/Software-Products/status", AdrSoftwareProductStatusVersionMin, AdrSoftwareProductStatusVersionMax)]
+ // ADR SSA
+ [InlineData("/CDR-register/v1/all/data-recipients/brands/da7da031-ad91-449e-83e6-d07e7328ef66/software-products/69A28fF3-413F-4255-aF86-3Bd6df7f6Bc3/ssa", AdrSsaVersionMin, AdrSsaVersionMax)]
+ [InlineData("/cdr-register/v1/banking/Data-Recipients/brands/da7da031-ad91-449e-83e6-d07e7328ef66/software-products/69A28FF3-413F-4255-AF86-3BD6DF7F6BC3/ssa", AdrSsaVersionMin, AdrSsaVersionMax)]
+ [InlineData("/cdr-register/v1/non-bank-lending/data-recipients/Brands/DA7DA031-AD91-449E-83E6-D07E7328EF66/software-products/69a28ff3-413f-4255-af86-3bd6df7f6bc3/ssa", AdrSsaVersionMin, AdrSsaVersionMax)]
+ [InlineData("/cdr-register/V1/telco/data-recipients/brands/da7da031-ad91-449e-83e6-d07e7328ef66/Software-Products/69a28ff3-413f-4255-af86-3bd6df7f6bc3/ssa", AdrSsaVersionMin, AdrSsaVersionMax)]
+#pragma warning restore SA1515 // Single-line comment should be preceded by blank line
+ public void GetApiEndpointVersionOption_ShouldReturnEndpoint(string path, int min, int max)
+ {
+ var result = this._underTest.GetApiEndpointVersionOption(path);
+ Assert.NotNull(result);
+ Assert.True(result.IsVersioned);
+ Assert.Equal(result.CurrentMinVersion, min);
+ Assert.Equal(result.CurrentMaxVersion, max);
+ }
+ }
+}
diff --git a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
index 3ec7fad..67a62aa 100644
--- a/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
+++ b/Source/CDR.Register.API.Infrastructure.Tests.UnitTests/Versioning/CdrVersionReaderTests.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using CDR.Register.API.Infrastructure.Models;
using CDR.Register.API.Infrastructure.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
@@ -15,8 +16,8 @@ public partial class CdrVersionReaderTests
public void Read_DataHolderStatus_NoXvHeader_ShouldReturn1()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "1";
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["1"];
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/status"));
@@ -32,11 +33,13 @@ public void Read_DataHolderStatus_NoXvHeader_ShouldReturn1()
public void Read_DataHolderStatus_EmptyXvHeader_ShouldReturn1()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "1";
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["1"];
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues(string.Empty));
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues(string.Empty) },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/status"));
@@ -54,151 +57,164 @@ public void Read_DataHolderStatus_EmptyXvHeader_ShouldReturn1()
public void Read_NoXvHeader_ShouldReturnMissingVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
- var expectedVersion = "Missing Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_EmptyXvHeader_ShouldReturnMissingVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues(string.Empty));
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues(string.Empty) },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Missing Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_NullXvHeader_ShouldReturnMissingVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", default);
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", default },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Missing Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_InvalidXvHeader_ShouldReturnInvalidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("foo"));
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("foo") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Invalid Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_SetToZeroXvHeader_ShouldReturnInvalidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("0"));
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("0") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Invalid Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_LessThanZeroXvHeader_ShouldReturnInvalidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("-1"));
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("-1") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Invalid Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-v", ex.HeaderName);
}
[Fact]
public void Read_GreaterThanMaxXvHeader_ShouldReturnUnsupportedVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("99"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("99") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Unsupported Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ Assert.Throws(action);
}
[Fact]
public void Read_ValidXvHeader_ShouldReturnValidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "2";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("2"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["2"];
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("2") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
@@ -216,10 +232,12 @@ public void Read_ValidXvHeader_ShouldReturnValidVersion()
public void Read_UppercaseXvHeader_ShouldReturnValidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "2";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("X-V", new StringValues("2"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["2"];
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "X-V", new StringValues("2") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-holders/brands"));
@@ -237,10 +255,12 @@ public void Read_UppercaseXvHeader_ShouldReturnValidVersion()
public void Read_InvalidPath_ShouldReturn1()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "1";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("X-V", new StringValues("1"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["1"];
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "X-V", new StringValues("1") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/invalid/path"));
@@ -258,11 +278,13 @@ public void Read_InvalidPath_ShouldReturn1()
public void Read_WithRange_ShouldReturnMaxVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "3";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("4"));
- mockHttpHeaders.Add("x-min-v", new StringValues("3"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["4"];
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("5") },
+ { "x-min-v", new StringValues("4") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-recipients"));
@@ -280,11 +302,14 @@ public void Read_WithRange_ShouldReturnMaxVersion()
public void Read_WithUppercaseXminV_ShouldReturnMaxVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "3";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("4"));
- mockHttpHeaders.Add("X-MIN-V", new StringValues("3"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["4"];
+
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("5") },
+ { "X-MIN-V", new StringValues("4") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-recipients"));
@@ -302,11 +327,13 @@ public void Read_WithUppercaseXminV_ShouldReturnMaxVersion()
public void Read_XminVGreaterThanXV_ShouldBeIgnored()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var expectedVersion = "3";
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("3"));
- mockHttpHeaders.Add("x-min-v", new StringValues("4"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ IReadOnlyCollection expectedVersion = ["3"];
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("3") },
+ { "x-min-v", new StringValues("4") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-recipients"));
@@ -324,42 +351,45 @@ public void Read_XminVGreaterThanXV_ShouldBeIgnored()
public void Read_InvalidRange_ShouldReturnUnsupportedVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("5"));
- mockHttpHeaders.Add("x-min-v", new StringValues("4"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("6") },
+ { "x-min-v", new StringValues("5") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-recipients"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Unsupported Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ Assert.Throws(action);
}
[Fact]
public void Read_ValidXvInvalidXminV_ShouldReturnInvalidVersion()
{
// Arrange.
- var apiVersionReader = new CdrVersionReader(new Models.CdrApiOptions());
- var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase));
- mockHttpHeaders.Add("x-v", new StringValues("3"));
- mockHttpHeaders.Add("x-min-v", new StringValues("foo"));
+ var apiVersionReader = new CdrVersionReader(new CdrApiOptions());
+ var mockHttpHeaders = new HeaderDictionary(new Dictionary(StringComparer.OrdinalIgnoreCase))
+ {
+ { "x-v", new StringValues("3") },
+ { "x-min-v", new StringValues("foo") },
+ };
var mockHttpRequest = Substitute.For();
mockHttpRequest.Path.Returns(new PathString("/cdr-register/v1/all/data-recipients"));
mockHttpRequest.Headers.Returns(mockHttpHeaders);
- var expectedVersion = "Invalid Version";
// Act.
- var actualVersion = apiVersionReader.Read(mockHttpRequest);
+ var action = () => apiVersionReader.Read(mockHttpRequest);
// Assert.
- Assert.Equal(expectedVersion, actualVersion);
+ var ex = Assert.Throws(action);
+ Assert.Equal("x-min-v", ex.HeaderName);
}
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj b/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
index 14df0a6..3523833 100644
--- a/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
+++ b/Source/CDR.Register.API.Infrastructure/CDR.Register.API.Infrastructure.csproj
@@ -16,7 +16,7 @@
true
-
+
true
diff --git a/Source/CDR.Register.API.Infrastructure/Configuration/ConfigureSwaggerOptions.cs b/Source/CDR.Register.API.Infrastructure/Configuration/ConfigureSwaggerOptions.cs
index ba9275b..bd38fd7 100644
--- a/Source/CDR.Register.API.Infrastructure/Configuration/ConfigureSwaggerOptions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Configuration/ConfigureSwaggerOptions.cs
@@ -1,5 +1,5 @@
-using CDR.Register.API.Infrastructure.Models;
-using Microsoft.AspNetCore.Mvc.ApiExplorer;
+using Asp.Versioning.ApiExplorer;
+using CDR.Register.API.Infrastructure.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerGen;
diff --git a/Source/CDR.Register.API.Infrastructure/Extensions.cs b/Source/CDR.Register.API.Infrastructure/Extensions.cs
index d6551f8..ef52dc5 100644
--- a/Source/CDR.Register.API.Infrastructure/Extensions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Extensions.cs
@@ -7,10 +7,14 @@
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Asp.Versioning;
+using Asp.Versioning.ApiExplorer;
using CDR.Register.API.Infrastructure.Authorization;
using CDR.Register.API.Infrastructure.Configuration;
using CDR.Register.API.Infrastructure.Models;
using CDR.Register.API.Infrastructure.SwaggerFilters;
+using CDR.Register.API.Infrastructure.Versioning;
+using CDR.Register.Domain.Extensions;
using CDR.Register.Repository.Infrastructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
@@ -67,7 +71,7 @@ public static bool ValidateIssuer(this HttpContext context)
return false;
}
- // For a stronger match validating dynamic base path with an conformance ID instead of confromanceId only
+ // For a stronger match validating dynamic base path with an conformance ID rather than only the ID
return issuer?.Contains(context.Request.PathBase) ?? false;
}
@@ -166,7 +170,7 @@ public static void AddAuthenticationAuthorization(this IServiceCollection servic
{
var allAuthPolicies = AuthorisationPolicies.GetAllPolicies();
- // Apply all listed policities from a single source of truth that is also used for self-documentation
+ // Apply all listed policies from a single source of truth that is also used for self-documentation
foreach (var pol in allAuthPolicies)
{
options.AddPolicy(pol.Name, policy =>
@@ -316,16 +320,20 @@ public static string GetHostNameAsUri(this ControllerBase controller, IConfigura
return new Uri(url.Replace(currentHost, newHostName));
}
+ ///
+ /// Converts to an value.
+ ///
+ /// The industry string.
+ /// The appropriate enumeration value.
+ /// Thrown when the provided industry cannot be matched to an enum value.
public static Industry ToIndustry(this string industry)
{
- if (Enum.IsDefined(typeof(Industry), industry.ToUpper()))
- {
- return (Industry)Enum.Parse(typeof(Industry), industry, true);
- }
- else
+ if (EnumExtensions.TryParseFromDescription(industry, out var value))
{
- throw new NotSupportedException($"Invalid industry: {industry}");
+ return value;
}
+
+ throw new NotSupportedException($"Invalid industry: {industry}");
}
public static IEnumerable GetValueAsList(this IConfiguration configuration, string key, string delimiter)
@@ -425,6 +433,28 @@ public static string GetCommonNameFromDistinguishedName(this string distinguishe
}
}
+ ///
+ /// Add CDR-specific API versioning and API explorer.
+ ///
+ /// The services.
+ /// Additional setup actions to configure beyond the default settings.
+ /// Additional setup actions to configure beyond the default settings.
+ /// The versioning builder.
+ public static IApiVersioningBuilder AddCdrApiVersioning(this IServiceCollection services, Action? setupVersioningAction = null, Action? setupExplorerAction = null)
+ {
+ return services
+ .AddApiVersioning(options =>
+ {
+ options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); // uses default options atm
+ setupVersioningAction?.Invoke(options);
+ })
+ .AddApiExplorer(options =>
+ {
+ options.GroupNameFormat = Constants.Versioning.GroupNameFormat;
+ setupExplorerAction?.Invoke(options);
+ });
+ }
+
public static IServiceCollection AddCdrSwaggerGen(this IServiceCollection services, Action configureRegisterSwaggerOptions, bool isVersioned = true)
{
var options = new CdrSwaggerOptions();
@@ -435,12 +465,6 @@ public static IServiceCollection AddCdrSwaggerGen(this IServiceCollection servic
if (isVersioned)
{
services.AddTransient, ConfigureSwaggerOptions>();
-
- // Required for our Swagger setup to work when endpoints have been versioned
- services.AddVersionedApiExplorer(opt =>
- {
- opt.GroupNameFormat = options.VersionedApiGroupNameFormat;
- });
}
else
{
@@ -459,6 +483,7 @@ public static IServiceCollection AddCdrSwaggerGen(this IServiceCollection servic
c.SchemaFilter();
c.OperationFilter();
c.OperationFilter();
+ c.OperationFilter();
if (options.IncludeAuthentication)
{
diff --git a/Source/CDR.Register.API.Infrastructure/Extensions/CdrSwaggerMiddlewareExtensions.cs b/Source/CDR.Register.API.Infrastructure/Extensions/CdrSwaggerMiddlewareExtensions.cs
index 3fd94ac..0780669 100644
--- a/Source/CDR.Register.API.Infrastructure/Extensions/CdrSwaggerMiddlewareExtensions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Extensions/CdrSwaggerMiddlewareExtensions.cs
@@ -1,6 +1,6 @@
using System.Linq;
+using Asp.Versioning.ApiExplorer;
using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
namespace CDR.Register.API.Infrastructure
diff --git a/Source/CDR.Register.API.Infrastructure/Filters/CheckIndustryAttribute.cs b/Source/CDR.Register.API.Infrastructure/Filters/CheckIndustryAttribute.cs
index 4ed0ec8..99e88aa 100644
--- a/Source/CDR.Register.API.Infrastructure/Filters/CheckIndustryAttribute.cs
+++ b/Source/CDR.Register.API.Infrastructure/Filters/CheckIndustryAttribute.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using CDR.Register.Domain.Extensions;
using CDR.Register.Domain.Models;
using CDR.Register.Repository.Infrastructure;
using Microsoft.AspNetCore.Mvc;
@@ -7,23 +9,36 @@
namespace CDR.Register.API.Infrastructure.Filters
{
///
- /// Checks the industry parameter is supported, if not then responds with BadRequest and appropriate ResponseErrorList.
+ /// Checks the industry parameter(s) are supported, if not then responds with and appropriate payload.
///
+ /// The industry parameter is case-insensitive.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class CheckIndustryAttribute : ActionFilterAttribute
{
- private readonly string _industryRestriction;
-
+ ///
+ /// Initializes a new instance of the class, configured to allow any valid industry.
+ ///
public CheckIndustryAttribute()
{
- this._industryRestriction = string.Empty;
+ this.IndustryRestrictions = [];
}
- public CheckIndustryAttribute(Industry industryRestriction)
+ ///
+ /// Initializes a new instance of the class, configured to only allow industries specified in .
+ ///
+ /// The specific industries this endpoint allows.
+ public CheckIndustryAttribute(params Industry[] industryRestrictions)
{
- this._industryRestriction = industryRestriction.ToString().ToUpper();
+ this.IndustryRestrictions = industryRestrictions;
}
+ public Industry[] IndustryRestrictions { get; }
+
+ ///
+ /// Validate that the industry provided is allowed based on the industry restrictions configured for this instance.
+ ///
+ /// Changes the action result to a with an appropriate error message if the industry is not allowed.
+ /// The executing action context.
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ActionArguments["industry"] is string industry && !this.IsValidIndustry(industry))
@@ -34,6 +49,17 @@ public override void OnActionExecuting(ActionExecutingContext context)
base.OnActionExecuting(context);
}
+ ///
+ /// Validate the industry provided is:
+ ///
+ /// - not null
+ /// - a valid industry
+ /// - allowed based on restrictions
+ ///
+ ///
+ /// The industry requested.
+ /// Industry value is case-insensitive.
+ /// A flag indicating if the industry is valid, and allowed.
private bool IsValidIndustry(string industry)
{
// Industry needs to be provided.
@@ -43,13 +69,13 @@ private bool IsValidIndustry(string industry)
}
// Convert the incoming industry value to an enum.
- if (!Enum.TryParse(industry.ToUpper(), out Industry industryItem))
+ if (!EnumExtensions.TryParseFromDescription(industry, out Industry industryItem))
{
return false;
}
- // Check that the incoming industry matches the industry restriction, if set.
- if (!string.IsNullOrEmpty(this._industryRestriction) && !string.Equals(this._industryRestriction, industryItem.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // Check that the incoming industry matches the industry restriction, if any are specified.
+ if (this.IndustryRestrictions.Any() && !this.IndustryRestrictions.Contains(industryItem))
{
return false;
}
diff --git a/Source/CDR.Register.API.Infrastructure/Middleware/ApiExceptionHandler.cs b/Source/CDR.Register.API.Infrastructure/Middleware/ApiExceptionHandler.cs
index 714fa3f..7d10161 100644
--- a/Source/CDR.Register.API.Infrastructure/Middleware/ApiExceptionHandler.cs
+++ b/Source/CDR.Register.API.Infrastructure/Middleware/ApiExceptionHandler.cs
@@ -1,4 +1,5 @@
-using System.Net;
+using System;
+using System.Net;
using System.Threading.Tasks;
using CDR.Register.API.Infrastructure.Versioning;
using CDR.Register.Domain.Models;
@@ -12,53 +13,47 @@ namespace CDR.Register.API.Infrastructure.Middleware
{
public static class ApiExceptionHandler
{
+ private static readonly JsonSerializerSettings SerializerSettings = new()
+ {
+ Formatting = Formatting.Indented,
+ NullValueHandling = NullValueHandling.Ignore,
+ ContractResolver = new DefaultContractResolver
+ {
+ NamingStrategy = new CamelCaseNamingStrategy(),
+ },
+ };
+
public static async Task Handle(HttpContext context)
{
var exceptionDetails = context.Features.Get();
var ex = exceptionDetails?.Error;
- if (ex != null)
+ if (ex == null)
{
- var handledError = string.Empty;
- var statusCode = (int)HttpStatusCode.BadRequest;
- var jsonSerializerSettings = new JsonSerializerSettings()
- {
- Formatting = Formatting.Indented,
- NullValueHandling = NullValueHandling.Ignore,
- ContractResolver = new DefaultContractResolver
- {
- NamingStrategy = new CamelCaseNamingStrategy(),
- },
- };
+ return;
+ }
- if (ex is InvalidVersionException)
- {
- statusCode = (int)HttpStatusCode.BadRequest;
- handledError = JsonConvert.SerializeObject(new ResponseErrorList().AddInvalidXVInvalidVersion(), jsonSerializerSettings);
- }
+ (HttpStatusCode statusCode, ResponseErrorList errors) = ex switch
+ {
+ InvalidVersionException =>
+ (HttpStatusCode.BadRequest, new ResponseErrorList().AddInvalidXVInvalidVersion()),
+
+ UnsupportedVersionException =>
+ (HttpStatusCode.NotAcceptable, new ResponseErrorList().AddInvalidXVUnsupportedVersion()),
- if (ex is UnsupportedVersionException)
- {
- statusCode = (int)HttpStatusCode.NotAcceptable;
- handledError = JsonConvert.SerializeObject(new ResponseErrorList().AddInvalidXVUnsupportedVersion(), jsonSerializerSettings);
- }
+ MissingRequiredHeaderException missingRequiredHeaderException when missingRequiredHeaderException?.HeaderName == Headers.X_V =>
+ (HttpStatusCode.BadRequest, new ResponseErrorList().AddInvalidXVMissingRequiredHeader()),
- if (ex.GetType() == typeof(MissingRequiredHeaderException))
- {
- var missingRequiredHeaderException = ex as MissingRequiredHeaderException;
- if (missingRequiredHeaderException?.HeaderName == Headers.X_V)
- {
- statusCode = (int)HttpStatusCode.BadRequest;
- handledError = JsonConvert.SerializeObject(new ResponseErrorList().AddInvalidXVMissingRequiredHeader(), jsonSerializerSettings);
- }
- }
+ _ =>
+ (HttpStatusCode.InternalServerError, new ResponseErrorList().AddUnexpectedError()),
+ };
- if (!string.IsNullOrEmpty(handledError))
- {
- context.Response.StatusCode = statusCode;
- context.Response.ContentType = "application/json";
- await context.Response.WriteAsync(handledError).ConfigureAwait(false);
- }
+ if (errors.HasErrors())
+ {
+ var handledError = JsonConvert.SerializeObject(errors, SerializerSettings);
+ context.Response.StatusCode = (int)statusCode;
+ context.Response.ContentType = "application/json";
+ await context.Response.WriteAsync(handledError).ConfigureAwait(false);
}
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Models/CdrApiOptions.cs b/Source/CDR.Register.API.Infrastructure/Models/CdrApiOptions.cs
index 56fb2bc..f15fff8 100644
--- a/Source/CDR.Register.API.Infrastructure/Models/CdrApiOptions.cs
+++ b/Source/CDR.Register.API.Infrastructure/Models/CdrApiOptions.cs
@@ -6,25 +6,28 @@ namespace CDR.Register.API.Infrastructure.Models
{
public class CdrApiOptions
{
- private static readonly List _supportedApiVersions = new List
- {
- // (?i) is to make the regex case insensitive
- // (%7B)* and (%7D)* represent the possibility of a { and } in the path, to cover the value '{industry}' for OAS generation purposes
+ private const string Id = @"[A-Za-z0-9\-]*"; // any letter, number, or hyphen
+ private const string Industry = @"(%7B)*[A-Za-z-]*(%7D)*"; // (%7B)* and (%7D)* represent the possibility of a { and } in the path, to cover the value '{industry}' for OAS generation purposes
+ private const string BasePathV1 = @$"\/cdr-register\/v1\/{Industry}";
+ private const string AdminBasePath = @"\/admin";
- // Register
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-holders\/brands", true, 2),
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-holders\/status", false, 1),
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-recipients", true, 3),
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-recipients\/status", true, 2),
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-recipients\/brands\/software-products\/status", true, 2),
- new CdrApiEndpointVersionOptions(@"(?i)\/cdr-register\/v1\/(%7B)*[A-Za-z]*(%7D)*\/data-recipients\/brands\/[A-Za-z0-9\-]*\/software-products\/[A-Za-z0-9\-]*\/ssa", true, 3),
+ private static readonly CdrApiEndpointVersionOptions[] _supportedApiVersions =
+ [
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-holders\/brands", true, 2, 3, 3),
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-holders\/status", false, 1, 2, 2), // This is intentionally not enforcing x-v header to be mandatory inline with v1 of the standards, if v1 becomes obsolete isXvMandatory should be true.
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-recipients", true, 3, 4, 4),
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-recipients\/status", true, 2, 3, 3),
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-recipients\/brands\/software-products\/status", true, 2, 3, 3),
+ new CdrApiEndpointVersionOptions(@$"{BasePathV1}\/data-recipients\/brands\/{Id}\/software-products\/{Id}\/ssa", true, 3, 4, 4),
+ ];
- // Admin
- new CdrApiEndpointVersionOptions(@"(?i)\/admin\/metadata\/data-holders", true, 1),
- new CdrApiEndpointVersionOptions(@"(?i)\/admin\/metadata\/data-recipients", true, 1),
- };
+ private static readonly CdrApiEndpointVersionOptions[] _supportedAdminVersions =
+ [
+ new CdrApiEndpointVersionOptions(@$"{AdminBasePath}\/metadata\/data-holders", true, 1),
+ new CdrApiEndpointVersionOptions(@$"{AdminBasePath}\/metadata\/data-recipients", true, 1),
+ ];
- public List EndpointVersionOptions { get; } = _supportedApiVersions;
+ public List EndpointVersionOptions { get; } = [.. _supportedApiVersions, .. _supportedAdminVersions];
public string DefaultVersion { get; set; } = "1";
@@ -32,7 +35,7 @@ public class CdrApiOptions
{
foreach (var supportedApi in this.EndpointVersionOptions.OrderByDescending(v => v.Path.Length))
{
- var regEx = new System.Text.RegularExpressions.Regex(supportedApi.Path);
+ var regEx = new System.Text.RegularExpressions.Regex(supportedApi.Path, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if (regEx.IsMatch(path))
{
return supportedApi;
diff --git a/Source/CDR.Register.API.Infrastructure/Models/JsonWebKey.cs b/Source/CDR.Register.API.Infrastructure/Models/JsonWebKey.cs
index 182393a..92fcf1e 100644
--- a/Source/CDR.Register.API.Infrastructure/Models/JsonWebKey.cs
+++ b/Source/CDR.Register.API.Infrastructure/Models/JsonWebKey.cs
@@ -1,35 +1,41 @@
-using System;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
namespace CDR.Register.API.Infrastructure.Models
{
public class JsonWebKey
{
- [JsonProperty("alg")]
- public string Alg { get; set; } = string.Empty;
+ [JsonProperty("alg", NullValueHandling = NullValueHandling.Ignore)]
+ public string? Alg { get; set; } = null;
- [JsonProperty("e")]
- public string E { get; set; } = string.Empty;
+ [JsonProperty("e", NullValueHandling = NullValueHandling.Ignore)]
+ public string? E { get; set; } = null;
[JsonProperty("key_ops")]
- public string[] Key_ops { get; set; } = [];
+ public string[]? Key_ops { get; set; } = null;
- [JsonProperty("kid")]
- public string Kid { get; set; } = string.Empty;
+ [JsonProperty("kid", NullValueHandling = NullValueHandling.Ignore)]
+ public string? Kid { get; set; } = null;
- [JsonProperty("kty")]
+ [JsonProperty("kty", Required = Required.Always)]
public string Kty { get; set; } = string.Empty;
- [JsonProperty("n")]
- public string N { get; set; } = string.Empty;
+ [JsonProperty("n", NullValueHandling = NullValueHandling.Ignore)]
+ public string? N { get; set; } = null;
- [JsonProperty("use")]
- public string Use { get; set; } = string.Empty;
+ [JsonProperty("use", NullValueHandling = NullValueHandling.Ignore)]
+ public string? Use { get; set; } = null;
- [JsonProperty("x5t")]
- public string X5t { get; set; } = string.Empty;
+ [JsonProperty("x5t", NullValueHandling = NullValueHandling.Ignore)]
+ public string? X5t { get; set; } = null;
[JsonProperty("x5c")]
- public string[] X5c { get; set; } = [];
+ public string[]? X5c { get; set; } = null;
+
+ // -------------------------
+ // Serialization controls
+ // -------------------------
+ public bool ShouldSerializeKey_ops() => this.Key_ops is { Length: > 0 };
+
+ public bool ShouldSerializeX5c() => this.X5c is { Length: > 0 };
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Services/DataRecipientStatusCheckService.cs b/Source/CDR.Register.API.Infrastructure/Services/DataRecipientStatusCheckService.cs
index 9c21282..d9faff1 100644
--- a/Source/CDR.Register.API.Infrastructure/Services/DataRecipientStatusCheckService.cs
+++ b/Source/CDR.Register.API.Infrastructure/Services/DataRecipientStatusCheckService.cs
@@ -26,7 +26,7 @@ public DataRecipientStatusCheckService(IRegisterDiscoveryRepository registerDisc
public async Task ValidateSoftwareProductStatus(Guid softwareProductId)
{
// Get the latest data recipient details from the repository
- var softwareProduct = await this._registerDiscoveryRepository.GetSoftwareProductIdAsync(softwareProductId);
+ var softwareProduct = await this._registerDiscoveryRepository.GetSoftwareProductId(softwareProductId);
// Perform validations
ResponseErrorList errorList = new ResponseErrorList();
diff --git a/Source/CDR.Register.API.Infrastructure/SwaggerFilters/IndustryParamsOperationFilter.cs b/Source/CDR.Register.API.Infrastructure/SwaggerFilters/IndustryParamsOperationFilter.cs
new file mode 100644
index 0000000..369a0e1
--- /dev/null
+++ b/Source/CDR.Register.API.Infrastructure/SwaggerFilters/IndustryParamsOperationFilter.cs
@@ -0,0 +1,27 @@
+using System.Linq;
+using System.Reflection;
+using CDR.Register.Domain.Extensions;
+using Microsoft.OpenApi.Any;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+
+namespace CDR.Register.API.Infrastructure.SwaggerFilters
+{
+ public class IndustryParamsOperationFilter : IOperationFilter
+ {
+ public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ {
+ foreach (var s in operation.Parameters.Where(o => o.Name == "industry"))
+ {
+ var checkIndustries = context.MethodInfo.GetCustomAttributes().SingleOrDefault();
+
+ if (checkIndustries != null)
+ {
+ var examples = checkIndustries.IndustryRestrictions.Select(x => new OpenApiString(EnumExtensions.GetDescription(x)));
+
+ s.Schema.Enum = [..examples];
+ }
+ }
+ }
+ }
+}
diff --git a/Source/CDR.Register.API.Infrastructure/SwaggerFilters/SetupApiVersionParamsOperationFilter.cs b/Source/CDR.Register.API.Infrastructure/SwaggerFilters/SetupApiVersionParamsOperationFilter.cs
index 508f3ce..81fbbf6 100644
--- a/Source/CDR.Register.API.Infrastructure/SwaggerFilters/SetupApiVersionParamsOperationFilter.cs
+++ b/Source/CDR.Register.API.Infrastructure/SwaggerFilters/SetupApiVersionParamsOperationFilter.cs
@@ -1,8 +1,11 @@
using System.Linq;
using CDR.Register.API.Infrastructure.Models;
+using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Options;
+using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
+using static CDR.Register.API.Infrastructure.Constants;
namespace CDR.Register.API.Infrastructure.SwaggerFilters
{
@@ -19,13 +22,34 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var versionOption = this._options.GetApiEndpointVersionOption($"/{context.ApiDescription.RelativePath}");
- foreach (var s in operation.Parameters.Where(o => o.Name == "x-v" || o.Name == "x-min-v"))
+ foreach (var s in operation.Parameters.Where(o => o.Name == Headers.X_V || o.Name == Headers.X_MIN_V))
{
s.Required = false;
- if (versionOption != null && versionOption.IsXVHeaderMandatory && s.Name == "x-v")
+ var apiVersion = context.ApiDescription.GetApiVersion();
+
+ switch (s.Name)
{
- s.Required = true;
+ case Headers.X_V:
+ if (versionOption?.IsXVHeaderMandatory == true)
+ {
+ s.Required = true;
+ }
+
+ if (apiVersion != null)
+ {
+ s.Example = new OpenApiString(apiVersion.MajorVersion.ToString());
+ }
+
+ break;
+
+ case Headers.X_MIN_V:
+ if (versionOption != null)
+ {
+ s.Example = new OpenApiString(versionOption.CurrentMinVersion.ToString());
+ }
+
+ break;
}
}
}
diff --git a/Source/CDR.Register.API.Infrastructure/Versioning/ApiVersionErrorResponse.cs b/Source/CDR.Register.API.Infrastructure/Versioning/ApiVersionErrorResponse.cs
deleted file mode 100644
index 640c461..0000000
--- a/Source/CDR.Register.API.Infrastructure/Versioning/ApiVersionErrorResponse.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using CDR.Register.Domain.Models;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Versioning;
-using Microsoft.Extensions.Logging;
-
-namespace CDR.Register.API.Infrastructure.Versioning
-{
- public class ApiVersionErrorResponse : DefaultErrorResponseProvider
- {
- private readonly ILogger _logger;
-
- public ApiVersionErrorResponse()
- {
- this._logger = new LoggerFactory().CreateLogger();
- }
-
- public override IActionResult CreateResponse(ErrorResponseContext context)
- {
- var errorList = new ResponseErrorList();
- int statusCode;
-
- // Determine what the return status code and message will be, default to 500 - Internal Server Error
- if (context.Message.Contains(Domain.Constants.ErrorTitles.MissingVersion))
- {
- errorList.AddInvalidXVMissingRequiredHeader();
- statusCode = StatusCodes.Status400BadRequest;
- }
- else if (context.Message.Contains(Domain.Constants.ErrorTitles.InvalidVersion))
- {
- errorList.AddInvalidXVInvalidVersion();
- statusCode = StatusCodes.Status400BadRequest;
- }
- else if (context.Message.Contains(Domain.Constants.ErrorTitles.UnsupportedVersion))
- {
- errorList.AddInvalidXVUnsupportedVersion();
- statusCode = StatusCodes.Status406NotAcceptable;
- }
- else
- {
- errorList.AddUnexpectedError();
- statusCode = StatusCodes.Status500InternalServerError;
- }
-
- this._logger.LogError("Error detail {Detail}", errorList.Errors[0].Detail);
-
- return new ObjectResult(errorList) { StatusCode = statusCode };
- }
- }
-}
diff --git a/Source/CDR.Register.API.Infrastructure/Versioning/CdrVersionReader.cs b/Source/CDR.Register.API.Infrastructure/Versioning/CdrVersionReader.cs
index d349259..9923660 100644
--- a/Source/CDR.Register.API.Infrastructure/Versioning/CdrVersionReader.cs
+++ b/Source/CDR.Register.API.Infrastructure/Versioning/CdrVersionReader.cs
@@ -1,7 +1,9 @@
-using CDR.Register.API.Infrastructure.Models;
+using System.Collections.Generic;
+using Asp.Versioning;
+using CDR.Register.API.Infrastructure.Models;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.Extensions.Primitives;
+using static CDR.Register.API.Infrastructure.Constants;
namespace CDR.Register.API.Infrastructure.Versioning
{
@@ -19,11 +21,11 @@ public CdrVersionReader(CdrApiOptions options)
public void AddParameters(IApiVersionParameterDescriptionContext context)
{
- context.AddParameter("x-v", ApiVersionParameterLocation.Header);
- context.AddParameter("x-min-v", ApiVersionParameterLocation.Header);
+ context.AddParameter(Headers.X_V, ApiVersionParameterLocation.Header);
+ context.AddParameter(Headers.X_MIN_V, ApiVersionParameterLocation.Header);
}
- public string? Read(HttpRequest request)
+ public IReadOnlyList Read(HttpRequest request)
{
var endpointOption = this._options.GetApiEndpointVersionOption(request.Path);
@@ -34,34 +36,34 @@ public void AddParameters(IApiVersionParameterDescriptionContext context)
}
else if (!endpointOption.IsVersioned)
{
- return this._options.DefaultVersion;
+ return [this._options.DefaultVersion];
}
// If x-min-v is passed in, we expect it to be a Positive Integer, the x-v value is parsed out of the header and will be validated by the Package itself
// Refer to Standards here - https://consumerdatastandardsaustralia.github.io/standards/#http-headers
// When there is error in x-min-v, we return custom String x-min-v '' this is then manipulated in ApiVersionErrorResponse for a user friendly error message.
- if (!request.Headers.TryGetValue("x-v", out var xvValue) || string.IsNullOrWhiteSpace(xvValue))
+ if (!request.Headers.TryGetValue(Headers.X_V, out var xvValue) || string.IsNullOrWhiteSpace(xvValue))
{
if (endpointOption.IsXVHeaderMandatory)
{
- return Domain.Constants.ErrorTitles.MissingVersion;
+ throw new MissingRequiredHeaderException(Headers.X_V);
}
xvValue = endpointOption.CurrentMinVersion.ToString();
- request.Headers.Remove("x-v"); // Added this to handle both the missing header (just add) and the header with a blank value (update)
- request.Headers.Append("x-v", xvValue);
+ request.Headers.Remove(Headers.X_V); // Added this to handle both the missing header (just add) and the header with a blank value (update)
+ request.Headers.Append(Headers.X_V, xvValue);
}
if (int.TryParse(xvValue, out int xvInt) && xvInt > 0)
{
- request.Headers.TryGetValue("x-min-v", out var xvMinValue);
+ request.Headers.TryGetValue(Headers.X_MIN_V, out var xvMinValue);
xvValue = CalculateVersion(xvInt, xvMinValue, endpointOption);
return xvValue;
}
- return Domain.Constants.ErrorTitles.InvalidVersion;
+ throw new InvalidVersionException(Headers.X_V);
}
private static string? CalculateVersion(int xvInt, string? xvMinString, CdrApiEndpointVersionOptions endpointOption)
@@ -70,14 +72,14 @@ public void AddParameters(IApiVersionParameterDescriptionContext context)
{
if (!int.TryParse(xvMinString, out int xvMinInt) || xvMinInt < 1)
{
- return Domain.Constants.ErrorTitles.InvalidVersion;
+ throw new InvalidVersionException(Headers.X_MIN_V);
}
if (xvMinInt < xvInt)
{
if (xvMinInt > endpointOption.CurrentMaxVersion || xvInt < endpointOption.CurrentMinVersion)
{
- return Domain.Constants.ErrorTitles.UnsupportedVersion;
+ throw new UnsupportedVersionException();
}
return xvInt > endpointOption.CurrentMaxVersion ? endpointOption.CurrentMaxVersion.ToString() : xvInt.ToString();
@@ -86,7 +88,7 @@ public void AddParameters(IApiVersionParameterDescriptionContext context)
if (xvInt < endpointOption.CurrentMinVersion || xvInt > endpointOption.CurrentMaxVersion)
{
- return Domain.Constants.ErrorTitles.UnsupportedVersion;
+ throw new UnsupportedVersionException();
}
return xvInt.ToString();
diff --git a/Source/CDR.Register.Admin.API/Business/AdminMappingProfile.cs b/Source/CDR.Register.Admin.API/Business/AdminMappingProfile.cs
index 08c85da..64774ac 100644
--- a/Source/CDR.Register.Admin.API/Business/AdminMappingProfile.cs
+++ b/Source/CDR.Register.Admin.API/Business/AdminMappingProfile.cs
@@ -3,7 +3,6 @@
using CDR.Register.Admin.API.Business.Model;
using CDR.Register.Domain.Entities;
using CDR.Register.Repository.Enums;
-using Microsoft.Extensions.Configuration;
using DomainEntities = CDR.Register.Domain.Entities;
namespace CDR.Register.Admin.API.Business
@@ -12,28 +11,32 @@ public class AdminMappingProfile : Profile
{
public AdminMappingProfile()
{
- this.CreateMap()
+ this.CreateMap()
.ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source))
- .ForMember(dest => dest.DataRecipientBrands, source => source.MapFrom(source => source.DataRecipientBrands));
+ .ForMember(dest => dest.DataRecipientBrands, source => source.MapFrom(source => source.DataRecipientBrands))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
- this.CreateMap()
- .ForMember(dest => dest.AccreditationLevelId, source => source.MapFrom(source => source.AccreditationLevel));
+ this.CreateMap()
+ .ForMember(dest => dest.AccreditationLevelId, source => source.MapFrom(source => source.AccreditationLevel))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
- this.CreateMap()
+ this.CreateMap()
.ForMember(dest => dest.BrandStatus, source => source.MapFrom(source => source.Status))
- .ForMember(dest => dest.BrandId, source => source.MapFrom(source => source.DataRecipientBrandId));
+ .ForMember(dest => dest.BrandId, source => source.MapFrom(source => source.DataRecipientBrandId))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
- this.CreateMap()
+ this.CreateMap()
.ForMember(dest => dest.RedirectUri, source => source.MapFrom(src => src.RedirectUris != null ? string.Join(" ", src.RedirectUris) : string.Empty))
.ForMember(dest => dest.RedirectUris, opts => opts.Ignore()) // Ignore this as it is a computed property with no setter
- .ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src.Scope ?? string.Empty));
+ .ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src.Scope ?? string.Empty))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
- this.CreateMap();
+ this.CreateMap().MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
// DH Brand Mappings
- this.CreateMap();
- this.CreateMap();
- this.CreateMap();
+ this.CreateMap().MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
+ this.CreateMap().MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
+ this.CreateMap().MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.LegalEntityId, source => source.MapFrom(source => source.LegalEntityId))
@@ -47,13 +50,15 @@ public AdminMappingProfile()
.ForMember(dest => dest.Arbn, source => source.MapFrom(source => source.Arbn))
.ForMember(dest => dest.AnzsicDivision, source => source.MapFrom(source => source.AnzsicDivision))
.ForMember(dest => dest.OrganisationType, source => source.MapFrom(source => source.OrganisationType))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ToUpper()));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ToUpper()))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.Industries, (IMemberConfigurationExpression> source) => source.MapFrom(source => source.Industries))
- .ForMember(dest => dest.Industry, source => source.MapFrom(source => source.Industries.Length > 0 ? source.Industries[0] : string.Empty))
+ .ForMember(dest => dest.Industry, source => source.MapFrom(source => source.Industries.Length > 0 ? source.Industries[0].ToLowerInvariant() : string.Empty))
.ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source == null ? null : source.LegalEntity))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.LegalEntity == null ? string.Empty : source.LegalEntity.Status.ToUpper()));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.LegalEntity == null ? string.Empty : source.LegalEntity.Status.ToUpper()))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.BrandId, source => source.MapFrom(source => source.DataHolderBrandId))
@@ -63,7 +68,8 @@ public AdminMappingProfile()
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => string.Compare(source.Status, BrandStatusType.Active.ToString(), true)))
.ForMember(dest => dest.DataHolderAuthentications, source => source.MapFrom(source => new[] { source.AuthDetails }))
.ForMember(dest => dest.DataHolderBrandServiceEndpoint, source => source.MapFrom(source => source.EndpointDetail))
- .ForMember(dest => dest.DataHolder, source => source.MapFrom(source => source));
+ .ForMember(dest => dest.DataHolder, source => source.MapFrom(source => source))
+ .MaxDepth(Domain.Constants.MappingConstants.MaxDepth);
}
}
}
diff --git a/Source/CDR.Register.Admin.API/Business/Model/DataHolderBrandModel.cs b/Source/CDR.Register.Admin.API/Business/Model/DataHolderBrandModel.cs
index 18e7370..729dd58 100644
--- a/Source/CDR.Register.Admin.API/Business/Model/DataHolderBrandModel.cs
+++ b/Source/CDR.Register.Admin.API/Business/Model/DataHolderBrandModel.cs
@@ -12,6 +12,8 @@ public class DataHolderBrandModel
public string BrandName { get; set; } = string.Empty;
+ public string BrandGroup { get; set; } = string.Empty;
+
public string[] Industries { get; set; } = [];
public string LogoUri { get; set; } = string.Empty;
diff --git a/Source/CDR.Register.Admin.API/Business/Model/DataHolderEndpointModel.cs b/Source/CDR.Register.Admin.API/Business/Model/DataHolderEndpointModel.cs
index 789f38e..5087ed5 100644
--- a/Source/CDR.Register.Admin.API/Business/Model/DataHolderEndpointModel.cs
+++ b/Source/CDR.Register.Admin.API/Business/Model/DataHolderEndpointModel.cs
@@ -6,6 +6,8 @@ public class DataHolderEndpointModel
public string PublicBaseUri { get; set; } = string.Empty;
+ public string ProductBaseUri { get; set; } = string.Empty;
+
public string ResourceBaseUri { get; set; } = string.Empty;
public string InfosecBaseUri { get; set; } = string.Empty;
diff --git a/Source/CDR.Register.Admin.API/Business/Validators/DataHolderBrandValidator.cs b/Source/CDR.Register.Admin.API/Business/Validators/DataHolderBrandValidator.cs
index 066c095..c06e68e 100644
--- a/Source/CDR.Register.Admin.API/Business/Validators/DataHolderBrandValidator.cs
+++ b/Source/CDR.Register.Admin.API/Business/Validators/DataHolderBrandValidator.cs
@@ -1,6 +1,7 @@
using System;
using CDR.Register.Admin.API.Business.Model;
using CDR.Register.Domain.Enums;
+using CDR.Register.Domain.Extensions;
using FluentValidation;
using static CDR.Register.Domain.Constants;
@@ -21,7 +22,7 @@ public DataHolderBrandValidator()
this.RuleFor(x => x.AuthDetails).Must(x => x != null).WithErrorCode(ErrorCodes.Cds.MissingRequiredField).WithMessage(ErrorTitles.MissingRequiredField);
// Enum Validations
- this.RuleForEach(x => x.Industries).Must(x => Enum.TryParse(x, true, out Industry _)).WithErrorCode(ErrorCodes.Cds.InvalidField).WithMessage(ErrorTitles.InvalidField);
+ this.RuleForEach(x => x.Industries).Must(x => EnumExtensions.TryParseFromDescription(x, out Industry _)).WithErrorCode(ErrorCodes.Cds.InvalidField).WithMessage(ErrorTitles.InvalidField);
this.RuleFor(x => x.Status).Must(x => Enum.TryParse(x, true, out DhParticipationStatus _)).WithErrorCode(ErrorCodes.Cds.InvalidField).WithMessage(ErrorTitles.InvalidField);
// Length Validations
diff --git a/Source/CDR.Register.Admin.API/Controllers/AdminController.cs b/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
index be0a655..52dfd9f 100644
--- a/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
+++ b/Source/CDR.Register.Admin.API/Controllers/AdminController.cs
@@ -2,6 +2,7 @@
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
+using Asp.Versioning;
using AutoMapper;
using CDR.Register.Admin.API.Business.Model;
using CDR.Register.Admin.API.Business.Validators;
diff --git a/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs b/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
index 38f58e7..3584e0e 100644
--- a/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
+++ b/Source/CDR.Register.Admin.API/Controllers/LoopbackController.cs
@@ -3,6 +3,7 @@
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
+using Asp.Versioning;
using CDR.Register.API.Infrastructure.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
diff --git a/Source/CDR.Register.Admin.API/Data/seed-data.Container.json b/Source/CDR.Register.Admin.API/Data/seed-data.Container.json
index 3cfb74d..ee809b7 100644
--- a/Source/CDR.Register.Admin.API/Data/seed-data.Container.json
+++ b/Source/CDR.Register.Admin.API/Data/seed-data.Container.json
@@ -24,6 +24,7 @@
{
"brandId": "cfcaf0df-401b-47f2-98af-94787289eca8",
"brandName": "Mock Data Holder (Energy)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://smarterenergy/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T10:00:00",
@@ -36,6 +37,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8100",
+ "productBaseUri": "https://host.docker.internal:8100",
"resourceBaseUri": "https://host.docker.internal:8102",
"infoSecBaseUri": "https://host.docker.internal:8101",
"extensionBaseUri": "",
@@ -45,6 +47,7 @@
{
"brandId": "6859d9f9-9cf9-486d-bc85-5d43a7e116de",
"brandName": "Cut Price Energy -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://cutpriceenergy/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T11:00:00",
@@ -57,6 +60,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8100",
+ "productBaseUri": "https://localhost:8100",
"resourceBaseUri": "https://localhost:8102",
"infoSecBaseUri": "https://localhost:8101",
"extensionBaseUri": "",
@@ -91,6 +95,7 @@
{
"brandId": "d50b74cf-e992-42fd-86d4-582ac9d72dbb",
"brandName": "Mock Energy Tool",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T09:00:00",
@@ -147,6 +152,7 @@
{
"brandId": "804fc2fb-18a7-4235-9a49-2af393d18bc7",
"brandName": "Mock Data Holder (Banking)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://bank1/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -159,6 +165,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -169,6 +176,54 @@
}
]
},
+ {
+ "legalEntityId": "07568be9-ed72-4268-8a8f-83cf60608dff",
+ "legalEntityName": "Non Bank Legal Entity 1",
+ "logoUri": "https://non-bank/logo.png",
+ "registrationNumber": "48219",
+ "registrationDate": "2021-12-01T10:00:00",
+ "registeredCountry": "AUSTRALIA",
+ "abn": "58392017462",
+ "acn": "473915802",
+ "arbn": null,
+ "anzsicDivision": "6221",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 3,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "7f3c2a41-9b8e-4e6c-9df1-12c4b8f0a6e3",
+ "brandName": "Mock Data Holder (Non-Bank Lending)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://non-bank1/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.non.bank1/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://host.docker.internal:8200",
+ "productBaseUri": "https://host.docker.internal:8200",
+ "resourceBaseUri": "https://host.docker.internal:8202",
+ "infoSecBaseUri": "https://host.docker.internal:8201",
+ "extensionBaseUri": "",
+ "websiteUri": "https://non-bank1/"
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"legalEntityId": "18b75a76-5821-4c9e-b465-4709291cf0f4",
"legalEntityName": "Mock Software Company",
@@ -193,6 +248,7 @@
{
"brandId": "ffb1c8ba-279e-44d8-96f0-1bc34a6b436f",
"brandName": "Mock Finance Tools",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -249,6 +305,7 @@
{
"brandId": "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55",
"brandName": "New Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://newbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -261,6 +318,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": null, // intentionally not provided
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -295,6 +353,7 @@
{
"brandId": "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d",
"brandName": "Sun -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sunbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -307,6 +366,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -316,6 +376,7 @@
{
"brandId": "a2cd9cd1-e3c7-493b-86d8-f9f319ca0732",
"brandName": "Brighter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://brighterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-01-01T11:58:00",
@@ -328,6 +389,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -362,6 +424,7 @@
{
"brandId": "62f4a113-defe-4f99-bd9c-625277bc0e36",
"brandName": "mildBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mildbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-11T11:58:00",
@@ -374,6 +437,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -383,6 +447,7 @@
{
"brandId": "81d3d5cc-cdb6-4253-a78b-b17155dde7fd",
"brandName": "extrahotBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://extrahotbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-16T11:58:00",
@@ -395,6 +460,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.extrahotbank",
+ "productBaseUri": "https://publicapi.extrahotbank",
"resourceBaseUri": "https://api.extrahotbank",
"infoSecBaseUri": "https://idp.extrahotbank",
"extensionBaseUri": "",
@@ -429,6 +495,7 @@
{
"brandId": "9928cf0f-70c7-40ea-b7ad-cad190232f68",
"brandName": "Ive Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://ivebank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-03T11:58:00",
@@ -441,6 +508,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -475,6 +543,7 @@
{
"brandId": "7c97c3b5-fe64-4b35-8ae0-17fa5d4aa0a8",
"brandName": "Eva Bank corp -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://evabankcorp/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-26T11:58:00",
@@ -487,6 +556,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -521,6 +591,7 @@
{
"brandId": "a5252bde-d1a6-413f-8f53-f7e2f6ab3f77",
"brandName": "Royal Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://royalbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -533,6 +604,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -567,6 +639,7 @@
{
"brandId": "c1ff7731-5843-4384-88d8-6062afde7c5b",
"brandName": "central bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://centralbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-03-06T11:58:00",
@@ -579,6 +652,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -613,6 +687,7 @@
{
"brandId": "2192a459-5ef5-4493-afe1-56c3d03fc1ba",
"brandName": "Fox Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://foxbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-21T11:58:00",
@@ -625,6 +700,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -659,6 +735,7 @@
{
"brandId": "8aa8e9a6-1dc7-4428-baea-d1f4533428b9",
"brandName": "Grand Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://grandbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-29T11:58:00",
@@ -671,6 +748,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -705,6 +783,7 @@
{
"brandId": "85168ace-9211-45e3-bb75-f85c54e66f10",
"brandName": "Kiss Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://kissbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -717,6 +796,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -751,6 +831,7 @@
{
"brandId": "bb03be60-5c46-422e-a27e-aefa0015078d",
"brandName": "Luna -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://lunabank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -763,6 +844,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -797,6 +879,7 @@
{
"brandId": "52d23611-4493-4a21-9095-44ae9eb85841",
"brandName": "Mu Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mubank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -809,6 +892,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -843,6 +927,7 @@
{
"brandId": "557f42e8-4e00-4b03-a9c9-d97796b6418b",
"brandName": "Noon Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://noonbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -855,6 +940,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -889,6 +975,7 @@
{
"brandId": "a5e45351-d13c-4690-93d1-3da515e71a92",
"brandName": "Oppo Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://oppobank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -901,6 +988,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -935,6 +1023,7 @@
{
"brandId": "97e53112-73b2-482a-b352-39d389d67916",
"brandName": "Pepper Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://pepperbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -947,6 +1036,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -981,6 +1071,7 @@
{
"brandId": "895e54c5-93e0-405f-8072-0a9871bac8b5",
"brandName": "QQ Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://qqbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -993,6 +1084,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1027,6 +1119,7 @@
{
"brandId": "975375f7-2bd9-44b5-a188-43d65ca8eaae",
"brandName": "Run Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://runbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1039,6 +1132,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1073,6 +1167,7 @@
{
"brandId": "b648f694-0dee-4f5e-bd2c-9837ac08fb7b",
"brandName": "SaS Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sasbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1085,6 +1180,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1119,6 +1215,7 @@
{
"brandId": "f8bce914-ac8d-436a-b265-19baca6d1df2",
"brandName": "TnT Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://tntbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1131,6 +1228,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1165,6 +1263,7 @@
{
"brandId": "e748eadf-4aa4-4e2f-b3da-fb4a9d511994",
"brandName": "Bank Brand 2 -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://bank2/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1177,6 +1276,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1211,6 +1311,7 @@
{
"brandId": "9f8df3e2-6866-42af-91d4-5faa3204f0b8",
"brandName": "Smarter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://smarterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1223,6 +1324,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1232,6 +1334,7 @@
{
"brandId": "81d3d5cb-cdb6-4253-a78b-b17155dde7fd",
"brandName": "MyBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1244,6 +1347,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.mybank",
+ "productBaseUri": "https://publicapi.mybank",
"resourceBaseUri": "https://api.mybank",
"infoSecBaseUri": "https://idp.mybank",
"extensionBaseUri": "",
@@ -1278,6 +1382,7 @@
{
"brandId": "cf217aba-e00d-48d5-9c3d-03af0b91cb80",
"brandName": "Hall Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallardbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-19T11:58:00",
@@ -1290,6 +1395,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1299,6 +1405,7 @@
{
"brandId": "920f296d-5f2f-49de-876c-15a4aa1b4a79",
"brandName": "Hallway -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallwaybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1311,6 +1418,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.hallwaybank",
+ "productBaseUri": "https://publicapi.hallwaybank",
"resourceBaseUri": "https://api.hallwaybank",
"infoSecBaseUri": "https://idp.hallwaybank",
"extensionBaseUri": "",
@@ -1345,6 +1453,7 @@
{
"brandId": "bc144967-d6f8-47a6-8590-07caf522141b",
"brandName": "Jobs Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jobsbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1357,6 +1466,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://host.docker.internal:8000",
+ "productBaseUri": "https://host.docker.internal:8000",
"resourceBaseUri": "https://host.docker.internal:8002",
"infoSecBaseUri": "https://host.docker.internal:8001",
"extensionBaseUri": "",
@@ -1366,6 +1476,7 @@
{
"brandId": "7b47ecf8-a991-4dd3-adef-b89564005e8e",
"brandName": "offer bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://offerbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1378,6 +1489,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.offerbank",
+ "productBaseUri": "https://publicapi.offerbank",
"resourceBaseUri": "https://api.offerbank",
"infoSecBaseUri": "https://idp.offerbank",
"extensionBaseUri": "",
@@ -1387,6 +1499,7 @@
{
"brandId": "c3176245-4258-4383-b945-cd2f7c828d3c",
"brandName": "J bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1399,6 +1512,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.jbank",
+ "productBaseUri": "https://publicapi.jbank",
"resourceBaseUri": "https://api.jbank",
"infoSecBaseUri": "https://idp.jbank",
"extensionBaseUri": "",
@@ -1433,6 +1547,7 @@
{
"brandId": "20c0864b-ceef-4de0-8944-eb0962f825eb",
"brandName": "Finance X",
+ "brandGroup": null,
"logoUri": "https://fintechx/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1555,6 +1670,7 @@
{
"brandId": "fe123396-4eba-4518-aade-b245ceea78af",
"brandName": "XRay Financial",
+ "brandGroup": null,
"logoUri": "https://xraysoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1611,6 +1727,7 @@
{
"brandId": "8fe9791a-e4a8-4104-b1cb-e0df41189520",
"brandName": "WOW",
+ "brandGroup": null,
"logoUri": "https://wowsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-02-06T11:58:00",
@@ -1667,6 +1784,7 @@
{
"brandId": "a7171ba3-fd05-456f-a859-be4e1cbcc17d",
"brandName": "OLM Software",
+ "brandGroup": null,
"logoUri": "https://olmsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1723,6 +1841,7 @@
{
"brandId": "8a3441aa-1242-493a-b466-dcbfffe5a441",
"brandName": "xlogical",
+ "brandGroup": null,
"logoUri": "https://xlogical/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1779,6 +1898,7 @@
{
"brandId": "46b33515-b4a5-4b1c-b5b4-25654d675be6",
"brandName": "HotFinTech",
+ "brandGroup": null,
"logoUri": "https://hotfintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1857,6 +1977,7 @@
{
"brandId": "ebbcc2f2-817e-42b8-8a28-cd45902159e0",
"brandName": "ZeroFintech",
+ "brandGroup": null,
"logoUri": "https://zerofintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1935,6 +2056,7 @@
{
"brandId": "f3f0c40b-9df8-491a-af1d-81cb9ab5f021",
"brandName": "YoYo",
+ "brandGroup": null,
"logoUri": "https://yoyosoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
diff --git a/Source/CDR.Register.Admin.API/Data/seed-data.Development.json b/Source/CDR.Register.Admin.API/Data/seed-data.Development.json
index 6c2d45b..3604a9f 100644
--- a/Source/CDR.Register.Admin.API/Data/seed-data.Development.json
+++ b/Source/CDR.Register.Admin.API/Data/seed-data.Development.json
@@ -24,6 +24,7 @@
{
"brandId": "cfcaf0df-401b-47f2-98af-94787289eca8",
"brandName": "Mock Data Holder (Energy)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://smarterenergy/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T10:00:00",
@@ -36,6 +37,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8100",
+ "productBaseUri": "https://localhost:8100",
"resourceBaseUri": "https://localhost:8102",
"infoSecBaseUri": "https://localhost:8101",
"extensionBaseUri": "",
@@ -45,6 +47,7 @@
{
"brandId": "6859d9f9-9cf9-486d-bc85-5d43a7e116de",
"brandName": "Cut Price Energy -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://cutpriceenergy/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T11:00:00",
@@ -57,6 +60,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8100",
+ "productBaseUri": "https://localhost:8100",
"resourceBaseUri": "https://localhost:8102",
"infoSecBaseUri": "https://localhost:8101",
"extensionBaseUri": "",
@@ -91,6 +95,7 @@
{
"brandId": "d50b74cf-e992-42fd-86d4-582ac9d72dbb",
"brandName": "Mock Energy Tool",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T09:00:00",
@@ -147,6 +152,7 @@
{
"brandId": "804fc2fb-18a7-4235-9a49-2af393d18bc7",
"brandName": "Mock Data Holder (Banking)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://bank1/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -159,6 +165,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -169,6 +176,54 @@
}
]
},
+ {
+ "legalEntityId": "07568be9-ed72-4268-8a8f-83cf60608dff",
+ "legalEntityName": "Non Bank Legal Entity 1",
+ "logoUri": "https://non-bank/logo.png",
+ "registrationNumber": "48219",
+ "registrationDate": "2021-12-01T10:00:00",
+ "registeredCountry": "AUSTRALIA",
+ "abn": "58392017462",
+ "acn": "473915802",
+ "arbn": null,
+ "anzsicDivision": "6221",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 3,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "7f3c2a41-9b8e-4e6c-9df1-12c4b8f0a6e3",
+ "brandName": "Mock Data Holder (Non-Bank Lending)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://non-bank1/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.non.bank1/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://localhost:8200",
+ "productBaseUri": "https://localhost:8200",
+ "resourceBaseUri": "https://localhost:8202",
+ "infoSecBaseUri": "https://localhost:8201",
+ "extensionBaseUri": "",
+ "websiteUri": "https://non-bank1/"
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"legalEntityId": "18b75a76-5821-4c9e-b465-4709291cf0f4",
"legalEntityName": "Mock Software Company",
@@ -193,6 +248,7 @@
{
"brandId": "ffb1c8ba-279e-44d8-96f0-1bc34a6b436f",
"brandName": "Mock Finance Tools",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -249,6 +305,7 @@
{
"brandId": "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55",
"brandName": "New Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://newbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -261,6 +318,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": null, // intentionally not provided
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -295,6 +353,7 @@
{
"brandId": "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d",
"brandName": "Sun -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sunbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -307,6 +366,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -316,6 +376,7 @@
{
"brandId": "a2cd9cd1-e3c7-493b-86d8-f9f319ca0732",
"brandName": "Brighter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://brighterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-01-01T11:58:00",
@@ -328,6 +389,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -362,6 +424,7 @@
{
"brandId": "62f4a113-defe-4f99-bd9c-625277bc0e36",
"brandName": "mildBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mildbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-11T11:58:00",
@@ -374,6 +437,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -383,6 +447,7 @@
{
"brandId": "81d3d5cc-cdb6-4253-a78b-b17155dde7fd",
"brandName": "extrahotBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://extrahotbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-16T11:58:00",
@@ -395,6 +460,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.extrahotbank",
+ "productBaseUri": "https://publicapi.extrahotbank",
"resourceBaseUri": "https://api.extrahotbank",
"infoSecBaseUri": "https://idp.extrahotbank",
"extensionBaseUri": "",
@@ -429,6 +495,7 @@
{
"brandId": "9928cf0f-70c7-40ea-b7ad-cad190232f68",
"brandName": "Ive Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://ivebank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-03T11:58:00",
@@ -441,6 +508,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -475,6 +543,7 @@
{
"brandId": "7c97c3b5-fe64-4b35-8ae0-17fa5d4aa0a8",
"brandName": "Eva Bank corp -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://evabankcorp/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-26T11:58:00",
@@ -487,6 +556,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -521,6 +591,7 @@
{
"brandId": "a5252bde-d1a6-413f-8f53-f7e2f6ab3f77",
"brandName": "Royal Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://royalbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -533,6 +604,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -567,6 +639,7 @@
{
"brandId": "c1ff7731-5843-4384-88d8-6062afde7c5b",
"brandName": "central bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://centralbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-03-06T11:58:00",
@@ -579,6 +652,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -613,6 +687,7 @@
{
"brandId": "2192a459-5ef5-4493-afe1-56c3d03fc1ba",
"brandName": "Fox Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://foxbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-21T11:58:00",
@@ -625,6 +700,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -659,6 +735,7 @@
{
"brandId": "8aa8e9a6-1dc7-4428-baea-d1f4533428b9",
"brandName": "Grand Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://grandbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-29T11:58:00",
@@ -671,6 +748,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -705,6 +783,7 @@
{
"brandId": "85168ace-9211-45e3-bb75-f85c54e66f10",
"brandName": "Kiss Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://kissbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -717,6 +796,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -751,6 +831,7 @@
{
"brandId": "bb03be60-5c46-422e-a27e-aefa0015078d",
"brandName": "Luna -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://lunabank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -763,6 +844,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -797,6 +879,7 @@
{
"brandId": "52d23611-4493-4a21-9095-44ae9eb85841",
"brandName": "Mu Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mubank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -809,6 +892,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -843,6 +927,7 @@
{
"brandId": "557f42e8-4e00-4b03-a9c9-d97796b6418b",
"brandName": "Noon Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://noonbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -855,6 +940,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -889,6 +975,7 @@
{
"brandId": "a5e45351-d13c-4690-93d1-3da515e71a92",
"brandName": "Oppo Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://oppobank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -901,6 +988,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -935,6 +1023,7 @@
{
"brandId": "97e53112-73b2-482a-b352-39d389d67916",
"brandName": "Pepper Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://pepperbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -947,6 +1036,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -981,6 +1071,7 @@
{
"brandId": "895e54c5-93e0-405f-8072-0a9871bac8b5",
"brandName": "QQ Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://qqbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -993,6 +1084,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1027,6 +1119,7 @@
{
"brandId": "975375f7-2bd9-44b5-a188-43d65ca8eaae",
"brandName": "Run Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://runbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1039,6 +1132,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1073,6 +1167,7 @@
{
"brandId": "b648f694-0dee-4f5e-bd2c-9837ac08fb7b",
"brandName": "SaS Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sasbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1085,6 +1180,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1119,6 +1215,7 @@
{
"brandId": "f8bce914-ac8d-436a-b265-19baca6d1df2",
"brandName": "TnT Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://tntbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1131,6 +1228,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1165,6 +1263,7 @@
{
"brandId": "e748eadf-4aa4-4e2f-b3da-fb4a9d511994",
"brandName": "Bank Brand 2 -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://bank2/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1177,6 +1276,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1211,6 +1311,7 @@
{
"brandId": "9f8df3e2-6866-42af-91d4-5faa3204f0b8",
"brandName": "Smarter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://smarterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1223,6 +1324,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1232,6 +1334,7 @@
{
"brandId": "81d3d5cb-cdb6-4253-a78b-b17155dde7fd",
"brandName": "MyBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1244,6 +1347,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.mybank",
+ "productBaseUri": "https://publicapi.mybank",
"resourceBaseUri": "https://api.mybank",
"infoSecBaseUri": "https://idp.mybank",
"extensionBaseUri": "",
@@ -1278,6 +1382,7 @@
{
"brandId": "cf217aba-e00d-48d5-9c3d-03af0b91cb80",
"brandName": "Hall Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallardbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-19T11:58:00",
@@ -1290,6 +1395,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1299,6 +1405,7 @@
{
"brandId": "920f296d-5f2f-49de-876c-15a4aa1b4a79",
"brandName": "Hallway -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallwaybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1311,6 +1418,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.hallwaybank",
+ "productBaseUri": "https://publicapi.hallwaybank",
"resourceBaseUri": "https://api.hallwaybank",
"infoSecBaseUri": "https://idp.hallwaybank",
"extensionBaseUri": "",
@@ -1345,6 +1453,7 @@
{
"brandId": "bc144967-d6f8-47a6-8590-07caf522141b",
"brandName": "Jobs Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jobsbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1357,6 +1466,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://localhost:8000",
+ "productBaseUri": "https://localhost:8000",
"resourceBaseUri": "https://localhost:8002",
"infoSecBaseUri": "https://localhost:8001",
"extensionBaseUri": "",
@@ -1366,6 +1476,7 @@
{
"brandId": "7b47ecf8-a991-4dd3-adef-b89564005e8e",
"brandName": "offer bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://offerbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1378,6 +1489,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.offerbank",
+ "productBaseUri": "https://publicapi.offerbank",
"resourceBaseUri": "https://api.offerbank",
"infoSecBaseUri": "https://idp.offerbank",
"extensionBaseUri": "",
@@ -1387,6 +1499,7 @@
{
"brandId": "c3176245-4258-4383-b945-cd2f7c828d3c",
"brandName": "J bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1399,6 +1512,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.jbank",
+ "productBaseUri": "https://publicapi.jbank",
"resourceBaseUri": "https://api.jbank",
"infoSecBaseUri": "https://idp.jbank",
"extensionBaseUri": "",
@@ -1433,6 +1547,7 @@
{
"brandId": "20c0864b-ceef-4de0-8944-eb0962f825eb",
"brandName": "Finance X",
+ "brandGroup": null,
"logoUri": "https://fintechx/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1555,6 +1670,7 @@
{
"brandId": "fe123396-4eba-4518-aade-b245ceea78af",
"brandName": "XRay Financial",
+ "brandGroup": null,
"logoUri": "https://xraysoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1611,6 +1727,7 @@
{
"brandId": "8fe9791a-e4a8-4104-b1cb-e0df41189520",
"brandName": "WOW",
+ "brandGroup": null,
"logoUri": "https://wowsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-02-06T11:58:00",
@@ -1667,6 +1784,7 @@
{
"brandId": "a7171ba3-fd05-456f-a859-be4e1cbcc17d",
"brandName": "OLM Software",
+ "brandGroup": null,
"logoUri": "https://olmsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1723,6 +1841,7 @@
{
"brandId": "8a3441aa-1242-493a-b466-dcbfffe5a441",
"brandName": "xlogical",
+ "brandGroup": null,
"logoUri": "https://xlogical/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1779,6 +1898,7 @@
{
"brandId": "46b33515-b4a5-4b1c-b5b4-25654d675be6",
"brandName": "HotFinTech",
+ "brandGroup": null,
"logoUri": "https://hotfintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1857,6 +1977,7 @@
{
"brandId": "ebbcc2f2-817e-42b8-8a28-cd45902159e0",
"brandName": "ZeroFintech",
+ "brandGroup": null,
"logoUri": "https://zerofintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1935,6 +2056,7 @@
{
"brandId": "f3f0c40b-9df8-491a-af1d-81cb9ab5f021",
"brandName": "YoYo",
+ "brandGroup": null,
"logoUri": "https://yoyosoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1991,6 +2113,7 @@
{
"brandId": "2dda1b75-aa5e-4ff3-abff-af0863cf9ffc",
"brandName": "Another Energy Tool",
+ "brandGroup": null,
"logoUri": "https://anotherenergytool/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T09:00:00",
diff --git a/Source/CDR.Register.Admin.API/Data/seed-data.Release.json b/Source/CDR.Register.Admin.API/Data/seed-data.Release.json
index a915524..2a986f2 100644
--- a/Source/CDR.Register.Admin.API/Data/seed-data.Release.json
+++ b/Source/CDR.Register.Admin.API/Data/seed-data.Release.json
@@ -24,6 +24,7 @@
{
"brandId": "cfcaf0df-401b-47f2-98af-94787289eca8",
"brandName": "Mock Data Holder (Energy)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://smarterenergy/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T10:00:00",
@@ -36,6 +37,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://mock-data-holder-energy:8100",
+ "productBaseUri": "https://mock-data-holder-energy:8100",
"resourceBaseUri": "https://mock-data-holder-energy:8102",
"infoSecBaseUri": "https://mock-data-holder-energy:8101",
"extensionBaseUri": "",
@@ -45,6 +47,7 @@
{
"brandId": "6859d9f9-9cf9-486d-bc85-5d43a7e116de",
"brandName": "Cut Price Energy -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://cutpriceenergy/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T11:00:00",
@@ -57,6 +60,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://api.cutpriceenergy:8100",
+ "productBaseUri": "https://api.cutpriceenergy:8100",
"resourceBaseUri": "https://api.cutpriceenergy:8102",
"infoSecBaseUri": "https://api.cutpriceenergy:8101",
"extensionBaseUri": "",
@@ -91,6 +95,7 @@
{
"brandId": "d50b74cf-e992-42fd-86d4-582ac9d72dbb",
"brandName": "Mock Energy Tool",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-12-01T09:00:00",
@@ -147,6 +152,7 @@
{
"brandId": "804fc2fb-18a7-4235-9a49-2af393d18bc7",
"brandName": "Mock Data Holder (Banking)",
+ "brandGroup": "CDR Mock Brands",
"logoUri": "https://bank1/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -159,6 +165,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://mock-data-holder:8000",
+ "productBaseUri": "https://mock-data-holder:8000",
"resourceBaseUri": "https://mock-data-holder:8002",
"infoSecBaseUri": "https://mock-data-holder:8001",
"extensionBaseUri": "",
@@ -169,6 +176,54 @@
}
]
},
+ {
+ "legalEntityId": "07568be9-ed72-4268-8a8f-83cf60608dff",
+ "legalEntityName": "Non Bank Legal Entity 1",
+ "logoUri": "https://non-bank/logo.png",
+ "registrationNumber": "48219",
+ "registrationDate": "2021-12-01T10:00:00",
+ "registeredCountry": "AUSTRALIA",
+ "abn": "58392017462",
+ "acn": "473915802",
+ "arbn": null,
+ "anzsicDivision": "6221",
+ "organisationTypeId": 2,
+ "legalEntityStatusId": 1,
+ "accreditationNumber": null,
+ "accreditationLevelId": null,
+ "participations": [
+ {
+ "participationTypeId": 1,
+ "industryId": 3,
+ "statusId": 1,
+ "brands": [
+ {
+ "brandId": "7f3c2a41-9b8e-4e6c-9df1-12c4b8f0a6e3",
+ "brandName": "Mock Data Holder (Non-Bank Lending)",
+ "brandGroup": "CDR Mock Brands",
+ "logoUri": "https://non-bank1/img/logo.png",
+ "brandStatusId": 1,
+ "lastUpdated": "2021-04-06T11:58:00",
+ "authDetails": [
+ {
+ "registerUTypeId": 1,
+ "jwksEndpoint": "https://idp.non.bank1/jwks"
+ }
+ ],
+ "endpoint": {
+ "version": 1,
+ "publicBaseUri": "https://mock-data-holder:8200",
+ "productBaseUri": "https://mock-data-holder:8200",
+ "resourceBaseUri": "https://mock-data-holder:8202",
+ "infoSecBaseUri": "https://mock-data-holder:8201",
+ "extensionBaseUri": "",
+ "websiteUri": "https://non-bank1/"
+ }
+ }
+ ]
+ }
+ ]
+ },
{
"legalEntityId": "18b75a76-5821-4c9e-b465-4709291cf0f4",
"legalEntityName": "Mock Software Company",
@@ -193,6 +248,7 @@
{
"brandId": "ffb1c8ba-279e-44d8-96f0-1bc34a6b436f",
"brandName": "Mock Finance Tools",
+ "brandGroup": null,
"logoUri": "https://mocksoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -249,6 +305,7 @@
{
"brandId": "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55",
"brandName": "New Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://newbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -261,6 +318,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.newbank",
+ "productBaseUri": null, // intentionally not provided
"resourceBaseUri": "https://api.newbank",
"infoSecBaseUri": "https://idp.newbank",
"extensionBaseUri": "",
@@ -295,6 +353,7 @@
{
"brandId": "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d",
"brandName": "Sun -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sunbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -307,6 +366,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.sunbank",
+ "productBaseUri": "https://publicapi.sunbank",
"resourceBaseUri": "https://api.sunbank",
"infoSecBaseUri": "https://idp.sunbank",
"extensionBaseUri": "",
@@ -316,6 +376,7 @@
{
"brandId": "a2cd9cd1-e3c7-493b-86d8-f9f319ca0732",
"brandName": "Brighter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://brighterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-01-01T11:58:00",
@@ -328,6 +389,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.brighterbank",
+ "productBaseUri": "https://publicapi.brighterbank",
"resourceBaseUri": "https://api.brighterbank",
"infoSecBaseUri": "https://idp.brighterbank",
"extensionBaseUri": "",
@@ -362,6 +424,7 @@
{
"brandId": "62f4a113-defe-4f99-bd9c-625277bc0e36",
"brandName": "mildBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mildbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-11T11:58:00",
@@ -374,6 +437,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.mildbank",
+ "productBaseUri": "https://publicapi.mildbank",
"resourceBaseUri": "https://api.mildbank",
"infoSecBaseUri": "https://idp.mildbank",
"extensionBaseUri": "",
@@ -383,6 +447,7 @@
{
"brandId": "81d3d5cc-cdb6-4253-a78b-b17155dde7fd",
"brandName": "extrahotBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://extrahotbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-16T11:58:00",
@@ -395,6 +460,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.extrahotbank",
+ "productBaseUri": "https://publicapi.extrahotbank",
"resourceBaseUri": "https://api.extrahotbank",
"infoSecBaseUri": "https://idp.extrahotbank",
"extensionBaseUri": "",
@@ -429,6 +495,7 @@
{
"brandId": "9928cf0f-70c7-40ea-b7ad-cad190232f68",
"brandName": "Ive Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://ivebank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-03T11:58:00",
@@ -441,6 +508,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.ivebank",
+ "productBaseUri": "https://publicapi.ivebank",
"resourceBaseUri": "https://api.ivebank",
"infoSecBaseUri": "https://idp.ivebank",
"extensionBaseUri": "",
@@ -475,6 +543,7 @@
{
"brandId": "7c97c3b5-fe64-4b35-8ae0-17fa5d4aa0a8",
"brandName": "Eva Bank corp -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://evabankcorp/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-26T11:58:00",
@@ -487,6 +556,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.evabank",
+ "productBaseUri": "https://publicapi.evabank",
"resourceBaseUri": "https://api.evabank",
"infoSecBaseUri": "https://idp.evabank",
"extensionBaseUri": "",
@@ -521,6 +591,7 @@
{
"brandId": "a5252bde-d1a6-413f-8f53-f7e2f6ab3f77",
"brandName": "Royal Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://royalbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-01T11:58:00",
@@ -533,6 +604,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.royalbank",
+ "productBaseUri": "https://publicapi.royalbank",
"resourceBaseUri": "https://api.royalbank",
"infoSecBaseUri": "https://idp.royalbank",
"extensionBaseUri": "",
@@ -567,6 +639,7 @@
{
"brandId": "c1ff7731-5843-4384-88d8-6062afde7c5b",
"brandName": "central bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://centralbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-03-06T11:58:00",
@@ -579,6 +652,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.centralbank",
+ "productBaseUri": "https://publicapi.centralbank",
"resourceBaseUri": "https://api.centralbank",
"infoSecBaseUri": "https://idp.centralbank",
"extensionBaseUri": "",
@@ -613,6 +687,7 @@
{
"brandId": "2192a459-5ef5-4493-afe1-56c3d03fc1ba",
"brandName": "Fox Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://foxbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-21T11:58:00",
@@ -625,6 +700,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.foxbank",
+ "productBaseUri": "https://publicapi.foxbank",
"resourceBaseUri": "https://api.foxbank",
"infoSecBaseUri": "https://idp.foxbank",
"extensionBaseUri": "",
@@ -659,6 +735,7 @@
{
"brandId": "8aa8e9a6-1dc7-4428-baea-d1f4533428b9",
"brandName": "Grand Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://grandbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-29T11:58:00",
@@ -671,6 +748,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.grandbank",
+ "productBaseUri": "https://publicapi.grandbank",
"resourceBaseUri": "https://api.grandbank",
"infoSecBaseUri": "https://idp.grandbank",
"extensionBaseUri": "",
@@ -705,6 +783,7 @@
{
"brandId": "85168ace-9211-45e3-bb75-f85c54e66f10",
"brandName": "Kiss Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://kissbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -717,6 +796,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.kissbank",
+ "productBaseUri": "https://publicapi.kissbank",
"resourceBaseUri": "https://api.kissbank",
"infoSecBaseUri": "https://idp.kissbank",
"extensionBaseUri": "",
@@ -751,6 +831,7 @@
{
"brandId": "bb03be60-5c46-422e-a27e-aefa0015078d",
"brandName": "Luna -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://lunabank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-12T11:58:00",
@@ -763,6 +844,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.lunabank",
+ "productBaseUri": "https://publicapi.lunabank",
"resourceBaseUri": "https://api.lunabank",
"infoSecBaseUri": "https://idp.lunabank",
"extensionBaseUri": "",
@@ -797,6 +879,7 @@
{
"brandId": "52d23611-4493-4a21-9095-44ae9eb85841",
"brandName": "Mu Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mubank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -809,6 +892,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.mubank",
+ "productBaseUri": "https://publicapi.mubank",
"resourceBaseUri": "https://api.mubank",
"infoSecBaseUri": "https://idp.mubank",
"extensionBaseUri": "",
@@ -843,6 +927,7 @@
{
"brandId": "557f42e8-4e00-4b03-a9c9-d97796b6418b",
"brandName": "Noon Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://noonbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -855,6 +940,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.noonbank",
+ "productBaseUri": "https://publicapi.noonbank",
"resourceBaseUri": "https://api.noonbank",
"infoSecBaseUri": "https://idp.noonbank",
"extensionBaseUri": "",
@@ -889,6 +975,7 @@
{
"brandId": "a5e45351-d13c-4690-93d1-3da515e71a92",
"brandName": "Oppo Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://oppobank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -901,6 +988,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.oppobank",
+ "productBaseUri": "https://publicapi.oppobank",
"resourceBaseUri": "https://api.oppobank",
"infoSecBaseUri": "https://idp.oppobank",
"extensionBaseUri": "",
@@ -935,6 +1023,7 @@
{
"brandId": "97e53112-73b2-482a-b352-39d389d67916",
"brandName": "Pepper Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://pepperbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -947,6 +1036,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.pepperbank",
+ "productBaseUri": "https://publicapi.pepperbank",
"resourceBaseUri": "https://api.pepperbank",
"infoSecBaseUri": "https://idp.pepperbank",
"extensionBaseUri": "",
@@ -981,6 +1071,7 @@
{
"brandId": "895e54c5-93e0-405f-8072-0a9871bac8b5",
"brandName": "QQ Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://qqbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -993,6 +1084,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.qqbank",
+ "productBaseUri": "https://publicapi.qqbank",
"resourceBaseUri": "https://api.qqbank",
"infoSecBaseUri": "https://idp.qqbank",
"extensionBaseUri": "",
@@ -1027,6 +1119,7 @@
{
"brandId": "975375f7-2bd9-44b5-a188-43d65ca8eaae",
"brandName": "Run Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://runbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1039,6 +1132,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.runbank",
+ "productBaseUri": "https://publicapi.runbank",
"resourceBaseUri": "https://api.runbank",
"infoSecBaseUri": "https://idp.runbank",
"extensionBaseUri": "",
@@ -1073,6 +1167,7 @@
{
"brandId": "b648f694-0dee-4f5e-bd2c-9837ac08fb7b",
"brandName": "SaS Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://sasbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1085,6 +1180,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.sasbank",
+ "productBaseUri": "https://publicapi.sasbank",
"resourceBaseUri": "https://api.sasbank",
"infoSecBaseUri": "https://idp.sasbank",
"extensionBaseUri": "",
@@ -1119,6 +1215,7 @@
{
"brandId": "f8bce914-ac8d-436a-b265-19baca6d1df2",
"brandName": "TnT Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://tntbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-09T11:58:00",
@@ -1131,6 +1228,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.tntbank",
+ "productBaseUri": "https://publicapi.tntbank",
"resourceBaseUri": "https://api.tntbank",
"infoSecBaseUri": "https://idp.tntbank",
"extensionBaseUri": "",
@@ -1165,6 +1263,7 @@
{
"brandId": "e748eadf-4aa4-4e2f-b3da-fb4a9d511994",
"brandName": "Bank Brand 2 -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://bank2/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1177,6 +1276,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.bank2",
+ "productBaseUri": "https://publicapi.bank2",
"resourceBaseUri": "https://api.bank2",
"infoSecBaseUri": "https://idp.bank2",
"extensionBaseUri": "",
@@ -1211,6 +1311,7 @@
{
"brandId": "9f8df3e2-6866-42af-91d4-5faa3204f0b8",
"brandName": "Smarter Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://smarterbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1223,6 +1324,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.smarterbank",
+ "productBaseUri": "https://publicapi.smarterbank",
"resourceBaseUri": "https://api.smarterbank",
"infoSecBaseUri": "https://idp.smarterbank",
"extensionBaseUri": "",
@@ -1232,6 +1334,7 @@
{
"brandId": "81d3d5cb-cdb6-4253-a78b-b17155dde7fd",
"brandName": "MyBank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://mybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1244,6 +1347,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.mybank",
+ "productBaseUri": "https://publicapi.mybank",
"resourceBaseUri": "https://api.mybank",
"infoSecBaseUri": "https://idp.mybank",
"extensionBaseUri": "",
@@ -1278,6 +1382,7 @@
{
"brandId": "cf217aba-e00d-48d5-9c3d-03af0b91cb80",
"brandName": "Hall Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallardbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-19T11:58:00",
@@ -1290,6 +1395,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.hallbank",
+ "productBaseUri": "https://publicapi.hallbank",
"resourceBaseUri": "https://api.hallbank",
"infoSecBaseUri": "https://idp.hallbank",
"extensionBaseUri": "",
@@ -1299,6 +1405,7 @@
{
"brandId": "920f296d-5f2f-49de-876c-15a4aa1b4a79",
"brandName": "Hallway -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://hallwaybank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1311,6 +1418,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.hallwaybank",
+ "productBaseUri": "https://publicapi.hallwaybank",
"resourceBaseUri": "https://api.hallwaybank",
"infoSecBaseUri": "https://idp.hallwaybank",
"extensionBaseUri": "",
@@ -1345,6 +1453,7 @@
{
"brandId": "bc144967-d6f8-47a6-8590-07caf522141b",
"brandName": "Jobs Bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jobsbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1357,6 +1466,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.jobsbank",
+ "productBaseUri": "https://publicapi.jobsbank",
"resourceBaseUri": "https://api.jobsbank",
"infoSecBaseUri": "https://idp.jobsbank",
"extensionBaseUri": "",
@@ -1366,6 +1476,7 @@
{
"brandId": "7b47ecf8-a991-4dd3-adef-b89564005e8e",
"brandName": "offer bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://offerbank/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1378,6 +1489,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.offerbank",
+ "productBaseUri": "https://publicapi.offerbank",
"resourceBaseUri": "https://api.offerbank",
"infoSecBaseUri": "https://idp.offerbank",
"extensionBaseUri": "",
@@ -1387,6 +1499,7 @@
{
"brandId": "c3176245-4258-4383-b945-cd2f7c828d3c",
"brandName": "J bank -- dummy data holder -- do not use",
+ "brandGroup": null,
"logoUri": "https://jbank/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-18T11:58:00",
@@ -1399,6 +1512,7 @@
"endpoint": {
"version": 1,
"publicBaseUri": "https://publicapi.jbank",
+ "productBaseUri": "https://publicapi.jbank",
"resourceBaseUri": "https://api.jbank",
"infoSecBaseUri": "https://idp.jbank",
"extensionBaseUri": "",
@@ -1433,6 +1547,7 @@
{
"brandId": "20c0864b-ceef-4de0-8944-eb0962f825eb",
"brandName": "Finance X",
+ "brandGroup": null,
"logoUri": "https://fintechx/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1555,6 +1670,7 @@
{
"brandId": "fe123396-4eba-4518-aade-b245ceea78af",
"brandName": "XRay Financial",
+ "brandGroup": null,
"logoUri": "https://xraysoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1611,6 +1727,7 @@
{
"brandId": "8fe9791a-e4a8-4104-b1cb-e0df41189520",
"brandName": "WOW",
+ "brandGroup": null,
"logoUri": "https://wowsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-02-06T11:58:00",
@@ -1667,6 +1784,7 @@
{
"brandId": "a7171ba3-fd05-456f-a859-be4e1cbcc17d",
"brandName": "OLM Software",
+ "brandGroup": null,
"logoUri": "https://olmsoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1723,6 +1841,7 @@
{
"brandId": "8a3441aa-1242-493a-b466-dcbfffe5a441",
"brandName": "xlogical",
+ "brandGroup": null,
"logoUri": "https://xlogical/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
@@ -1779,6 +1898,7 @@
{
"brandId": "46b33515-b4a5-4b1c-b5b4-25654d675be6",
"brandName": "HotFinTech",
+ "brandGroup": null,
"logoUri": "https://hotfintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1857,6 +1977,7 @@
{
"brandId": "ebbcc2f2-817e-42b8-8a28-cd45902159e0",
"brandName": "ZeroFintech",
+ "brandGroup": null,
"logoUri": "https://zerofintech/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-05T11:58:00",
@@ -1935,6 +2056,7 @@
{
"brandId": "f3f0c40b-9df8-491a-af1d-81cb9ab5f021",
"brandName": "YoYo",
+ "brandGroup": null,
"logoUri": "https://yoyosoftware/img/logo.png",
"brandStatusId": 1,
"lastUpdated": "2021-04-06T11:58:00",
diff --git a/Source/CDR.Register.Admin.API/Startup.cs b/Source/CDR.Register.Admin.API/Startup.cs
index 2a67e7b..a4b8001 100644
--- a/Source/CDR.Register.Admin.API/Startup.cs
+++ b/Source/CDR.Register.Admin.API/Startup.cs
@@ -6,8 +6,7 @@
using CDR.Register.Admin.API.Business.Validators;
using CDR.Register.Admin.API.Extensions;
using CDR.Register.API.Infrastructure;
-using CDR.Register.API.Infrastructure.Models;
-using CDR.Register.API.Infrastructure.Versioning;
+using CDR.Register.API.Infrastructure.Middleware;
using CDR.Register.Domain.Extensions;
using CDR.Register.Repository.Infrastructure;
using FluentValidation;
@@ -54,11 +53,9 @@ public void ConfigureServices(IServiceCollection services)
services.AddControllers();
- services.AddApiVersioning(options =>
+ services.AddCdrApiVersioning(opt =>
{
- options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); // uses default options atm
- options.ErrorResponses = new ApiVersionErrorResponse();
- options.ReportApiVersions = true;
+ opt.ReportApiVersions = true;
});
var enableSwagger = this.Configuration.GetValue(ConfigurationKeys.EnableSwagger);
@@ -90,6 +87,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
app.UseDeveloperExceptionPage();
}
+ app.UseExceptionHandler(exceptionHandlerApp =>
+ {
+ exceptionHandlerApp.Run(async context => await ApiExceptionHandler.Handle(context));
+ });
+
app.UseSerilogRequestLogging();
app.UseHttpsRedirection();
@@ -131,7 +133,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<
var context = serviceScope.ServiceProvider.GetRequiredService();
if (context == null)
{
- logger.LogError("Mirgation failed. Unable to get {Name}", nameof(RegisterDatabaseContext));
+ logger.LogError("Migration failed. Unable to get {Name}", nameof(RegisterDatabaseContext));
throw new InvalidOperationException($"Unable to get {nameof(RegisterDatabaseContext)}");
}
diff --git a/Source/CDR.Register.Discovery.API.UnitTests/CDR.Register.Discovery.API.UnitTests.csproj b/Source/CDR.Register.Discovery.API.UnitTests/CDR.Register.Discovery.API.UnitTests.csproj
new file mode 100644
index 0000000..18b9899
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API.UnitTests/CDR.Register.Discovery.API.UnitTests.csproj
@@ -0,0 +1,44 @@
+
+
+
+ false
+ false
+ $(TargetFrameworkVersion)
+ $(Version)
+ $(Version)
+ $(Version)
+ True
+ true
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/CDR.Register.Discovery.API.UnitTests/DiscoveryServiceTests.cs b/Source/CDR.Register.Discovery.API.UnitTests/DiscoveryServiceTests.cs
new file mode 100644
index 0000000..c7d0bc3
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API.UnitTests/DiscoveryServiceTests.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper;
+using CDR.Register.Discovery.API.Business;
+using CDR.Register.Repository.Infrastructure;
+using CDR.Register.Repository.Interfaces;
+using CDR.Register.Repository.Specifications;
+using Google.Protobuf.Compiler;
+using NSubstitute;
+
+namespace CDR.Register.Discovery.API.UnitTests
+{
+ public class DiscoveryServiceTests
+ {
+ private readonly IRegisterDiscoveryRepository _repository = Substitute.For();
+ private readonly IMapper _mapper = Substitute.For();
+
+ [Theory]
+ [InlineData(2, typeof(BrandSpecifications.ExcludeNblIndustry))]
+ [InlineData(3, typeof(BrandSpecifications.AllIndustries))]
+ public async Task GetDataHolderBrands_UsesCorrectSpecification(int version, Type expectedType)
+ {
+ // Arrange
+ Type specificationType = null;
+ _ = await this._repository.GetDataHolderBrands(Industry.ALL, Arg.Do(x => specificationType = x.GetType()), Arg.Any(), Arg.Any(), Arg.Any());
+ var service = new DiscoveryService(this._repository, this._mapper);
+
+ // Act
+ _ = await service.GetDataHolderBrands(Industry.ALL, DateTime.UtcNow, 1, 1, version);
+
+ // Assert
+ Assert.Equal(expectedType, specificationType);
+ }
+
+ [Fact]
+ public async Task GetDataHolderBrands_ThrowsExceptionForUnsupportedVersion()
+ {
+ // Arrange
+ var service = new DiscoveryService(this._repository, this._mapper);
+
+ // Act
+ var action = async () => await service.GetDataHolderBrands(Industry.ALL, DateTime.UtcNow, 1, 1, 1);
+
+ // Assert
+ await Assert.ThrowsAsync(action);
+ }
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/DiscoveryService.cs b/Source/CDR.Register.Discovery.API/Business/DiscoveryService.cs
index a789a90..2697780 100644
--- a/Source/CDR.Register.Discovery.API/Business/DiscoveryService.cs
+++ b/Source/CDR.Register.Discovery.API/Business/DiscoveryService.cs
@@ -1,35 +1,39 @@
using System;
using System.Threading.Tasks;
using AutoMapper;
+using CDR.Register.Discovery.API.Business.Models;
using CDR.Register.Discovery.API.Business.Responses;
using CDR.Register.Repository.Infrastructure;
using CDR.Register.Repository.Interfaces;
+using CDR.Register.Repository.Specifications;
namespace CDR.Register.Discovery.API.Business
{
- public class DiscoveryService : IDiscoveryService
+ public class DiscoveryService(IRegisterDiscoveryRepository registerDiscoveryRepository, IMapper mapper) : IDiscoveryService
{
- private readonly IRegisterDiscoveryRepository _registerDiscoveryRepository;
- private readonly IMapper _mapper;
-
- public DiscoveryService(
- IRegisterDiscoveryRepository registerDiscoveryRepository,
- IMapper mapper)
+ public async Task> GetDataHolderBrands(Industry industry, DateTime? updatedSince, int page, int pageSize, int version)
{
- this._registerDiscoveryRepository = registerDiscoveryRepository;
- this._mapper = mapper;
- }
+ IBrandSpecification specification = version switch
+ {
+ 2 => new BrandSpecifications.ExcludeNblIndustry(),
+ 3 => new BrandSpecifications.AllIndustries(),
+ _ => throw new NotImplementedException("Unknown version"),
+ };
- public async Task GetDataHolderBrandsAsync(Industry industry, DateTime? updatedSince, int page, int pageSize)
- {
- var entity = await this._registerDiscoveryRepository.GetDataHolderBrandsAsync(industry, updatedSince, page, pageSize);
- return this._mapper.Map(entity);
+ var entity = await registerDiscoveryRepository.GetDataHolderBrands(industry, specification, updatedSince, page, pageSize);
+
+ return version switch
+ {
+ 2 => mapper.Map(entity),
+ 3 => mapper.Map(entity),
+ _ => throw new NotImplementedException("Unknown version"),
+ };
}
- public async Task GetDataRecipientsAsync(Industry industry)
+ public async Task GetDataRecipientsAsync()
{
- var entity = await this._registerDiscoveryRepository.GetDataRecipientsAsync(industry);
- return this._mapper.Map(entity);
+ var entity = await registerDiscoveryRepository.GetDataRecipientsAsync();
+ return mapper.Map(entity);
}
}
}
diff --git a/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs b/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
index 4091824..04ca8c2 100644
--- a/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
+++ b/Source/CDR.Register.Discovery.API/Business/IDiscoveryService.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
+using CDR.Register.Discovery.API.Business.Models;
using CDR.Register.Discovery.API.Business.Responses;
using CDR.Register.Repository.Infrastructure;
@@ -7,8 +8,8 @@ namespace CDR.Register.Discovery.API.Business
{
public interface IDiscoveryService
{
- Task GetDataHolderBrandsAsync(Industry industry, DateTime? updatedSince, int page, int pageSize);
+ Task> GetDataHolderBrands(Industry industry, DateTime? updatedSince, int page, int pageSize, int version);
- Task GetDataRecipientsAsync(Industry industry);
+ Task GetDataRecipientsAsync();
}
}
diff --git a/Source/CDR.Register.Discovery.API/Business/MappingProfile.cs b/Source/CDR.Register.Discovery.API/Business/MappingProfile.cs
index bead95f..c6e1d23 100644
--- a/Source/CDR.Register.Discovery.API/Business/MappingProfile.cs
+++ b/Source/CDR.Register.Discovery.API/Business/MappingProfile.cs
@@ -3,6 +3,7 @@
using CDR.Register.API.Infrastructure.Models;
using CDR.Register.Discovery.API.Business.Models;
using CDR.Register.Discovery.API.Business.Responses;
+using CDR.Register.Domain;
using CDR.Register.Domain.Entities;
using CDR.Register.Domain.ValueObjects;
@@ -12,11 +13,12 @@ public class MappingProfile : Profile
{
public MappingProfile()
{
- this.CreateMap(typeof(Page<>), typeof(MetaPaginated));
+ this.CreateMap(typeof(Page<>), typeof(MetaPaginated)).MaxDepth(Constants.MappingConstants.MaxDepth);
- this.CreateMap();
+ this.CreateMap().MaxDepth(Constants.MappingConstants.MaxDepth);
- this.CreateMap();
+ this.CreateMap().MaxDepth(Constants.MappingConstants.MaxDepth);
+ this.CreateMap().MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.LegalEntityId, source => source.MapFrom(source => source.LegalEntityId))
@@ -30,29 +32,49 @@ public MappingProfile()
.ForMember(dest => dest.Arbn, source => source.MapFrom(source => source.Arbn))
.ForMember(dest => dest.AnzsicDivision, source => source.MapFrom(source => source.AnzsicDivision))
.ForMember(dest => dest.OrganisationType, source => source.MapFrom(source => source.OrganisationType))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ToUpper()));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ToUpper()))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap, ResponseRegisterDataHolderBrandList>()
.ForMember(dest => dest.Data, source => source.MapFrom(source => source.Data))
- .ForMember(dest => dest.Meta, source => source.MapFrom(source => source));
+ .ForMember(dest => dest.Meta, source => source.MapFrom(source => source))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
- this.CreateMap()
+ this.CreateMap, ResponseRegisterDataHolderBrandListV2>()
+ .ForMember(dest => dest.Data, source => source.MapFrom(source => source.Data))
+ .ForMember(dest => dest.Meta, source => source.MapFrom(source => source))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
+
+ this.CreateMap()
.ForMember(dest => dest.DataHolderBrandId, source => source.MapFrom(source => source.BrandId))
.ForMember(dest => dest.Industries, source => source.MapFrom(source => new List { source.DataHolder.Industry.ToLower() }))
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.BrandStatus))
.ForMember(dest => dest.AuthDetails, source => source.MapFrom(source => source.DataHolderAuthentications))
.ForMember(dest => dest.EndpointDetail, source => source.MapFrom(source => source.DataHolderBrandServiceEndpoint))
- .ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source.DataHolder.LegalEntity));
+ .ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source.DataHolder.LegalEntity))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
+
+ this.CreateMap()
+ .ForMember(dest => dest.DataHolderBrandId, source => source.MapFrom(source => source.BrandId))
+ .ForMember(dest => dest.BrandGroup, source => source.MapFrom(source => source.BrandGroup))
+ .ForMember(dest => dest.Industries, source => source.MapFrom(source => new List { source.DataHolder.Industry.ToLower() }))
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.BrandStatus))
+ .ForMember(dest => dest.AuthDetails, source => source.MapFrom(source => source.DataHolderAuthentications))
+ .ForMember(dest => dest.EndpointDetail, source => source.MapFrom(source => source.DataHolderBrandServiceEndpoint))
+ .ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source.DataHolder.LegalEntity))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.DataRecipientBrandId, source => source.MapFrom(source => source.BrandId))
.ForMember(dest => dest.BrandName, source => source.MapFrom(source => source.BrandName))
.ForMember(dest => dest.LogoUri, source => source.MapFrom(source => source.LogoUri))
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.BrandStatus))
- .ForMember(dest => dest.SoftwareProducts, source => source.MapFrom(source => source.SoftwareProducts));
+ .ForMember(dest => dest.SoftwareProducts, source => source.MapFrom(source => source.SoftwareProducts))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
- .ForMember(dest => dest.Data, source => source.MapFrom(source => source));
+ .ForMember(dest => dest.Data, source => source.MapFrom(source => source))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.LegalEntityId, source => source.MapFrom(source => source.LegalEntity.LegalEntityId))
@@ -62,13 +84,15 @@ public MappingProfile()
.ForMember(dest => dest.LogoUri, source => source.MapFrom(source => source.LegalEntity.LogoUri))
.ForMember(dest => dest.DataRecipientBrands, source => source.MapFrom(source => source.DataRecipientBrands))
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status))
- .ForMember(dest => dest.LastUpdated, source => source.MapFrom(source => source.LastUpdated));
+ .ForMember(dest => dest.LastUpdated, source => source.MapFrom(source => source.LastUpdated))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.SoftwareProductId, source => source.MapFrom(source => source.SoftwareProductId))
.ForMember(dest => dest.SoftwareProductName, source => source.MapFrom(source => source.SoftwareProductName))
.ForMember(dest => dest.LogoUri, source => source.MapFrom(source => source.LogoUri))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
}
}
}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/IRegisterDataHolderBrand.cs b/Source/CDR.Register.Discovery.API/Business/Models/IRegisterDataHolderBrand.cs
new file mode 100644
index 0000000..834a1d4
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API/Business/Models/IRegisterDataHolderBrand.cs
@@ -0,0 +1,6 @@
+namespace CDR.Register.Discovery.API.Business.Models
+{
+ public interface IRegisterDataHolderBrand
+ {
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrand.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrand.cs
new file mode 100644
index 0000000..a10c1c8
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrand.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace CDR.Register.Discovery.API.Business.Models
+{
+ [Obsolete("Deprecated in the standards, used by versions prior to V1.35.0. This is aligned with RAAP implementation and can be removed when the endpoint is no longer supported.", false)]
+ public class RegisterDataHolderBrand : IRegisterDataHolderBrand
+ {
+ public string DataHolderBrandId { get; set; }
+
+ public string BrandName { get; set; }
+
+ public List Industries { get; set; }
+
+ public string LogoUri { get; set; }
+
+ public DataHolderLegalEntityModel LegalEntity { get; set; }
+
+ public string Status { get; set; }
+
+ public AuthDetailModel[] AuthDetails { get; set; }
+
+ public DateTime LastUpdated { get; set; }
+
+ public RegisterDataHolderBrandServiceEndpoint EndpointDetail { get; set; }
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpoint.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpoint.cs
new file mode 100644
index 0000000..418db4c
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpoint.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace CDR.Register.Discovery.API.Business.Models
+{
+ [Obsolete("Deprecated in the standards, used by versions prior to V1.35.0. This is aligned with RAAP implementation and can be removed when the endpoint is no longer supported.", false)]
+ public class RegisterDataHolderBrandServiceEndpoint
+ {
+ public string Version { get; set; }
+
+ public string PublicBaseUri { get; set; }
+
+ public string ResourceBaseUri { get; set; }
+
+ public string InfosecBaseUri { get; set; }
+
+ public string ExtensionBaseUri { get; set; }
+
+ public string WebsiteUri { get; set; }
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpointV2.cs
similarity index 77%
rename from Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs
rename to Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpointV2.cs
index 6d4a4c5..827ee61 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/EndPointDetailModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandServiceEndpointV2.cs
@@ -1,9 +1,11 @@
namespace CDR.Register.Discovery.API.Business.Models
{
- public class EndpointDetailModel
+ public class RegisterDataHolderBrandServiceEndpointV2
{
public string Version { get; set; }
+ public string ProductBaseUri { get; set; }
+
public string PublicBaseUri { get; set; }
public string ResourceBaseUri { get; set; }
diff --git a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandV2.cs
similarity index 72%
rename from Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs
rename to Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandV2.cs
index 18db58f..5ac6fa8 100644
--- a/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandModel.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Models/RegisterDataHolderBrandV2.cs
@@ -3,7 +3,7 @@
namespace CDR.Register.Discovery.API.Business.Models
{
- public class RegisterDataHolderBrandModel
+ public class RegisterDataHolderBrandV2 : IRegisterDataHolderBrand
{
public string DataHolderBrandId { get; set; }
@@ -17,10 +17,12 @@ public class RegisterDataHolderBrandModel
public string Status { get; set; }
- public EndpointDetailModel EndpointDetail { get; set; }
-
public AuthDetailModel[] AuthDetails { get; set; }
public DateTime LastUpdated { get; set; }
+
+ public string BrandGroup { get; set; }
+
+ public RegisterDataHolderBrandServiceEndpointV2 EndpointDetail { get; set; }
}
}
diff --git a/Source/CDR.Register.Discovery.API/Business/Responses/IResponseRegisterDataHolderBrandList.cs b/Source/CDR.Register.Discovery.API/Business/Responses/IResponseRegisterDataHolderBrandList.cs
new file mode 100644
index 0000000..bce0cfc
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API/Business/Responses/IResponseRegisterDataHolderBrandList.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+using CDR.Register.API.Infrastructure.Models;
+using CDR.Register.Discovery.API.Business.Models;
+
+namespace CDR.Register.Discovery.API.Business.Responses
+{
+ ///
+ /// Response with list of DH Brands.
+ ///
+ /// The DH Brand collection.
+ public interface IResponseRegisterDataHolderBrandList
+ where T : IRegisterDataHolderBrand
+ {
+ IEnumerable Data { get; }
+
+ LinksPaginated Links { get; set; }
+
+ MetaPaginated Meta { get; set; }
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
index d6ab71f..ac319af 100644
--- a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
+++ b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandList.cs
@@ -1,12 +1,14 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using CDR.Register.API.Infrastructure.Models;
using CDR.Register.Discovery.API.Business.Models;
namespace CDR.Register.Discovery.API.Business.Responses
{
- public class ResponseRegisterDataHolderBrandList
+ [Obsolete("Deprecated in the standards, used by versions prior to V1.35.0. This is aligned with RAAP implementation and can be removed when the endpoint is no longer supported.", false)]
+ public class ResponseRegisterDataHolderBrandList : IResponseRegisterDataHolderBrandList
{
- public IEnumerable Data { get; set; }
+ public IEnumerable Data { get; set; }
public LinksPaginated Links { get; set; } = new LinksPaginated();
diff --git a/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandListV2.cs b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandListV2.cs
new file mode 100644
index 0000000..0c6a428
--- /dev/null
+++ b/Source/CDR.Register.Discovery.API/Business/Responses/ResponseRegisterDataHolderBrandListV2.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+using CDR.Register.API.Infrastructure.Models;
+using CDR.Register.Discovery.API.Business.Models;
+
+namespace CDR.Register.Discovery.API.Business.Responses
+{
+ public class ResponseRegisterDataHolderBrandListV2 : IResponseRegisterDataHolderBrandList
+ {
+ public IEnumerable Data { get; set; }
+
+ public LinksPaginated Links { get; set; } = new LinksPaginated();
+
+ public MetaPaginated Meta { get; set; } = new MetaPaginated();
+ }
+}
diff --git a/Source/CDR.Register.Discovery.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Discovery.xml b/Source/CDR.Register.Discovery.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Discovery.xml
index 0892b3d..f4eb5d3 100644
--- a/Source/CDR.Register.Discovery.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Discovery.xml
+++ b/Source/CDR.Register.Discovery.API/ConsumerDataRight.ParticipantTooling.MockRegister.API.Discovery.xml
@@ -4,6 +4,12 @@
CDR.Register.Discovery.API
+
+
+ Response with list of DH Brands.
+
+ The DH Brand collection.
+
Performs checks against the software product id from the access token.
diff --git a/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs b/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
index f8f8f4b..03559bc 100644
--- a/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
+++ b/Source/CDR.Register.Discovery.API/Controllers/DiscoveryController.cs
@@ -2,6 +2,7 @@
using System.Globalization;
using System.Net;
using System.Threading.Tasks;
+using Asp.Versioning;
using CDR.Register.API.Infrastructure;
using CDR.Register.API.Infrastructure.Authorization;
using CDR.Register.API.Infrastructure.Filters;
@@ -22,7 +23,9 @@ public class DiscoveryController : ControllerBase
{
// Route names.
private const string ROUTE_GET_DATA_HOLDER_BRANDS_XV2 = "GetDataHolderBrandsXV2";
+ private const string ROUTE_GET_DATA_HOLDER_BRANDS_XV3 = "GetDataHolderBrandsXV3";
private const string ROUTE_GET_DATA_RECIPIENTS_XV3 = "GetDataRecipientsXV3";
+ private const string ROUTE_GET_DATA_RECIPIENTS_XV4 = "GetDataRecipientsXV4";
private readonly IDiscoveryService _discoveryService;
private readonly IDataRecipientStatusCheckService _statusCheckService;
@@ -38,18 +41,71 @@ public DiscoveryController(
this._statusCheckService = statusCheckService;
}
+ [Obsolete("Deprecated in the standards, used by versions prior to V1.35.0. This is aligned with RAAP implementation and can be removed when the endpoint is no longer supported.", false)]
[HttpGet("v1/{industry}/data-holders/brands", Name = ROUTE_GET_DATA_HOLDER_BRANDS_XV2)]
[PolicyAuthorize(RegisterAuthorisationPolicy.DataHolderBrandsApiMultiIndustry)]
[ApiVersion("2")]
[ReturnXV("2")]
[ETag]
+ [CheckIndustry(Repository.Infrastructure.Industry.BANKING, Repository.Infrastructure.Industry.ENERGY, Repository.Infrastructure.Industry.TELCO, Repository.Infrastructure.Industry.ALL)]
+ [ServiceFilter(typeof(LogActionEntryAttribute))]
+ public Task GetDataHolderBrandsXV2(
+ string industry,
+ [FromQuery(Name = "updated-since"), CheckDate] string updatedSince,
+ [FromQuery(Name = "page"), CheckPage] string page,
+ [FromQuery(Name = "page-size"), CheckPageSize] string pageSize)
+ => this.GetDataHolderBrands(2, ROUTE_GET_DATA_HOLDER_BRANDS_XV2, industry, updatedSince, page, pageSize);
+
+ [HttpGet("v1/{industry}/data-holders/brands", Name = ROUTE_GET_DATA_HOLDER_BRANDS_XV3)]
+ [PolicyAuthorize(RegisterAuthorisationPolicy.DataHolderBrandsApiMultiIndustry)]
+ [ApiVersion("3")]
+ [ReturnXV("3")]
+ [ETag]
[CheckIndustry]
[ServiceFilter(typeof(LogActionEntryAttribute))]
- public async Task GetDataHolderBrandsXV2(
+ public Task GetDataHolderBrandsXV3(
string industry,
[FromQuery(Name = "updated-since"), CheckDate] string updatedSince,
[FromQuery(Name = "page"), CheckPage] string page,
[FromQuery(Name = "page-size"), CheckPageSize] string pageSize)
+ => this.GetDataHolderBrands(3, ROUTE_GET_DATA_HOLDER_BRANDS_XV3, industry, updatedSince, page, pageSize);
+
+ [HttpGet("v1/{industry}/data-recipients", Name = ROUTE_GET_DATA_RECIPIENTS_XV3)]
+ [ReturnXV("3")]
+ [ApiVersion("3")]
+ [ETag]
+ [CheckIndustry(Repository.Infrastructure.Industry.BANKING, Repository.Infrastructure.Industry.ENERGY, Repository.Infrastructure.Industry.TELCO, Repository.Infrastructure.Industry.ALL)]
+ [ServiceFilter(typeof(LogActionEntryAttribute))]
+ public async Task GetDataRecipientsXV3(string industry)
+ {
+ return await this.GetDataRecipients();
+ }
+
+ [HttpGet("v1/{industry}/data-recipients", Name = ROUTE_GET_DATA_RECIPIENTS_XV4)]
+ [ReturnXV("4")]
+ [ApiVersion("4")]
+ [ETag]
+ [CheckIndustry(Repository.Infrastructure.Industry.ALL)]
+ [ServiceFilter(typeof(LogActionEntryAttribute))]
+ public async Task GetDataRecipientsXV4(string industry)
+ {
+ return await this.GetDataRecipients();
+ }
+
+ private async Task GetDataRecipients()
+ {
+ var response = await this._discoveryService.GetDataRecipientsAsync();
+ response.Links = this.GetSelf(this._configuration, this.HttpContext, string.Empty);
+ return this.Ok(response);
+ }
+
+ private async Task GetDataHolderBrands(
+ int version,
+ string routeName,
+ string industry,
+ string updatedSince,
+ string page,
+ string pageSize)
{
// CTS conformance ID validations
var basePathExpression = this._configuration.GetValue(Constants.ConfigurationKeys.BasePathExpression);
@@ -73,7 +129,7 @@ public async Task GetDataHolderBrandsXV2(
DateTime? updatedSinceDate = string.IsNullOrEmpty(updatedSince) ? (DateTime?)null : DateTime.Parse(updatedSince, CultureInfo.InvariantCulture);
int pageNumber = string.IsNullOrEmpty(page) ? 1 : int.Parse(page);
int pageSizeNumber = string.IsNullOrEmpty(pageSize) ? 25 : int.Parse(pageSize);
- var response = await this._discoveryService.GetDataHolderBrandsAsync(industry.ToIndustry(), updatedSinceDate, pageNumber, pageSizeNumber);
+ var response = await this._discoveryService.GetDataHolderBrands(industry.ToIndustry(), updatedSinceDate, pageNumber, pageSizeNumber, version);
// Check if the given page number is out of range
if (pageNumber != 1 && pageNumber > response.Meta.TotalPages)
@@ -83,7 +139,7 @@ public async Task GetDataHolderBrandsXV2(
// Set pagination meta data
response.Links = this.GetPaginated(
- ROUTE_GET_DATA_HOLDER_BRANDS_XV2,
+ routeName,
this._configuration,
updatedSinceDate,
pageNumber,
@@ -95,19 +151,6 @@ public async Task GetDataHolderBrandsXV2(
return this.Ok(response);
}
- [HttpGet("v1/{industry}/data-recipients", Name = ROUTE_GET_DATA_RECIPIENTS_XV3)]
- [ReturnXV("3")]
- [ApiVersion("3")]
- [ETag]
- [CheckIndustry]
- [ServiceFilter(typeof(LogActionEntryAttribute))]
- public async Task GetDataRecipientsXV3(string industry)
- {
- var response = await this._discoveryService.GetDataRecipientsAsync(industry.ToIndustry());
- response.Links = this.GetSelf(this._configuration, this.HttpContext, string.Empty);
- return this.Ok(response);
- }
-
///
/// Performs checks against the software product id from the access token.
///
diff --git a/Source/CDR.Register.Discovery.API/Startup.cs b/Source/CDR.Register.Discovery.API/Startup.cs
index 9815640..df4ff1f 100644
--- a/Source/CDR.Register.Discovery.API/Startup.cs
+++ b/Source/CDR.Register.Discovery.API/Startup.cs
@@ -41,11 +41,7 @@ public void ConfigureServices(IServiceCollection services)
options.InvalidModelStateResponseFactory = ModelStateErrorMiddleware.ExecuteResult;
});
- services.AddApiVersioning(options =>
- {
- options.ApiVersionReader = new CdrVersionReader(new CdrApiOptions()); // uses default options atm
- options.ErrorResponses = new ApiVersionErrorResponse();
- });
+ services.AddCdrApiVersioning();
var enableSwagger = this.Configuration.GetValue(ConfigurationKeys.EnableSwagger);
if (enableSwagger)
diff --git a/Source/CDR.Register.Domain.UnitTests/Extensions/EnumExtensionsTests.cs b/Source/CDR.Register.Domain.UnitTests/Extensions/EnumExtensionsTests.cs
new file mode 100644
index 0000000..409e21d
--- /dev/null
+++ b/Source/CDR.Register.Domain.UnitTests/Extensions/EnumExtensionsTests.cs
@@ -0,0 +1,68 @@
+using System.ComponentModel;
+using CDR.Register.Domain.Extensions;
+using Xunit;
+
+namespace CDR.Register.Domain.UnitTests
+{
+ public class EnumExtensionsTests
+ {
+ private const string ExpectedDescription = "Value With Description";
+
+ public enum TestValue
+ {
+ [Description(ExpectedDescription)]
+ WithDescription = 100,
+ SansDescription = 200,
+ }
+
+ [Theory]
+ [InlineData(nameof(TestValue.WithDescription), true, TestValue.WithDescription)]
+ [InlineData(nameof(TestValue.SansDescription), true, TestValue.SansDescription)]
+ [InlineData(TestValue.WithDescription, true, TestValue.WithDescription)]
+ [InlineData(TestValue.SansDescription, true, TestValue.SansDescription)]
+ [InlineData(100, true, TestValue.WithDescription)]
+ [InlineData(200, true, TestValue.SansDescription)]
+ [InlineData("invalid", false, default)]
+ [InlineData("", false, default)]
+ [InlineData(0, false, default)]
+ public void TryParseFromDescription_ReturnsExpectedValue(object obj, bool expectedResult, TestValue? expectedValue)
+ {
+ var input = obj.ToString();
+
+ var result = input.TryParseFromDescription(out var value);
+
+ Assert.Equal(expectedResult, result);
+
+ if (result)
+ {
+ Assert.Equal(expectedValue, value);
+ }
+ }
+
+ [Theory]
+ [InlineData(nameof(TestValue.WithDescription), TestValue.WithDescription)]
+ [InlineData(nameof(TestValue.SansDescription), TestValue.SansDescription)]
+ [InlineData(TestValue.WithDescription, TestValue.WithDescription)]
+ [InlineData(TestValue.SansDescription, TestValue.SansDescription)]
+ [InlineData(100, TestValue.WithDescription)]
+ [InlineData(200, TestValue.SansDescription)]
+ public void ParseFromDescription_ReturnsExpectedValue(object obj, TestValue? expectedValue)
+ {
+ var input = obj.ToString();
+
+ var result = input.ParseFromDescription();
+
+ Assert.Equal(expectedValue, result);
+ }
+
+ [Theory]
+ [InlineData(TestValue.WithDescription, ExpectedDescription)]
+ [InlineData(TestValue.SansDescription, null)]
+ public void GetDescription_ReturnsExpectedValue(TestValue value, string expected)
+ {
+ var result = value.GetDescription();
+
+ Assert.Equal(expected, result);
+ }
+ }
+}
diff --git a/Source/CDR.Register.Domain/Constants.cs b/Source/CDR.Register.Domain/Constants.cs
index 980f485..80f6769 100644
--- a/Source/CDR.Register.Domain/Constants.cs
+++ b/Source/CDR.Register.Domain/Constants.cs
@@ -84,5 +84,10 @@ public static class ErrorTitles
public const string InvalidIndustry = "Invalid Industry";
public const string InvalidSoftwareProduct = "Invalid Software Product";
}
+
+ public static class MappingConstants
+ {
+ public const int MaxDepth = 32;
+ }
}
}
diff --git a/Source/CDR.Register.Domain/Entities/Brand.cs b/Source/CDR.Register.Domain/Entities/Brand.cs
index 9b10eed..89b3e49 100644
--- a/Source/CDR.Register.Domain/Entities/Brand.cs
+++ b/Source/CDR.Register.Domain/Entities/Brand.cs
@@ -10,6 +10,8 @@ public abstract class Brand
public string BrandName { get; set; }
+ public string BrandGroup { get; set; }
+
public string LogoUri { get; set; }
public string BrandStatus { get; set; }
diff --git a/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs b/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
index d2045cf..1474d9e 100644
--- a/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
+++ b/Source/CDR.Register.Domain/Entities/DataHolderBrandServiceEndpoint.cs
@@ -6,6 +6,8 @@ public class DataHolderBrandServiceEndpoint
public string PublicBaseUri { get; set; }
+ public string ProductBaseUri { get; set; }
+
public string ResourceBaseUri { get; set; }
public string InfosecBaseUri { get; set; }
diff --git a/Source/CDR.Register.Domain/Enums/Industry.cs b/Source/CDR.Register.Domain/Enums/Industry.cs
index 5164956..0eb5088 100644
--- a/Source/CDR.Register.Domain/Enums/Industry.cs
+++ b/Source/CDR.Register.Domain/Enums/Industry.cs
@@ -1,10 +1,46 @@
-namespace CDR.Register.Domain.Enums
+using System.ComponentModel;
+using System.Runtime.Serialization;
+
+namespace CDR.Register.Domain.Enums
{
+ ///
+ /// The industry.
+ ///
public enum Industry
{
+ ///
+ /// All industries.
+ ///
+ [Description("all")]
+ [EnumMember(Value = "all")]
All = 0,
- Banking,
- Energy,
- Telco,
+
+ ///
+ /// Banking.
+ ///
+ [Description("banking")]
+ [EnumMember(Value = "banking")]
+ Banking = 1,
+
+ ///
+ /// Energy.
+ ///
+ [Description("energy")]
+ [EnumMember(Value = "energy")]
+ Energy = 2,
+
+ ///
+ /// Non-Bank Lending.
+ ///
+ [Description("non-bank-lending")]
+ [EnumMember(Value = "non-bank-lending")]
+ NonBankLending = 3,
+
+ ///
+ /// Telecoms Company.
+ ///
+ [Description("telco")]
+ [EnumMember(Value = "telco")]
+ Telco = 4,
}
}
diff --git a/Source/CDR.Register.Domain/Extensions/EnumExtensions.cs b/Source/CDR.Register.Domain/Extensions/EnumExtensions.cs
new file mode 100644
index 0000000..2fa1a8a
--- /dev/null
+++ b/Source/CDR.Register.Domain/Extensions/EnumExtensions.cs
@@ -0,0 +1,89 @@
+using System;
+using System.ComponentModel;
+using System.Reflection;
+using Newtonsoft.Json.Linq;
+
+namespace CDR.Register.Domain.Extensions
+{
+ public static class EnumExtensions
+ {
+ ///
+ /// Attempts to match the input with the on the enum value, if present otherwise the value itself.
+ ///
+ /// This is case-insensitive.
+ /// The type of .
+ /// The input string to match against the enum value name or description.
+ /// The value of with the matching name or description.
+ /// A flag indicating whether a matching enum value was found.
+ public static bool TryParseFromDescription(this string input, out T value)
+ where T : struct, Enum
+ {
+ var type = typeof(T);
+
+ foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
+ {
+ var attribute = field.GetCustomAttribute();
+ if (attribute != null &&
+ attribute.Description.Equals(input, StringComparison.OrdinalIgnoreCase))
+ {
+ value = (T)field.GetValue(null)!;
+ return true;
+ }
+ }
+
+ if (Enum.TryParse(input, ignoreCase: true, out value))
+ {
+ return Enum.IsDefined(value);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Gets the description for a value of .
+ ///
+ /// The type of .
+ /// The enum value to fetch a name for.
+ /// The description of the enum value.
+ public static string GetDescription(this T value)
+ where T : struct, Enum
+ {
+ var type = typeof(T);
+ var name = value.ToString();
+
+ var field = type.GetField(name);
+ if (field == null)
+ {
+ return null;
+ }
+
+ var attribute = field.GetCustomAttribute();
+ return attribute?.Description;
+ }
+
+ ///
+ /// Matches the input with the on the enum value, if present otherwise the value itself.
+ ///
+ /// This is case-insensitive.
+ /// The type of .
+ /// The input string to match against the enum value name or description.
+ /// A flag indicating whether a matching enum value was found.
+ public static T ParseFromDescription(this string input)
+ where T : struct, Enum
+ {
+ var type = typeof(T);
+
+ foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
+ {
+ var attribute = field.GetCustomAttribute();
+ if (attribute != null &&
+ attribute.Description.Equals(input, StringComparison.OrdinalIgnoreCase))
+ {
+ return (T)field.GetValue(null)!;
+ }
+ }
+
+ return Enum.Parse(input, true);
+ }
+ }
+}
diff --git a/Source/CDR.Register.Infosec/Controllers/TokenController.cs b/Source/CDR.Register.Infosec/Controllers/TokenController.cs
index 18a1cdc..cce70bd 100644
--- a/Source/CDR.Register.Infosec/Controllers/TokenController.cs
+++ b/Source/CDR.Register.Infosec/Controllers/TokenController.cs
@@ -74,18 +74,20 @@ private static (bool IsValid, string? Error, string? ErrorDescription, SoftwareP
private static (bool IsValid, string? Error, string? ErrorDescription, SoftwareProductInfosec? Client) ValidateScope(string? scope)
{
- if (string.IsNullOrEmpty(scope))
+ if (string.IsNullOrWhiteSpace(scope))
{
return (false, ErrorCodes.Generic.InvalidClient, "empty scope", null);
}
- var scopes = scope.Split(' ');
- foreach (var s in scopes)
+ var scopes = scope.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+
+ // This was rewritten to abide by S3267 code style during patching.
+ // However, this may lead to a bug in future if the supported scopes are expanded as it does not allow
+ // scopes that INCLUDE 'cdr-register:read' but rather enforces scopes are ONLY 'cdr-register:read'
+ // this should probably be !scopes.Contains(Constants.Scopes.RegisterRead, StringComparison.Ordinal)
+ if (scopes.Any(s => !s.Equals(Constants.Scopes.RegisterRead, StringComparison.Ordinal)))
{
- if (!s.Equals(Constants.Scopes.RegisterRead))
- {
- return (false, ErrorCodes.Generic.InvalidClient, "invalid scope", null);
- }
+ return (false, ErrorCodes.Generic.InvalidClient, "invalid scope", null);
}
return (true, null, null, null);
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataHolderBrandsXV3_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataHolderBrandsXV3_MultiIndustry_Tests.cs
new file mode 100644
index 0000000..a4be879
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataHolderBrandsXV3_MultiIndustry_Tests.cs
@@ -0,0 +1,1156 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using CDR.Register.IntegrationTests.Infrastructure;
+using CDR.Register.Repository.Enums;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.Discovery
+{
+ ///
+ /// Integration tests for GetDataHolderBrands V3.
+ ///
+ ///
+ /// This is similar to except
+ /// that for x-v:3 the additional non-bank-lending industry should be supported.
+ ///
+ public class GetDataHolderBrandsXV3_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : BaseTest(outputHelper, testFixture)
+ {
+ private const string BrandId = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
+ private const string SoftwareProductId = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
+
+ ///
+ /// The current endpoint version under test.
+ ///
+ private const string EndpointVersion = "3";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "2";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "4";
+
+ ///
+ /// Actions that need to be performed before the request, such as setting status of Brand or Software Product.
+ ///
+ private delegate void BeforeRequest();
+
+ ///
+ /// Actions that need to be performed after the request, such as restoring status of Brand or Software Product.
+ ///
+ private delegate void AfterRequest();
+
+ // Participation/Brand/SoftwareProduct Ids
+ private static string ParticipationId => GetParticipationId(BrandId); // lookup
+
+ ///
+ /// The request with no additional query parameters should return the expected results using the defaults (first page, 25 records).
+ ///
+ /// The industry to request.
+ /// The expected status code.
+ /// A representing the asynchronous unit test.
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithNoQueryString_ShouldRespondWith_200OK_First25RecordsAsync(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
+ {
+ await Test_QueryParameters_RespondWithExpectedStatusAndBody(null, null, null, industry, expectedStatusCode);
+ }
+
+ ///
+ /// The request with CTS paths and no additional query parameters should return the expected results using the defaults (first page, 25 records).
+ ///
+ /// The industry to request.
+ /// The expected status code.
+ /// A representing the asynchronous unit test.
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithDynamicPaths_AndNoQueryString_ShouldRespondWith_200OK_First25RecordsAsync(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
+ {
+ // Arrange
+ string conformanceId = Guid.NewGuid().ToString();
+ string tokenEndpoint = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL, conformanceId)}/idp/connect/token";
+ var getDataHolderBrandsUrl = $"{GenerateDynamicCtsUrl(DISCOVERY_DOWNSTREAM_BASE_URL, conformanceId)}/cdr-register/v1/{industry}/data-holders/brands";
+ string expectedDataHolderBrandsUrl = ReplaceSecureHostName(getDataHolderBrandsUrl, DISCOVERY_DOWNSTREAM_BASE_URL);
+
+ var expectedResponse = GetExpectedResponse(expectedDataHolderBrandsUrl, expectedDataHolderBrandsUrl, null, null, null, industry);
+
+ // Arrange - Get access token
+ var accessToken = await new IntegrationTests.Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ Scope = "cdr-register:read",
+ Audience = ReplaceSecureHostName(tokenEndpoint, IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL),
+ TokenEndPoint = tokenEndpoint,
+ CertificateThumbprint = DEFAULT_CERTIFICATE_THUMBPRINT,
+ CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME,
+ }.GetAsync(addCertificateToRequest: false);
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = getDataHolderBrandsUrl,
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ CertificateThumbprint = DEFAULT_CERTIFICATE_THUMBPRINT,
+ CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(api.XV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedResponse, response.Content);
+ }
+ }
+ }
+
+ ///
+ /// The request with page-size and page query parameter should return with the expected page and record count.
+ ///
+ /// The industry to request.
+ /// The page.
+ /// The page size.
+ /// The expected status code.
+ /// A representing the asynchronous unit test.
+ [Theory]
+ [InlineData(null, null, 5, HttpStatusCode.NotFound)]
+ [InlineData("banking", null, 5)]
+ [InlineData("banking", 3, 5)]
+ [InlineData("banking", 6, 5)]
+ public async Task Get_WithPageSize_ShouldRespondWith_200OK_Page1Of5Records(string? industry, int? page = null, int? pageSize = 5, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
+ {
+ await Test_QueryParameters_RespondWithExpectedStatusAndBody(null, page, pageSize, industry, expectedStatusCode);
+ }
+
+ ///
+ /// The request with an updated-since query parameter should return the expected page and record count.
+ ///
+ /// The industry to request.
+ /// The value for updated-since query parameter.
+ /// The value for page query parameter.
+ /// The value for page-size query parameter.
+ /// The expected status code.
+ /// A representing the asynchronous unit test.
+ [Theory]
+ [InlineData(null, "2021-04-01T00:00:00Z", null, null, HttpStatusCode.NotFound)]
+ [InlineData("banking", "2021-04-01T00:00:00Z", 6, 5)]
+ [InlineData("banking", "2021-04-30T00:00:00Z", null, null)]
+ [InlineData("energy", "2021-04-30T00:00:00Z", null, null)]
+ [InlineData("non-bank-lending", "2021-04-30T00:00:00Z", null, null)]
+ [InlineData("telco", "2021-04-30T00:00:00Z", null, null)]
+ public async Task Get_WithUpdatedSince_ShouldRespondWith_200OK_ExpectedRecordCount(string? industry, string updatedSince, int? page = null, int? pageSize = 5, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
+ {
+ var updatedSinceDate = DateTime.Parse(updatedSince, CultureInfo.InvariantCulture);
+ await Test_QueryParameters_RespondWithExpectedStatusAndBody(updatedSinceDate, page, pageSize, industry, expectedStatusCode);
+ }
+
+ [Theory]
+ [InlineData("", HttpStatusCode.NotFound, null)] // "" is effectively no date so the filter will not take effect. It won't be invalid, it will be a 200 OK.
+ [InlineData("foo", HttpStatusCode.NotFound, null)] // abc in AC
+ [InlineData("32/32/2021", HttpStatusCode.NotFound, null)]
+ [InlineData("", HttpStatusCode.OK, "banking")] // "" is effectively no date so the filter will not take effect. It won't be invalid, it will be a 200 OK.
+ [InlineData("foo", HttpStatusCode.BadRequest, "banking")] // abc in AC
+ [InlineData("32/32/2021", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("", HttpStatusCode.OK, "energy")] // "" is effectively no date so the filter will not take effect. It won't be invalid, it will be a 200 OK.
+ [InlineData("foo", HttpStatusCode.BadRequest, "energy")] // abc in AC
+ [InlineData("32/32/2021", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("", HttpStatusCode.OK, "telco")] // "" is effectively no date so the filter will not take effect. It won't be invalid, it will be a 200 OK.
+ [InlineData("foo", HttpStatusCode.BadRequest, "telco")] // abc in AC
+ [InlineData("32/32/2021", HttpStatusCode.BadRequest, "telco")]
+ public async Task Get_WithUpdatedSinceInvalidDate_ShouldRespondWith_400BadRequest_InvalidDateTimeString(string updatedSince, HttpStatusCode expectedStatusCode, string? industry)
+ {
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands?updated-since={updatedSince}",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ // Assert - Check error response
+ if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check error response
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/InvalidDateTime",
+ "title": "Invalid DateTime",
+ "detail": "updated-since should be valid DateTimeString",
+ }
+ ]
+ }
+ """;
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)] // DF: this will be a 404 now.
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithMissingAccessToken_ShouldRespondWith_401Unauthorized(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
+ {
+ await Test_WithAccessToken_RespondsWithClientErrorStatusCode(null, industry, expectedStatusCode);
+ }
+
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)] // DF: this will be a 404 now.
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithInvalidAccessToken_ShouldRespondWith_401Unauthorized(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
+ {
+ await Test_WithAccessToken_RespondsWithClientErrorStatusCode("foo", industry, expectedStatusCode);
+ }
+
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)] // DF: this will be a 404 now.
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithExpiredAccessToken_ShouldRespondWith_401Unauthorized(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
+ {
+ // Arrange
+ // Expired at "Tuesday, May 18, 2021 11:33:45 PM GMT+10:00"
+ var accessToken = "eyJhbGciOiJQUzI1NiIsImtpZCI6IkFBMjRGMTg1RUUzRjY3NTA0ODA4RkM0RTI2QjEzNUI5OUU2M0JEQTkiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJxaVR4aGU0X1oxQklDUHhPSnJFMXVaNWp2YWsifQ.eyJuYmYiOjE2MjEzNDQ1MjUsImV4cCI6MTYyMTM0NDgyNSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzAwMC9pZHAiLCJhdWQiOiJjZHItcmVnaXN0ZXIiLCJjbGllbnRfaWQiOiI2ZjdhMWI4ZS04Nzk5LTQ4YTgtOTAxMS1lMzkyMDM5MWY3MTMiLCJqdGkiOiJDODRBNTM5MTA2QjI4NUJBODI2RjZGMDQ3MjU4RjBBNCIsImlhdCI6MTYyMTM0NDUyNSwic2NvcGUiOlsiY2RyLXJlZ2lzdGVyOmJhbms6cmVhZCJdLCJjbmYiOnsieDV0I1MyNTYiOiI1OEQ3NkY3QTYxQ0Q3MjZEQTFDNTRGNjg5OEU4RTY5RUE0Qzg4MDYwIn19.RTU-zrqkb-WXcJzCz62SJ4h19lj8MDyGcvLOmg0qx05WFbAsY4mEP3gsoqM1LJfq4ncw7RqSvbkCNQQ-NOnyoBHF8MGe7mzdUh3YrD0_lTg20Dkx1-l044svtP_CKTI3rXT3bZaYWce0Tb1s3mrJzfN3ja23o93FGR-wbIwHp2347b0DxjznpKBw5meLhAjS7OCx6_uMm1la6IziSQgqMd2WaA-od7w8J5br-Nn-QZZi7X1KGiPEKFDFNk8KrUdPc4NCH6t7f-Sbc34KNNEWfAOJkWdDrmsBaifSlWvSlS4nUnurGHYkmimA2JUuv3ZTqzCcLRamEER1ZoTcIs_PDw";
+
+ await Test_WithAccessToken_RespondsWithClientErrorStatusCode(accessToken, industry, expectedStatusCode);
+ }
+
+ [Theory]
+ [InlineData(null, HttpStatusCode.NotFound)]
+ [InlineData("banking")]
+ [InlineData("energy")]
+ [InlineData("non-bank-lending")]
+ [InlineData("telco")]
+ public async Task Get_WithDifferentHolderOfKey_ShouldRespondWith_401Unauthorized(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
+ {
+ // Arrange
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = ADDITIONAL_CERTIFICATE_FILENAME, // ie different holder of key
+ CertificatePassword = ADDITIONAL_CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+ }
+ }
+
+ [Theory]
+ [InlineData("", HttpStatusCode.NotFound, null)] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.NotFound, null)]
+ [InlineData("-1", HttpStatusCode.NotFound, null)]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.NotFound, null)]
+ [InlineData("foo", HttpStatusCode.NotFound, null)]
+ [InlineData("", HttpStatusCode.OK, "banking")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("", HttpStatusCode.OK, "energy")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("", HttpStatusCode.OK, "non-bank-lending")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("", HttpStatusCode.OK, "telco")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "telco")]
+ public async Task Get_WithInvalidPageSize_ShouldRespondWith_400BadRequest_PageSizeMustBePositiveInteger(string pageSize, HttpStatusCode expectedStatusCode, string? industry)
+ {
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/InvalidPageSize",
+ "title": "Invalid Page Size",
+ "detail": "Page size not a positive Integer",
+ }
+ ]
+ }
+ """;
+ await Test_EndpointRespondsSuccessfullyOrWithExpectedError(
+ $"page-size={pageSize}",
+ expectedStatusCode,
+ expectedContent,
+ industry);
+ }
+
+ [Theory]
+ [InlineData("", HttpStatusCode.NotFound, null)] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.NotFound, null)]
+ [InlineData("-1", HttpStatusCode.NotFound, null)]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.NotFound, null)]
+ [InlineData("foo", HttpStatusCode.NotFound, null)]
+ [InlineData("", HttpStatusCode.OK, "banking")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "banking")]
+ [InlineData("", HttpStatusCode.OK, "energy")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "energy")]
+ [InlineData("", HttpStatusCode.OK, "non-bank-lending")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "non-bank-lending")]
+ [InlineData("", HttpStatusCode.OK, "telco")] // "" is effectively not providing a page-size, so it will default to 25.
+ [InlineData("0", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("-1", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("99999999999999999999999999999999999999999999999999", HttpStatusCode.BadRequest, "telco")]
+ [InlineData("foo", HttpStatusCode.BadRequest, "telco")]
+ public async Task Get_WithInvalidPage_ShouldRespondWith_400BadRequest_PageMustBePositiveInteger(string page, HttpStatusCode expectedStatusCode, string? industry)
+ {
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/Invalid",
+ "title": "Invalid Field",
+ "detail": "Page not a positive integer",
+ }
+ ]
+ }
+ """;
+ await Test_EndpointRespondsSuccessfullyOrWithExpectedError(
+ $"page={page}",
+ expectedStatusCode,
+ expectedContent,
+ industry);
+ }
+
+ [Theory]
+ [InlineData(EndpointVersion, null, HttpStatusCode.NotFound)]
+ [InlineData(EndpointVersion, "banking")]
+ [InlineData(EndpointVersion, "energy")]
+ [InlineData(EndpointVersion, "non-bank-lending")]
+ [InlineData(EndpointVersion, "telco")]
+ public async Task Get_WithPageOutOfRange_ShouldRespondWith_400BadRequest_PageExceedsMaxNumberOfPages(string page, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest)
+ {
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/Invalid",
+ "title": "Invalid Field",
+ "detail": "Page is out of range",
+ }
+ ]
+ }
+ """;
+ await Test_EndpointRespondsSuccessfullyOrWithExpectedError(
+ $"page={page}",
+ expectedStatusCode,
+ expectedContent,
+ industry);
+ }
+
+ [Theory]
+ [InlineData("1001", null, HttpStatusCode.NotFound)]
+ [InlineData("1001", "banking")]
+ [InlineData("1001", "energy")]
+ [InlineData("1001", "non-bank-lending")]
+ [InlineData("1001", "telco")]
+ public async Task Get_WithPageSizeTooLarge_ShouldRespondWith_400BadRequest_PageSizeTooLarge(string pageSize, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.BadRequest)
+ {
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/Invalid",
+ "title": "Invalid Field",
+ "detail": "Page size too large",
+ }
+ ]
+ }
+ """;
+ await Test_EndpointRespondsSuccessfullyOrWithExpectedError(
+ $"page-size={pageSize}",
+ expectedStatusCode,
+ expectedContent,
+ industry);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Suspended
+ [InlineData(4, HttpStatusCode.NotFound, null)] // Revoked
+ [InlineData(5, HttpStatusCode.NotFound, null)] // Surrendered
+ [InlineData(6, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "banking")] // Revoked
+ [InlineData(5, HttpStatusCode.Forbidden, "banking")] // Surrendered
+ [InlineData(6, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "energy")] // Revoked
+ [InlineData(5, HttpStatusCode.Forbidden, "energy")] // Surrendered
+ [InlineData(6, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "non-bank-lending")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "non-bank-lending")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "non-bank-lending")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "non-bank-lending")] // Revoked
+ [InlineData(5, HttpStatusCode.Forbidden, "non-bank-lending")] // Surrendered
+ [InlineData(6, HttpStatusCode.Forbidden, "non-bank-lending")] // Inactive
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden, "telco")] // Revoked
+ [InlineData(5, HttpStatusCode.Forbidden, "telco")] // Surrendered
+ [InlineData(6, HttpStatusCode.Forbidden, "telco")] // Inactive
+ public async Task Get_WithDataRecipientNotActive_ShouldRespondWith_403Forbidden(
+ int participationStatusId,
+ HttpStatusCode expectedStatusCode,
+ string? industry)
+ {
+ var saveParticipationStatusId = GetParticipationStatusId(ParticipationId);
+
+ await Test_EndpointValidatesAdrStatus(
+ expectedStatusCode,
+ beforeRequest: () => SetParticipationStatusId(ParticipationId, participationStatusId),
+ afterRequest: () => SetParticipationStatusId(ParticipationId, saveParticipationStatusId),
+ industry: industry);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "non-bank-lending")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "non-bank-lending")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "non-bank-lending")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
+ public async Task Get_WithDataRecipientBrandNotActive_ShouldRespondWith_403Forbidden(
+ int brandStatusId,
+ HttpStatusCode expectedStatusCode,
+ string? industry)
+ {
+ int saveBrandStatusId = GetBrandStatusId(BrandId);
+
+ await Test_EndpointValidatesAdrStatus(
+ expectedStatusCode,
+ beforeRequest: () => SetBrandStatusId(BrandId, brandStatusId),
+ afterRequest: () => SetBrandStatusId(BrandId, saveBrandStatusId),
+ industry: industry);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.NotFound, null)] // Active
+ [InlineData(2, HttpStatusCode.NotFound, null)] // Inactive
+ [InlineData(3, HttpStatusCode.NotFound, null)] // Removed
+ [InlineData(1, HttpStatusCode.OK, "banking")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "banking")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "banking")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "energy")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "energy")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "energy")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "non-bank-lending")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "non-bank-lending")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "non-bank-lending")] // Removed
+ [InlineData(1, HttpStatusCode.OK, "telco")] // Active
+ [InlineData(2, HttpStatusCode.Forbidden, "telco")] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden, "telco")] // Removed
+ public async Task Get_WithDataRecipientSoftwareProductNotActive_ShouldRespondWith_403Forbidden(
+ int softwareProductStatusId,
+ HttpStatusCode expectedStatusCode,
+ string? industry)
+ {
+ int saveSoftwareProductStatusId = GetSoftwareProductStatusId(SoftwareProductId);
+
+ await Test_EndpointValidatesAdrStatus(
+ expectedStatusCode,
+ beforeRequest: () => SetSoftwareProductStatusId(SoftwareProductId, softwareProductStatusId),
+ afterRequest: () => SetSoftwareProductStatusId(SoftwareProductId, saveSoftwareProductStatusId),
+ industry: industry);
+ }
+
+ [Theory]
+ [InlineData("all")]
+ public async Task Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag(string? industry)
+ {
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ // Arrange - Get brands and save the ETag
+ var expectedETag = (await new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ IfNoneMatch = null, // ie If-None-Match is not set
+ }.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
+
+ // Act - Use Etag
+ var response = await new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ IfNoneMatch = expectedETag,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.NotModified);
+
+ // Assert - No content
+ (await response.Content.ReadAsStringAsync()).Should().BeNullOrEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData("foo")]
+ public async Task Get_WithInvalidIndustry_ShouldRespondWith_400BadRequest(string industry)
+ {
+ // Arrange
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
+
+ // Assert - Check error response
+ if (response.StatusCode != HttpStatusCode.OK)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check error response
+ var expectedContent = @"
+ {
+ ""errors"": [
+ {
+ ""code"": ""urn:au-cds:error:cds-all:Field/Invalid"",
+ ""title"": ""Invalid Field"",
+ ""detail"": ""industry"",
+ }
+ ]
+ }";
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(null, "cdr-register:read", HttpStatusCode.NotFound)] // No industry
+ [InlineData("banking", "cdr-register:read", HttpStatusCode.OK)]
+ [InlineData("energy", "cdr-register:read", HttpStatusCode.OK)]
+ [InlineData("non-bank-lending", "cdr-register:read", HttpStatusCode.OK)]
+ [InlineData("telco", "cdr-register:read", HttpStatusCode.OK)]
+ public async Task Get_WithScope_ShouldRespondWith_200OK(string? industry, string scope, HttpStatusCode expectedStatusCode)
+ {
+ // Arrange
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ Scope = scope,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+ }
+ }
+
+ [Theory]
+ [InlineData(EndpointVersion, UnsupportedEndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Should return current version - x-min-v is ignored when > x-v
+ [InlineData(EndpointVersion, LegacyEndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Should return current version - x-v is supported and higher than x-min-v
+ [InlineData(EndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Should return current version - x-v is supported equal to x-min-v
+ [InlineData(UnsupportedEndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Should return current version - x-v is NOT supported and x-min-v is supported
+ [InlineData(EndpointVersion, UnsupportedEndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "BANKing")] // Valid. Should return current version - x-min-v is ignored when > x-v
+ [InlineData(EndpointVersion, LegacyEndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "Telco")] // Valid. Should return current version - x-v is supported and higher than x-min-v
+ [InlineData(EndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "energy")] // Valid. Should return current version - x-v is supported equal to x-min-v
+ [InlineData(EndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "mining")] // Invalid Industry
+
+ [InlineData(EndpointVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v (not a positive integer)
+ [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", EndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+
+ // Also check industry specific calls
+ [InlineData(UnsupportedEndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "", "banking")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData(UnsupportedEndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "", "energy")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData(UnsupportedEndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "", "non-bank-lending")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+ [InlineData(UnsupportedEndpointVersion, EndpointVersion, EndpointVersion, HttpStatusCode.OK, true, "", "telco")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
+
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "energy")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "non-bank-lending")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "telco")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "banking")] // Invalid. x-v header is missing
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "energy")] // Invalid. x-v header is missing
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "non-bank-lending")] // Invalid. x-v header is missing
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "telco")] // Invalid. x-v header is missing
+
+ public async Task ValidateVersionHeader(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expectedError, string industry = "all")
+ {
+ // Arrange
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = xv,
+ XMinV = minXv,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expectedError, response.Content);
+ }
+ }
+ }
+
+ private static async Task Test_QueryParameters_RespondWithExpectedStatusAndBody(
+ DateTime? updatedSince,
+ int? queryPage,
+ int? queryPageSize,
+ string? industry = null,
+ HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
+ {
+ static string GetUrl(string baseUrl, DateTime? updatedSince, int? queryPage, int? queryPageSize)
+ {
+ // Build query
+ var query = new KeyValuePairBuilder();
+
+ if (updatedSince != null)
+ {
+ query.Add("updated-since", ((DateTime)updatedSince).ToString("yyyy-MM-ddTHH:mm:ssZ"));
+ }
+
+ if (queryPage != null)
+ {
+ query.Add("page", queryPage.Value);
+ }
+
+ if (queryPageSize != null)
+ {
+ query.Add("page-size", queryPageSize.Value);
+ }
+
+ return query.Count > 0 ?
+ $"{baseUrl}?{query.Value}" :
+ baseUrl;
+ }
+
+ // Arrange
+ var baseUrl = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands";
+ var url = GetUrl(baseUrl, updatedSince, queryPage, queryPageSize);
+
+ var expectedResponse = GetExpectedResponse(baseUrl, url, updatedSince, queryPage, queryPageSize, industry);
+
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(api.XV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedResponse, response.Content);
+ }
+ }
+ }
+
+ private static string GetExpectedResponse(string baseUrl, string selfUrl, DateTime? updatedSince, int? requestedPage, int? requestedPageSize, string? industry = null)
+ {
+ static string Link(string baseUrl, DateTime? updatedSince, int? page = null, int? pageSize = null)
+ {
+ var query = new KeyValuePairBuilder();
+
+ if (updatedSince != null)
+ {
+ query.Add("updated-since", ((DateTime)updatedSince).ToString("yyyy-MM-ddTHH\\%3Amm\\%3Ass.fffffffZ"));
+ }
+
+ if (page != null)
+ {
+ query.Add("page", page.Value);
+ }
+
+ if (pageSize != null)
+ {
+ query.Add("page-size", pageSize.Value);
+ }
+
+ return query.Count == 0 ?
+ baseUrl :
+ $"{baseUrl}?{query.Value}";
+ }
+
+ if (industry == "all")
+ {
+ industry = null; // treat "all" same as no industry
+ }
+
+ var page = requestedPage ?? 1;
+ var pageSize = requestedPageSize ?? 25;
+
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var allData = dbContext.Brands.AsNoTracking()
+ .Include(brand => brand.Endpoint)
+ .Include(brand => brand.BrandStatus)
+ .Include(brand => brand.AuthDetails)
+ .ThenInclude(authDetail => authDetail.RegisterUType)
+ .Include(brand => brand.Participation.LegalEntity.OrganisationType)
+ .Include(brand => brand.Participation.Industry)
+ .Where(brand =>
+ brand.Participation.ParticipationTypeId == ParticipationTypes.Dh &&
+ (industry == null || (industry != null && brand.Participation.Industry.IndustryTypeCode == industry)))
+ .Where(brand => brand.Participation.StatusId == ParticipationStatusType.Active)
+ .Where(brand => brand.BrandStatusId == BrandStatusType.Active)
+ .Where(brand => updatedSince == null || brand.LastUpdated > updatedSince);
+
+ var totalRecords = allData.Count();
+ var totalPages = (int)Math.Ceiling((double)totalRecords / pageSize);
+ const int minPage = 1;
+ if (page < minPage)
+ {
+ throw new Exception($"Page {page} out of range. Min Page is {minPage}");
+ }
+
+ var maxPage = ((totalRecords - 1) / pageSize) + 1;
+ if (page > maxPage)
+ {
+ throw new Exception($"Page {page} out of range. Max Page is {maxPage} (Records={totalRecords}, PageSize={pageSize})");
+ }
+
+ var data = allData
+ .OrderBy(brand => brand.BrandName).ThenBy(brand => brand.BrandId)
+ .Skip((page - 1) * pageSize)
+ .Take(pageSize)
+ .Select(brand => new
+ {
+ dataHolderBrandId = brand.BrandId,
+ brandName = brand.BrandName,
+ brandGroup = brand.BrandGroup,
+ industries = new string[] { brand.Participation.Industry.IndustryTypeCode.ToLower() },
+ logoUri = brand.LogoUri,
+ legalEntity = new
+ {
+ legalEntityId = brand.Participation.LegalEntity.LegalEntityId,
+ legalEntityName = brand.Participation.LegalEntity.LegalEntityName,
+ logoUri = brand.Participation.LegalEntity.LogoUri,
+ registrationNumber = brand.Participation.LegalEntity.RegistrationNumber,
+ registrationDate = brand.Participation.LegalEntity.RegistrationDate == null ? null : brand.Participation.LegalEntity.RegistrationDate.Value.ToString("yyyy-MM-dd"),
+ registeredCountry = brand.Participation.LegalEntity.RegisteredCountry,
+ abn = brand.Participation.LegalEntity.Abn,
+ acn = brand.Participation.LegalEntity.Acn,
+ arbn = brand.Participation.LegalEntity.Arbn,
+ anzsicDivision = brand.Participation.LegalEntity.AnzsicDivision,
+ organisationType = brand.Participation.LegalEntity.OrganisationType.OrganisationTypeCode,
+ status = brand.Participation.Status.ParticipationStatusCode.ToUpper(),
+ },
+ status = brand.BrandStatus.BrandStatusCode,
+ endpointDetail = new
+ {
+ version = brand.Endpoint.Version,
+ publicBaseUri = brand.Endpoint.PublicBaseUri,
+ productBaseUri = brand.Endpoint.ProductBaseUri,
+ resourceBaseUri = brand.Endpoint.ResourceBaseUri,
+ infosecBaseUri = brand.Endpoint.InfosecBaseUri,
+ extensionBaseUri = brand.Endpoint.ExtensionBaseUri,
+ websiteUri = brand.Endpoint.WebsiteUri,
+ },
+ authDetails = brand.AuthDetails.Select(authDetails => new
+ {
+ registerUType = authDetails.RegisterUType.RegisterUTypeCode,
+ jwksEndpoint = authDetails.JwksEndpoint,
+ }),
+ lastUpdated = brand.LastUpdated.ToString("yyyy-MM-ddTHH:mm:ssZ"),
+ })
+ .ToList();
+
+ var expectedResponse = new
+ {
+ data,
+ links = new
+ {
+ first = totalPages == 0 ?
+ null :
+ Link(baseUrl, updatedSince, 1, pageSize),
+ last = totalPages == 0 ?
+ null :
+ Link(baseUrl, updatedSince, totalPages, pageSize),
+ next = totalPages == 0 || page == totalPages ?
+ null :
+ Link(baseUrl, updatedSince, page + 1, pageSize),
+ prev = totalPages == 0 || page == 1 ?
+ null :
+ Link(baseUrl, updatedSince, page - 1, pageSize),
+ self = selfUrl,
+ },
+ meta = new
+ {
+ totalRecords,
+ totalPages,
+ },
+ };
+
+ return JsonConvert.SerializeObject(expectedResponse);
+ }
+
+ ///
+ /// Ensures that the endpoint responds with the expected client error status code for a given access token.
+ ///
+ /// The access token.
+ /// The industry.
+ /// The expected status code.
+ /// A representing the asynchronous operation.
+ private static async Task Test_WithAccessToken_RespondsWithClientErrorStatusCode(string? accessToken, string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.Unauthorized)
+ {
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+ }
+ }
+
+ ///
+ /// Validate that the request with the given query string and valid authorization responds successfully, or with an appropriate error message.
+ ///
+ /// The query string to test.
+ /// The expected response status.
+ /// The expected response error content.
+ /// The industry.
+ /// A representing the asynchronous operation.
+ private static async Task Test_EndpointRespondsSuccessfullyOrWithExpectedError(string queryString, HttpStatusCode expectedStatusCode, string expectedContent, string? industry)
+ {
+ // Arrange
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands?{queryString}",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ // Assert - Check error response
+ if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check error response
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+ }
+ }
+
+ ///
+ /// Validates the ADR status is validated.
+ ///
+ /// The expected response status.
+ /// Set up actions to change state prior to making the request.
+ /// Post-request actions to reset state.
+ /// The industry.
+ /// A representing the asynchronous operation.
+ private static async Task Test_EndpointValidatesAdrStatus(
+ HttpStatusCode expectedStatusCode,
+ BeforeRequest? beforeRequest,
+ AfterRequest? afterRequest,
+ string? industry)
+ {
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-holders/brands",
+ AccessToken = accessToken,
+ XV = EndpointVersion,
+ };
+
+ beforeRequest?.Invoke();
+ try
+ {
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ // Assert - Check error response
+ if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NotFound)
+ {
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check error response
+ var expectedContent = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Authorisation/AdrStatusNotActive",
+ "title": "ADR Status Is Not Active",
+ "detail": "",
+ }
+ ]
+ }
+ """;
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+ }
+ }
+ finally
+ {
+ afterRequest?.Invoke();
+ }
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataRecipientsXV4_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataRecipientsXV4_MultiIndustry_Tests.cs
new file mode 100644
index 0000000..02662c4
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/GetDataRecipientsXV4_MultiIndustry_Tests.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using CDR.Register.Repository.Enums;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.Discovery
+{
+ ///
+ /// Integration tests for GetDataRecipients.
+ ///
+ public class GetDataRecipientsXV4_MultiIndustry_Tests : BaseTest
+ {
+ ///
+ /// The current endpoint version under test.
+ ///
+ private const string SupportedVersion = "4";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "3";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "5";
+
+ public GetDataRecipientsXV4_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, "all")]
+ public async Task Get_WithXV_ShouldRespondWith_200OK_DataRecipients(string xv, string industry)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients";
+ var expectedDataRecipients = GetExpectedDataRecipients(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // // Assert - Check XV
+ Assert_HasHeader(xv, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipients, response.Content);
+ }
+ }
+
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(SupportedVersion, "all")]
+ public async Task CTS_URL_Get_WithXV_ShouldRespondWith_200OK_DataRecipients(string xv, string industry)
+ {
+ // Arrange
+ var url = $"{GenerateDynamicCtsUrl(DISCOVERY_DOWNSTREAM_BASE_URL)}/cdr-register/v1/{industry}/data-recipients";
+ var expectedDataRecipients = GetExpectedDataRecipients(ReplacePublicHostName(url, DISCOVERY_DOWNSTREAM_BASE_URL));
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // // Assert - Check XV
+ Assert_HasHeader(xv, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipients, response.Content);
+ }
+ }
+
+ [Theory]
+ [InlineData(null)] // AC04
+ [InlineData("foo")] // AC06
+ public async Task Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients";
+ var expectedDataRecipients = GetExpectedDataRecipients(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = SupportedVersion,
+ IfNoneMatch = ifNoneMatch,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(SupportedVersion, response.Headers, "x-v");
+
+ // Assert - Check has any ETag
+ Assert_HasHeader(null, response.Headers, "ETag");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipients, response.Content);
+ }
+ }
+
+ [Fact]
+ public async Task Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
+ {
+ // Arrange - Get SoftwareProductsStatus and save the ETag
+ var expectedETag = (await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients",
+ XV = SupportedVersion,
+ IfNoneMatch = null, // ie If-None-Match is not set
+ }.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/all/data-recipients",
+ XV = SupportedVersion,
+ IfNoneMatch = expectedETag,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.NotModified);
+
+ // Assert - No content
+ (await response.Content.ReadAsStringAsync()).Should().BeNullOrEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is supported and higher than x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is supported equal to x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "banking")] // Invalid. Industry other than 'All'
+ [InlineData(SupportedVersion, LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "ENERGY")] // Invalid.Industry other than 'All'
+ [InlineData(SupportedVersion, LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "telCO")] // Invalid.Industry other than 'All'
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "non-bank-lending")] // Invalid. Industry other than 'All'
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "Mining")] // Invalid. Industry other than 'All'
+ [InlineData(LegacyEndpointVersion, "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "non-bank-lending")] // Invalid. Industry other than 'All'
+ [InlineData(UnsupportedEndpointVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is NOT supported and x-min-v is supported
+ [InlineData(SupportedVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // invalid. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", SupportedVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+
+ public async Task VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "all")
+ {
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients",
+ XV = xv,
+ XMinV = minXv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expecetdError, response.Content);
+ }
+ }
+ }
+
+ // Get expected data recipients
+ private static string GetExpectedDataRecipients(string url)
+ {
+ try
+ {
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var expectedDataRecipients = new
+ {
+ data = dbContext.Participations.AsNoTracking()
+ .Include(participation => participation.Status)
+ .Include(participation => participation.Industry)
+ .Include(participation => participation.LegalEntity)
+ .Include(participation => participation.Brands)
+ .ThenInclude(brand => brand.BrandStatus)
+ .Include(participation => participation.Brands)
+ .ThenInclude(brand => brand.SoftwareProducts)
+ .ThenInclude(softwareProduct => softwareProduct.Status)
+ .Where(participation => participation.ParticipationTypeId == ParticipationTypes.Dr)
+ .OrderBy(participation => participation.LegalEntityId)
+ .Select(participation => new
+ {
+ legalEntityId = participation.LegalEntityId,
+ legalEntityName = participation.LegalEntity.LegalEntityName,
+ accreditationNumber = participation.LegalEntity.AccreditationNumber,
+ accreditationLevel = participation.LegalEntity.AccreditationLevel.AccreditationLevelCode.ToUpper(), // DF: accreditation level should be uppercase.
+ logoUri = participation.LegalEntity.LogoUri,
+ dataRecipientBrands = participation.Brands.OrderBy(b => b.BrandId).Select(brand => new
+ {
+ dataRecipientBrandId = brand.BrandId,
+ brandName = brand.BrandName,
+ logoUri = brand.LogoUri,
+ softwareProducts = brand.SoftwareProducts.OrderBy(sp => sp.SoftwareProductId.ToString()).Select(softwareProduct => new
+ {
+ softwareProductId = softwareProduct.SoftwareProductId,
+ softwareProductName = softwareProduct.SoftwareProductName,
+ softwareProductDescription = softwareProduct.SoftwareProductDescription,
+ logoUri = softwareProduct.LogoUri,
+ status = softwareProduct.Status.SoftwareProductStatusCode,
+ }),
+ status = brand.BrandStatus.BrandStatusCode,
+ }),
+ status = participation.Status.ParticipationStatusCode,
+ lastUpdated = participation.Brands.OrderByDescending(brand => brand.LastUpdated).First().LastUpdated.ToString("yyyy-MM-ddTHH:mm:ssZ"),
+ })
+ .ToList(),
+
+ // DF: these are new properties that need to be included in the Get Data Recipients payload.
+ links = new
+ {
+ self = url,
+ },
+ meta = new object(),
+ };
+
+ string result = JsonConvert.SerializeObject(expectedDataRecipients);
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Error getting expected data recipients - {ex.Message}");
+ }
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
index a7ce3ae..92a4401 100644
--- a/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/US27560_GetDataRecipients_MultiIndustry_Tests.cs
@@ -171,21 +171,21 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
}
[Theory]
- [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("3", "5", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
[InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
[InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported equal to x-min-v
- [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("5", "3", "4", HttpStatusCode.BadRequest, true, "")] // Invalid. Should return v4 - x-v is NOT supported
[InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
[InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // invalid. x-v is not supported and x-min-v invalid
- [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
+ [InlineData("5", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // invalid. x-v is not supported and x-min-v invalid
+ [InlineData("5", "5", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
[InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
[InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("5", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
[InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
diff --git a/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrandsXV2_MultiIndustry_Tests.cs
similarity index 96%
rename from Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs
rename to Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrandsXV2_MultiIndustry_Tests.cs
index efb6a88..71bde4e 100644
--- a/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrands_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Discovery/US27562_GetDataHolderBrandsXV2_MultiIndustry_Tests.cs
@@ -21,12 +21,12 @@ namespace CDR.Register.IntegrationTests.API.Discovery
///
/// Integration tests for GetDataHolderBrands.
///
- public class US27562_GetDataHolderBrands_MultiIndustry_Tests : BaseTest
+ public class US27562_GetDataHolderBrandsXV2_MultiIndustry_Tests : BaseTest
{
private const string BRANDID = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
private const string SOFTWAREPRODUCTID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
- public US27562_GetDataHolderBrands_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ public US27562_GetDataHolderBrandsXV2_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
: base(outputHelper, testFixture)
{
}
@@ -43,6 +43,7 @@ public US27562_GetDataHolderBrands_MultiIndustry_Tests(ITestOutputHelper outputH
[InlineData("banking")]
[InlineData("energy")]
[InlineData("telco")]
+ [InlineData("non-bank-lending", HttpStatusCode.BadRequest)]
public async Task AC01_Get_WithNoQueryString_ShouldRespondWith_200OK_First25RecordsAsync(string? industry, HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
{
await Test_AC01_AC02_AC03_AC04_AC05_AC06(null, null, null, industry, expectedStatusCode);
@@ -574,6 +575,7 @@ public async Task ACX20_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotMod
[Theory]
[InlineData("foo")]
+ [InlineData("non-bank-lending")]
public async Task ACX01_Get_WithInvalidIndustry_ShouldRespondWith_400BadRequest(string industry)
{
// Arrange
@@ -662,32 +664,35 @@ public async Task ACX02_Get_WithScope_ShouldRespondWith_200OK(string? industry,
[Theory]
[InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "BANKing")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "tELCO")] // Valid. Should return v2 - x-v is supported equal to x-min-v
[InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported but there is a newer version
[InlineData("2", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v (not a positive integer)
+ [InlineData("2", "3", "2", HttpStatusCode.OK, true, "ENERGY")] // Valid. Should return v2 - x-min-v is ignored when > x-v
[InlineData("99", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v (not a positive integer)
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
[InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
[InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
[InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
// Also check industry specific calls
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "banking")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "energy")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "", "telco")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "energy")] // Unsupported. x-v is not supported and x-min-v invalid
- [InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "telco")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "", "banking")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "", "energy")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "", "telco")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "energy")] // Unsupported. x-v is not supported and x-min-v invalid
+ [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "telco")] // Unsupported. x-v is not supported and x-min-v invalid
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "banking")] // Invalid. x-v header is missing
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "energy")] // Invalid. x-v header is missing
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR, "telco")] // Invalid. x-v header is missing
+ [InlineData("2", null, "2", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "non-bank-lending")] // Invalid industry. Non-bank lending isn't supported for V2.
public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "all")
{
@@ -854,6 +859,7 @@ static string Link(string baseUrl, DateTime? updatedSince, int? page = null, int
.ThenInclude(authDetail => authDetail.RegisterUType)
.Include(brand => brand.Participation.LegalEntity.OrganisationType)
.Include(brand => brand.Participation.Industry)
+ .Where(brand => brand.Participation.Industry.IndustryTypeId != Industry.NONBANKLENDING)
.Where(brand =>
brand.Participation.ParticipationTypeId == ParticipationTypes.Dh &&
(industry == null || (industry != null && brand.Participation.Industry.IndustryTypeCode == industry)))
diff --git a/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.AccessTokenType.cs b/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.AccessTokenType.cs
new file mode 100644
index 0000000..fdcb9ae
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.AccessTokenType.cs
@@ -0,0 +1,15 @@
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.SSA
+{
+public partial class GetSoftwareStatementAssertion_Tests
+ {
+ private enum AccessTokenType
+ {
+ ValidAccessToken, // Get and send valid access token
+ InvalidAccessToken, // Send an invalid access token
+ ExpiredAccessToken, // Send expired access token
+ NoAccessToken, // Don't send any access token
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.cs b/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.cs
new file mode 100644
index 0000000..f25e91c
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/SSA/GetSoftwareStatementAssertion_Tests.cs
@@ -0,0 +1,590 @@
+using System;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Azure.Core;
+using CDR.Register.IntegrationTests.Extensions;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.IdentityModel.Tokens;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.SSA
+{
+ ///
+ /// Integration tests for GetSoftwareStatementAssertion.
+ ///
+ public partial class GetSoftwareStatementAssertion_Tests : BaseTest
+ {
+ ///
+ /// The supported version.
+ ///
+ private const string SupportedVersion = "4";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "3";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "5";
+
+ ///
+ /// The obsolete (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string ObsoleteEndpointVersion = "2";
+
+ private const string BrandId = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
+ private const string SoftwareProductId = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
+
+ private const string ExpectedContentAdrStatusNotActive = @"
+ {
+ ""errors"": [
+ {
+ ""code"": ""urn:au-cds:error:cds-all:Authorisation/AdrStatusNotActive"",
+ ""title"": ""ADR Status Is Not Active"",
+ ""detail"": """",
+ }
+ ]
+ }";
+
+ public GetSoftwareStatementAssertion_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
+ private delegate void BeforeSSARequest();
+
+ private delegate void AfterSSARequest();
+
+ // Participation/Brand/SoftwareProduct Ids
+ private static string ParticipationId => GetParticipationId(BrandId); // lookup.
+
+ [Theory]
+ [InlineData(SupportedVersion)]
+ public async Task GetSSA_WithXV1_ShouldRespondWith_200OK_V4ofSSA(string xv)
+ {
+ // Arrange - Get SoftwareProduct
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+ var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
+ .Include(sp => sp.Brand)
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
+ .SingleAsync();
+
+ // Arrange - Get access token
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ // Act - Send request to SSA API
+ var response = await new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa",
+ XV = xv.ToString(),
+ AccessToken = accessToken,
+ }.SendAsync();
+
+ await AssertSsa(response, softwareProduct, xv);
+ }
+
+ [Theory]
+ [InlineData("all")]
+ public async Task GetSSA_WithDifferentIndustry_ShouldRespondWith_DifferentScopes(string industry)
+ {
+ // Arrange - Get SoftwareProduct
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+ var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
+ .Include(sp => sp.Brand)
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
+ .SingleAsync();
+
+ // Arrange - Get access token
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ // Act - Send request to SSA API
+ var response = await new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa",
+ XV = SupportedVersion,
+ AccessToken = accessToken,
+ }.SendAsync();
+
+ await AssertSsa(response, softwareProduct, SupportedVersion);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.OK)] // Active
+ [InlineData(2, HttpStatusCode.Forbidden)] // Removed
+ [InlineData(3, HttpStatusCode.Forbidden)] // Suspended
+ [InlineData(4, HttpStatusCode.Forbidden)] // Revoked
+ [InlineData(5, HttpStatusCode.Forbidden)] // Surrendered
+ [InlineData(6, HttpStatusCode.Forbidden)] // Inactive
+ public async Task GetSSA_WithParticipationStatusNotActive_ShouldRespondWith_403Forbidden(
+ int participationStatusId,
+ HttpStatusCode expectedStatusCode)
+ {
+ int saveParticipationStatusId = GetParticipationStatusId(ParticipationId);
+
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ expectedStatusCode,
+ beforeRequest: () => SetParticipationStatusId(ParticipationId, participationStatusId),
+ afterRequest: () => SetParticipationStatusId(ParticipationId, saveParticipationStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.OK)] // Active
+ [InlineData(2, HttpStatusCode.Forbidden)] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ public async Task GetSSA_WithBrandNotActive_ShouldRespondWith_403Forbidden(
+ int brandStatusId,
+ HttpStatusCode expectedStatusCode)
+ {
+ int saveBrandStatusId = GetBrandStatusId(BrandId);
+
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ expectedStatusCode,
+ beforeRequest: () => SetBrandStatusId(BrandId, brandStatusId),
+ afterRequest: () => SetBrandStatusId(BrandId, saveBrandStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
+ }
+
+ [Theory]
+ [InlineData(1, HttpStatusCode.OK)] // Active
+ [InlineData(2, HttpStatusCode.Forbidden)] // Inactive
+ [InlineData(3, HttpStatusCode.Forbidden)] // Removed
+ public async Task GetSSA_WithSoftwareProductNotActive_ShouldRespondWith_403Forbidden(
+ int softwareProductStatusId,
+ HttpStatusCode expectedStatusCode)
+ {
+ int saveSoftwareProductStatusId = GetSoftwareProductStatusId(SoftwareProductId);
+
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ expectedStatusCode,
+ beforeRequest: () => SetSoftwareProductStatusId(SoftwareProductId, softwareProductStatusId),
+ afterRequest: () => SetSoftwareProductStatusId(SoftwareProductId, saveSoftwareProductStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion)]
+ public async Task GetSSA_WithNoAccessToken_ShouldRespondWith_401Unauthorized(string x_v)
+ {
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.Unauthorized,
+ AccessTokenType.NoAccessToken,
+ x_v: x_v);
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion)]
+ public async Task GetSSA_WithInvalidAccessToken_ShouldRespondWith_401Unauthorized(string x_v)
+ {
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.Unauthorized,
+ AccessTokenType.InvalidAccessToken,
+ x_v: x_v);
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion)]
+ public async Task GetSSA_WithExpiredAccessToken_ShouldRespondWith_401Unauthorized(string x_v)
+ {
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.Unauthorized,
+ AccessTokenType.ExpiredAccessToken,
+ x_v: x_v);
+ }
+
+ [Fact]
+ public async Task GetSSA_DifferentHolderOfKey_ShouldRespondWith_401Unauthorized()
+ {
+ await Test_GetSSA(
+ ADDITIONAL_CERTIFICATE_FILENAME,
+ ADDITIONAL_CERTIFICATE_PASSWORD,
+ HttpStatusCode.Unauthorized,
+ getAccessTokenCertificateFilename: CERTIFICATE_FILENAME,
+ getAccessTokenCertificatePassword: CERTIFICATE_PASSWORD);
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, "foo")]
+ public async Task GetSSA_InvalidSoftwareProductId_ShouldRespondWith_404NotFound(string xv, string softwareProductId)
+ {
+ var expectedContent =
+ $@"
+ {{
+ ""errors"": [
+ {{
+ ""code"": ""urn:au-cds:error:cds-register:Field/InvalidSoftwareProduct"",
+ ""title"": ""Invalid Software Product"",
+ ""detail"": ""{softwareProductId}"",
+ }}
+ ]
+ }}";
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.NotFound,
+ x_v: xv,
+ softwareProductId: softwareProductId,
+ expectedContent: expectedContent);
+ }
+
+ [Theory]
+ [InlineData("")]
+ public async Task GetSSA_WithMissingSoftwareProductId_ShouldRespondWith_404NotFound(string softwareProductId)
+ {
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.NotFound,
+ x_v: "3",
+ softwareProductId: softwareProductId);
+ }
+
+ [Fact]
+ public async Task GetSSA_WithRandomBrandId_ShouldRespondWith_404NotFound()
+ {
+ await Test_GetSSA(
+ CERTIFICATE_FILENAME,
+ CERTIFICATE_PASSWORD,
+ HttpStatusCode.NotFound,
+ brandId: Guid.NewGuid().ToString());
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is supported and higher than x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is supported equal to x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "banking")] // Invalid. Industry other than 'All'
+ [InlineData(SupportedVersion, LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "ENERGY")] // Invalid.Industry other than 'All'
+ [InlineData(SupportedVersion, LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "telCO")] // Invalid.Industry other than 'All'
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "non-bank-lending")] // Invalid. Industry other than 'All'
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "Mining")] // Invalid. Industry other than 'All'
+ [InlineData(LegacyEndpointVersion, "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "non-bank-lending")] // Invalid. Industry other than 'All'
+ [InlineData(UnsupportedEndpointVersion, SupportedVersion, "4", HttpStatusCode.OK, true, "")] // Valid. Should return v4 - x-v is NOT supported and x-min-v is supported
+ [InlineData(SupportedVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 4
+ [InlineData(ObsoleteEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", SupportedVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+
+ public async Task ACX01_VersionHeaderValidation(string? xv, string? xminv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "all")
+ {
+ // Arrange
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa";
+
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ }.GetAsync();
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ AccessToken = accessToken,
+ XV = xv,
+ XMinV = xminv,
+ };
+
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expecetdError, response.Content);
+ }
+ }
+ }
+
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(SupportedVersion)]
+ public async Task CTS_URL_GetSSA_WithXV1_ShouldRespondWith_200OK_V4ofSSA(string xv)
+ {
+ string conformanceId = Guid.NewGuid().ToString();
+ string tokenEndpoint = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL, conformanceId)}/idp/connect/token";
+ string ssasEndpoint = $"{GenerateDynamicCtsUrl(SSA_DOWNSTREAM_BASE_URL, conformanceId)}/cdr-register/v1/all/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa";
+
+ // Arrange - Get SoftwareProduct
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+ Repository.Entities.SoftwareProduct softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
+ .Include(sp => sp.Brand)
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
+ .SingleAsync();
+
+ // Arrange - Get access token
+ var accessToken = await new Infrastructure.AccessToken
+ {
+ CertificateFilename = CERTIFICATE_FILENAME,
+ CertificatePassword = CERTIFICATE_PASSWORD,
+ Scope = "cdr-register:read",
+ Audience = ReplaceSecureHostName(tokenEndpoint, IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL),
+ TokenEndPoint = tokenEndpoint,
+ CertificateThumbprint = DEFAULT_CERTIFICATE_THUMBPRINT,
+ CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME,
+ }.GetAsync(addCertificateToRequest: false);
+
+ // Act - Send request to SSA API
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = ssasEndpoint,
+ XV = xv.ToString(),
+ AccessToken = accessToken,
+ CertificateThumbprint = DEFAULT_CERTIFICATE_THUMBPRINT,
+ CertificateCn = DEFAULT_CERTIFICATE_COMMON_NAME,
+ }.SendAsync();
+
+ await AssertSsa(response, softwareProduct, xv);
+ }
+
+ private static async Task AssertSsa(HttpResponseMessage response, Repository.Entities.SoftwareProduct softwareProduct, string xv)
+ {
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ // Get the SSA JWKS from the Register.
+ var ssaJwks = await GetSsaJwks();
+
+ // Assert - Check XV
+ Assert_HasHeader(xv.ToString(), response.Headers, "x-v");
+
+ // Assert - SSA
+ var ssa = new JwtSecurityTokenHandler().ReadJwtToken(await response.Content.ReadAsStringAsync());
+
+ // Assert - SSA Header
+ ssa.Header.Alg.Should().Be("PS256");
+ ssa.Header.Kid.Should().Be(ssaJwks.Keys[0].Kid);
+ ssa.Header.Typ.Should().Be("JWT");
+
+ // Assert - SSA Claims
+ ssa.AssertClaim("iss", "cdr-register");
+
+ ssa.AssertClaim("iat", null);
+ ssa.AssertClaim("exp", null);
+ long iat = Convert.ToInt64(ssa.Claim("iat").Value);
+ long exp = Convert.ToInt64(ssa.Claim("exp").Value);
+ exp.Should().Be(iat + 600); // Check expiry is 10 minutes (ie 600 seconds)
+
+ ssa.AssertClaim("jti", null);
+ ssa.AssertClaim("org_id", softwareProduct.Brand.BrandId.ToString());
+ ssa.AssertClaim("org_name", softwareProduct.Brand.BrandName);
+ ssa.AssertClaim("client_name", softwareProduct.SoftwareProductName);
+ ssa.AssertClaim("client_description", softwareProduct.SoftwareProductDescription);
+ ssa.AssertClaim("client_uri", softwareProduct.ClientUri);
+ ssa.AssertClaimIsArray("redirect_uris", softwareProduct.RedirectUris.Split(" "));
+ ssa.AssertClaim("logo_uri", softwareProduct.LogoUri);
+ ssa.AssertClaim("tos_uri", softwareProduct.TosUri, true);
+ ssa.AssertClaim("policy_uri", softwareProduct.PolicyUri, true);
+ ssa.AssertClaim("jwks_uri", softwareProduct.JwksUri);
+ ssa.AssertClaim("revocation_uri", softwareProduct.RevocationUri);
+ ssa.AssertClaim("software_id", softwareProduct.SoftwareProductId.ToString());
+ ssa.AssertClaim("software_roles", "data-recipient-software-product");
+ ssa.AssertClaim("scope", softwareProduct.Scope);
+
+ if (int.Parse(xv) >= 2)
+ {
+ ssa.AssertClaim("recipient_base_uri", softwareProduct.RecipientBaseUri);
+ }
+
+ // Assert - Validate SSA Signature
+ var validationParameters = new TokenValidationParameters()
+ {
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.FromMinutes(2),
+
+ RequireSignedTokens = true,
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = ssaJwks.Keys[0],
+
+ ValidateIssuer = true,
+ ValidIssuer = "cdr-register",
+
+ ValidateAudience = false,
+ };
+
+ // Validate token (throws exception if token fails to validate)
+ new JwtSecurityTokenHandler().ValidateToken(ssa.RawData, validationParameters, out _);
+ }
+ }
+ }
+
+ private static async Task Test_GetSSA(
+ string certificateFilename,
+ string certificatePassword,
+ HttpStatusCode expectedStatusCode,
+ AccessTokenType accessTokenType = AccessTokenType.ValidAccessToken,
+ BeforeSSARequest? beforeRequest = null,
+ AfterSSARequest? afterRequest = null,
+ string? x_v = "3",
+ string? x_min_v = null,
+ string? expectedContent = null,
+ string? getAccessTokenCertificateFilename = null,
+ string? getAccessTokenCertificatePassword = null,
+ string? expectedXV = null,
+ string? industry = "all",
+ string brandId = BrandId,
+ string softwareProductId = SoftwareProductId)
+ {
+ // Arrange
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{brandId}/software-products/{softwareProductId}/ssa";
+
+ var accessToken = await GetAccessToken(
+ accessTokenType,
+ getAccessTokenCertificateFilename,
+ getAccessTokenCertificatePassword,
+ certificateFilename,
+ certificatePassword);
+
+ var api = new Infrastructure.Api
+ {
+ CertificateFilename = certificateFilename,
+ CertificatePassword = certificatePassword,
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ AccessToken = accessToken,
+ XV = x_v,
+ XMinV = x_min_v,
+ };
+
+ beforeRequest?.Invoke();
+ try
+ {
+ // Act
+ var response = await api.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedStatusCode);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV ?? x_v, response.Headers, "x-v");
+ }
+
+ // Assert - Check expected content
+ if (expectedContent != null)
+ {
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+ }
+ }
+ finally
+ {
+ afterRequest?.Invoke();
+ }
+ }
+
+ private static async Task GetAccessToken(
+ AccessTokenType accessTokenType,
+ string? getAccessTokenCertificateFilename,
+ string? getAccessTokenCertificatePassword,
+ string certificateFilename,
+ string certificatePassword)
+ {
+ // Access token
+ switch (accessTokenType)
+ {
+ case AccessTokenType.ValidAccessToken:
+ // Get the access token with the valid certificate.
+ return await new Infrastructure.AccessToken
+ {
+ CertificateFilename = getAccessTokenCertificateFilename ?? certificateFilename,
+ CertificatePassword = getAccessTokenCertificatePassword ?? certificatePassword,
+ }.GetAsync();
+
+ case AccessTokenType.InvalidAccessToken:
+ return "foo";
+
+ case AccessTokenType.ExpiredAccessToken:
+ // Represents an expired access token.
+ // "exp": 1621344825
+ // Expired at "Tuesday, May 18, 2021 11:33:45 PM GMT+10:00"
+ return "eyJhbGciOiJQUzI1NiIsImtpZCI6IkFBMjRGMTg1RUUzRjY3NTA0ODA4RkM0RTI2QjEzNUI5OUU2M0JEQTkiLCJ0eXAiOiJhdCtqd3QiLCJ4NXQiOiJxaVR4aGU0X1oxQklDUHhPSnJFMXVaNWp2YWsifQ.eyJuYmYiOjE2MjEzNDQ1MjUsImV4cCI6MTYyMTM0NDgyNSwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzAwMC9pZHAiLCJhdWQiOiJjZHItcmVnaXN0ZXIiLCJjbGllbnRfaWQiOiI2ZjdhMWI4ZS04Nzk5LTQ4YTgtOTAxMS1lMzkyMDM5MWY3MTMiLCJqdGkiOiJDODRBNTM5MTA2QjI4NUJBODI2RjZGMDQ3MjU4RjBBNCIsImlhdCI6MTYyMTM0NDUyNSwic2NvcGUiOlsiY2RyLXJlZ2lzdGVyOmJhbms6cmVhZCJdLCJjbmYiOnsieDV0I1MyNTYiOiI1OEQ3NkY3QTYxQ0Q3MjZEQTFDNTRGNjg5OEU4RTY5RUE0Qzg4MDYwIn19.RTU-zrqkb-WXcJzCz62SJ4h19lj8MDyGcvLOmg0qx05WFbAsY4mEP3gsoqM1LJfq4ncw7RqSvbkCNQQ-NOnyoBHF8MGe7mzdUh3YrD0_lTg20Dkx1-l044svtP_CKTI3rXT3bZaYWce0Tb1s3mrJzfN3ja23o93FGR-wbIwHp2347b0DxjznpKBw5meLhAjS7OCx6_uMm1la6IziSQgqMd2WaA-od7w8J5br-Nn-QZZi7X1KGiPEKFDFNk8KrUdPc4NCH6t7f-Sbc34KNNEWfAOJkWdDrmsBaifSlWvSlS4nUnurGHYkmimA2JUuv3ZTqzCcLRamEER1ZoTcIs_PDw";
+
+ case AccessTokenType.NoAccessToken:
+ return null;
+
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
+ private static async Task GetSsaJwks()
+ {
+ var clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
+
+ var jwksClient = new HttpClient(clientHandler);
+ var jwksResponse = await jwksClient.GetAsync($"{TLS_BaseURL}/cdr-register/v1/jwks");
+ return new JsonWebKeySet(await jwksResponse.Content.ReadAsStringAsync());
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
index 6801377..41c3bfb 100644
--- a/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/SSA/US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests.cs
@@ -23,10 +23,10 @@ namespace CDR.Register.IntegrationTests.API.SSA
///
public partial class US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests : BaseTest
{
- private const string BRANDID = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
- private const string SOFTWAREPRODUCTID = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
+ private const string BrandId = "20C0864B-CEEF-4DE0-8944-EB0962F825EB";
+ private const string SoftwareProductId = "86ECB655-9EBA-409C-9BE3-59E7ADF7080D";
- private const string EXPECTEDCONTENT_ADRSTATUSNOTACTIVE = @"
+ private const string ExpectedContentAdrStatusNotActive = @"
{
""errors"": [
{
@@ -47,7 +47,7 @@ public US27564_GetSoftwareStatementAssertion_MultiIndustry_Tests(ITestOutputHelp
private delegate void AfterSSARequest();
// Participation/Brand/SoftwareProduct Ids
- private static string PARTICIPATIONID => GetParticipationId(BRANDID); // lookup.
+ private static string ParticipationId => GetParticipationId(BrandId); // lookup.
[Theory]
[InlineData(3)]
@@ -57,7 +57,7 @@ public async Task AC01_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int xv)
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
- .Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
.SingleAsync();
// Arrange - Get access token
@@ -73,7 +73,7 @@ public async Task AC01_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(int xv)
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
HttpMethod = HttpMethod.Get,
- URL = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa",
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa",
XV = xv.ToString(),
AccessToken = accessToken,
}.SendAsync();
@@ -92,7 +92,7 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
var softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
- .Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
.SingleAsync();
// Arrange - Get access token
@@ -108,7 +108,7 @@ public async Task ACX99_GetSSA_WithDifferentIndustry_ShouldRespondWith_Different
CertificateFilename = CERTIFICATE_FILENAME,
CertificatePassword = CERTIFICATE_PASSWORD,
HttpMethod = HttpMethod.Get,
- URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa",
+ URL = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa",
XV = "3",
AccessToken = accessToken,
}.SendAsync();
@@ -127,15 +127,15 @@ public async Task AC03_GetSSA_WithParticipationStatusNotActive_ShouldRespondWith
int participationStatusId,
HttpStatusCode expectedStatusCode)
{
- int saveParticipationStatusId = GetParticipationStatusId(PARTICIPATIONID);
+ int saveParticipationStatusId = GetParticipationStatusId(ParticipationId);
await Test_GetSSA(
CERTIFICATE_FILENAME,
CERTIFICATE_PASSWORD,
expectedStatusCode,
- beforeRequest: () => SetParticipationStatusId(PARTICIPATIONID, participationStatusId),
- afterRequest: () => SetParticipationStatusId(PARTICIPATIONID, saveParticipationStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
+ beforeRequest: () => SetParticipationStatusId(ParticipationId, participationStatusId),
+ afterRequest: () => SetParticipationStatusId(ParticipationId, saveParticipationStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
}
[Theory]
@@ -146,15 +146,15 @@ public async Task AC04_GetSSA_WithBrandNotActive_ShouldRespondWith_403Forbidden(
int brandStatusId,
HttpStatusCode expectedStatusCode)
{
- int saveBrandStatusId = GetBrandStatusId(BRANDID);
+ int saveBrandStatusId = GetBrandStatusId(BrandId);
await Test_GetSSA(
CERTIFICATE_FILENAME,
CERTIFICATE_PASSWORD,
expectedStatusCode,
- beforeRequest: () => SetBrandStatusId(BRANDID, brandStatusId),
- afterRequest: () => SetBrandStatusId(BRANDID, saveBrandStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
+ beforeRequest: () => SetBrandStatusId(BrandId, brandStatusId),
+ afterRequest: () => SetBrandStatusId(BrandId, saveBrandStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
}
[Theory]
@@ -165,15 +165,15 @@ public async Task AC05_GetSSA_WithSoftwareProductNotActive_ShouldRespondWith_403
int softwareProductStatusId,
HttpStatusCode expectedStatusCode)
{
- int saveSoftwareProductStatusId = GetSoftwareProductStatusId(SOFTWAREPRODUCTID);
+ int saveSoftwareProductStatusId = GetSoftwareProductStatusId(SoftwareProductId);
await Test_GetSSA(
CERTIFICATE_FILENAME,
CERTIFICATE_PASSWORD,
expectedStatusCode,
- beforeRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, softwareProductStatusId),
- afterRequest: () => SetSoftwareProductStatusId(SOFTWAREPRODUCTID, saveSoftwareProductStatusId),
- expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : EXPECTEDCONTENT_ADRSTATUSNOTACTIVE);
+ beforeRequest: () => SetSoftwareProductStatusId(SoftwareProductId, softwareProductStatusId),
+ afterRequest: () => SetSoftwareProductStatusId(SoftwareProductId, saveSoftwareProductStatusId),
+ expectedContent: expectedStatusCode == HttpStatusCode.OK ? null : ExpectedContentAdrStatusNotActive);
}
[Theory]
@@ -270,28 +270,27 @@ await Test_GetSSA(
}
[Theory]
- [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("3", "5", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
[InlineData("3", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
[InlineData("3", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported equal to x-min-v
- [InlineData("4", "3", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is NOT supported and x-min-v is supported
[InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
- [InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
- [InlineData("4", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
- [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
+ [InlineData("5", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData("5", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData("5", "5", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 3
[InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("2", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("foo", "3", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
[InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
+ [InlineData("5", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 3
[InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
public async Task ACX01_VersionHeaderValidation(string? xv, string? xminv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
{
// Arrange
- string url = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
+ string url = $"{MTLS_BaseURL}/cdr-register/v1/all/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa";
var accessToken = await new Infrastructure.AccessToken
{
@@ -339,13 +338,13 @@ public async Task AC01_CTS_URL_GetSSA_WithXV1_ShouldRespondWith_200OK_V3ofSSA(in
{
string conformanceId = Guid.NewGuid().ToString();
string tokenEndpoint = $"{GenerateDynamicCtsUrl(IDENTITY_PROVIDER_DOWNSTREAM_BASE_URL, conformanceId)}/idp/connect/token";
- string ssasEndpoint = $"{GenerateDynamicCtsUrl(SSA_DOWNSTREAM_BASE_URL, conformanceId)}/cdr-register/v1/all/data-recipients/brands/{BRANDID}/software-products/{SOFTWAREPRODUCTID}/ssa";
+ string ssasEndpoint = $"{GenerateDynamicCtsUrl(SSA_DOWNSTREAM_BASE_URL, conformanceId)}/cdr-register/v1/all/data-recipients/brands/{BrandId}/software-products/{SoftwareProductId}/ssa";
// Arrange - Get SoftwareProduct
using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
Repository.Entities.SoftwareProduct softwareProduct = await dbContext.SoftwareProducts.AsNoTracking()
.Include(sp => sp.Brand)
- .Where(sp => sp.SoftwareProductId == new Guid(SOFTWAREPRODUCTID))
+ .Where(sp => sp.SoftwareProductId == new Guid(SoftwareProductId))
.SingleAsync();
// Arrange - Get access token
@@ -464,8 +463,8 @@ private static async Task Test_GetSSA(
string? getAccessTokenCertificatePassword = null,
string? expectedXV = null,
string? industry = "all",
- string brandId = BRANDID,
- string softwareProductId = SOFTWAREPRODUCTID)
+ string brandId = BrandId,
+ string softwareProductId = SoftwareProductId)
{
// Arrange
string url = $"{MTLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/{brandId}/software-products/{softwareProductId}/ssa";
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/GetDataHolderStatusXV2_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/GetDataHolderStatusXV2_MultiIndustry_Tests.cs
new file mode 100644
index 0000000..b14160a
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/Status/GetDataHolderStatusXV2_MultiIndustry_Tests.cs
@@ -0,0 +1,347 @@
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using CDR.Register.IntegrationTests.API.Update;
+using CDR.Register.Repository.Enums;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.Status
+{
+ ///
+ /// Integration tests for Get Data Holder Status V2 endpoints.
+ ///
+ public class GetDataHolderStatusXV2_MultiIndustry_Tests : BaseTest
+ {
+ ///
+ /// The supported industry in V3.
+ ///
+ private const string SupportedIndustry = "all";
+
+ ///
+ /// The supported version - 3.
+ ///
+ private const string SupportedVersion = "2";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "1";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "5";
+
+ public GetDataHolderStatusXV2_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_ShouldRespondWith_200OK_DataHolderStatuses(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-holders/status";
+ var expected = GetExpectedDataHolderStatuses(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expected, response.Content);
+ }
+ }
+
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_WithDynamicPaths_ShouldRespondWith_200OK_DataHolderStatuses(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/{SupportedIndustry}/data-holders/status";
+
+ var expectedUrl = ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL);
+
+ var expected = GetExpectedDataHolderStatuses(expectedUrl);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expected, response.Content);
+ }
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("foo")]
+ public async Task Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-holders/status";
+ var expected = GetExpectedDataHolderStatuses(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = SupportedVersion,
+ IfNoneMatch = ifNoneMatch,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(SupportedVersion, response.Headers, "x-v");
+
+ // Assert - Check has any ETag
+ Assert_HasHeader(null, response.Headers, "ETag");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expected, response.Content);
+ }
+ }
+
+ [Fact]
+ public async Task Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
+ {
+ // Arrange - Get SoftwareProductsStatus and save the ETag
+ var expectedETag = (await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-holders/status",
+ XV = SupportedVersion,
+ IfNoneMatch = null, // ie If-None-Match is not set
+ }.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-holders/status",
+ XV = SupportedVersion,
+ IfNoneMatch = expectedETag,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.NotModified);
+
+ // Assert - No content
+ (await response.Content.ReadAsStringAsync()).Should().BeNullOrEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return supported version - x-min-v is ignored when > x-v
+ [InlineData(LegacyEndpointVersion, UnsupportedEndpointVersion, LegacyEndpointVersion, HttpStatusCode.BadRequest, true, "", "non-bank-lending")] // Invalid industry. x-v is supported but industry is not supported for this version
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return supported version - x-v is supported and higher than x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return supported version - x-v is supported equal to x-min-v
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "", "banking")] // Valid. Should return supported version as it supports 'Banking' industry.
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "", "energy")] // Valid. Should return supported version as it supports 'Energy' industry.
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "", "telco")] // Valid. Should return supported version as it supports 'Telco' industry.
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "", "non-bank-lending")] // Valid. Should return supported version as it supports 'Non-Bank Lending' industry.
+ [InlineData(SupportedVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData(SupportedVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed maximum supported version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than a supported version
+ [InlineData(SupportedVersion, LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALIDFIELD_INDUSTRY, "mining")] // Valid. Should return error code 400 - Bad Request - Invalid Path Parameter
+ [InlineData("", "", LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Should return supported version.
+ [InlineData("", UnsupportedEndpointVersion, LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Valid. empty header behaves like no header
+ [InlineData(null, UnsupportedEndpointVersion, LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Valid. No x-v header, defaults to v1.
+ [InlineData(LegacyEndpointVersion, UnsupportedEndpointVersion, LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Valid. Explicit v1 header to confirm API still supports v1
+
+ // Ensure the x-v is optional until v1 is no longer supported
+ [InlineData("", null, LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Invalid. x-v header is an empty string
+ [InlineData(null, null, LegacyEndpointVersion, HttpStatusCode.OK, true, "")] // Invalid. x-v header is missing
+ public async Task VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expectedError, string industry = "all")
+ {
+ // Arrange
+ var request = new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-holders/status",
+ XV = xv,
+ XMinV = minXv,
+ };
+
+ // Act
+ var response = await request.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expectedError, response.Content);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(LegacyEndpointVersion, "all")] // Explicit v1
+ [InlineData(LegacyEndpointVersion, "banking")] // v1
+ [InlineData(SupportedVersion, "all")] // v2
+ [InlineData(SupportedVersion, "non-bank-lending")] // NBL v2
+ [InlineData(SupportedVersion, "banking")]
+
+ public async Task ValidateDataHolderStatusByIndustry(string? xv, string industry)
+ {
+ // Arrange
+ var request = new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-holders/status",
+ XV = xv,
+ };
+
+ // Act
+ var response = await request.SendAsync();
+
+ // Assert status code first
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert
+ string expectedContent = string.Empty;
+
+ if (string.IsNullOrEmpty(xv) || xv == LegacyEndpointVersion)
+ {
+ expectedContent = GetExpectedDataHolderStatusesLegacy(request.URL, industry);
+ }
+ else if (xv == SupportedVersion)
+ {
+ expectedContent = GetExpectedDataHolderStatuses(request.URL, industry);
+ }
+
+ await Assert_HasContent_Json(expectedContent, response.Content);
+ }
+
+ private static string GetExpectedDataHolderStatuses(string url, string industry = SupportedIndustry)
+ {
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var expectedDataHolderStatuses = new
+ {
+ data = dbContext.Participations.AsNoTracking()
+ .Include(p => p.Status)
+ .Where(p => p.ParticipationTypeId == ParticipationTypes.Dh)
+ .Where(p => p.Industry.IndustryTypeCode == industry || industry == "all")
+
+ .Select(p => new
+ {
+ legalEntityId = p.LegalEntityId,
+ status = p.Status.ParticipationStatusCode,
+ })
+ .OrderBy(p => p.legalEntityId)
+ .ToList(),
+ links = new
+ {
+ self = url,
+ },
+ meta = new object(),
+ };
+
+ return JsonConvert.SerializeObject(expectedDataHolderStatuses);
+ }
+
+ private static string GetExpectedDataHolderStatusesLegacy(string url, string industry = SupportedIndustry)
+ {
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var expectedDataHolderStatuses = new
+ {
+ data = dbContext.Participations.AsNoTracking()
+ .Include(p => p.Status)
+ .Where(p => p.ParticipationTypeId == ParticipationTypes.Dh)
+ .Where(p => p.Industry.IndustryTypeCode == industry || industry == "all")
+ .Where(p => p.Industry.IndustryTypeCode != "non-bank-lending")
+ .Select(p => new
+ {
+ legalEntityId = p.LegalEntityId,
+ status = p.Status.ParticipationStatusCode,
+ })
+ .OrderBy(p => p.legalEntityId)
+ .ToList(),
+ links = new
+ {
+ self = url,
+ },
+ meta = new object(),
+ };
+
+ return JsonConvert.SerializeObject(expectedDataHolderStatuses);
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/GetDataRecipientStatusXV3_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/GetDataRecipientStatusXV3_MultiIndustry_Tests.cs
new file mode 100644
index 0000000..2fbd3f6
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/Status/GetDataRecipientStatusXV3_MultiIndustry_Tests.cs
@@ -0,0 +1,272 @@
+using System;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using CDR.Register.Repository.Enums;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.Status
+{
+ ///
+ /// Integration tests for GetDataRecipientStatus V3 endpoints.
+ ///
+ public class GetDataRecipientStatusXV3_MultiIndustry_Tests : BaseTest
+ {
+ ///
+ /// The supported industry in V3.
+ ///
+ private const string SupportedIndustry = "all";
+
+ ///
+ /// The supported version - 3.
+ ///
+ private const string SupportedVersion = "3";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "2";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "4";
+
+ public GetDataRecipientStatusXV3_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_ShouldRespondWith_200OK_DataRecipientsStatus(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/status";
+ var expectedDataRecipientStatus = GetExpectedDataRecipientsStatus(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipientStatus, response.Content);
+ }
+ }
+
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_WithDynamicPaths_ShouldRespondWith_200OK_DataRecipientsStatus(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/{SupportedIndustry}/data-recipients/status";
+
+ var expectedUrl = ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL);
+
+ var expectedDataRecipientStatus = GetExpectedDataRecipientsStatus(expectedUrl);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipientStatus, response.Content);
+ }
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("foo")]
+ public async Task Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/status";
+ var expectedDataRecipientsStatus = GetExpectedDataRecipientsStatus(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = SupportedVersion,
+ IfNoneMatch = ifNoneMatch,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(SupportedVersion, response.Headers, "x-v");
+
+ // Assert - Check has any ETag
+ Assert_HasHeader(null, response.Headers, "ETag");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedDataRecipientsStatus, response.Content);
+ }
+ }
+
+ [Fact]
+ public async Task Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
+ {
+ // Arrange - Get SoftwareProductsStatus and save the ETag
+ var expectedETag = (await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/status",
+ XV = SupportedVersion,
+ IfNoneMatch = null, // ie If-None-Match is not set
+ }.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/status",
+ XV = SupportedVersion,
+ IfNoneMatch = expectedETag,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.NotModified);
+
+ // Assert - No content
+ (await response.Content.ReadAsStringAsync()).Should().BeNullOrEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "banking")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "Energy")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "TELCO")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, "1", SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData(UnsupportedEndpointVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "banking")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData(UnsupportedEndpointVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "", "all")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData(SupportedVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData(SupportedVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed maximum supported version
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed maximum supported version
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+
+ public async Task VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "all")
+ {
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/status",
+ XV = xv,
+ XMinV = minXv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expecetdError, response.Content);
+ }
+ }
+ }
+
+ private static string GetExpectedDataRecipientsStatus(string url)
+ {
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var expectedDataRecipientsStatus = new
+ {
+ data = dbContext.Participations.AsNoTracking()
+ .Include(p => p.Status)
+ .Where(p => p.ParticipationTypeId == ParticipationTypes.Dr)
+ .Select(p => new
+ {
+ legalEntityId = p.LegalEntityId,
+ status = p.Status.ParticipationStatusCode,
+ })
+ .OrderBy(p => p.legalEntityId.ToString())
+ .ToList(),
+ links = new
+ {
+ self = url,
+ },
+ meta = new object(),
+ };
+
+ return JsonConvert.SerializeObject(expectedDataRecipientsStatus);
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/GetSoftwareProductStatusXV3_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/GetSoftwareProductStatusXV3_MultiIndustry_Tests.cs
new file mode 100644
index 0000000..8d80022
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/API/Status/GetSoftwareProductStatusXV3_MultiIndustry_Tests.cs
@@ -0,0 +1,267 @@
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using CDR.Register.Repository.Infrastructure;
+using FluentAssertions;
+using FluentAssertions.Execution;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace CDR.Register.IntegrationTests.API.Status
+{
+ ///
+ /// Integration tests for GetSoftwareProductStatus v3 endpoints.
+ ///
+ public class GetSoftwareProductStatusXV3_MultiIndustry_Tests : BaseTest
+ {
+ ///
+ /// The supported industry in V3.
+ ///
+ private const string SupportedIndustry = "all";
+
+ ///
+ /// The supported version - 3.
+ ///
+ private const string SupportedVersion = "3";
+
+ ///
+ /// The previous endpoint version which is still supported.
+ ///
+ private const string LegacyEndpointVersion = "2";
+
+ ///
+ /// The future (not implemented) endpoint version, which isn't supported.
+ ///
+ private const string UnsupportedEndpointVersion = "4";
+
+ public GetSoftwareProductStatusXV3_MultiIndustry_Tests(ITestOutputHelper outputHelper, TestFixture testFixture)
+ : base(outputHelper, testFixture)
+ {
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_ShouldRespondWith_200OK_SoftwareProductStatus(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/brands/software-products/status";
+ var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedSoftwareProductsStatus, response.Content);
+ }
+ }
+
+ [Trait("Category", "CTSONLY")]
+ [Theory]
+ [InlineData(SupportedVersion, SupportedVersion)]
+ public async Task Get_WithDynamicPaths_ShouldRespondWith_200OK_SoftwareProductStatus(string? xv, string expectedXV)
+ {
+ // Arrange
+ var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/{SupportedIndustry}/data-recipients/brands/software-products/status";
+ var expectedUrl = ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL);
+
+ var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(expectedUrl);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = xv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(expectedXV, response.Headers, "x-v");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedSoftwareProductsStatus, response.Content);
+ }
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("foo")]
+ public async Task Get_WithIfNoneMatch_ShouldRespondWith_200OK_ETag(string? ifNoneMatch)
+ {
+ // Arrange
+ var url = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/brands/software-products/status";
+ var expectedSoftwareProductsStatus = GetExpectedSoftwareProductStatus(url);
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = url,
+ XV = SupportedVersion,
+ IfNoneMatch = ifNoneMatch,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ // Assert - Check XV
+ Assert_HasHeader(SupportedVersion, response.Headers, "x-v");
+
+ // Assert - Check has any ETag
+ Assert_HasHeader(null, response.Headers, "ETag");
+
+ // Assert - Check json
+ await Assert_HasContent_Json(expectedSoftwareProductsStatus, response.Content);
+ }
+ }
+
+ [Fact]
+ public async Task Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModified_ETag()
+ {
+ // Arrange - Get SoftwareProductsStatus and save the ETag
+ var expectedETag = (await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/brands/software-products/status",
+ XV = SupportedVersion,
+ IfNoneMatch = null, // ie If-None-Match is not set
+ }.SendAsync()).Headers.GetValues("ETag").First().Trim('"');
+
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{SupportedIndustry}/data-recipients/brands/software-products/status",
+ XV = SupportedVersion,
+ IfNoneMatch = expectedETag,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.NotModified);
+
+ // Assert - No content
+ (await response.Content.ReadAsStringAsync()).Should().BeNullOrEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "banking")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "Energy")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, UnsupportedEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "TELCO")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData(SupportedVersion, "1", SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-v is supported and higher than x-min-v
+ [InlineData(SupportedVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData(UnsupportedEndpointVersion, LegacyEndpointVersion, SupportedVersion, HttpStatusCode.BadRequest, true, "", "banking")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData(UnsupportedEndpointVersion, SupportedVersion, SupportedVersion, HttpStatusCode.OK, true, "", "all")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData(SupportedVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
+ [InlineData(UnsupportedEndpointVersion, "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
+ [InlineData(SupportedVersion, "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
+ [InlineData(UnsupportedEndpointVersion, UnsupportedEndpointVersion, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed maximum supported version
+ [InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
+ [InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
+ [InlineData("foo", LegacyEndpointVersion, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
+ [InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
+ [InlineData(UnsupportedEndpointVersion, null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed maximum supported version
+ [InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
+ [InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
+ public async Task VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expectedError, string industry = SupportedIndustry)
+ {
+ // Act
+ var response = await new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/software-products/status",
+ XV = xv,
+ XMinV = minXv,
+ }.SendAsync();
+
+ // Assert
+ using (new AssertionScope())
+ {
+ // Assert - Check status code
+ response.StatusCode.Should().Be(expectedHttpStatusCode);
+
+ // Assert - Check content type
+ Assert_HasContentType_ApplicationJson(response.Content);
+
+ if (isExpectedToBeSupported)
+ {
+ // Assert - Check x-v returned header
+ Assert_HasHeader(expectedXv, response.Headers, "x-v");
+ }
+ else
+ {
+ // Assert - Check error response
+ await Assert_HasContent_Json(expectedError, response.Content);
+ }
+ }
+ }
+
+ private static string GetExpectedSoftwareProductStatus(string url)
+ {
+ using var dbContext = new RegisterDatabaseContext(new DbContextOptionsBuilder().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options);
+
+ var expectedSoftwareProductsStatus = new
+ {
+ data = dbContext.SoftwareProducts.AsNoTracking()
+ .Include(sp => sp.Status)
+ .Select(sp => new
+ {
+ softwareProductId = sp.SoftwareProductId,
+ status = sp.Status.SoftwareProductStatusCode,
+ })
+ .OrderBy(sp => sp.softwareProductId.ToString())
+ .ToList(),
+ links = new
+ {
+ self = url,
+ },
+ meta = new object(),
+ };
+
+ return JsonConvert.SerializeObject(expectedSoftwareProductsStatus);
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
index 6d0fb10..356ae35 100644
--- a/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Status/US27556_GetDataRecipientStatus_MultiIndustry_Tests.cs
@@ -68,17 +68,7 @@ public async Task AC01_AC02_CTS_URL_Get_ShouldRespondWith_200OK_DataRecipientsSt
// Arrange
var url = $"{GenerateDynamicCtsUrl(STATUS_DOWNSTREAM_BASE_URL)}/cdr-register/v1/all/data-recipients/status";
- string publicHostName = Configuration["PublicHostName"] ?? string.Empty;
- string expectedUrl;
-
- if (string.IsNullOrEmpty(publicHostName))
- {
- expectedUrl = url;
- }
- else
- {
- expectedUrl = url.Replace(STATUS_DOWNSTREAM_BASE_URL, publicHostName);
- }
+ var expectedUrl = ReplacePublicHostName(url, STATUS_DOWNSTREAM_BASE_URL);
var expectedDataRecipientStatus = GetExpectedDataRecipientsStatus(expectedUrl);
@@ -178,30 +168,36 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
}
[Theory]
- [InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
[InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("2", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Invalid. x-min-v is non-positive integer
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "", "Energy")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "4", "2", HttpStatusCode.OK, true, "", "banKing")] // Valid. Should return v2 - x-v is supported and x-min-v is non supported so ignored
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "", "TELCO")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.BadRequest, true, "", "non-bank-lending")] // Invalid industry. Non-bank lending isn't supported for V2.
+ [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("3", "4", "3", HttpStatusCode.BadRequest, true, "", "Telco")] // Invalid industry. x-v is supported but industry is not supported for v3
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData("1", "2", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
[InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
[InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
[InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
[InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
[InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
-
- public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
+ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError, string industry = "All")
{
// Act
var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
- URL = $"{TLS_BaseURL}/cdr-register/v1/banking/data-recipients/status",
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/status",
XV = xv,
XMinV = minXv,
}.SendAsync();
diff --git a/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs b/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
index d4325fa..06365f9 100644
--- a/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Status/US27558_GetSoftwareProductStatus_MultiIndustry_Tests.cs
@@ -164,29 +164,36 @@ public async Task AC05_Get_WithIfNoneMatchKnownETAG_ShouldRespondWith_304NotModi
[Theory]
[InlineData("2", "3", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-min-v is ignored when > x-v
- [InlineData("2", "1", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
[InlineData("2", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is supported equal to x-min-v
- [InlineData("3", "2", "2", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported Z
+ [InlineData("2", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR, "banking")] // Invalid. x-min-v is non-positive integer
+ [InlineData("2", "1", "2", HttpStatusCode.OK, true, "", "Energy")] // Valid. Should return v2 - x-v is supported and higher than x-min-v
+ [InlineData("2", "4", "2", HttpStatusCode.OK, true, "", "banKing")] // Valid. Should return v2 - x-v is supported and x-min-v is non supported so ignored
+ [InlineData("2", "2", "2", HttpStatusCode.OK, true, "", "TELCO")] // Valid. Should return v2 - x-v is supported equal to x-min-v
+ [InlineData("2", "2", "2", HttpStatusCode.BadRequest, true, "", "non-bank-lending")] // Invalid industry. Non-bank lending isn't supported for V2.
+ [InlineData("3", "4", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v3 - x-min-v is ignored when > x-v
+ [InlineData("4", "2", "3", HttpStatusCode.OK, true, "")] // Valid. Should return v2 - x-v is NOT supported and x-min-v is supported. BadRequest as v3 doesn't support 'Banking' industry
+ [InlineData("1", "2", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("3", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is supported but x-min-v is invalid (not a positive integer)
[InlineData("4", "foo", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v is invalid (not a positive integer)
[InlineData("3", "0", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is not supported and x-min-v invalid
- [InlineData("3", "3", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
+ [InlineData("4", "4", "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. Both x-v and x-min-v exceed supported version of 2
[InlineData("1", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is an obsolete version
[InlineData("foo", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("0", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (not a positive integer) is invalid with missing x-min-v
[InlineData("foo", "2", "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v is invalid with valid x-min-v
[InlineData("-1", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_INVALID_VERSION_ERROR)] // Invalid. x-v (negative integer) is invalid with missing x-min-v
- [InlineData("3", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
+ [InlineData("4", null, "N/A", HttpStatusCode.NotAcceptable, false, EXPECTED_UNSUPPORTED_ERROR)] // Unsupported. x-v is higher than supported version of 2
[InlineData("", null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is an empty string
[InlineData(null, null, "N/A", HttpStatusCode.BadRequest, false, EXPECTED_MISSING_X_V_ERROR)] // Invalid. x-v header is missing
- public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expecetdError)
+ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string expectedXv, HttpStatusCode expectedHttpStatusCode, bool isExpectedToBeSupported, string expectedError, string industry = "all")
{
// Act
var response = await new Infrastructure.Api
{
HttpMethod = HttpMethod.Get,
- URL = $"{TLS_BaseURL}/cdr-register/v1/banking/data-recipients/brands/software-products/status",
+ URL = $"{TLS_BaseURL}/cdr-register/v1/{industry}/data-recipients/brands/software-products/status",
XV = xv,
XMinV = minXv,
}.SendAsync();
@@ -208,7 +215,7 @@ public async Task ACXX_VersionHeaderValidation(string? xv, string? minXv, string
else
{
// Assert - Check error response
- await Assert_HasContent_Json(expecetdError, response.Content);
+ await Assert_HasContent_Json(expectedError, response.Content);
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
index 6d267b1..c61370d 100644
--- a/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
+++ b/Source/CDR.Register.IntegrationTests/API/Update/US50480_UpdateDataHolders.cs
@@ -27,6 +27,8 @@ public class US50480_UpdateDataHolders : BaseTest
private const string TEST_DATA_BASE_URI = "https://TestAumationLogoUri.gov.au";
+ private static readonly Dictionary IndustryMapping = new() { { Industry.Banking, "Banking" }, { Industry.Energy, "Energy" }, { Industry.NonBankLending, "Non-Bank-Lending" } };
+
public US50480_UpdateDataHolders(ITestOutputHelper outputHelper, TestFixture testFixture)
: base(outputHelper, testFixture)
{
@@ -36,15 +38,17 @@ public enum Industry
{
Banking,
Energy,
+ NonBankLending,
}
[Theory]
[InlineData(Industry.Banking)]
[InlineData(Industry.Energy)]
+ [InlineData(Industry.NonBankLending)]
public async Task AC02_Add_New_DataHolder_With_Only_Mandatory_Fields_Http_200(Industry industry)
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(industry, false);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(industry, false);
// Send to Register
HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
@@ -53,31 +57,33 @@ public async Task AC02_Add_New_DataHolder_With_Only_Mandatory_Fields_Http_200(In
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, response, industry);
// Assert participation created correctly
- VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", industry.ToString(), dataHolderMetadata.Status);
+ VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", IndustryMapping[industry].ToLowerInvariant(), dataHolderMetadata.Status);
}
[Theory]
[InlineData(Industry.Banking)]
[InlineData(Industry.Energy)]
+ [InlineData(Industry.NonBankLending)]
public async Task AC02_Add_New_DataHolder_With_All_Fields_Fields_Http_200(Industry industry)
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(industry, true);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(industry, true);
// Send to Register
- HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
+ var payload = GetJsonFromModel(dataHolderMetadata);
+ HttpResponseMessage response = await PostUpdateDataHolderRequest(payload);
// Assert http response and database updates.
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, response, industry);
- VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", industry.ToString(), dataHolderMetadata.Status);
+ VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", IndustryMapping[industry].ToLowerInvariant(), dataHolderMetadata.Status);
}
[Fact]
public async Task AC03_Modify_Existing_DataHolder_200()
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send Original request to Register
HttpResponseMessage originalResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
@@ -97,14 +103,14 @@ public async Task AC03_Modify_Existing_DataHolder_200()
// Assert http response and database updates.
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, modifiedResponse, Industry.Banking);
- VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString(), dataHolderMetadata.Status);
+ VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString().ToLowerInvariant(), dataHolderMetadata.Status);
}
[Fact]
public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
{
// Generate valid payload.
- DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata originalDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send to Register
await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
@@ -116,7 +122,7 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
VerifySuccessfulDataHolderUpdate(originalDataHolderMetadata, originalResponse, Industry.Banking);
// Generate valid payload.
- DataHolderMetadata newDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata newDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity
newDataHolderMetadata.LegalEntity.LegalEntityId = originalDataHolderMetadata.LegalEntity.LegalEntityId;
@@ -135,14 +141,14 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_200()
// Also Check Original is not affected
VerifySuccessfulDataHolderUpdate(originalDataHolderMetadata, originalResponse, Industry.Banking);
- VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString(), newDataHolderMetadata.Status);
+ VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString().ToLowerInvariant(), newDataHolderMetadata.Status);
}
[Fact]
public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Industry_200()
{
// Generate valid Banking payload.
- DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata originalDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send to Register
_ = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata));
@@ -154,7 +160,7 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Ind
VerifySuccessfulDataHolderUpdate(originalDataHolderMetadata, originalResponse, Industry.Banking);
// Generate valid Energy payload.
- DataHolderMetadata newDataHolderMetadata = CreateValidDataholderMetadata(Industry.Energy, true);
+ DataHolderMetadata newDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Energy, true);
// Set Legal Entity Id to Original Legal Entity Id. Register should attach new brand to Legal Entity, and create a new participation record.
newDataHolderMetadata.LegalEntity.LegalEntityId = originalDataHolderMetadata.LegalEntity.LegalEntityId;
@@ -171,10 +177,10 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Ind
VerifySuccessfulDataHolderUpdate(newDataHolderMetadata, modifiedResponse, Industry.Energy);
// Verify Banking Participant
- VerifyParticipationRecord(originalDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString(), originalDataHolderMetadata.Status);
+ VerifyParticipationRecord(originalDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Banking.ToString().ToLowerInvariant(), originalDataHolderMetadata.Status);
// Verify Energy(subsequent) Participant
- VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Energy.ToString(), newDataHolderMetadata.Status);
+ VerifyParticipationRecord(newDataHolderMetadata.LegalEntity.LegalEntityId, "DH", Industry.Energy.ToString().ToLowerInvariant(), newDataHolderMetadata.Status);
}
[Theory]
@@ -182,8 +188,8 @@ public async Task AC03_Add_New_Brand_To_Existing_Legal_Entity_With_Different_Ind
[InlineData(null)]
public async Task AC04_Missing_Version_In_Header_Http_400(string xv)
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata originalDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
@@ -200,7 +206,7 @@ public async Task AC04_Missing_Version_In_Header_Http_400(string xv)
[InlineData("1.1")]
public async Task AC05_Invalid_Version_Http_400(string xv)
{
- DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata originalDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
@@ -216,7 +222,7 @@ public async Task AC05_Invalid_Version_Http_400(string xv)
[InlineData("20")]
public async Task AC10_Unsupported_Version_Http_400(string xv)
{
- DataHolderMetadata originalDataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata originalDataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send to Register with blank x-v header
var response = await PostUpdateDataHolderRequest(GetJsonFromModel(originalDataHolderMetadata), xv: xv);
@@ -252,8 +258,8 @@ public async Task AC06_Missing_Mandatory_Fields_Http_400(string testId, string e
{
Log.Information("Executing test for: {TestId}", testId);
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
Log.Information("original:\n{JsonModel}", GetJsonFromModel(dataHolderMetadata));
dataHolderMetadata = RemoveModelElementBasedOnJsonPath(dataHolderMetadata, elementToRemove);
@@ -286,7 +292,7 @@ public async Task AC06_Missing_Mandatory_Fields_Http_400(string testId, string e
[InlineData("Max Length EndPoint - WebsiteUri", "endpointDetail.websiteUri", 1000)]
[InlineData("Max Length Legal Entity - Name", "legalEntity.legalEntityName", 200)]
- // we don't check accredatation number for DHs as they don't have it.
+ // we don't check accreditation number for DHs as they don't have it.
[InlineData("Max Length Legal Entity - logoUri", "legalEntity.logoUri", 1000)]
[InlineData("Max Length Legal Entity - Registration Number", "legalEntity.registrationNumber", 100)]
[InlineData("Max Length Legal Entity - Registered Country", "legalEntity.registeredCountry", 100)]
@@ -297,19 +303,19 @@ public async Task AC06_Missing_Mandatory_Fields_Http_400(string testId, string e
[InlineData("Max Length Auth Details - JwksEndpoint", "authDetails.jwksEndpoint", 1000)]
public async Task ACXX_Maximum_Field_Length_Exceeded(string testId, string elementUnderTest, int maxLength)
{
- Log.Information("Executing test for: {TestId} : Max Lenght: {MaxLength}", testId, maxLength);
+ Log.Information("Executing test for: {TestId} : Max Length: {MaxLength}", testId, maxLength);
// Create dataHolder using maximum field length
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
string maxLengthValue = maxLength.GenerateRandomString();
dataHolderMetadata = ReplaceModelValueBasedOnJsonPath(dataHolderMetadata, elementUnderTest, maxLengthValue);
- Log.Information($"+ve Scenario using maximum field lenght of '{maxLength}':\n{GetJsonFromModel(dataHolderMetadata)}");
+ Log.Information($"+ve Scenario using maximum field length of '{maxLength}':\n{GetJsonFromModel(dataHolderMetadata)}");
// Send and verify positive scenario
HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
await VerifyInvalidAndValidFieldResponse(response, dataHolderMetadata, ConvertJsonPathToPascalCase(elementUnderTest), maxLengthValue, true);
- // Create dataHolder using maximum field lenght plus one
+ // Create dataHolder using maximum field length plus one
string maxLengthPlusOneValue = (maxLength + 1).GenerateRandomString();
dataHolderMetadata = ReplaceModelValueBasedOnJsonPath(dataHolderMetadata, elementUnderTest, maxLengthPlusOneValue);
Log.Information($"-ve:\n{GetJsonFromModel(dataHolderMetadata)}");
@@ -323,32 +329,29 @@ public async Task ACXX_Maximum_Field_Length_Exceeded(string testId, string eleme
[InlineData("BANKING")]
[InlineData("ENERGY")]
[InlineData("Energy")]
+ [InlineData("Non-Bank-Lending")]
[InlineData("foo", false)]
public async Task AC07_Valid_And_Invalid_Industry(string industry, bool isValid = true)
{
- Industry industryEnum;
-
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
- Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
-
- dataHolderMetadata.Industries.Clear();
- dataHolderMetadata.Industries.Add(industry);
-
- Log.Information($"modified:\n{GetJsonFromModel(dataHolderMetadata)}");
+ Industry? industryEnum = industry.ToUpperInvariant() switch
+ {
+ "ENERGY" => Industry.Energy,
+ "NON-BANK-LENDING" => Industry.NonBankLending,
+ "BANKING" => Industry.Banking,
+ _ => null,
+ };
- HttpResponseMessage httpResponseMessage = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(industryEnum ?? Industry.Banking, false);
- switch (industry.ToUpper())
+ Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
+ if (!industryEnum.HasValue)
{
- case "ENERGY":
- industryEnum = Industry.Energy;
- break;
-
- default:
- industryEnum = Industry.Banking;
- break;
+ dataHolderMetadata.Industries = [industry];
+ Log.Information($"modified:\n{GetJsonFromModel(dataHolderMetadata)}");
}
+ HttpResponseMessage httpResponseMessage = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
+
dataHolderMetadata.Industries = dataHolderMetadata.Industries.ConvertAll(x => x.ToUpper());
await VerifyInvalidAndValidFieldResponse(httpResponseMessage, dataHolderMetadata, "Industries[0]", industry, isValid, industryEnum);
@@ -362,7 +365,7 @@ public async Task AC07_Valid_And_Invalid_Industry(string industry, bool isValid
[InlineData("foo", false)]
public async Task AC07_Valid_And_Invalid_Data_Holder_Status(string status, bool isValid = true)
{
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
dataHolderMetadata.Status = status;
@@ -387,7 +390,7 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Status(string status, bool
[InlineData("foo", false)]
public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Organisation_Type(string orgType, bool isValid = true)
{
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
dataHolderMetadata.LegalEntity.OrganisationType = orgType;
@@ -409,7 +412,7 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Organisation_T
[InlineData("foo", false)]
public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Status(string status, bool isValid = true)
{
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
dataHolderMetadata.LegalEntity.Status = status;
@@ -429,7 +432,7 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Legal_Entity_Status(string
[InlineData("foo", false)]
public async Task AC07_Valid_And_Invalid_Data_Holder_Auth_Details_RegisterUType(string registerUType, bool isValid = true)
{
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
Log.Information($"original:\n{GetJsonFromModel(dataHolderMetadata)}");
dataHolderMetadata.AuthDetails.RegisterUType = registerUType;
@@ -446,8 +449,8 @@ public async Task AC07_Valid_And_Invalid_Data_Holder_Auth_Details_RegisterUType(
[Fact]
public async Task AC08_Brand_Already_Associated_With_Different_Legal_Entity_400()
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send Original request to Register
HttpResponseMessage originalResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
@@ -466,8 +469,8 @@ public async Task AC08_Brand_Already_Associated_With_Different_Legal_Entity_400(
[Fact]
public async Task AC09_Brand_Already_Associated_With_Same_Legal_Entity_And_Different_Industry_400()
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, true);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, true);
// Send Original request to Register
HttpResponseMessage originalResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata));
@@ -484,6 +487,140 @@ public async Task AC09_Brand_Already_Associated_With_Same_Legal_Entity_And_Diffe
await VerifyInvalidPayloadResponse(modifiedResponse, $"Brand {dataHolderMetadata.DataHolderBrandId} is already associated with the same legal entity in a different industry.");
}
+ // Test Case:1
+ [Fact]
+ public void MockDataHolderBankingShouldHaveSeeded()
+ {
+ // Arrange
+ var legalEntityId = "0d332caa-8cd8-4ac9-8898-20641c54bc8c"; // Bank Legal Entity
+ var brandId = "804fc2fb-18a7-4235-9a49-2af393d18bc7"; // Mock Data Holder (Banking)
+
+ // Act
+ var result = GetActualDataHolderFromDatabase(legalEntityId, brandId, Industry.Banking);
+
+ // Assert
+ Assert.NotNull(result);
+ var resultDh = JsonConvert.DeserializeObject(result);
+ resultDh.Should().NotBeNull();
+ }
+
+ [Fact] // Test Case:2
+ public void NewBankShouldHaveSeededWithoutProductBaseUri()
+ {
+ // Arrange
+ var legalEntityId = "93ef5f28-7f30-43f2-8e5c-b1e3cb39ce90"; // New Bank
+ var brandId = "6e9cfaf7-ecae-4de3-bbc5-ea9f366bdf55"; // New Bank -- dummy data holder -- do not use
+
+ // Act
+ var result = GetActualDataHolderFromDatabase(legalEntityId, brandId, Industry.Banking);
+
+ // Assert
+ Assert.NotNull(result);
+ var resultDh = JsonConvert.DeserializeObject(result);
+ resultDh.EndpointDetail.ProductBaseUri.Should().BeNull();
+ }
+
+ [Fact] // Test Case:3
+ public void SunBankShouldHaveSeededWithProductBaseUri()
+ {
+ // Arrange
+ var legalEntityId = "aeca53ab-2a90-4737-938d-987ce195ca14"; // Sun bank
+ var brandId = "f6dfbe5b-c57a-4ec2-bc97-66c1f7fe6c1d"; // "Sun -- dummy data holder -- do not use"
+
+ // Act
+ var result = GetActualDataHolderFromDatabase(legalEntityId, brandId, Industry.Banking);
+
+ // Assert
+ Assert.NotNull(result);
+ var resultDh = JsonConvert.DeserializeObject(result);
+ resultDh.EndpointDetail.ProductBaseUri.Should().NotBeNull();
+ }
+
+ [Fact] // Test case:4
+ public async Task GetMetaDataShouldMatchSeedData()
+ {
+ // Arrange
+ var api = new Infrastructure.Api
+ {
+ HttpMethod = HttpMethod.Get,
+ URL = $"{ADMIN_BaseURL}/admin/metadata",
+ };
+
+ // Expected payload should match seed file
+ await TestFixture.Seeddata();
+ var expectedPayload = await System.IO.File.ReadAllTextAsync(SEEDDATA_FILENAME);
+ var expectedData = JsonConvert.DeserializeObject(expectedPayload);
+
+ // Act - API
+ var response = await api.SendAsync();
+ var result = await response.Content.ReadAsStringAsync();
+
+ var apiData = JsonConvert.DeserializeObject(result);
+
+ // Assert
+ using var scope = new AssertionScope();
+
+ // Assert - Check status code
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ apiData.Should().NotBeNull();
+ expectedPayload.Should().NotBeNull();
+
+ apiData.LegalEntities.Should().BeEquivalentTo(
+ expectedData.LegalEntities.OrderBy(x => x.LegalEntityName),
+ opt => opt
+ .ComparingRecordsByValue()
+ .Excluding(su => su.Path.EndsWith(nameof(LegalEntity.Participation.ParticipationId))));
+
+ // Because seed data doesn't include ParticipationIds we ignore them above,
+ // but still want to ensure they are set in the API response
+ apiData.LegalEntities
+ .SelectMany(le => le.Participations)
+ .All(p => p.ParticipationId.HasValue && p.ParticipationId != Guid.Empty)
+ .Should().BeTrue();
+ }
+
+ [Fact]
+ public async Task UpdateDataHolderMetadataWithNBLShouldUpdateAndPersistSuccessfully()
+ {
+ // Arrange
+ var industry = Industry.NonBankLending;
+ var metadata = CreateValidDataHolderMetadata(industry, true);
+
+ // AC: Additional attributes for NBL
+ metadata.BrandGroup = "TestBrandGroup";
+ metadata.EndpointDetail.ProductBaseUri = "https://test.com/products";
+
+ // Act - update
+ var updateResponse = await PostUpdateDataHolderRequest(GetJsonFromModel(metadata));
+ using var scope = new AssertionScope();
+
+ // Assert
+ updateResponse.StatusCode.Should().Be(HttpStatusCode.OK);
+
+ VerifySuccessfulDataHolderUpdate(metadata, updateResponse, industry);
+ var expectedIndustry = "non-bank-lending";
+ VerifyParticipationRecord(metadata.LegalEntity.LegalEntityId, "DH", expectedIndustry, "ACTIVE");
+ }
+
+ [Fact]
+ public async Task UpdateDataHolderMEtaDataWithInvalidIndustryShouldReturnBadRequest()
+ {
+ // Arrange
+ var metadata = CreateValidDataHolderMetadata(Industry.Banking, true);
+
+ // Force invalid industry
+ metadata.Industries = new List { "invalid industry" };
+
+ // Act
+ var response = await PostUpdateDataHolderRequest(GetJsonFromModel(metadata));
+
+ // Assert
+ response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
+ var content = await response.Content.ReadAsStringAsync();
+ content.ToLower().Should().Contain("invalid");
+ }
+
[Trait("Category", "CTSONLY")]
[Theory]
[InlineData(Industry.Banking)]
@@ -493,8 +630,8 @@ public async Task AC02_Add_New_DataHolder_WithValidToken_200(Industry industry)
// Get the token
var accessToken = await GetAzureAdAccessToken();
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(industry, false);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(industry, false);
// Send to Register
HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata), accessToken: accessToken);
@@ -503,7 +640,7 @@ public async Task AC02_Add_New_DataHolder_WithValidToken_200(Industry industry)
VerifySuccessfulDataHolderUpdate(dataHolderMetadata, response, industry);
// Assert participation created correctly
- VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", industry.ToString(), dataHolderMetadata.Status);
+ VerifyParticipationRecord(dataHolderMetadata.LegalEntity.LegalEntityId, "DH", IndustryMapping[industry].ToLowerInvariant(), dataHolderMetadata.Status);
}
[Trait("Category", "CTSONLY")]
@@ -512,8 +649,8 @@ public async Task AC02_Add_New_DataHolder_WithValidToken_200(Industry industry)
[InlineData(EXPIRED_ACCESS_TOKEN)]
public async Task AC02_Add_New_DataHolder_InvalidToken_401(string accessToken)
{
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
// Send to Register
HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata), accessToken: accessToken);
@@ -529,8 +666,8 @@ public async Task AC02_Add_New_DataHolder_InvalidRole_401()
// Get the token
var accessToken = await GetInvalidAzureAdAccessToken();
- // Generate valid payload with only mandatory/minimun fields.
- DataHolderMetadata dataHolderMetadata = CreateValidDataholderMetadata(Industry.Banking, false);
+ // Generate valid payload with only mandatory/minimum fields.
+ DataHolderMetadata dataHolderMetadata = CreateValidDataHolderMetadata(Industry.Banking, false);
// Send to Register
HttpResponseMessage response = await PostUpdateDataHolderRequest(GetJsonFromModel(dataHolderMetadata), accessToken: accessToken);
@@ -567,11 +704,11 @@ private static async Task PostUpdateDataHolderRequest(strin
return httpResponse;
}
- private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage response, DataHolderMetadata dataHolderMetadata, string field, string value, bool isValid, Industry industry = Industry.Banking)
+ private static async Task VerifyInvalidAndValidFieldResponse(HttpResponseMessage response, DataHolderMetadata dataHolderMetadata, string field, string value, bool isValid, Industry? industry = Industry.Banking)
{
if (isValid)
{
- string actualDataHolder = GetActualDataHolderFromDatabase(dataHolderMetadata.LegalEntity.LegalEntityId, dataHolderMetadata.DataHolderBrandId, industry);
+ string actualDataHolder = GetActualDataHolderFromDatabase(dataHolderMetadata.LegalEntity.LegalEntityId, dataHolderMetadata.DataHolderBrandId, industry.Value);
Assert_Json(GetJsonFromModel(dataHolderMetadata), actualDataHolder);
}
@@ -607,36 +744,40 @@ private static void VerifySuccessfulDataHolderUpdate(DataHolderMetadata expected
}
}
- private static DataHolderMetadata CreateValidDataholderMetadata(Industry industry, bool includeOptionalFields = false)
+ private static DataHolderMetadata CreateValidDataHolderMetadata(Industry industry, bool includeOptionalFields = false)
{
- DataHolderMetadata dataHolderMetadata = new DataHolderMetadata();
- dataHolderMetadata.DataHolderBrandId = Guid.NewGuid().ToString();
- dataHolderMetadata.BrandName = "Test Automation Brand Name";
- dataHolderMetadata.Industries = new List { industry.ToString().ToUpper() };
- dataHolderMetadata.Status = "ACTIVE";
- dataHolderMetadata.LogoUri = $"{TEST_DATA_BASE_URI}/logo.png";
-
- dataHolderMetadata.LegalEntity = new DataHolderMetadata.LegalEntityChild()
+ var dataHolderMetadata = new DataHolderMetadata
{
- LegalEntityId = Guid.NewGuid().ToString(),
- LegalEntityName = "Test Automation Generated Legal Entity Name",
- LogoUri = $"{TEST_DATA_BASE_URI}/logo.png",
+ DataHolderBrandId = Guid.NewGuid().ToString(),
+ BrandName = "Test Automation Brand Name",
+ BrandGroup = "Test Automation Brand Group",
+ Industries = [IndustryMapping[industry].ToUpperInvariant()],
Status = "ACTIVE",
- };
-
- dataHolderMetadata.EndpointDetail = new DataHolderMetadata.EndpointDetailChild()
- {
- Version = "1",
- PublicBaseUri = $"{TEST_DATA_BASE_URI}/publicBaseUri",
- ResourceBaseUri = $"{TEST_DATA_BASE_URI}/resourceBaseUri",
- InfosecBaseUri = $"{TEST_DATA_BASE_URI}/infosecBaseUri",
- WebsiteUri = $"{TEST_DATA_BASE_URI}/websiteUri",
- };
+ LogoUri = $"{TEST_DATA_BASE_URI}/logo.png",
- dataHolderMetadata.AuthDetails = new DataHolderMetadata.AuthDetailsChild()
- {
- RegisterUType = "SIGNED-JWT",
- JwksEndpoint = $"{TEST_DATA_BASE_URI}/jwks.json",
+ LegalEntity = new DataHolderMetadata.LegalEntityChild
+ {
+ LegalEntityId = Guid.NewGuid().ToString(),
+ LegalEntityName = "Test Automation Generated Legal Entity Name",
+ LogoUri = $"{TEST_DATA_BASE_URI}/logo.png",
+ Status = "ACTIVE",
+ },
+
+ EndpointDetail = new DataHolderMetadata.EndpointDetailChild
+ {
+ Version = "1",
+ PublicBaseUri = $"{TEST_DATA_BASE_URI}/publicBaseUri",
+ ProductBaseUri = $"{TEST_DATA_BASE_URI}/productBaseUri",
+ ResourceBaseUri = $"{TEST_DATA_BASE_URI}/resourceBaseUri",
+ InfosecBaseUri = $"{TEST_DATA_BASE_URI}/infosecBaseUri",
+ WebsiteUri = $"{TEST_DATA_BASE_URI}/websiteUri",
+ },
+
+ AuthDetails = new DataHolderMetadata.AuthDetailsChild
+ {
+ RegisterUType = "SIGNED-JWT",
+ JwksEndpoint = $"{TEST_DATA_BASE_URI}/jwks.json",
+ },
};
if (includeOptionalFields)
@@ -671,13 +812,14 @@ private static string GetActualDataHolderFromDatabase(string legalEntityId, stri
.Include(participation => participation.Brands)
.ThenInclude(brandStatus => brandStatus.BrandStatus)
.Include(participation => participation.Brands)
- .Where(participation => participation.LegalEntityId == legalEntityIdGuid
- && participation.Industry.IndustryTypeCode == industry.ToString())
+ .Where(participation => participation.LegalEntityId == legalEntityIdGuid)
+ .Where(participation => participation.Industry.IndustryTypeCode == IndustryMapping[industry].ToUpperInvariant())
.OrderBy(participation => participation.LegalEntityId)
.Select(participation => participation.Brands.Where(brand => brand.BrandId == Guid.Parse(brandId)).Select(brand => new
{
dataHolderBrandId = brand.BrandId,
brandName = brand.BrandName,
+ brandGroup = brand.BrandGroup, // White-labelling
industries = new List { participation.Industry.IndustryTypeCode.ToUpper() },
logoUri = brand.LogoUri,
status = brand.BrandStatus.BrandStatusCode,
@@ -702,6 +844,7 @@ private static string GetActualDataHolderFromDatabase(string legalEntityId, stri
{
version = brand.Endpoint.Version,
publicBaseUri = brand.Endpoint.PublicBaseUri,
+ productBaseUri = brand.Endpoint.ProductBaseUri, // White-labelling
resourceBaseUri = brand.Endpoint.ResourceBaseUri,
infosecBaseUri = brand.Endpoint.InfosecBaseUri,
extensionBaseUri = brand.Endpoint.ExtensionBaseUri,
@@ -740,8 +883,8 @@ private static async Task GetAzureAdAccessToken()
throw new Exception($"Unable to retrieve access token from Azure AD.\n Http Status Code: {response.StatusCode}\nResponse Body:{responseBody}");
}
- var tokenResnse = JsonConvert.DeserializeObject(responseBody);
- return tokenResnse.Access_token;
+ var tokenResponse = JsonConvert.DeserializeObject(responseBody);
+ return tokenResponse.Access_token;
}
private static async Task GetInvalidAzureAdAccessToken()
@@ -762,8 +905,8 @@ private static async Task GetInvalidAzureAdAccessToken()
throw new Exception($"Unable to retrieve access token from Azure AD.\n Http Status Code: {response.StatusCode}\nResponse Body:{responseBody}");
}
- var tokenResnse = JsonConvert.DeserializeObject(responseBody);
- return tokenResnse.Access_token;
+ var tokenResponse = JsonConvert.DeserializeObject(responseBody);
+ return tokenResponse.Access_token;
}
}
}
diff --git a/Source/CDR.Register.IntegrationTests/BaseTest.cs b/Source/CDR.Register.IntegrationTests/BaseTest.cs
index 293ee38..7cc952c 100644
--- a/Source/CDR.Register.IntegrationTests/BaseTest.cs
+++ b/Source/CDR.Register.IntegrationTests/BaseTest.cs
@@ -51,38 +51,53 @@ public abstract class BaseTest : BaseTest0, IClassFixture
protected const string DEFAULT_CERTIFICATE_THUMBPRINT = "f0e5146a51f16e236844cf0353d791f11865e405";
protected const string DEFAULT_CERTIFICATE_COMMON_NAME = "MockDataRecipient";
- protected const string EXPECTED_UNSUPPORTED_ERROR = @"
+ protected const string EXPECTED_UNSUPPORTED_ERROR = """
{
- ""errors"": [
+ "errors": [
{
- ""code"": ""urn:au-cds:error:cds-all:Header/UnsupportedVersion"",
- ""title"": ""Unsupported Version"",
- ""detail"": ""Requested version is lower than the minimum version or greater than maximum version."",
+ "code": "urn:au-cds:error:cds-all:Header/UnsupportedVersion",
+ "title": "Unsupported Version",
+ "detail": "Requested version is lower than the minimum version or greater than maximum version.",
}
]
- }";
+ }
+ """;
- protected const string EXPECTED_INVALID_VERSION_ERROR = @"
+ protected const string EXPECTED_INVALID_VERSION_ERROR = """
{
- ""errors"": [
+ "errors": [
{
- ""code"": ""urn:au-cds:error:cds-all:Header/InvalidVersion"",
- ""title"": ""Invalid Version"",
- ""detail"": ""Version is not a positive Integer.""
+ "code": "urn:au-cds:error:cds-all:Header/InvalidVersion",
+ "title": "Invalid Version",
+ "detail": "Version is not a positive Integer."
}
]
- }";
+ }
+ """;
- protected const string EXPECTED_MISSING_X_V_ERROR = @"
+ protected const string EXPECTED_MISSING_X_V_ERROR = """
{
- ""errors"": [
+ "errors": [
{
- ""code"": ""urn:au-cds:error:cds-all:Header/Missing"",
- ""title"": ""Missing Required Header"",
- ""detail"": ""An API version x-v header is required, but was not specified."",
+ "code": "urn:au-cds:error:cds-all:Header/Missing",
+ "title": "Missing Required Header",
+ "detail": "An API version x-v header is required, but was not specified.",
}
]
- }";
+ }
+ """;
+
+ protected const string EXPECTED_INVALIDFIELD_INDUSTRY = """
+ {
+ "errors": [
+ {
+ "code": "urn:au-cds:error:cds-all:Field/Invalid",
+ "title": "Invalid Field",
+ "detail": "industry"
+ }
+ ]
+ }
+ """;
private const string REGISTER_RW = "DefaultConnection";
private static IConfigurationRoot? configuration;
@@ -393,7 +408,7 @@ public static string GenerateDynamicCtsUrl(string baseUrl, string? conformanceId
}
}
- protected static void VerifyParticipationRecord(string legalEntiryId, string expectedParticipationType, string expectedIndustryType, string expectedStatus)
+ protected static void VerifyParticipationRecord(string legalEntityId, string expectedParticipationType, string expectedIndustryType, string expectedStatus)
{
using SqlConnection registerConnection = new SqlConnection(BaseTest.CONNECTIONSTRING_REGISTER_RW);
@@ -414,7 +429,7 @@ Participation p
FULL JOIN IndustryType i ON p.IndustryId = i.IndustryTypeId
FULL JOIN ParticipationStatus ps ON p.StatusId = ps.ParticipationStatusId
WHERE
- p.LegalEntityId = '{legalEntiryId}'
+ p.LegalEntityId = '{legalEntityId}'
AND pt.ParticipationTypeCode = '{expectedParticipationType}' ";
if (expectedIndustryType == null)
@@ -458,7 +473,7 @@ Participation p
}
catch (Exception e)
{
- throw new Exception($"Error Getting Participation Record for Legal Entity: {legalEntiryId}", e);
+ throw new Exception($"Error Getting Participation Record for Legal Entity: {legalEntityId}", e);
}
}
diff --git a/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs b/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
index d5b2d37..ccaf9fe 100644
--- a/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
+++ b/Source/CDR.Register.IntegrationTests/Models/DataHolderMetadata.cs
@@ -20,6 +20,9 @@ public class DataHolderMetadata
[JsonProperty("status")]
public string Status { get; set; }
+ [JsonProperty("brandGroup")]
+ public string BrandGroup { get; set; }
+
[JsonProperty("endpointDetail")]
public EndpointDetailChild EndpointDetail { get; set; }
@@ -46,6 +49,9 @@ public class EndpointDetailChild
[JsonProperty("publicBaseUri")]
public string PublicBaseUri { get; set; }
+ [JsonProperty("productBaseUri")]
+ public string ProductBaseUri { get; set; }
+
[JsonProperty("resourceBaseUri")]
public string ResourceBaseUri { get; set; }
diff --git a/Source/CDR.Register.IntegrationTests/Models/LegalEntity.cs b/Source/CDR.Register.IntegrationTests/Models/LegalEntity.cs
new file mode 100644
index 0000000..24a58c2
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/Models/LegalEntity.cs
@@ -0,0 +1,187 @@
+using System;
+using Newtonsoft.Json;
+
+namespace CDR.Register.IntegrationTests.Models;
+
+public class LegalEntity
+{
+ [JsonProperty("legalEntityId")]
+ public Guid LegalEntityId { get; set; }
+
+ [JsonProperty("legalEntityName")]
+ public string LegalEntityName { get; set; }
+
+ [JsonProperty("logoUri")]
+ public Uri LogoUri { get; set; }
+
+ [JsonProperty("registrationNumber")]
+ public string RegistrationNumber { get; set; }
+
+ [JsonProperty("registrationDate")]
+ public DateTimeOffset? RegistrationDate { get; set; }
+
+ [JsonProperty("registeredCountry")]
+ public string RegisteredCountry { get; set; }
+
+ [JsonProperty("abn")]
+ public string Abn { get; set; }
+
+ [JsonProperty("acn")]
+ public string Acn { get; set; }
+
+ [JsonProperty("anzsicDivision")]
+ public string AnzsicDivision { get; set; }
+
+ [JsonProperty("organisationTypeId")]
+ public int? OrganisationTypeId { get; set; }
+
+ [JsonProperty("participations")]
+ public Participation[] Participations { get; set; }
+
+ [JsonProperty("arbn")]
+ public string Arbn { get; set; }
+
+ [JsonProperty("accreditationNumber", NullValueHandling = NullValueHandling.Ignore)]
+ public string AccreditationNumber { get; set; }
+
+ [JsonProperty("accreditationLevelId", NullValueHandling = NullValueHandling.Ignore)]
+ public int? AccreditationLevelId { get; set; }
+
+ public class Participation
+ {
+ [JsonProperty("participationId", NullValueHandling = NullValueHandling.Ignore)]
+ public Guid? ParticipationId { get; set; }
+
+ [JsonProperty("participationTypeId")]
+ public int ParticipationTypeId { get; set; }
+
+ [JsonProperty("industryId")]
+ public int? IndustryId { get; set; }
+
+ [JsonProperty("statusId")]
+ public int StatusId { get; set; }
+
+ [JsonProperty("brands")]
+ public Brand[] Brands { get; set; }
+
+ public class Brand
+ {
+ [JsonProperty("brandId")]
+ public Guid BrandId { get; set; }
+
+ [JsonProperty("brandName")]
+ public string BrandName { get; set; }
+
+ [JsonProperty("brandGroup")]
+ public string BrandGroup { get; set; }
+
+ [JsonProperty("logoUri")]
+ public Uri LogoUri { get; set; }
+
+ [JsonProperty("brandStatusId")]
+ public int BrandStatusId { get; set; }
+
+ [JsonProperty("lastUpdated")]
+ public DateTimeOffset LastUpdated { get; set; }
+
+ [JsonProperty("softwareProducts")]
+ public SoftwareProduct[] SoftwareProducts { get; set; } = [];
+
+ [JsonProperty("authDetails", NullValueHandling = NullValueHandling.Ignore)]
+ public AuthDetail[] AuthDetails { get; set; } = [];
+
+ [JsonProperty("endpoint", NullValueHandling = NullValueHandling.Ignore)]
+ public Endpoint Endpoints { get; set; }
+
+ public class AuthDetail
+ {
+ [JsonProperty("registerUTypeId")]
+ public int RegisterUTypeId { get; set; }
+
+ [JsonProperty("jwksEndpoint")]
+ public Uri JwksEndpoint { get; set; }
+ }
+
+ public class Endpoint
+ {
+ [JsonProperty("version")]
+ public string Version { get; set; }
+
+ [JsonProperty("publicBaseUri")]
+ public Uri PublicBaseUri { get; set; }
+
+ [JsonProperty("productBaseUri")]
+ public Uri ProductBaseUri { get; set; }
+
+ [JsonProperty("resourceBaseUri")]
+ public Uri ResourceBaseUri { get; set; }
+
+ [JsonProperty("infosecBaseUri")]
+ public Uri InfosecBaseUri { get; set; }
+
+ [JsonProperty("extensionBaseUri")]
+ public string ExtensionBaseUri { get; set; }
+
+ [JsonProperty("websiteUri")]
+ public Uri WebsiteUri { get; set; }
+ }
+
+ public class SoftwareProduct
+ {
+ [JsonProperty("softwareProductId")]
+ public Guid SoftwareProductId { get; set; }
+
+ [JsonProperty("softwareProductName")]
+ public string SoftwareProductName { get; set; }
+
+ [JsonProperty("softwareProductDescription")]
+ public string SoftwareProductDescription { get; set; }
+
+ [JsonProperty("logoUri")]
+ public Uri LogoUri { get; set; }
+
+ [JsonProperty("sectorIdentifierUri")]
+ public Uri SectorIdentifierUri { get; set; }
+
+ [JsonProperty("clientUri")]
+ public Uri ClientUri { get; set; }
+
+ [JsonProperty("tosUri")]
+ public Uri TosUri { get; set; }
+
+ [JsonProperty("policyUri")]
+ public Uri PolicyUri { get; set; }
+
+ [JsonProperty("recipientBaseUri")]
+ public Uri RecipientBaseUri { get; set; }
+
+ [JsonProperty("revocationUri")]
+ public Uri RevocationUri { get; set; }
+
+ [JsonProperty("redirectUris")]
+ public Uri RedirectUris { get; set; }
+
+ [JsonProperty("jwksUri")]
+ public Uri JwksUri { get; set; }
+
+ [JsonProperty("scope")]
+ public string Scope { get; set; }
+
+ [JsonProperty("statusId")]
+ public int StatusId { get; set; }
+
+ [JsonProperty("certificates")]
+ public Certificate[] Certificates { get; set; }
+
+ public class Certificate
+ {
+ [JsonProperty("commonName")]
+ public string CommonName { get; set; }
+
+ [JsonProperty("thumbprint")]
+ public string Thumbprint { get; set; }
+ }
+ }
+ }
+ }
+}
diff --git a/Source/CDR.Register.IntegrationTests/Models/MetaData.cs b/Source/CDR.Register.IntegrationTests/Models/MetaData.cs
new file mode 100644
index 0000000..6b2ffcd
--- /dev/null
+++ b/Source/CDR.Register.IntegrationTests/Models/MetaData.cs
@@ -0,0 +1,10 @@
+using System;
+using Newtonsoft.Json;
+
+namespace CDR.Register.IntegrationTests.Models;
+
+public class MetaData
+{
+ [JsonProperty("legalEntities")]
+ public LegalEntity[] LegalEntities { get; set; }
+}
diff --git a/Source/CDR.Register.IntegrationTests/Start-Register.bat b/Source/CDR.Register.IntegrationTests/Start-Register.bat
index 778b8a2..7ba702d 100644
--- a/Source/CDR.Register.IntegrationTests/Start-Register.bat
+++ b/Source/CDR.Register.IntegrationTests/Start-Register.bat
@@ -11,6 +11,7 @@ REM --title SSA_API -d ../CDR.Register.SSA.API dotnet run; ^
REM --title Status_API -d ../CDR.Register.Status.API dotnet run; ^
REM --title Admin_API -d ../CDR.Register.Admin.API dotnet run
-docker compose -f ../docker-compose.IntegrationTests.yml up -d --build mssql mock-register
+docker compose -f ../docker-compose.IntegrationTests.yml up -d --build --force-recreate mssql mock-register
echo Supporting infrastructure for tests will now stop.
-pause
\ No newline at end of file
+pause
+docker compose -f ../docker-compose.IntegrationTests.yml down
\ No newline at end of file
diff --git a/Source/CDR.Register.IntegrationTests/integration.Release.runsettings b/Source/CDR.Register.IntegrationTests/integration.Release.runsettings
index d6714e4..12da201 100644
--- a/Source/CDR.Register.IntegrationTests/integration.Release.runsettings
+++ b/Source/CDR.Register.IntegrationTests/integration.Release.runsettings
@@ -2,6 +2,9 @@
+ true
+
+ (Category!=CTSONLY)
Release
diff --git a/Source/CDR.Register.Repository.UnitTests/BrandSpecificationTests.cs b/Source/CDR.Register.Repository.UnitTests/BrandSpecificationTests.cs
new file mode 100644
index 0000000..fb8ee22
--- /dev/null
+++ b/Source/CDR.Register.Repository.UnitTests/BrandSpecificationTests.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Linq;
+using CDR.Register.Repository.Infrastructure;
+using CDR.Register.Repository.Specifications;
+
+namespace CDR.Register.Repository.UnitTests
+{
+ ///
+ /// Test Brand Specifications.
+ ///
+ public class BrandSpecificationTests
+ {
+ private readonly Entities.Brand _banking =
+ new() { BrandName = nameof(Industry.BANKING), Participation = new() { IndustryId = Industry.BANKING } };
+
+ private readonly Entities.Brand _energy =
+ new() { BrandName = nameof(Industry.ENERGY), Participation = new() { IndustryId = Industry.ENERGY } };
+
+ private readonly Entities.Brand _telco =
+ new() { BrandName = nameof(Industry.TELCO), Participation = new() { IndustryId = Industry.TELCO } };
+
+ private readonly Entities.Brand _nonBankLending =
+ new() { BrandName = nameof(Industry.NONBANKLENDING), Participation = new() { IndustryId = Industry.NONBANKLENDING } };
+
+ private readonly IQueryable _brands;
+
+ public BrandSpecificationTests()
+ {
+ this._brands = new Entities.Brand[]
+ {
+ this._banking,
+ this._energy,
+ this._telco,
+ this._nonBankLending,
+ }.AsQueryable();
+ }
+
+ [Fact]
+ public void ExcludeNblIndustrySpecification_AppliesSuccessfully()
+ {
+ var underTest = new BrandSpecifications.ExcludeNblIndustry();
+
+ var result = underTest.Apply(this._brands);
+
+ Assert.NotEqual(this._brands.Count(), result.Count());
+ Assert.DoesNotContain(this._nonBankLending, result);
+ }
+
+ [Fact]
+ public void AllIndustriesSpecification_AppliesSuccessfully()
+ {
+ var underTest = new BrandSpecifications.AllIndustries();
+
+ var result = underTest.Apply(this._brands);
+
+ Assert.Equal(this._brands.Count(), result.Count());
+ }
+ }
+}
diff --git a/Source/CDR.Register.Repository.UnitTests/CDR.Register.Repository.UnitTests.csproj b/Source/CDR.Register.Repository.UnitTests/CDR.Register.Repository.UnitTests.csproj
new file mode 100644
index 0000000..916216b
--- /dev/null
+++ b/Source/CDR.Register.Repository.UnitTests/CDR.Register.Repository.UnitTests.csproj
@@ -0,0 +1,44 @@
+
+
+
+ false
+ false
+ $(TargetFrameworkVersion)
+ $(Version)
+ $(Version)
+ $(Version)
+ True
+ true
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/CDR.Register.Repository.UnitTests/ParticipantSpecificationTests.cs b/Source/CDR.Register.Repository.UnitTests/ParticipantSpecificationTests.cs
new file mode 100644
index 0000000..c794594
--- /dev/null
+++ b/Source/CDR.Register.Repository.UnitTests/ParticipantSpecificationTests.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Linq;
+using CDR.Register.Repository.Infrastructure;
+using CDR.Register.Repository.Specifications;
+
+namespace CDR.Register.Repository.UnitTests
+{
+ ///
+ /// Test Participation Specifications.
+ ///
+ public class ParticipantSpecificationTests
+ {
+ private readonly Entities.Participation _banking = new() { IndustryId = Industry.BANKING };
+
+ private readonly Entities.Participation _energy = new() { IndustryId = Industry.ENERGY };
+
+ private readonly Entities.Participation _telco = new() { IndustryId = Industry.TELCO };
+
+ private readonly Entities.Participation _nonBankLending = new() { IndustryId = Industry.NONBANKLENDING };
+
+ private readonly IQueryable _participations;
+
+ public ParticipantSpecificationTests()
+ {
+ this._participations = new Entities.Participation[]
+ {
+ this._banking,
+ this._energy,
+ this._telco,
+ this._nonBankLending,
+ }.AsQueryable();
+ }
+
+ [Fact]
+ public void ExcludeNblIndustrySpecification_AppliesSuccessfully()
+ {
+ var underTest = new ParticipationsSpecifications.ExcludeNblIndustry();
+
+ var result = underTest.Apply(this._participations);
+
+ Assert.NotEqual(this._participations.Count(), result.Count());
+ Assert.DoesNotContain(this._nonBankLending, result);
+ }
+
+ [Fact]
+ public void AllIndustriesSpecification_AppliesSuccessfully()
+ {
+ var underTest = new ParticipationsSpecifications.AllIndustries();
+
+ var result = underTest.Apply(this._participations);
+
+ Assert.Equal(this._participations.Count(), result.Count());
+ }
+ }
+}
diff --git a/Source/CDR.Register.Repository/CDR.Register.Repository.csproj b/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
index e219e81..f40f275 100644
--- a/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
+++ b/Source/CDR.Register.Repository/CDR.Register.Repository.csproj
@@ -7,8 +7,9 @@
true
false
+
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -25,6 +26,11 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/Source/CDR.Register.Repository/Entities/Brand.cs b/Source/CDR.Register.Repository/Entities/Brand.cs
index 38ee51f..5936375 100644
--- a/Source/CDR.Register.Repository/Entities/Brand.cs
+++ b/Source/CDR.Register.Repository/Entities/Brand.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using CDR.Register.Repository.Enums;
@@ -19,6 +20,10 @@ public Brand()
[Required]
public string BrandName { get; set; }
+ [MaxLength(100)]
+ [Description("The brand group for white-labelling")]
+ public string BrandGroup { get; set; }
+
[MaxLength(1000)]
[Required]
diff --git a/Source/CDR.Register.Repository/Entities/Endpoint.cs b/Source/CDR.Register.Repository/Entities/Endpoint.cs
index 8cb0838..6fdf228 100644
--- a/Source/CDR.Register.Repository/Entities/Endpoint.cs
+++ b/Source/CDR.Register.Repository/Entities/Endpoint.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -18,6 +19,10 @@ public class Endpoint
[Required]
public string PublicBaseUri { get; set; }
+ [MaxLength(1000)]
+ [Description("The PRD base URI")]
+ public string ProductBaseUri { get; set; }
+
[MaxLength(1000)]
[Required]
public string ResourceBaseUri { get; set; }
diff --git a/Source/CDR.Register.Repository/Entities/Enumerations.cs b/Source/CDR.Register.Repository/Entities/Enumerations.cs
deleted file mode 100644
index f26c4e8..0000000
--- a/Source/CDR.Register.Repository/Entities/Enumerations.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-namespace CDR.Register.Repository.Entities.Enumerations
-{
- public enum Industry
- {
- ALL = 0,
- BANKING,
- ENERGY,
- TELCO,
- }
-
- public enum OrganisationType
- {
- Unknown = 0,
- SoleTrader = 1,
- Company = 2,
- Partnership = 3,
- Trust = 4,
- GovernmentEntity = 5,
- Other = 6,
- }
-
- public enum AccreditationLevel
- {
- // Sponsored by Default
- Sponsored = 0,
- Unrestricted = 1,
- }
-
- public enum ParticipationStatus
- {
- Unknown = 0,
- Active = 1,
- Removed = 2,
- Suspended = 3,
- Revoked = 4,
- Surrendered = 5,
- Inactive = 6,
- }
-
- public enum LegalEntityStatus
- {
- Active = 1,
- Removed = 2,
- }
-
- public enum BrandStatus
- {
- Unknown = 0,
- Active = 1,
- Inactive = 2,
- Removed = 3,
- }
-
- public enum ParticipationType
- {
- Unknown = 0,
- Dh = 1,
- Dr = 2,
- }
-
- public enum RegisterUType
- {
- Unknown = 0,
- SignedJwt = 1,
- }
-
- public enum SoftwareProductStatus
- {
- Unknown = 0,
- Active = 1,
- Inactive = 2,
- Removed = 3,
- }
-}
diff --git a/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs b/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
index 2ea0ddf..6e6c671 100644
--- a/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
+++ b/Source/CDR.Register.Repository/IRegisterDiscoveryRepository.cs
@@ -2,15 +2,16 @@
using System.Threading.Tasks;
using CDR.Register.Domain.Entities;
using CDR.Register.Domain.ValueObjects;
+using CDR.Register.Repository.Specifications;
namespace CDR.Register.Repository.Interfaces
{
public interface IRegisterDiscoveryRepository
{
- Task> GetDataHolderBrandsAsync(Infrastructure.Industry industry, DateTime? updatedSince, int page, int pageSize);
+ Task> GetDataHolderBrands(Infrastructure.Industry industry, IBrandSpecification specification, DateTime? updatedSince, int page, int pageSize);
- Task GetDataRecipientsAsync(Infrastructure.Industry industry);
+ Task GetDataRecipientsAsync();
- Task GetSoftwareProductIdAsync(Guid softwareProductId);
+ Task GetSoftwareProductId(Guid softwareProductId);
}
}
diff --git a/Source/CDR.Register.Repository/IRegisterStatusRepository.cs b/Source/CDR.Register.Repository/IRegisterStatusRepository.cs
index 96dfa7f..1d27c18 100644
--- a/Source/CDR.Register.Repository/IRegisterStatusRepository.cs
+++ b/Source/CDR.Register.Repository/IRegisterStatusRepository.cs
@@ -1,14 +1,15 @@
using System.Threading.Tasks;
using CDR.Register.Domain.Entities;
+using CDR.Register.Repository.Specifications;
namespace CDR.Register.Repository.Interfaces
{
public interface IRegisterStatusRepository
{
- Task GetDataRecipientStatusesAsync(Infrastructure.Industry industry);
+ Task GetDataRecipientStatuses(Infrastructure.Industry industry, IParticipationSpecification specification);
- Task GetSoftwareProductStatusesAsync(Infrastructure.Industry industry);
+ Task GetSoftwareProductStatuses(Infrastructure.Industry industry, IParticipationSpecification specification);
- Task GetDataHolderStatusesAsync(Infrastructure.Industry industry);
+ Task GetDataHolderStatuses(Infrastructure.Industry industry, IParticipationSpecification specification);
}
}
diff --git a/Source/CDR.Register.Repository/Infrastructure/Extensions.cs b/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
index 258a4eb..b5d4ccc 100644
--- a/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/Extensions.cs
@@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using CDR.Register.Domain.Extensions;
using CDR.Register.Domain.ValueObjects;
using CDR.Register.Repository.Entities;
using CDR.Register.Repository.Enums;
@@ -20,8 +21,9 @@ public static void SeedDatabase(this ModelBuilder modelBuilder)
{
// Add Seed Data for the reference types
modelBuilder.Entity().HasData(
- new IndustryType { IndustryTypeId = Industry.BANKING, IndustryTypeCode = Industry.BANKING.ToString().ToLower() },
- new IndustryType { IndustryTypeId = Industry.ENERGY, IndustryTypeCode = Industry.ENERGY.ToString().ToLower() });
+ new IndustryType { IndustryTypeId = Industry.BANKING, IndustryTypeCode = EnumExtensions.GetDescription(Industry.BANKING) },
+ new IndustryType { IndustryTypeId = Industry.ENERGY, IndustryTypeCode = EnumExtensions.GetDescription(Industry.ENERGY) },
+ new IndustryType { IndustryTypeId = Industry.NONBANKLENDING, IndustryTypeCode = EnumExtensions.GetDescription(Industry.NONBANKLENDING) });
modelBuilder.Entity().HasData(
new OrganisationType { OrganisationTypeId = OrganisationTypes.SoleTrader, OrganisationTypeCode = "SOLE_TRADER" },
diff --git a/Source/CDR.Register.Repository/Infrastructure/Industry.cs b/Source/CDR.Register.Repository/Infrastructure/Industry.cs
index ccb8e76..88104a1 100644
--- a/Source/CDR.Register.Repository/Infrastructure/Industry.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/Industry.cs
@@ -1,10 +1,46 @@
-namespace CDR.Register.Repository.Infrastructure
+using System.ComponentModel;
+using System.Runtime.Serialization;
+
+namespace CDR.Register.Repository.Infrastructure
{
+ ///
+ /// The industry.
+ ///
public enum Industry
{
+ ///
+ /// All industries.
+ ///
+ [Description("all")]
+ [EnumMember(Value = "all")]
ALL = 0,
- BANKING,
- ENERGY,
- TELCO,
+
+ ///
+ /// Banking.
+ ///
+ [Description("banking")]
+ [EnumMember(Value = "banking")]
+ BANKING = 1,
+
+ ///
+ /// Energy.
+ ///
+ [Description("energy")]
+ [EnumMember(Value = "energy")]
+ ENERGY = 2,
+
+ ///
+ /// Non-Bank Lending.
+ ///
+ [Description("non-bank-lending")]
+ [EnumMember(Value = "non-bank-lending")]
+ NONBANKLENDING = 3,
+
+ ///
+ /// Telecoms Company.
+ ///
+ [Description("telco")]
+ [EnumMember(Value = "telco")]
+ TELCO = 4,
}
}
diff --git a/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs b/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
index 3e72c35..13e7e85 100644
--- a/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/MappingProfile.cs
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using AutoMapper;
+using CDR.Register.Domain;
+using CDR.Register.Domain.Extensions;
using CDR.Register.Repository.Entities;
using CDR.Register.Repository.Enums;
using DomainEntities = CDR.Register.Domain.Entities;
@@ -13,19 +15,24 @@ public MappingProfile()
{
this.CreateMap()
.ForMember(dest => dest.OrganisationType, source => source.MapFrom(source => source.OrganisationType.OrganisationTypeCode))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Participations.FirstOrDefault().Status.ParticipationStatusCode.ToUpper()));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Participations.FirstOrDefault().Status.ParticipationStatusCode.ToUpper()))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
+
this.CreateMap()
.ForMember(dest => dest.OrganisationTypeId, source => source.MapFrom(source =>
source.OrganisationType == null ? null : Enum.Parse(typeof(OrganisationTypes), source.OrganisationType.Replace("_", string.Empty), true)))
- .ForMember(dest => dest.OrganisationType, opt => opt.Ignore());
+ .ForMember(dest => dest.OrganisationType, opt => opt.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.OrganisationType, source => source.MapFrom(source => source.OrganisationType.OrganisationTypeCode))
- .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Participations.FirstOrDefault().Status.ParticipationStatusCode.ToUpper()));
+ .ForMember(dest => dest.Status, source => source.MapFrom(source => source.Participations.FirstOrDefault().Status.ParticipationStatusCode.ToUpper()))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.OrganisationTypeId, source => source.MapFrom(source => source.OrganisationType == null ? null : Enum.Parse(typeof(OrganisationTypes), source.OrganisationType.Replace("_", string.Empty), true)))
- .ForMember(dest => dest.OrganisationType, opt => opt.Ignore());
+ .ForMember(dest => dest.OrganisationType, opt => opt.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.DataHolderId, source => source.MapFrom(source => source.ParticipationId))
@@ -33,14 +40,16 @@ public MappingProfile()
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => source.Status.ParticipationStatusId == ParticipationStatusType.Active))
.ForMember(dest => dest.Industry, source => source.MapFrom(source => source.Industry.IndustryTypeCode))
.ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source.LegalEntity))
- .ForMember(dest => dest.Brands, source => source.MapFrom(source => source.Brands));
+ .ForMember(dest => dest.Brands, source => source.MapFrom(source => source.Brands))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.StatusId, source => source.MapFrom(source => Enum.Parse(typeof(ParticipationStatusType), source.Status, true)))
- .ForMember(dest => dest.IndustryId, source => source.MapFrom(source => Enum.Parse(typeof(Industry), source.Industry, true)))
+ .ForMember(dest => dest.IndustryId, source => source.MapFrom(source => EnumExtensions.ParseFromDescription(source.Industry)))
.ForMember(dest => dest.ParticipationTypeId, source => source.MapFrom(source => ParticipationTypes.Dh)) // This is a Dh Participation
.ForMember(dest => dest.Industry, opt => opt.Ignore())
.ForMember(dest => dest.Status, opt => opt.Ignore())
- .ForMember(dest => dest.ParticipationType, opt => opt.Ignore());
+ .ForMember(dest => dest.ParticipationType, opt => opt.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.DataRecipientId, source => source.MapFrom(source => source.ParticipationId))
@@ -48,10 +57,12 @@ public MappingProfile()
.ForMember(dest => dest.LegalEntity, source => source.MapFrom(source => source.LegalEntity))
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.ParticipationStatusCode))
.ForMember(dest => dest.DataRecipientBrands, source => source.MapFrom(source => source.Brands))
+ .MaxDepth(Constants.MappingConstants.MaxDepth)
.ReverseMap();
this.CreateMap()
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.StatusId.ToString().ToUpper()))
+ .MaxDepth(Constants.MappingConstants.MaxDepth)
.ReverseMap();
this.CreateMap()
@@ -59,57 +70,67 @@ public MappingProfile()
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => source.BrandStatus.BrandStatusId == BrandStatusType.Active))
.ForMember(dest => dest.DataHolderAuthentications, source => source.MapFrom(source => source.AuthDetails))
.ForMember(dest => dest.DataHolderBrandServiceEndpoint, source => source.MapFrom(source => source.Endpoint))
- .ForMember(dest => dest.DataHolder, source => source.MapFrom(source => source.Participation));
+ .ForMember(dest => dest.DataHolder, source => source.MapFrom(source => source.Participation))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.BrandName, source => source.MapFrom(source => source.BrandName))
.ForMember(dest => dest.LogoUri, source => source.MapFrom(source => source.LogoUri))
.ForMember(dest => dest.BrandStatusId, source => source.MapFrom(source => Enum.Parse(typeof(BrandStatusType), source.BrandStatus, true)))
- .ForMember(dest => dest.BrandStatus, opt => opt.Ignore());
+ .ForMember(dest => dest.BrandStatus, opt => opt.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.BrandStatus, source => source.MapFrom(source => source.BrandStatus.BrandStatusCode))
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => source.BrandStatus.BrandStatusId == BrandStatusType.Active))
.ForMember(dest => dest.SoftwareProducts, source => source.MapFrom(source => source.SoftwareProducts))
- .ForMember(dest => dest.DataRecipient, source => source.MapFrom(source => source.Participation));
+ .ForMember(dest => dest.DataRecipient, source => source.MapFrom(source => source.Participation))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.BrandStatusId, source => source.MapFrom(source => Enum.Parse(typeof(BrandStatusType), source.BrandStatus, true)))
.ForMember(dest => dest.BrandStatus, opts => opts.Ignore())
- .ForMember(dest => dest.SoftwareProducts, opts => opts.Ignore());
+ .ForMember(dest => dest.SoftwareProducts, opts => opts.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.Status, source => source.MapFrom(source => source.Status.SoftwareProductStatusCode))
.ForMember(dest => dest.IsActive, source => source.MapFrom(source => source.Status.SoftwareProductStatusId == SoftwareProductStatusType.Active))
.ForMember(dest => dest.RedirectUri, source => source.MapFrom(src => src.RedirectUris))
.ForMember(dest => dest.RedirectUris, opts => opts.Ignore()) // Ignore this as it is a computed property with no setter
- .ForMember(dest => dest.DataRecipientBrand, source => source.MapFrom(s => s.Brand));
+ .ForMember(dest => dest.DataRecipientBrand, source => source.MapFrom(s => s.Brand))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.StatusId, source => source.MapFrom(source => Enum.Parse(typeof(SoftwareProductStatusType), source.Status, true)))
.ForMember(dest => dest.RedirectUris, source => source.MapFrom(src => src.RedirectUris != null ? string.Join(" ", src.RedirectUris) : string.Empty))
.ForMember(dest => dest.Status, opts => opts.Ignore())
- .ForMember(dest => dest.Certificates, opts => opts.Ignore());
+ .ForMember(dest => dest.Certificates, opts => opts.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.Id, source => source.MapFrom(s => s.SoftwareProductId))
.ForMember(dest => dest.Name, source => source.MapFrom(s => s.SoftwareProductName))
.ForMember(dest => dest.JwksUri, source => source.MapFrom(s => s.JwksUri))
- .ForMember(dest => dest.X509Certificates, source => source.MapFrom(s => s.Certificates));
+ .ForMember(dest => dest.X509Certificates, source => source.MapFrom(s => s.Certificates))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
- this.CreateMap().ReverseMap();
+ this.CreateMap().ReverseMap().MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
- .ForMember(dest => dest.RegisterUType, source => source.MapFrom(source => source.RegisterUType.RegisterUTypeCode));
+ .ForMember(dest => dest.RegisterUType, source => source.MapFrom(source => source.RegisterUType.RegisterUTypeCode))
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
.ForMember(dest => dest.RegisterUTypeId, source => source.MapFrom(source =>
Enum.Parse(typeof(RegisterUTypes), source.RegisterUType.Replace("-", string.Empty), true)))
.ForMember(dest => dest.JwksEndpoint, source => source.MapFrom(source => source.JwksEndpoint))
.ForMember(dest => dest.RegisterUType, opt => opt.Ignore())
.ForMember(dest => dest.Brand, opt => opt.Ignore())
- .ForMember(dest => dest.BrandId, opt => opt.Ignore());
+ .ForMember(dest => dest.BrandId, opt => opt.Ignore())
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
this.CreateMap()
- .ReverseMap();
+ .ReverseMap()
+ .MaxDepth(Constants.MappingConstants.MaxDepth);
}
}
}
diff --git a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
index e5dbddf..4fc8ec7 100644
--- a/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
+++ b/Source/CDR.Register.Repository/Infrastructure/RegisterDatabaseContext.cs
@@ -1,4 +1,6 @@
-using System.Linq;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
using CDR.Register.Repository.Entities;
using Microsoft.EntityFrameworkCore;
@@ -69,9 +71,52 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity().ToTable("Participation", t => t.IsTemporal());
modelBuilder.Entity().ToTable("SoftwareProduct", t => t.IsTemporal());
modelBuilder.Entity().ToTable("SoftwareProductCertificate", t => t.IsTemporal());
+ AddColumnDescriptions(modelBuilder);
// Seed the database with reference data and initial data
modelBuilder.SeedDatabase();
}
+
+ ///
+ /// Process entities in the model for any Description attributes on their properties, and translate them to a comment so that the underlying store has that additional metadata.
+ ///
+ /// For MSSQL, this will populate the MS_DESCRIPTION property on the columns.
+ /// The EF model.
+ private static void AddColumnDescriptions(ModelBuilder modelBuilder)
+ {
+ foreach (var entityType in modelBuilder.Model.GetEntityTypes())
+ {
+ var clrType = entityType.ClrType;
+ if (clrType == null)
+ {
+ continue;
+ }
+
+ // Apply table-level comment from [Description]
+ var tableDesc = clrType.GetCustomAttribute();
+ if (tableDesc != null)
+ {
+ modelBuilder.Entity(clrType)
+ .ToTable(t => t.HasComment(tableDesc.Description));
+ }
+
+ // Apply property-level comments from [Description]
+ foreach (var propInfo in entityType.GetProperties().Select(x => x.PropertyInfo))
+ {
+ if (propInfo == null)
+ {
+ continue;
+ }
+
+ var propDesc = propInfo.GetCustomAttribute();
+ if (propDesc != null)
+ {
+ modelBuilder.Entity(clrType)
+ .Property(propInfo.Name)
+ .HasComment(propDesc.Description);
+ }
+ }
+ }
+ }
}
}
diff --git a/Source/CDR.Register.Repository/Migrations/20260206034555_AddNonBankLendingIndustry.Designer.cs b/Source/CDR.Register.Repository/Migrations/20260206034555_AddNonBankLendingIndustry.Designer.cs
new file mode 100644
index 0000000..afafabd
--- /dev/null
+++ b/Source/CDR.Register.Repository/Migrations/20260206034555_AddNonBankLendingIndustry.Designer.cs
@@ -0,0 +1,877 @@
+//
+using System;
+using CDR.Register.Repository.Infrastructure;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace CDR.Register.Repository.Migrations
+{
+ [DbContext(typeof(RegisterDatabaseContext))]
+ [Migration("20260206034555_AddNonBankLendingIndustry")]
+ partial class AddNonBankLendingIndustry
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.21")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("CDR.Register.Repository.Entities.AccreditationLevel", b =>
+ {
+ b.Property("AccreditationLevelId")
+ .HasColumnType("int");
+
+ b.Property("AccreditationLevelCode")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.HasKey("AccreditationLevelId");
+
+ b.ToTable("AccreditationLevel", (string)null);
+ });
+
+ modelBuilder.Entity("CDR.Register.Repository.Entities.AuthDetail", b =>
+ {
+ b.Property("BrandId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RegisterUTypeId")
+ .HasColumnType("int");
+
+ b.Property("JwksEndpoint")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("PeriodEnd")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodEnd");
+
+ b.Property("PeriodStart")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodStart");
+
+ b.HasKey("BrandId", "RegisterUTypeId");
+
+ b.HasIndex("RegisterUTypeId");
+
+ b.ToTable("AuthDetail", (string)null);
+
+ b.ToTable(tb => tb.IsTemporal(ttb =>
+ {
+ ttb.UseHistoryTable("AuthDetailHistory");
+ ttb
+ .HasPeriodStart("PeriodStart")
+ .HasColumnName("PeriodStart");
+ ttb
+ .HasPeriodEnd("PeriodEnd")
+ .HasColumnName("PeriodEnd");
+ }));
+ });
+
+ modelBuilder.Entity("CDR.Register.Repository.Entities.Brand", b =>
+ {
+ b.Property("BrandId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("BrandName")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("BrandStatusId")
+ .HasColumnType("int");
+
+ b.Property("LastUpdated")
+ .HasColumnType("datetime2");
+
+ b.Property("LogoUri")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("ParticipationId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PeriodEnd")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodEnd");
+
+ b.Property("PeriodStart")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodStart");
+
+ b.HasKey("BrandId");
+
+ b.HasIndex("BrandStatusId");
+
+ b.HasIndex("ParticipationId");
+
+ b.ToTable("Brand", (string)null);
+
+ b.ToTable(tb => tb.IsTemporal(ttb =>
+ {
+ ttb.UseHistoryTable("BrandHistory");
+ ttb
+ .HasPeriodStart("PeriodStart")
+ .HasColumnName("PeriodStart");
+ ttb
+ .HasPeriodEnd("PeriodEnd")
+ .HasColumnName("PeriodEnd");
+ }));
+ });
+
+ modelBuilder.Entity("CDR.Register.Repository.Entities.BrandStatus", b =>
+ {
+ b.Property("BrandStatusId")
+ .HasColumnType("int");
+
+ b.Property("BrandStatusCode")
+ .IsRequired()
+ .HasMaxLength(25)
+ .HasColumnType("nvarchar(25)");
+
+ b.HasKey("BrandStatusId");
+
+ b.ToTable("BrandStatus", (string)null);
+
+ b.HasData(
+ new
+ {
+ BrandStatusId = 1,
+ BrandStatusCode = "ACTIVE"
+ },
+ new
+ {
+ BrandStatusId = 2,
+ BrandStatusCode = "INACTIVE"
+ },
+ new
+ {
+ BrandStatusId = 3,
+ BrandStatusCode = "REMOVED"
+ });
+ });
+
+ modelBuilder.Entity("CDR.Register.Repository.Entities.Endpoint", b =>
+ {
+ b.Property("BrandId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ExtensionBaseUri")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("InfosecBaseUri")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("PeriodEnd")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodEnd");
+
+ b.Property("PeriodStart")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime2")
+ .HasColumnName("PeriodStart");
+
+ b.Property("PublicBaseUri")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("ResourceBaseUri")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("Version")
+ .IsRequired()
+ .HasMaxLength(25)
+ .HasColumnType("nvarchar(25)");
+
+ b.Property