diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml index 57bf55e8c..e37c4e212 100644 --- a/.github/workflows/check_pr.yml +++ b/.github/workflows/check_pr.yml @@ -27,21 +27,6 @@ jobs: with: configuration-path: '.github/auto_assign.yml' - check_source_branch: - name: Check Source Branches - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 # required to make the script available for next step - - name: Check Source Branches - uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0 # v6.3.3 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const script = require('./.github/workflows/github_scripts/check_source_branch.js') - script({github, context, core}) - - check_labels: name: Check Required Labels runs-on: ubuntu-latest diff --git a/.github/workflows/github_scripts/check_source_branch.js b/.github/workflows/github_scripts/check_source_branch.js deleted file mode 100644 index ca74afc78..000000000 --- a/.github/workflows/github_scripts/check_source_branch.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = ({github, context, core}) => { - console.log(github, context); - const {GITHUB_BASE_REF, GITHUB_HEAD_REF} = process.env; - - const allowedPrefixNames = ['hotfix', 'renovate', 'dependabot']; - - const isAllowedBranch = allowedPrefixNames.some(prefix => GITHUB_HEAD_REF.startsWith(prefix)); - - if (GITHUB_HEAD_REF !== 'next' && !isAllowedBranch && GITHUB_BASE_REF === 'main') { - core.setFailed(`Merge requests to main branch are only allowed from next branch or branches with a name that starts with hotfix`); - } -} diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 8bb7deb8a..f1b39a6b4 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: pagopa-selfcare-ms-backoffice description: Microservice that manage api keys for pagopa product from selfcare type: application -version: 0.399.0 -appVersion: "2.24.5" +version: 0.400.0 +appVersion: "2.24.5-1-next" dependencies: - name: microservice-chart version: 2.4.0 diff --git a/helm/values-dev.yaml b/helm/values-dev.yaml index 54291ea0d..8a0528331 100644 --- a/helm/values-dev.yaml +++ b/helm/values-dev.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.24.5" + tag: "2.24.5-1-next" pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-prod.yaml b/helm/values-prod.yaml index 76e949545..006603543 100644 --- a/helm/values-prod.yaml +++ b/helm/values-prod.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.24.5" #improve + tag: "2.24.5-1-next" #improve pullPolicy: Always livenessProbe: httpGet: diff --git a/helm/values-uat.yaml b/helm/values-uat.yaml index ffbe347ad..0a599ff5f 100644 --- a/helm/values-uat.yaml +++ b/helm/values-uat.yaml @@ -4,7 +4,7 @@ microservice-chart: fullnameOverride: "" image: repository: ghcr.io/pagopa/pagopa-selfcare-ms-backoffice-backend - tag: "2.24.5" #improve + tag: "2.24.5-1-next" #improve pullPolicy: Always livenessProbe: httpGet: diff --git a/infra/env/dev/encrypted.env b/infra/env/dev/encrypted.env index fc9fff109..44d4980d9 100644 --- a/infra/env/dev/encrypted.env +++ b/infra/env/dev/encrypted.env @@ -1,62 +1,63 @@ -WEBSITE_SITE_NAME=ENC[AES256_GCM,data:apnQj2iphapiSdOcEbxy9X56vSKp/LosBDOyXkOmYW7Q,iv:fFIMymUEUSQEDGcW2vccc3Jr1FkcwkA9yZas4JIl+b8=,tag:2JRa+/qYfM53+3yAciBinA==,type:str] -EXTERNAL_API_SERVICE_URL=ENC[AES256_GCM,data:Hxh+u8i6K74BaeTty7K/7Lm3DKqHxLdx0NFIopOescILzQ==,iv:+cnrt116kGb1MsyBcfK0hVLEHRFRMltt69Zj2z0Znhs=,tag:RoxjGlEuUke5f3DqhB6/gQ==,type:str] -PAGOPA_APIM_SERVICE_URL=ENC[AES256_GCM,data:K9m14gaVbpurIvQE0flfUmnCCgGpwJCnyCa9wVfxoxYJYw==,iv:kIYcy5Pu5F82lIEaUDascS1QeIOdh11/jfLUCUrNRW4=,tag:lmadlvvkozVDF/2G3qq9Uw==,type:str] -PAGOPA_SELFCARE_INTEGRATION_APIM_SERVICE_URL=ENC[AES256_GCM,data:DOQxv6FR6VdG28h3Dd/cmrvJYDC5LAzDDx5tcy9jfKXVLg==,iv:hy3XV84GLUw3jBhNTNreC19DmoN6/cQuDD6gaDFJynk=,tag:B5aJSbOTnnr+nT/TVRNLtA==,type:str] -GEC_SERVICE_URL=ENC[AES256_GCM,data:gBzxS2rGEQjHjUsDvA8OjOFPPB9KwQOiMN9YTwU2z1x9iw==,iv:20u5VsMIrYUJsOx26jHhqEWeaoKkjlCo1i5F6+h2L0E=,tag:L1bQv/0EHVZ3ckNPRcZXVg==,type:str] -TAXONOMY_SERVICE_URL=ENC[AES256_GCM,data:nnMHGUII15h0NaQT76H+JKuERC7ft4J+mbHR4zJ/iE4C5g==,iv:WB4kDTJaHbtPOEzLU5MhZNo9TtqhNbRKuKBNcW4bKwo=,tag:n8l/An01ADQlzg63Prthmw==,type:str] -ENABLE_CONFIDENTIAL_FILTER=ENC[AES256_GCM,data:R1/nPl4=,iv:m94CIOBPPakjZ5E+Ikd4luzFCGZI/anp8cFC7BIMxac=,tag:kKq24UQ2ijUAHwYxfc0/0A==,type:str] -MONGODB_NAME=ENC[AES256_GCM,data:+vLucC7yj8jvdn5rPa1rOA==,iv:3gptiX29IgicJj8eSKHZTXjIgabMwGiD+c9AOdoIfIE=,tag:UI4mMOThHjbN+oSoOVT2oQ==,type:str] -AUTHORIZATION_FLAG=ENC[AES256_GCM,data:5LVi+pc=,iv:5Qu1g93uhJSDk3gKYF5s+uexkmxPfIL6iMDlMV68Md0=,tag:kywsxsLB/NsF3wk4KMprUA==,type:str] -ENV=ENC[AES256_GCM,data:PMK+,iv:yVb53m+7EMs2W/7GDs90tVVl/Po+bdiNK1Nl0dpDM/4=,tag:cJQmFbGMuO9DFnDKTTEBDQ==,type:str] -REST_CLIENT_LOGGER_LEVEL=ENC[AES256_GCM,data:NQloEg==,iv:D42c9hkwVKWnGgzLEEoDNPShv9JPIyJp3ssw6+RSY34=,tag:xnDPIbK4NduBpxMlWgg5WA==,type:str] -AWS_REGION=ENC[AES256_GCM,data:07IGKwd/bVR9TQ==,iv:Qk096wPCP2v1LYbS/QaK3SfUutZER4K0/mbXuG21+Ws=,tag:5H/TcdwDyfz2PlUibdP9GQ==,type:str] -OTEL_SERVICE_NAME=ENC[AES256_GCM,data:HEK0AhNY2lYbo6orTN/kuGhSqBDALfMQSCsb+Vd7C0hHAg==,iv:D5NrYA9bJn9aN6+3vrNqVyHtjwIvLW7/ReJX/sAG6hk=,tag:kRqpMYifxEebhlGP7AJRAw==,type:str] -OTEL_RESOURCE_ATTRIBUTES=ENC[AES256_GCM,data:4cetw31bUe+ni/5csvEGRsvNZMhBH+FJnk0=,iv:QXAAoJi/jqLJoa60n5UspqgMnpAKeGYMKDIb9+vGvDs=,tag:u/JizQUsvsejOnqmwR4JAw==,type:str] -OTEL_EXPORTER_OTLP_ENDPOINT=ENC[AES256_GCM,data:wnHeidALo98r6kvA985Kom9hZLuMQWIUYMMGqZKTbp1EWkRgW1kA2WaL0qUm,iv:eNrj/L/jLgoE4LTurjgCBrQSU+f94GLTtc6NfnGzWTU=,tag:LM9JZJo41ebeygFT7z7iIQ==,type:str] -OTEL_LOGS_EXPORTER=ENC[AES256_GCM,data:kqwNOA==,iv:O6sKizp6awzocejF22wXfZc7TkuxprtfiK7g5TW90oU=,tag:KyEMl/c2IbCbVUJW7XIDng==,type:str] -OTEL_TRACES_SAMPLER=ENC[AES256_GCM,data:zeXvv17OinX/,iv:Ks0yzdd+Z8F+s3lO1ChbK0Yh/VYHqKHnzAyB6pgge78=,tag:WlIciS0rbEKJABtxh3MqXA==,type:str] -IBANS_EXPORT_CVS_PREVIEW_SIZE=ENC[AES256_GCM,data:Lw+j8w==,iv:GDeAP/r2jt8davbOepovu6xA7bOH5M65WdNKeQK31wM=,tag:OchkTBBOMQReMIikelMGAQ==,type:str] -CRONJOB_SCHEDULE_ENABLED=ENC[AES256_GCM,data:2eb2jQ==,iv:zkx4zKjzzULv2AgaPW2trHXIJL+fE4A0Ct5MfP0ZDVk=,tag:+8G3bzE339TZ0haT+nNPrQ==,type:str] -CRONJOB_SCHEDULE_IBANEXPORT=ENC[AES256_GCM,data:lXrxPQ+4y7NiJh7CfA==,iv:zfNcjVAmA8wXhaAfHEwA1GRHvmLu28jCsVQAj2iTQCE=,tag:bxZ6zbbmTdHGRb/zo+UoYw==,type:str] -EXTRACTION_IBANS_GETBROKERS_LIMIT=ENC[AES256_GCM,data:z1MC,iv:JrhIcc6l3gzWYArW0xf3u1bP1R+OF1YUsww4JK+zTdk=,tag:8AVLdDZw6VN7kq7BKdWq9w==,type:str] -EXTRACTION_IBANS_GETIBANS_LIMIT=ENC[AES256_GCM,data:FpJ0,iv:XJ6Msj7BMD4NZYqK6Sm4B09uLGDGq6K/yLusxTB40/0=,tag:Eu6C1XBzlqVvnQY1FAkkvA==,type:str] -EXTRACTION_IBANS_GETCIBYBROKER_LIMIT=ENC[AES256_GCM,data:wXHHXw==,iv:TIMG5lYaoKKI/MWTgZCpIPRh28v4lP3JBaMBOCxmzrY=,tag:m3ENQW+bdDw7VeqlSkpaRg==,type:str] -EXTRACTION_IBANS_CLEAN_OLDERTHANDAYS=ENC[AES256_GCM,data:gA==,iv:LP4yEfmA5ds93i/SuXyXVNfu5cDBXgKX5u25V3k9xXQ=,tag:IagFYvEspSmcpZqVaqRWOg==,type:str] -EXTRACTION_IBANS_PERSISTIBANBATCHSIZE=ENC[AES256_GCM,data:t64dXA==,iv:oEjHstWVnu3bBBYjuE7iVtO5n8yqZ+nzweTxd9bmz6I=,tag:H9jUnxV5Q5lCFkuNTFakPw==,type:str] -EXTRACTION_IBANS_EXPORTAGAINAFTERHOURS=ENC[AES256_GCM,data:RQ==,iv:L+X/DMkGNBNG6hcPxURFOf1d5nhcN+PPYjfkTJ0kOb0=,tag:fNc4SRGnmFz8LSdWp/ctiA==,type:str] -AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:S7QHYlSYGwAusCYqLLpfnXj6M3k=,iv:vQ63/v3JDaxrBBIDrfY1zNQs3OsklMnu/GZkMSxIsS0=,tag:15SOXG2EcHWaHoTP9pPseA==,type:str] -AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:exeCaqMBk+N+mQDtrsYGO5+PdTffTelhMNBP0ngKz3pq2woya3iMFQ==,iv:6V0j5xxHvrxuog79ClxRaYUIu3Y35TGgaZmYfTqnuNg=,tag:Sc9no7hhHVY3oPv++3NxyA==,type:str] -AWS_SES_USER=ENC[AES256_GCM,data:c3ZRJKLyMhu/zBqqsOnR5acZws44sMgRpWeXAR/79H1IkYhtTA==,iv:UHkdi1Upcz8yysQHgCzOiphTC4cjo/th8YmthZ53ML4=,tag:2NTl2K+GG3sQuqLaFKD0sw==,type:str] -SELFCARE_APIM_EXTERNAL_API_KEY_PAGOPA=ENC[AES256_GCM,data:058Z94R9dtDtK7Qr4KSe5jAZ+qb1fK59Y/Kgs+LmZ7o=,iv:HDn75r8FJnEc04I8RWU80Dk5OYqCVr/7w6ew81i8mp4=,tag:C5DBIy+u2z5e9uvw17pXqw==,type:str] -PAPGOPA_APIM_GEC_API_KEY_PAGOPA=ENC[AES256_GCM,data:B6JX2rxflZBe266o4c9MHY5NyKlhdrUzsiK/TIMukdk=,iv:NriFmbmg1Rme2zDEGt437i6gu2mCvJKqbsZlGO5d1c8=,tag:XyTan1L0300ZEvfa/qTvNA==,type:str] -PAPGOPA_APIM_GPD_API_KEY_PAGOPA=ENC[AES256_GCM,data:jPhqIXhXwFfEaom4MFf5ZbeQZdq6LLzfnYy5BLLoqv8=,iv:qUEsrf/8KJUKzZCEvy6KWYgaa2T93TWceOED6ZiiBkY=,tag:tfl5Ks2v0dPZeWrFx4NxAQ==,type:str] -PAPGOPA_APIM_TAXONOMY_API_KEY_PAGOPA=ENC[AES256_GCM,data:kUHz3Mbl4uTf+K40EKBJEaCXr22ZGSKW0yWZhYGGQYk=,iv:n32CXZ9dAy7D6Z+nNtki8rnxHi6JFwG7Yfd4RpUQKGk=,tag:CoqmwJQ12vZjMh5axwUCtQ==,type:str] -PAGOPA_APIM_API_CONFIG_API_KEY_PAGOPA=ENC[AES256_GCM,data:tnPAUr5AJgleTILF/6nPIVcXFc1A4ukNI7zkecB75y4=,iv:v1iYO2mfXomdP61qMNZkzosNLu165gf1P9c8IsOmW9I=,tag:VURjSL77o5zRc2L9O6d+Qw==,type:str] -PAGOPA_APIM_API_CONFIG_SELFCARE_INTEGRATION_API_KEY_PAGOPA=ENC[AES256_GCM,data:Xln70fJv2t5xbhZlTQLpZMa70tmMja+CcdrNap9I+2o=,iv:hEZLjfpJhH6zV/oZ2eGPETccStcQthNsLJp1FZUQ0is=,tag:zkdSDk4Y7cmAmX4J4pJTxA==,type:str] -APPLICATIONINSIGHTS_CONNECTION_STRING=ENC[AES256_GCM,data:V4Z9jlZx3suRzM+aBTfMq2pBx53Zmvmqg1lPdERKaFLB3/Ir6YBWlF6rkeC+UBGJBXgYIK6FuYY4GHR/VbSVfSX8H2ZbsM9WvBwv1rl0MHOo6sLHaaVI3r49DWPVptBhNmxnqI/bIg6oVzyWdJKfl75lqpOC2kl9laLCb0zTWkmWdwuPPTzbdkizaVjSJ2T6lnHEK6QYlMReptyEhpx/icTklGQaxTmcR2uiZbbdO007CD0N6O6qRC03w46Co0sS2jA+,iv:3+f8RRoexXg2qiL8XSQSni47oM3z8zIdOkYRsVC5XvM=,tag:1CV7PGDPJ4eN4GGTgK6OcA==,type:str] -JWT_TOKEN_PUBLIC_KEY=ENC[AES256_GCM,data:klBq3X6zTTBuaBFeGwilUBvhD/pmrYtKxPUYDpJYXgsBolvydO9H91Dt6tN6t08XBOv19YSbmqIXINRPo98ZB6LDFVB5iAoG/jYCzQ5WqbDNHXcW81DbjePIGdyb525tzt5c3I5wYtWC44cQvVmDV2YY9LTMXMWWhll3BpyHULYw2BiMqmK1jmt6hj3yEU8fSdDg+8GloRCJ4hsC5BPe2DszILzoVziJAKky5tWtX7M2sTymTbZM6JQfTA/Vetnzf1ULkvuvdehQorCxQ/3zIX/40dgra3S1Xk514h0LfvSztgU9MMbM0z79dvL/7HhfvoabIxx7UrbgK+EntoFHeE1jEZ7U4u4UbH3vZ8+8lOeTS2PuJrGTTLuoqeJmohaYcNOftWpm0XuObGwrv+nLLrwkZMvGg42ps3pH3lM+uuKhWeXA6vWNJU3gqYGYJzHKDyh2yJGmMZeHmQ1c/tevlo26IzwoTn946iUwaa7eH6kK+ddVMCOe9t+/Hbv43YTHH6vMH+ttuKenFHDEljS+tV3sdn+rCCaqnU8AlRSF0OUCIYjcRKQCp9ibx9RX7LHn3jVamrQC5FFOzg==,iv:FIi4BpGWuFPcUJh+VNMKUZDBKXWgufLGj12O+0HtJyE=,tag:uN8Aa0ZVRgIm9G6DLVwGxQ==,type:str] -TEST_EMAIL=ENC[AES256_GCM,data:VOJu6ZC/+FdEeKWi8EfWJv5GI8+7IbRD,iv:z0DOEjVDzBbIeuk91n21hKDdQLMaN0t8Fz2azM37lDg=,tag:HXG1LKQnFic5Fw09vH4T6Q==,type:str] -MONGODB_CONNECTION_URI=ENC[AES256_GCM,data:rhk1Zb/9dXxkiPna98tSB1w4zYddAxXBx2NHmkcYjp1HJJkAr472pznjprYT8aLTVBci2n4K41APDBcXQqKHJICVpPqLi+r8h320bMUA2m7Yvz7w3QnBudfOmX/naiNfYY2wsoSq02ROynANtGrNg7z+a2wDUNlf6mdfhno7ADbgzrL7z4QlPbjYflweQ15YpvyW0McRzwq8Rb6aoATzpGSUUGjzzUQXREmTVWkXrTr5GZzmMJQSYvLQ95jakluCx73VNUYitoiczndyDiFUUUTCOlhuFk+dRpguT3Ek8FvAouGnLybRoljD+TWccbW/IKWWK8CZNksCaa1khtP4c9VBA3TBWHegPMJvWjw4JhYACNnOz7TAVF/KvZpX7pCn9z3L6nNia/eUrPxl45rFFQGi2FfgCsAFicZGjIY=,iv:B4D2AgHtwjQwcUk48Tcx9ATBvBz7OAB+IH1jPNILPqk=,tag:nxwtqaMZMUpup1YRWSxVOQ==,type:str] -JIRA_URL=ENC[AES256_GCM,data:TW+/aueoo5hgo8ytcQGLurhkSeCsp7SMEB9RhA==,iv:WOzZcQeQrjh1RjkZFECRNjpCocn4vMkChenEyYFfHZU=,tag:Xe0ZPXrG/O5r7iuVy6jMUA==,type:str] -JIRA_USERNAME=ENC[AES256_GCM,data:VMaxhPUqSItAZucd3I04tsewp+g=,iv:u+kjjKttpBw4xKTJpWREFhOv3Kb9BpS/bUE8eT4tLDw=,tag:U28ihApX6V7VKVDTetuMug==,type:str] -JIRA_PASSWORD=ENC[AES256_GCM,data:yQPvgB1uz3P6OtlngrVeSO9p6KMZjeb7nOnFqTYy0SInMk42JrDVUMzoN8FztSpw0ytduoDPhmzVVJjR90UdAZm66G8i/qz+HuZE4JS8/74ll2i4HRvil89hoO4kiysOxzEt1Q9YDL6FMv+RGuVi9ZY7cw3iIwRi2LjVabSlzlJj3a4n3GYfiYapza+p8D15jOe3wQsEgTtymCL2QrgLIID5fly6tBbVWuxk8X+Hot3BHl2m53sLzpCA6CGb42tP,iv:2rU1kBO4UmUUf22N8JRK5E9fWBCc8TUvW3P3SKQNaHY=,tag:YK/XCHjYFZRa61egKLl+5w==,type:str] -JIRA_PROJECT_KEY=ENC[AES256_GCM,data:s0O5,iv:l+olEXH55qmXiSOCH8Kr46V/xgiqti8e2qeauWi1dzQ=,tag:TZUt/ne6uYLadbJ1NtNwOA==,type:str] -JIRA_REQ_TYPE_TASKID=ENC[AES256_GCM,data:vXWSmJk=,iv:3tWDduo807+zunPn5wTsSLsw73M7LtEhhMF22iEdpDM=,tag:aFVbuFtYr2DNNFfhtLqDfA==,type:str] -OTEL_EXPORTER_OTLP_HEADERS=ENC[AES256_GCM,data:3Kc69UEoELfez15jwCiwdKkvW3n4wQdR5ozC6p/seT6/c/61i37BxiKUpDR0HUg=,iv:o1iok52PPO9iugMlu6ZfmgJQNcZ0wacPvVs0Frs8PHM=,tag:34XqjBqBQvoNbKotuD5t6w==,type:str] -AZURE_CLIENT_SECRET=ENC[AES256_GCM,data:JLQPa5yShtwGLREC2UbiXnIlN+fOXM8o1NAXhrHDEesNnkPUu6HF3A==,iv:JbjfETOEgbx6BL6mN6qCaPFHpUePcxZB/DLXKkXFiWA=,tag:LerXpdF4IlU3UdRxDTkLow==,type:str] -AZURE_CLIENT_ID=ENC[AES256_GCM,data:GTgLFZIdl9GLy4JGbIyAVUQENymZrvxhTmGNTLoFl9WFkeE1,iv:UQiAdEaKC6xGl4CqzW6Hz2HABtWJL7k8cbAtxEcNR5Y=,tag:33NwAVRA0sDS+NFoKjpbpg==,type:str] -AZURE_TENANT_ID=ENC[AES256_GCM,data:JbeVKbnuKJnwperjcFJyrQvFo+HvLItKyElQbGf+bU0t8vLD,iv:vltIzqrAM02uS9qF4qwYzoJDo6+VW6sshJSmuBT5pA8=,tag:l7HGCflnAMseynMftpycew==,type:str] -AZURE_SUBSCRIPTION_ID=ENC[AES256_GCM,data:QTO5DCV1qT0O6RffR3JdoADlZg3pAtmCwpcGsNqEXSTotYTh,iv:Hye/OmhaAKs2aJKHBFxj/mcgrhEBPsZW0H/ZNkrEuBk=,tag:b77wjWoOdrlB3ArJ4DOzMg==,type:str] -AZURE_RESOURCE_GROUP=ENC[AES256_GCM,data:TpgBmHPm5RlmJOcs9zK1,iv:Zek8nNMC2VnED484lugMyXagdst4LGibhiSgW/R9aCI=,tag:OHuWGQnPHIlrYM47TD2hTQ==,type:str] -AZURE_SERVICE_NAME=ENC[AES256_GCM,data:NEqclSoVgbjOLpvtvw==,iv:tMABk7U5pMDGOoP9WgSkkgfyLlWp/XUI4S3tcZvkMtE=,tag:YzSj3q2XmZhjuFdNLl1bHA==,type:str] -APPCONFIGURATION_ENDPOINT=ENC[AES256_GCM,data:TTRn74Ih2hG+PL2mnCow9tuZcMzkeXobm3YxDfyXAR8iNKJZLg9O1/3prsmsvMy3pH4I38nv,iv:M4YEO76fOvBJzTcSQodw67BEpMftKN4zeCSS2WIdu9A=,tag:dzEwcKG6O9+PPlf6bqhfAA==,type:str] -PAGOPA_OPERATOR_EMAIL=ENC[AES256_GCM,data:ymk7WJi7kgnQTbfQO2MpNFW5jyY=,iv:Pq5kBO3KjBfPt/XD69nvuCfPcqvBI+Uw/pZ5pGpIong=,tag:8qALuvnkAEOW+lCICcdXSw==,type:str] -sops_azure_kv__list_0__map_created_at=2024-08-05T14:12:42Z -sops_azure_kv__list_0__map_enc=k4UMCUTu0_dh2Y0-7XN8GwDw0nI-9nofjFthBhtvmVB1aK4lxngQTOTCKOql4TOSYVBSYwy__NgefBwToLyk7WHbKpdhy6CfSeii9Xz2ZTWVyjdDtvTzSpiqY4lSd4UcM4bbWhwliOIJ5ZYFsGAlAmsfsbDX_gG9PNIhy-0et5QKsjgmA85AHG6ztCm5bikJeuvkKaGQcc3UL2r_D7rz9kTrSyMbAVD8PzROhCNWnyrTtb9qWXcxau2D4UH2u2vIqM0_SsUb6En7J-g6SQnHI_SRWHO02Wn0tlnxvTy4Obig1zNLMOCjlTfbxRaGAQ8WQhEx6Kygz9lmsmqANupyew +WEBSITE_SITE_NAME=ENC[AES256_GCM,data:o0QUw0J84dp/qzHvtkHQM35U/WcQvK4/MPg0X0PXpJbl,iv:ZhDdWExpvInpDCq6TTS8qa80s3ucNBDDkT5v6hYkYf4=,tag:wJH9Gg2x9zuD2xoo3R1oUA==,type:str] +EXTERNAL_API_SERVICE_URL=ENC[AES256_GCM,data:cLXOfblih/bsrsCg/M71+9xHmuNYTmtYt9t8mii65S/tnQ==,iv:5PvCVxPcilZV9Z8b4SEMAmusGGSkXgZnR/5PspE9/38=,tag:pqBXdztibwvR8QTOi1MYQg==,type:str] +PAGOPA_APIM_SERVICE_URL=ENC[AES256_GCM,data:GlF9PS3f0feL9Pztu0bhAeI7UbEqFAGpaQKjrAlLE5Jr7A==,iv:74/W3q6nlxM48NZ7e8AmcYAY21ohOSICOqErMf+Mj1s=,tag:mCwl6FUhKeEU5oX6435mig==,type:str] +PAGOPA_SELFCARE_INTEGRATION_APIM_SERVICE_URL=ENC[AES256_GCM,data:awdwMSupEEi59odVYCLuOpdcf2O685Vqm+HFWMo/mo5+Hg==,iv:cKVjmE1//FxT8yK61eB7vdXeDzmUH/qKscI4+RwXZhE=,tag:NtRKiO1O9lVEOypEyWFeqw==,type:str] +GEC_SERVICE_URL=ENC[AES256_GCM,data:tlQHDJ11FbNmbCxTMQMF/glIZ/UwX8mqIb+ZFu77oNQdoA==,iv:zeMx0fm78VhSCCyHXa/n4STu3IRHSetTiqA+8vy//hI=,tag:uwfUJ8Bt8hikIQnqjxWBWQ==,type:str] +TAXONOMY_SERVICE_URL=ENC[AES256_GCM,data:zFS4XGW60Hd1Q4qTE/RJNU0d6krNzjZQkl/K84uR0Efbmw==,iv:yDX0eHzYeJgHfOEaGc8LqNVUytdovJj8RrB1dw8f3bI=,tag:gXQqO1NEqWruuegonrBgeQ==,type:str] +ENABLE_CONFIDENTIAL_FILTER=ENC[AES256_GCM,data:1OOnHto=,iv:vr33u7xiPnvM2SPD297ZFJNnfNPsfFpLA4vdT7E03Fw=,tag:kYBuhg7aQtd2HMxFfLxPlA==,type:str] +MONGODB_NAME=ENC[AES256_GCM,data:AZ1JbMmrkvHSWXXJfPCTTQ==,iv:JWFTvZfZROPP2yk1ur6xfGyIsHPrlKxicLwb4ipImyg=,tag:4dLUQk8+FcL9WNfz64OA/A==,type:str] +AUTHORIZATION_FLAG=ENC[AES256_GCM,data:CRAPyuE=,iv:ank9GB9QZhByNxDh6fkakI/CtrAOZ/7iFmLPpMpqZr8=,tag:/pJCVWV/RDlO4oo+GXsUXA==,type:str] +ENV=ENC[AES256_GCM,data:jJCT,iv:KWHWkali76B8OEnZcszPgYBsSW2ZRg9P0t3IX+gEGEY=,tag:dkrP7qv712b0oirXJ8pjHg==,type:str] +REST_CLIENT_LOGGER_LEVEL=ENC[AES256_GCM,data:fD4sSA==,iv:pZ6zGIOTeSo5F8/LbxgTZkoHxI4C0hts8lchfyrMT+w=,tag:F5i5NlZ0AvFyryIIci1W2w==,type:str] +AWS_REGION=ENC[AES256_GCM,data:L8JGTUbPdupQsA==,iv:YQ9MEojLKpcbdKo83WjmsXx/rI2fLrOmwWhhyxIht6E=,tag:be1IwPQqmmv777AxbWUsSw==,type:str] +OTEL_SERVICE_NAME=ENC[AES256_GCM,data:Jv9nH4TbGbodimB75QYXgm5Qf/tF6EaXHTNGRFCFNyKHrg==,iv:zJUUlZceMpJVKEIn4Qqv8UUh3VY1BcMaOko69WubMZE=,tag:lYoedyTlt2oQXqh05KhdRg==,type:str] +OTEL_RESOURCE_ATTRIBUTES=ENC[AES256_GCM,data:POE1jUh0Q4RiubDDTbrC0rBi9FVbVF8kkJs=,iv:W4yBlJUH1zmzGbB/LWaxYaNokx2SRnPaNWTU3DBV/1s=,tag:ZMOfDBssfHmVn90Z3+RIIQ==,type:str] +OTEL_EXPORTER_OTLP_ENDPOINT=ENC[AES256_GCM,data:zi6PZ9TXv1bwi/1n6bl4mDYVIVHAPdkFYUAb6T+oP3DioQJlf9YuvQDohAb+,iv:nk6SqC9IKm+j6Q4vUIyJ1muEkr2L5z4/H3ZUtTCQ01w=,tag:MEKh8bxBr/6CAG2A8BjqTg==,type:str] +OTEL_LOGS_EXPORTER=ENC[AES256_GCM,data:iFeQnA==,iv:6gTRFB8cFDxUSLu61vCSzGZIdLAGHpII7rRB8RzFtCs=,tag:3sNsgzKBTuxkJzH6/9/i9w==,type:str] +OTEL_TRACES_SAMPLER=ENC[AES256_GCM,data:4bKAaC1tAzBr,iv:+wr3Q4o2ADA9P7dB0rVwVua1/+wNGDEmKH8ESWJ5Do4=,tag:29s4zCQl4vtExlJ9N8qAnw==,type:str] +IBANS_EXPORT_CVS_PREVIEW_SIZE=ENC[AES256_GCM,data:MmThbQ==,iv:LZtOgMubcGxdXMQOdPpJ6QQPT+vIwEu4ECst19izqcE=,tag:Y/wSsMzustzOkU2/y8S2Aw==,type:str] +CRONJOB_SCHEDULE_ENABLED=ENC[AES256_GCM,data:pE81HA==,iv:u1zjjih5lySsY0Z+CssLZbeb/u5sDWM0AlNVeUekrPI=,tag:DZ0ChdYTz/c7elphRi239w==,type:str] +CRONJOB_SCHEDULE_IBANEXPORT=ENC[AES256_GCM,data:RTLQRKQIFNQ4F5ymOQ==,iv:lr39docVROJqQpAk5tv8WAUZ5l3zZAJsf426NiavHPg=,tag:ySGsu1D0EL8HoJipJi8UsQ==,type:str] +EXTRACTION_IBANS_GETBROKERS_LIMIT=ENC[AES256_GCM,data:NPt1,iv:A0Zhpp5IObvESTC4jiBvViyiyIk7uxYxpGWZMeLLOSU=,tag:lUqsFkFIA/ojm8V3wQV7aw==,type:str] +EXTRACTION_IBANS_GETIBANS_LIMIT=ENC[AES256_GCM,data:MYwe,iv:yHd7ug58thb3uJ+/MmlD6Ju5x4Q80B07/YNVNDEu7hw=,tag:MWGCIJzSLAsqo7mbKYDB9A==,type:str] +EXTRACTION_IBANS_GETCIBYBROKER_LIMIT=ENC[AES256_GCM,data:T3+jpw==,iv:w3Z/SPiyYWbmBr8y2SeMqhvacDihR0WkflL68DcapZY=,tag:HiAWazrieanq0iaaulqC5A==,type:str] +EXTRACTION_IBANS_CLEAN_OLDERTHANDAYS=ENC[AES256_GCM,data:/g==,iv:X3OY5pewinneS+OA7eghz6Uz0o6duCPZmr2Ku0sHQI0=,tag:kwpTlYjWOvDTLkvWhcwFFg==,type:str] +EXTRACTION_IBANS_PERSISTIBANBATCHSIZE=ENC[AES256_GCM,data:qLH6dg==,iv:wtaDlmQBiogwnOVdcMO7tBFZ/DqIwXI9U+Hkc/ByuF4=,tag:KBxNvKHYuMMUlTjGa9blew==,type:str] +EXTRACTION_IBANS_EXPORTAGAINAFTERHOURS=ENC[AES256_GCM,data:7g==,iv:zCJ0BF55G1/al9f4dp0RAKPqnZquzwqdbUowsshltMY=,tag:B40g+BDwFlPaLVUf+GCv2g==,type:str] +AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:GH4snCzh9pXDGVqoB85dw0+U8HQ=,iv:+7J4mt/qF08YxqgU5x1eD3tnQJ7oKJSMdYzSGB5iWIY=,tag:Z4qguDyYyiR0nA5S4RWD1w==,type:str] +AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:TulMi4BvlgbA7BCKr2nInqLVvKM6ce/DFg+VPkZgCLjoiQs2UYa5+Q==,iv:4lLlck2muk7j6mmmdca6r+8WUDyUl0ibVkVMo5Mhq/I=,tag:IMfwFBHaInO/zTkdTRjz6w==,type:str] +AWS_SES_USER=ENC[AES256_GCM,data:Nad5XbY4YYU0PuQPtbVvuFy206YVMZgJEBsVdjHHBlgBNYOidQ==,iv:xrBEhoyX4cm/xRUTSY9/eV4RqrMm70g3EgqkwQYnDAo=,tag:mdd2Yh6dDB+2mF7liwjzJg==,type:str] +SELFCARE_APIM_EXTERNAL_API_KEY_PAGOPA=ENC[AES256_GCM,data:UQldOMc4xjUW0KX0YFBdStIGqgRCIpJiMaN5xMkWSMA=,iv:au0EHQVSn7ib39PK0e16IubEKV9i16I0D5iX2CkjCps=,tag:Gb0GbGljizHAHwekjE0itg==,type:str] +PAPGOPA_APIM_GEC_API_KEY_PAGOPA=ENC[AES256_GCM,data:cE6MV4+gcqzXYhDEyMwy2ofsHwWACqyt8DfGLHLPHHY=,iv:NBk3LymdQP1FDhGtFzSybA7deEYoKnT3RaOoGdw0y7U=,tag:njAkuSsoK50ZY7SCc/6W1Q==,type:str] +PAPGOPA_APIM_GPD_API_KEY_PAGOPA=ENC[AES256_GCM,data:KTthQfSfJwXjEL/IdK+kOefkbaINeqgxfDkvV5rMNrg=,iv:ALq6cC6X+aKgm80o9/2icvq0lw+gxxFnE+zb2UsxHyg=,tag:s9cninGn+wT3vxxvAC29Lw==,type:str] +PAPGOPA_APIM_TAXONOMY_API_KEY_PAGOPA=ENC[AES256_GCM,data:iBQJ5GoeH0xTqs1JQLEGAAdd0a8pRhaA+05PBFBLBp8=,iv:UyUGqAeXKFzUZh9BWblBmtPUU98dXlUidtNvQgj+tsA=,tag:CdYANtLnRV+ocZ/jDU5CcA==,type:str] +PAGOPA_APIM_API_CONFIG_API_KEY_PAGOPA=ENC[AES256_GCM,data:bLC5Iufz1OQ+A1jY9R220OgkI0wEImQgh+4IBDCk0/w=,iv:2enDN4n0WcpfrUXcVpR1Mw+hQ1RD6WDzmI7lqCFTryw=,tag:V8hMU44Bwnqk0KpPAVAEXg==,type:str] +PAGOPA_APIM_API_CONFIG_SELFCARE_INTEGRATION_API_KEY_PAGOPA=ENC[AES256_GCM,data:ByQuX2Y3EKqwCh64/Yp5ynLsKOHT5sTW+/Hlfo5AvTA=,iv:GTDYjNdzxCsg9ftyvcSP0OKq2ghK5qR74fOd3h8TM9o=,tag:xb+lyW60Jl7SCG+bNxyKuA==,type:str] +PAPGOPA_APIM_AUTHORIZER_CONFIG_API_KEY_PAGOPA=ENC[AES256_GCM,data:UR3ZQmEXmZqrwvtzbRWeGAqTdFmsvW6f6U50fNv9gxk=,iv:Ng8ZUDZ1fUqqhpnr51Nu1sOr/rVP/zyQVW0e27jrR0o=,tag:F8wRIUExDMdlJM+so0o5Rg==,type:str] +APPLICATIONINSIGHTS_CONNECTION_STRING=ENC[AES256_GCM,data:zTort0M5yssWLnMEQwalrpJ13heECqDyuSWFhwNUyUE8L81Sa0lG4C+Q9BhlAbRi7N4SAMsz9RHyRyAG39F2yOYl+3nrNDP7yTfElJn3ET+La2z00O2WwGQGr3C2q6S+yz7SDGWrensMg+zaaZJ7mAfXGtjkWoJZrsDdr2AhpedKTM+GvHq60/7O4EQeNX+7i/QwiBIUJYTLYuPUYKXMi5TDkCApQZnkYKtrR/0os/Un7MrtoOm6s3/Evkwz/0n8nc1l,iv:Qi34sueksPtEWAt2f3xoDQXGEcyzPt2dK1hUVrYJC0E=,tag:eSFSdG/TXFjJ0tSh34SyOA==,type:str] +JWT_TOKEN_PUBLIC_KEY=ENC[AES256_GCM,data:BlIB5C4+3vLWTlOGtO4WFZ3/xEUxCdOM0FmC568Vy2j/2EvaFT+ROc9sAba3BTQS+cIscThn4TjOuP+7Rvc+H5EgVerh2v4GeHdO8hp2wkgTOcJLZ5MgvQ1pXqrXqVHnbQLrLIE2x6ZwV4ZRF/rkTafUCqEOmpBrLkJ5wgnh9mvfI/PXxqOy7WukiUjNGjxhyDboFTmHZTmOp1eoWVQDzk5V8pFLOspUA1z+o1x1RDaIxGREsJ2j0GBjZ1F9ABRCqaRdY3dTGLk4PMSJer72MPgFiz+tLAfT18yRQN5dCtO08t7UT1GyzpNNAxUfKyoUyFSbfjeyuFfxLzK5waopqYlFkYA0AbMgAmjHa+whTJFCf8VP0YcAO/iHzb2KQGuHfX0lnjF1waD2nk67JwVbU/ceHwwDRyTsQvq088U+lhIf07p4j3b2R+hFSWW0OCs44XbLqGRGPsiVpdpQ0xlR+pwEaRd6tEpX73U7QUYhvmpTjJPudr8d69257izviPXrqihhBZprpy4POzfbM+u8msJkB6TfGqxnj5AsC5/iQ7Rirv91WkY6TFbVC8nlffKmSXhPNmzUgAc8lQ==,iv:2mRaTow0yawMDq84/5M68KH0D34w8WmdFvCgHIAd4YE=,tag:ZXC0OLix/M8pd/hWdjqJzw==,type:str] +TEST_EMAIL=ENC[AES256_GCM,data:NTHs/oeskkxM26rz3UkFq1GJt0T3avXB,iv:nK9TvjBwjYI8WFNcxeyMM3QFzvptTBOfcRRySAIwVdY=,tag:4AiHhDh2d1CWrLu1+e75gA==,type:str] +MONGODB_CONNECTION_URI=ENC[AES256_GCM,data:K8O64MSMeCJagqoxET52VRUhbIcgSMMlgW/4jmOZMOA1g3Bb6Y6+zkQ/9Lsb2fIFOAqkTcVIh4bdo0TO6DLvFkUSLFSs1MtDHKDWcj9Cx6/T1m6/z7vWZEDRmwJq5KW0CMjXQVVLAYxl6QEwd4jstRZwT2r1eDl6l9rrRDlPrSoqQSq7CusdL3/hTwwD2cVGhdY+maq8eEYp4CiDABfWHesQz3OT164GUFIEZgJqnGwA0uzmcSd8RcSGrF4CXXjz7CA/jtYHIxFojFsLn7WiX4YlAeqTKpyTgoSIfncjbuoQYnbcHq+8OvIBBHQpuD1xSJxQMzbakGiyR8EEMGAJixv5oQMK35pncHFTQwSZLLUw2ACgah7EIJ+pskvRLIjcVUWMp4TghD14UGrmwnFqJ6RzoQGhtV2tJAmPsBA=,iv:OacxxtkWMBP5XgOS2NvsmEvcjG2ZAGkwY7UqSucAwj0=,tag:O5BCXZ/IG0lHJpNo++sZEQ==,type:str] +JIRA_URL=ENC[AES256_GCM,data:qKv/8lilPc6OCkn5LDvwVGRLBTLDu6TkZ267sA==,iv:/+oOE8MBNZSWyuOvIBGDYgyxkS48sEBWpsElySzH8QY=,tag:i2GGJTqGwAegJgEk7/HSMA==,type:str] +JIRA_USERNAME=ENC[AES256_GCM,data:kx4SnHB7VFPFyjMp8rr5Kr4QJCw=,iv:PkKKxV1Ci6B0mgcEgD4D66kNbUEmj0mzHk/BKLCFHTA=,tag:QlDkJLIyUZxXJkvzkgnjtQ==,type:str] +JIRA_PASSWORD=ENC[AES256_GCM,data:XRuBl/n97BetJZyZD6uLV8FCyLgRZF1xH9YSQdgiMDAECl2tSr18bpCU6NdTVMKTYnXu2Lqt56YUW9hwPfnYEMNjnFhPBkS+9pC5Lca84x/Nh6fc7+FfgSwBM33bj/h5xfXP2RUnA6WMSXuLipqhiwT3GD+HBmHOmu4V15NNM5QO7P3seNAMkw6Zmu/tM72ogH2e7gt+0rn7aI8bJf1yOeePBBuNiJsLwnSNdRzJ12WT33Ms+VgQ6p0owTyGPiye,iv:vxL7em6kFSceTOeQM8tcrt1ZbpC4Trxwa7RciHLyzGI=,tag:eKA2Ra9muRcbwHA6r34ing==,type:str] +JIRA_PROJECT_KEY=ENC[AES256_GCM,data:TrHu,iv:BRgaLunsJRrCpg/cSxf1uEzMRb+/GhgErxR1KlhNu3E=,tag:ZmrS6R0dw24J2qYc2PGYhA==,type:str] +JIRA_REQ_TYPE_TASKID=ENC[AES256_GCM,data:P3hsiGU=,iv:i7gWWMhsxnOMpgMDV66LbXQzeo5GBNzw0J3AuKT1tRs=,tag:9/gKOi1FHgwS3LBPgXY+gQ==,type:str] +OTEL_EXPORTER_OTLP_HEADERS=ENC[AES256_GCM,data:mtm1GTa0RpmqY8VnuB6jXoIcn2SGblIqhlDZYn+7Bm5bzKgasipBO6oo6PowFbQ=,iv:z+hOgV3ob3iY/1jALuVyjGI8Pk4sJgSxdAmue9rtOIs=,tag:tKLkls7SaCLgfT7pHkJmHw==,type:str] +AZURE_CLIENT_SECRET=ENC[AES256_GCM,data:LlrN+w4wWQYNtn0JO9JkFU1sbAc6GRThOq5QODUkXFFcBTDtcfFc9w==,iv:ba2yI2vfrSx4S8wU3gMSqTkEY5h5eoZ3EJ0+c9XITY8=,tag:FrvaPz3UyZtd1KtPkFi45Q==,type:str] +AZURE_CLIENT_ID=ENC[AES256_GCM,data:LrrnwGZeCNTyBTYduDHBRPw9wK4yuJXR42zGRExtIujWwT2u,iv:GbMEioANUMZ2XYTIW7GuPSkoFsKLwFIJM+Rvi35PEy4=,tag:7fen8Zj+NTh0wSmR0ci8wA==,type:str] +AZURE_TENANT_ID=ENC[AES256_GCM,data:cTyQjgfbODJhuTw8BNAdlVeDuABVpGpYjqa+3mewJgAQA1dc,iv:mIt+z5riFrBvwXBMvRn0UJlTMiK1x8k8QfS8l33CehY=,tag:nhPgzGeDdYzBa+K3bShItw==,type:str] +AZURE_SUBSCRIPTION_ID=ENC[AES256_GCM,data:jfnCvfAgexkHIhok5QB8LeH4KoBd5PUgwIEvKzakDJ4Vzf/I,iv:YkpRA93+3RfbIJoMCsSM/fbK4j5VHJUFv9CX0xHi+HY=,tag:GlhdZe0dSzVdRbiPB1RjDQ==,type:str] +AZURE_RESOURCE_GROUP=ENC[AES256_GCM,data:QjXV5g39BoQpN5LUJKR3,iv:KSRfiVrOFXVGXcdbzk8tZiYI4otioRwEbQZSru2IKWE=,tag:vWnyE6LLXc7oFIulvaR5+g==,type:str] +AZURE_SERVICE_NAME=ENC[AES256_GCM,data:qpi2Jh6gZHjKHeVF+A==,iv:kd+Mjux9zrDn4vRM3KV5HcKOQ5ilW1kwuuBmHVwQx+k=,tag:TTim04rBFK+DCnEZgPfHag==,type:str] +APPCONFIGURATION_ENDPOINT=ENC[AES256_GCM,data:FZZQhFPe4mT7dmWPzL0IrCxGmpi2nvSktgFsQgJiWPj8GVu6Upos/tUMRqWGtxPYnMb7ocLf,iv:eYJ9Of+09lUPUpUEMkNRsDOMrOc74LAkDwkMhgJNNHw=,tag:fChs4G2OXSv7JsgYJN/HiA==,type:str] +PAGOPA_OPERATOR_EMAIL=ENC[AES256_GCM,data:eE46nNEGPIiKW6xKEjgNl8cMsJ8=,iv:5sgh9CMVFwQWUSN6qKL3Am51Uk52qDdmVZOxHjR6ubc=,tag:TthdxcX5fdJ0uJS2BmZSZg==,type:str] +sops_azure_kv__list_0__map_created_at=2024-09-19T12:19:24Z +sops_azure_kv__list_0__map_enc=f1TGouSXZ6Maf_GjTIBHEwt-LwZ0U6g4g5uU6XdHQGHMJkAFnG1oldYHNb84CLSLHRHNjmCIDiltBaZfu-be42EvoXSQH8toV0RpUdXXBxXAY0yo48OVSKk8UYnpoQBoVhOZn6ukw5izH8NCYv7v7zNXZ8PWQm28DF6uKGwpUuvJ_FuEFTssYmG6WMS_uFzGxTyLIFJGbcEDH4c-ocIir1Uv487aYLgaSGl1NhcD9S5_fyqhpfDoezBYPzraJDTCiA9SVFtKKMlAy8ao8x_qrG62ofKyHa3Vuuv6jJzoEi8hqlp6HMrGIct1wKFZfUgKePL1rSVPZWrV3HvQb69VEA sops_azure_kv__list_0__map_name=backoffice-sops-key sops_azure_kv__list_0__map_vault_url=https://pagopa-d-selfcare-kv.vault.azure.net sops_azure_kv__list_0__map_version=eee8180405ff48f99d9cc94326d4a625 -sops_lastmodified=2024-08-05T14:12:43Z -sops_mac=ENC[AES256_GCM,data:tYnki/tB2vtwWEMBCYk0RaEckB/txdkYh586Y2676IrF7B6XcWG+WcuVYWdnh3Ug4Kl/uCrOBEKeAv853uUsqrK/1r6RtxxpHhnx1K+eh3d7lVY4KUf1HQiODqnqTxJdd8IYKJt4ZnZixY3/J9DbMyb3JVycjIWYmDWytIbZTHQ=,iv:qjiC5ZaQ0zWvwNyN0l6Jq5uzTZjEYWQUmwn3+hQkbSQ=,tag:LLWP6vTQDnHcosaCGTOogA==,type:str] +sops_lastmodified=2024-09-19T12:19:26Z +sops_mac=ENC[AES256_GCM,data:YvgkTmLauAwydTf74X+SOIOjOY5Zoos/37tVguquX0g6iXRWGWARpByQmRntp3/REmF/qjuKFgfj06NtHB2Mp2JE1Q++8oNkVx+t2gxdEGh8VIZCvSTLs6dbSGZUfYObxDQLy0mSrERcJ9/89UFTvZztGZkMyTJLKW5CAQ5YoJg=,iv:CG7u58fDKaoBIOmd2KaOf/zxTzZS+y4zMD7luv+sNvk=,tag:Vo6RpqQ+rdoTLakBVedhmQ==,type:str] sops_unencrypted_suffix=_unencrypted sops_version=3.8.1 diff --git a/openapi/openapi.json b/openapi/openapi.json index 3752afe50..ab2160ebb 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -4,7 +4,7 @@ "description": "Microservice to manage PagoPA Backoffice", "termsOfService": "https://www.pagopa.gov.it/", "title": "SelfCare Backoffice", - "version": "2.24.5" + "version": "2.24.5-1-next" }, "servers": [ { @@ -8037,6 +8037,24 @@ "schema": { "type": "string" } + }, + { + "description": "Broker's institution id", + "in": "query", + "name": "institutionId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Broker's tax code", + "in": "query", + "name": "brokerTaxCode", + "required": true, + "schema": { + "type": "string" + } } ], "requestBody": { @@ -8358,6 +8376,24 @@ "type": "string" } }, + { + "description": "Broker's institution id", + "in": "query", + "name": "institutionId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Broker's tax code", + "in": "query", + "name": "brokerTaxCode", + "required": true, + "schema": { + "type": "string" + } + }, { "description": "Station's code", "in": "path", @@ -11278,6 +11314,7 @@ }, "/stations/station-code": { "get": { + "deprecated": true, "description": "Internal | External | Synchronous | Authorization | Authentication | TPS | Idempotency | Stateless | Read/Write Intense | Cacheable\n-|-|-|-|-|-|-|-|-|-\nY | N | Y | JWT | JWT | 1.0/sec | Y | Y | | N\n", "operationId": "getStationCode", "parameters": [ @@ -15298,6 +15335,10 @@ "type": "boolean", "description": "Describe the station connection's type, true synchronous, false asynchronous" }, + "isPaymentOptionsEnabled": { + "type": "boolean", + "description": "Flag that enables EC's payment options service" + }, "modifiedAt": { "type": "string", "description": "Station's last modified date", @@ -15404,6 +15445,10 @@ "type": "string", "description": "Station's redirect query string" }, + "restEndpoint": { + "type": "string", + "description": "Endpoint to all the API REST of the EC" + }, "rtInstantaneousDispatch": { "type": "boolean", "description": "Station's instantaneous rt dispatch" @@ -15532,6 +15577,10 @@ "type": "string", "description": "Station's ip v4" }, + "isPaymentOptionsEnabled": { + "type": "boolean", + "description": "Flag that enables EC's payment options service" + }, "newPassword": { "type": "string", "description": "Station's new password" @@ -15627,6 +15676,10 @@ "type": "string", "description": "Station's redirect query string" }, + "restEndpoint": { + "type": "string", + "description": "Endpoint to all the API REST of the EC" + }, "rtInstantaneousDispatch": { "type": "boolean", "description": "Station's instantaneous rt dispatch" @@ -16617,6 +16670,10 @@ "type": "boolean", "description": "Station's activation state" }, + "isPaymentOptionsEnabled": { + "type": "boolean", + "description": "Flag that enables EC's payment options service" + }, "note": { "type": "string", "description": "station note description by operation team" @@ -16657,6 +16714,10 @@ "type": "string", "description": "Station's redirect query string" }, + "restEndpoint": { + "type": "string", + "description": "Endpoint to all the API REST of the EC" + }, "service": { "type": "string", "description": "Station's service" @@ -16750,6 +16811,10 @@ "type": "boolean", "description": "Describe the station connection's type, true synchronous, false asynchronous" }, + "isPaymentOptionsEnabled": { + "type": "boolean", + "description": "Flag that enables EC's payment options service" + }, "modifiedAt": { "type": "string", "description": "Station's last modified date", @@ -16759,6 +16824,10 @@ "type": "string", "description": "Station's pof service" }, + "restEndpoint": { + "type": "string", + "description": "Endpoint to all the API REST of the EC" + }, "service": { "type": "string", "description": "Station's service" @@ -16847,4 +16916,4 @@ } } } -} +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index e9afb4363..a2ea64e8e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 2.5.14 pagopa-selfcare-ms-backoffice - 2.24.5 + 2.24.5-1-next SelfCare Backoffice Microservice to manage PagoPA Backoffice diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/ApiConfigSelfcareIntegrationClient.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/ApiConfigSelfcareIntegrationClient.java index e14e96e14..674c7c007 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/ApiConfigSelfcareIntegrationClient.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/client/ApiConfigSelfcareIntegrationClient.java @@ -7,6 +7,7 @@ import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.BrokerCreditorInstitutionDetails; import it.pagopa.selfcare.pagopa.backoffice.model.connector.station.StationDetailsList; import it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client.CreditorInstitutionInfo; +import it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client.CreditorInstitutionStationSegregationCodesList; import it.pagopa.selfcare.pagopa.backoffice.model.iban.Ibans; import it.pagopa.selfcare.pagopa.backoffice.model.iban.IbansList; import org.springframework.cloud.openfeign.FeignClient; @@ -91,4 +92,11 @@ List getStationCreditorInstitutions( @Valid Ibans getCreditorInstitutionIbans(@PathVariable("creditorinstitutioncode") String creditorInstitutionCode, @RequestParam String label); + + @GetMapping(value = "/brokers/{broker-tax-code}/creditor-institutions/segregation-codes", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + @Valid + CreditorInstitutionStationSegregationCodesList getCreditorInstitutionsSegregationCodeAssociatedToBroker( + @PathVariable("broker-tax-code") String brokerCode + ); } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionController.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionController.java index 9afed475a..a212b04d8 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionController.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionController.java @@ -136,9 +136,11 @@ public AvailableCodes getCreditorInstitutionSegregationCodes( @OpenApiTableMetadata public CreditorInstitutionStationEditResource associateStationToCreditorInstitution( @Parameter(description = "Creditor institution's tax code") @PathVariable("ci-tax-code") String ciTaxCode, + @Parameter(description = "Broker's institution id") @RequestParam("institutionId") String institutionId, + @Parameter(description = "Broker's tax code") @RequestParam("brokerTaxCode") String brokerTaxCode, @RequestBody @NotNull CreditorInstitutionStationDto dto ) { - return ciService.associateStationToCreditorInstitution(ciTaxCode, dto); + return this.ciService.associateStationToCreditorInstitution(ciTaxCode, institutionId, brokerTaxCode, dto); } @PutMapping(value = "/{ci-tax-code}/station", produces = {MediaType.APPLICATION_JSON_VALUE}) @@ -159,7 +161,7 @@ public CreditorInstitutionStationEditResource updateStationAssociationToCreditor @Parameter(description = "Creditor institution's tax code") @PathVariable("ci-tax-code") String ciTaxCode, @RequestBody @NotNull CreditorInstitutionStationDto dto ) { - return ciService.updateStationAssociationToCreditorInstitution(ciTaxCode, dto); + return this.ciService.updateStationAssociationToCreditorInstitution(ciTaxCode, dto); } @@ -179,9 +181,11 @@ public CreditorInstitutionStationEditResource updateStationAssociationToCreditor @OpenApiTableMetadata public void deleteCreditorInstitutionStationRelationship( @Parameter(description = "Creditor institution's code") @PathVariable("ci-tax-code") String ciTaxCode, + @Parameter(description = "Broker's institution id") @RequestParam("institutionId") String institutionId, + @Parameter(description = "Broker's tax code") @RequestParam("brokerTaxCode") String brokerTaxCode, @Parameter(description = "Station's code") @PathVariable("station-code") String stationCode ) { - ciService.deleteCreditorInstitutionStationRelationship(ciTaxCode, stationCode); + this.ciService.deleteCreditorInstitutionStationRelationship(ciTaxCode, stationCode, institutionId, brokerTaxCode); } @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE) diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/CreditorInstitutionMapperImpl.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/CreditorInstitutionMapperImpl.java index 4199a19fe..65ea2fbd9 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/CreditorInstitutionMapperImpl.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/CreditorInstitutionMapperImpl.java @@ -175,10 +175,10 @@ public CreditorInstitutionResource toResorce(CreditorInstitution model) { creditorInstitutionResource.setCbillCode(model.getCbillCode()); creditorInstitutionResource.setEnabled(model.getEnabled()); creditorInstitutionResource.setBroadcast(model.getBroadcast()); - creditorInstitutionResource.setMod4(model.getMod4()); - creditorInstitutionResource.setApplicationCode(model.getApplicationCode()); - creditorInstitutionResource.setAuxDigit(model.getAuxDigit()); - creditorInstitutionResource.setSegregationCode(model.getSegregationCode()); + creditorInstitutionResource.setMod4(String.valueOf(model.getMod4())); + creditorInstitutionResource.setApplicationCode(String.valueOf(model.getApplicationCode())); + creditorInstitutionResource.setAuxDigit(String.valueOf(model.getAuxDigit())); + creditorInstitutionResource.setSegregationCode(String.valueOf(model.getSegregationCode())); creditorInstitutionResource.setAca(model.getAca()); creditorInstitutionResource.setStandIn(model.getStandIn()); diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/StationMapperImpl.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/StationMapperImpl.java index dc0019a55..2e418e7e5 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/StationMapperImpl.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/mapper/StationMapperImpl.java @@ -14,6 +14,7 @@ import it.pagopa.selfcare.pagopa.backoffice.model.connector.wrapper.WrapperStatus; import it.pagopa.selfcare.pagopa.backoffice.model.stations.*; import it.pagopa.selfcare.pagopa.backoffice.util.Utility; +import org.jetbrains.annotations.NotNull; import java.time.Instant; import java.util.ArrayList; @@ -27,77 +28,31 @@ public class StationMapperImpl implements StationMapper { @Override public StationDetailResource toResource(StationDetails model) { - if(model == null) { + if (model == null) { return null; } - StationDetailResource stationDetailResource = new StationDetailResource(); - - stationDetailResource.setStationCode(model.getStationCode()); - stationDetailResource.setEnabled(model.getEnabled()); - stationDetailResource.setBrokerDescription(model.getBrokerDescription()); - stationDetailResource.setVersion(model.getVersion()); - stationDetailResource.setActivationDate(model.getActivationDate()); - stationDetailResource.setCreatedAt(model.getCreatedAt()); - stationDetailResource.setModifiedAt(model.getModifiedAt()); - stationDetailResource.setAssociatedCreditorInstitutions(model.getAssociatedCreditorInstitutions()); - stationDetailResource.setIp(model.getIp()); - stationDetailResource.setNewPassword(model.getNewPassword()); - stationDetailResource.setPassword(model.getPassword()); - stationDetailResource.setPort(model.getPort()); - stationDetailResource.setProtocol(model.getProtocol()); - stationDetailResource.setRedirectIp(model.getRedirectIp()); - stationDetailResource.setRedirectPath(model.getRedirectPath()); - stationDetailResource.setRedirectPort(model.getRedirectPort()); - stationDetailResource.setRedirectQueryString(model.getRedirectQueryString()); - stationDetailResource.setRedirectProtocol(model.getRedirectProtocol()); - stationDetailResource.setService(model.getService()); - stationDetailResource.setPofService(model.getPofService()); - stationDetailResource.setBrokerCode(model.getBrokerCode()); - stationDetailResource.setProtocol4Mod(model.getProtocol4Mod()); - stationDetailResource.setIp4Mod(model.getIp4Mod()); - stationDetailResource.setPort4Mod(model.getPort4Mod()); - stationDetailResource.setService4Mod(model.getService4Mod()); - stationDetailResource.setProxyEnabled(model.getProxyEnabled()); - stationDetailResource.setProxyHost(model.getProxyHost()); - stationDetailResource.setProxyPort(model.getProxyPort()); - stationDetailResource.setProxyUsername(model.getProxyUsername()); - stationDetailResource.setProxyPassword(model.getProxyPassword()); - stationDetailResource.setThreadNumber(model.getThreadNumber()); - stationDetailResource.setTimeoutA(model.getTimeoutA()); - stationDetailResource.setTimeoutB(model.getTimeoutB()); - stationDetailResource.setTimeoutC(model.getTimeoutC()); - stationDetailResource.setFlagOnline(model.getFlagOnline()); - stationDetailResource.setBrokerObjId(model.getBrokerObjId()); - stationDetailResource.setRtInstantaneousDispatch(model.getRtInstantaneousDispatch()); - stationDetailResource.setTargetHost(model.getTargetHost()); - stationDetailResource.setTargetPort(model.getTargetPort()); - stationDetailResource.setTargetPath(model.getTargetPath()); - stationDetailResource.setTargetHostPof(model.getTargetHostPof()); - stationDetailResource.setTargetPortPof(model.getTargetPortPof()); - stationDetailResource.setTargetPathPof(model.getTargetPathPof()); - stationDetailResource.setPrimitiveVersion(model.getPrimitiveVersion()); - stationDetailResource.setIsConnectionSync(model.getIsConnectionSync()); - - BrokerDetailsResource brokerDetailsResource = new BrokerDetailsResource(); - BrokerDetails brokerDetails = model.getIntermediarioPa(); - if(brokerDetails != null) { - brokerDetailsResource.setBrokerDetails(brokerDetails.getBrokerDetails()); - brokerDetailsResource.setExtendedFaultBean(brokerDetails.getExtendedFaultBean()); - brokerDetailsResource.setEnabled(brokerDetails.getEnabled()); - brokerDetailsResource.setBrokerCode(brokerDetails.getBrokerCode()); - stationDetailResource.setBrokerDetails(brokerDetailsResource); - } - - return stationDetailResource; + return mapBaseStationDetails(model); } @Override public StationDetailResource toResource(StationDetails model, WrapperStatus status, String createdBy, String modifiedBy, Instant createdAt, String note) { - if(model == null) { + if (model == null) { return null; } + StationDetailResource stationDetailResource = mapBaseStationDetails(model); + + stationDetailResource.setCreatedBy(createdBy); + stationDetailResource.setModifiedBy(modifiedBy); + stationDetailResource.setCreatedAt(createdAt); + stationDetailResource.setNote(note); + + return stationDetailResource; + } + + @NotNull + private static StationDetailResource mapBaseStationDetails(StationDetails model) { StationDetailResource stationDetailResource = new StationDetailResource(); stationDetailResource.setStationCode(model.getStationCode()); @@ -144,30 +99,27 @@ public StationDetailResource toResource(StationDetails model, WrapperStatus stat stationDetailResource.setTargetPortPof(model.getTargetPortPof()); stationDetailResource.setTargetPathPof(model.getTargetPathPof()); stationDetailResource.setPrimitiveVersion(model.getPrimitiveVersion()); - stationDetailResource.setWrapperStatus(status); - stationDetailResource.setCreatedBy(createdBy); - stationDetailResource.setModifiedBy(modifiedBy); - stationDetailResource.setCreatedAt(createdAt); stationDetailResource.setIsConnectionSync(model.getIsConnectionSync() != null ? model.getIsConnectionSync() : Utility.isConnectionSync(model)); - stationDetailResource.setNote(note); + + stationDetailResource.setRestEndpoint(model.getRestEndpoint()); + stationDetailResource.setIsPaymentOptionsEnabled(model.getIsPaymentOptionsEnabled()); BrokerDetailsResource brokerDetailsResource = new BrokerDetailsResource(); BrokerDetails brokerDetails = model.getIntermediarioPa(); - if(brokerDetails != null) { + if (brokerDetails != null) { brokerDetailsResource.setBrokerDetails(brokerDetails.getBrokerDetails()); brokerDetailsResource.setExtendedFaultBean(brokerDetails.getExtendedFaultBean()); brokerDetailsResource.setEnabled(brokerDetails.getEnabled()); brokerDetailsResource.setBrokerCode(brokerDetails.getBrokerCode()); stationDetailResource.setBrokerDetails(brokerDetailsResource); } - return stationDetailResource; } @Override public StationDetailResource toResource(WrapperEntityStations wrapperEntities) { - if(wrapperEntities == null) { + if (wrapperEntities == null) { return null; } WrapperEntityStation mostRecentEntity = getStationWrapperEntityOperationsSortedList(wrapperEntities).get(0); @@ -185,7 +137,7 @@ public StationDetailResource toResource(WrapperEntityStations wrapperEntities) { @Override public StationsResource toResource(Stations model) { - if(model == null) { + if (model == null) { return null; } @@ -201,7 +153,7 @@ public StationsResource toResource(Stations model) { @Override public StationResource toStationsResource(StationDetails model) { - if(model == null) { + if (model == null) { return null; } @@ -222,7 +174,7 @@ public StationResource toStationsResource(StationDetails model) { @Override public Station fromStationDetails(StationDetails stationDetails) { - if(stationDetails == null) { + if (stationDetails == null) { return null; } @@ -240,7 +192,7 @@ public Station fromStationDetails(StationDetails stationDetails) { @Override public Stations fromWrapperEntitiesList(WrapperEntitiesList wrapperEntitiesList) { - if(wrapperEntitiesList == null || wrapperEntitiesList.getWrapperEntities() == null) { + if (wrapperEntitiesList == null || wrapperEntitiesList.getWrapperEntities() == null) { return null; } @@ -257,7 +209,7 @@ public Stations fromWrapperEntitiesList(WrapperEntitiesList wrapperEntitiesList) @Override public StationDetailsResourceList fromStationDetailsList(StationDetailsList model) { - if(model == null) { + if (model == null) { return null; } StationDetailsResourceList resource = new StationDetailsResourceList(); @@ -268,7 +220,7 @@ public StationDetailsResourceList fromStationDetailsList(StationDetailsList mode } public WrapperStation toWrapperStation(Station model) { - if(model == null) { + if (model == null) { return null; } @@ -289,7 +241,7 @@ public WrapperStation toWrapperStation(Station model) { @Override public WrapperStations toWrapperStations(Stations model) { - if(model == null) { + if (model == null) { return null; } @@ -305,7 +257,7 @@ public WrapperStations toWrapperStations(Stations model) { @Override public WrapperStations toWrapperStations(WrapperStationList wrapperEntitiesList) { - if(wrapperEntitiesList == null) { + if (wrapperEntitiesList == null) { return null; } @@ -327,7 +279,7 @@ public WrapperStations toWrapperStations(WrapperStationList wrapperEntitiesList) @Override public WrapperStation toWrapperStation(WrapperEntityStation wrapperEntityOperations) { - if(wrapperEntityOperations == null) { + if (wrapperEntityOperations == null) { return null; } @@ -351,7 +303,7 @@ public WrapperStation toWrapperStation(WrapperEntityStation wrapperEntityOperati @Override public WrapperStationsResource toWrapperStationsResource(WrapperStations wrapperStations) { - if(wrapperStations == null) { + if (wrapperStations == null) { return null; } @@ -367,7 +319,7 @@ public WrapperStationsResource toWrapperStationsResource(WrapperStations wrapper @Override public WrapperStationResource toWrapperStationResource(WrapperStation wrapperStation) { - if(wrapperStation == null) { + if (wrapperStation == null) { return null; } @@ -390,7 +342,7 @@ public WrapperStationResource toWrapperStationResource(WrapperStation wrapperSta @Override public List toResourceList(WrapperEntitiesList wrapperEntitiesList) { - if(wrapperEntitiesList == null || wrapperEntitiesList.getWrapperEntities() == null) { + if (wrapperEntitiesList == null || wrapperEntitiesList.getWrapperEntities() == null) { return null; } @@ -408,7 +360,7 @@ public List toResourceList(WrapperEntitiesList wrapperEntitiesL @Override public List toResourceList(Stations stations) { - if(stations == null || stations.getStationsList() == null) { + if (stations == null || stations.getStationsList() == null) { return null; } @@ -420,7 +372,7 @@ public List toResourceList(Stations stations) { @Override public StationResource toResource(Station model) { - if(model == null) { + if (model == null) { return null; } @@ -440,7 +392,7 @@ public StationResource toResource(Station model) { @Override public StationDetails fromDto(StationDetailsDto model) { - if(model == null) { + if (model == null) { return null; } @@ -487,12 +439,15 @@ public StationDetails fromDto(StationDetailsDto model) { stationDetails.setTargetPortPof(model.getTargetPortPof()); stationDetails.setTargetHostPof(model.getTargetHostPof()); + stationDetails.setRestEndpoint(model.getRestEndpoint()); + stationDetails.setIsPaymentOptionsEnabled(model.getIsPaymentOptionsEnabled()); + return stationDetails; } @Override public StationDetails fromWrapperStationDetailsDto(WrapperStationDetailsDto model) { - if(model == null) { + if (model == null) { return null; } @@ -517,6 +472,9 @@ public StationDetails fromWrapperStationDetailsDto(WrapperStationDetailsDto mode stationDetails.setVersion(model.getVersion()); stationDetails.setBrokerDescription(model.getBrokerDescription()); + stationDetails.setRestEndpoint(model.getRestEndpoint()); + stationDetails.setIsPaymentOptionsEnabled(model.getIsPaymentOptionsEnabled()); + //default stationDetails.setTimeoutA(7L); stationDetails.setTimeoutB(30L); diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/authorization/AuthorizationMetadata.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/authorization/AuthorizationMetadata.java index 31080bf30..71b7c216c 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/authorization/AuthorizationMetadata.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/authorization/AuthorizationMetadata.java @@ -6,6 +6,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; + /** * Model that represent the authorization metadata */ @@ -20,5 +22,5 @@ public class AuthorizationMetadata { @JsonProperty("short_key") private String shortKey; - private AuthorizationGenericKeyValue content; + private List content; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitution.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitution.java index 4fde675a9..634fd4733 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitution.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitution.java @@ -1,9 +1,15 @@ package it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class CreditorInstitution { @JsonProperty("creditor_institution_code") private String creditorInstitutionCode; @@ -18,16 +24,16 @@ public class CreditorInstitution { private String cbillCode; @JsonProperty("application_code") - private String applicationCode; + private Long applicationCode; @JsonProperty("aux_digit") - private String auxDigit; + private Long auxDigit; @JsonProperty("segregation_code") - private String segregationCode; + private Long segregationCode; @JsonProperty("mod4") - private String mod4; + private Boolean mod4; @JsonProperty("broadcast") private Boolean broadcast; diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitutions.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitutions.java index 718d03826..ceda3f175 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitutions.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/creditorinstitution/CreditorInstitutions.java @@ -2,11 +2,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import it.pagopa.selfcare.pagopa.backoffice.model.connector.PageInfo; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.util.List; @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class CreditorInstitutions { @JsonProperty("creditor_institutions") diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/CreditorInstitutionStationEdit.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/CreditorInstitutionStationEdit.java index a59e7b8f6..78cb849d7 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/CreditorInstitutionStationEdit.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/CreditorInstitutionStationEdit.java @@ -1,9 +1,15 @@ package it.pagopa.selfcare.pagopa.backoffice.model.connector.station; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class CreditorInstitutionStationEdit { @JsonProperty("station_code") private String stationCode; diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/StationDetails.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/StationDetails.java index 4135be62a..9ec532ab0 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/StationDetails.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/connector/station/StationDetails.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import it.pagopa.selfcare.pagopa.backoffice.model.connector.broker.BrokerDetails; import it.pagopa.selfcare.pagopa.backoffice.model.connector.channel.Protocol; import lombok.Data; @@ -128,4 +129,10 @@ public class StationDetails extends Station { @JsonProperty("target_path_pof") private String targetPathPof; + @JsonProperty("is_payment_options_enabled") + @Schema(description = "Flag that enables EC's payment options service") + private Boolean isPaymentOptionsEnabled = false; + @JsonProperty("rest_endpoint") + @Schema(description = "Endpoint to all the API REST of the EC") + private String restEndpoint; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodes.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodes.java new file mode 100644 index 000000000..578b78729 --- /dev/null +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodes.java @@ -0,0 +1,34 @@ +package it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import javax.validation.constraints.NotBlank; +import java.util.List; + +/** + * Model that represent the tax code of a creditor institution and the list of its segregation codes + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) +public class CreditorInstitutionStationSegregationCodes { + + @JsonProperty("ci_tax_code") + @Schema(example = "02438750586", description = "The tax code of the creditor institution", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank + private String ciTaxCode; + + @JsonProperty("segregation_code_list") + @Schema(description = "List of segregation code used by the creditor institution in a broker station", requiredMode = Schema.RequiredMode.REQUIRED) + private List segregationCodes; +} diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodesList.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodesList.java new file mode 100644 index 000000000..b88a4c2c6 --- /dev/null +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/creditorinstituions/client/CreditorInstitutionStationSegregationCodesList.java @@ -0,0 +1,28 @@ +package it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * Model that represent a list of creditor institution with relative segregation codes + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) +public class CreditorInstitutionStationSegregationCodesList { + + @JsonProperty("ci_station_segregation_codes") + @NotNull + private List ciStationCodes; +} diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailResource.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailResource.java index 37f779ee5..be18398bb 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailResource.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailResource.java @@ -94,5 +94,8 @@ public class StationDetailResource extends StationResource { private String note; @Schema(description = "Flag that describe if there is a pending update for the station") private Boolean pendingUpdate; - + @Schema(description = "Flag that enables EC's payment options service") + private Boolean isPaymentOptionsEnabled = false; + @Schema(description = "Endpoint to all the API REST of the EC") + private String restEndpoint; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailsDto.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailsDto.java index 4b211bdad..845774395 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailsDto.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/StationDetailsDto.java @@ -120,4 +120,8 @@ public class StationDetailsDto { @JsonProperty(required = true) @Schema(description = "Url jira for StationDetail validation") private String validationUrl; + @Schema(description = "Flag that enables EC's payment options service") + private Boolean isPaymentOptionsEnabled = false; + @Schema(description = "Endpoint to all the API REST of the EC") + private String restEndpoint; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationDetailsDto.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationDetailsDto.java index 27d78bb78..e52dfe482 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationDetailsDto.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationDetailsDto.java @@ -69,4 +69,8 @@ public class WrapperStationDetailsDto { @JsonProperty(required = true) @Schema(description = "Url jira for StationDetail validation") private String validationUrl; + @Schema(description = "Flag that enables EC's payment options service") + private Boolean isPaymentOptionsEnabled = false; + @Schema(description = "Endpoint to all the API REST of the EC") + private String restEndpoint; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationResource.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationResource.java index aef5d3256..8c557ce2b 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationResource.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/model/stations/WrapperStationResource.java @@ -56,4 +56,8 @@ public class WrapperStationResource { private String targetPathPof; @Schema(description = "Describe the station connection's type, true synchronous, false asynchronous") private Boolean isConnectionSync = true; + @Schema(description = "Flag that enables EC's payment options service") + private Boolean isPaymentOptionsEnabled = false; + @Schema(description = "Endpoint to all the API REST of the EC") + private String restEndpoint; } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java index 4f8e28fbd..8087cb481 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementService.java @@ -2,6 +2,7 @@ import com.azure.spring.cloud.feature.management.FeatureManager; import feign.FeignException; +import it.pagopa.selfcare.pagopa.backoffice.client.ApiConfigSelfcareIntegrationClient; import it.pagopa.selfcare.pagopa.backoffice.client.AuthorizerConfigClient; import it.pagopa.selfcare.pagopa.backoffice.client.AzureApiManagerClient; import it.pagopa.selfcare.pagopa.backoffice.client.ExternalApiClient; @@ -9,8 +10,22 @@ import it.pagopa.selfcare.pagopa.backoffice.exception.AppException; import it.pagopa.selfcare.pagopa.backoffice.model.authorization.Authorization; import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationEntity; +import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationGenericKeyValue; +import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationMetadata; import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationOwner; -import it.pagopa.selfcare.pagopa.backoffice.model.institutions.*; +import it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client.CreditorInstitutionStationSegregationCodesList; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.Delegation; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.DelegationExternal; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.DelegationResource; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.Institution; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.InstitutionApiKeysResource; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.InstitutionDetail; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.InstitutionDetailResource; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.InstitutionResponse; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.Product; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.ProductResource; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.RoleType; +import it.pagopa.selfcare.pagopa.backoffice.model.institutions.Subscription; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.client.CreateInstitutionApiKeyDto; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.client.InstitutionApiKeys; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.client.InstitutionInfo; @@ -24,7 +39,13 @@ import org.springframework.stereotype.Service; import javax.validation.constraints.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static it.pagopa.selfcare.pagopa.backoffice.util.Utility.sanitizeLogParam; @Slf4j @Service @@ -32,11 +53,14 @@ public class ApiManagementService { private static final String PRIMARY = "primary"; private static final String SECONDARY = "secondary"; + private static final String AUTHORIZER_SEGREGATION_CODES_METADATA_SHORT_KEY = "_seg"; private final AzureApiManagerClient apimClient; private final ExternalApiClient externalApiClient; + private final ApiConfigSelfcareIntegrationClient apiConfigSelfcareIntegrationClient; + private final ModelMapper modelMapper; private final String testEmail; @@ -49,15 +73,19 @@ public class ApiManagementService { @Autowired - public ApiManagementService(AzureApiManagerClient apimClient, - ExternalApiClient externalApiClient, - ModelMapper modelMapper, - AuthorizerConfigClient authorizerConfigClient, - FeatureManager featureManager, - @Value("${institution.subscription.test-email}") String testEmail, - @Value("${info.properties.environment}") String environment) { + public ApiManagementService( + AzureApiManagerClient apimClient, + ExternalApiClient externalApiClient, + ApiConfigSelfcareIntegrationClient apiConfigSelfcareIntegrationClient, + ModelMapper modelMapper, + AuthorizerConfigClient authorizerConfigClient, + FeatureManager featureManager, + @Value("${institution.subscription.test-email}") String testEmail, + @Value("${info.properties.environment}") String environment + ) { this.apimClient = apimClient; this.externalApiClient = externalApiClient; + this.apiConfigSelfcareIntegrationClient = apiConfigSelfcareIntegrationClient; this.modelMapper = modelMapper; this.testEmail = testEmail; this.environment = environment; @@ -161,8 +189,7 @@ public InstitutionApiKeysResource getInstitutionApiKeys(String institutionId) { * @return the list of all institution's subscription's api keys */ public InstitutionApiKeysResource createSubscriptionKeys(String institutionId, Subscription subscriptionCode) { - InstitutionResponse institution = - getInstitutionResponse(institutionId); + InstitutionResponse institution = getInstitutionResponse(institutionId); String subscriptionId = String.format("%s%s", subscriptionCode.getPrefixId(), institution.getTaxCode()); String subscriptionName = String.format("%s %s", subscriptionCode.getDisplayName(), institution.getDescription()); @@ -178,7 +205,7 @@ public InstitutionApiKeysResource createSubscriptionKeys(String institutionId, S List apiSubscriptions = this.apimClient.getApiSubscriptions(institutionId); if (subscriptionCode.getAuthDomain() != null) { - List delegationResponse = getDelegationResponse(institutionId, subscriptionCode); + DelegationInfo delegationInfoResponse = getDelegationInfo(institutionId, subscriptionCode.getAuthDelegations(), institution.getTaxCode()); InstitutionApiKeys apiKeys = apiSubscriptions.stream() .filter(institutionApiKeys -> institutionApiKeys.getId().equals(subscriptionId)) @@ -186,11 +213,11 @@ public InstitutionApiKeysResource createSubscriptionKeys(String institutionId, S .orElseThrow(() -> new AppException(AppError.APIM_KEY_NOT_FOUND, institutionId)); // configure primary key - Authorization authorizationPrimaryKey = buildAuthorization(subscriptionCode.getAuthDomain(), subscriptionCode.getPrefixId(), apiKeys.getPrimaryKey(), institution, true, delegationResponse); + Authorization authorizationPrimaryKey = buildAuthorization(subscriptionCode, apiKeys.getPrimaryKey(), institution, true, delegationInfoResponse); this.authorizerConfigClient.createAuthorization(authorizationPrimaryKey); // configure secondary key - Authorization authorizationSecondaryKey = buildAuthorization(subscriptionCode.getAuthDomain(), subscriptionCode.getPrefixId(), apiKeys.getSecondaryKey(), institution, false, delegationResponse); + Authorization authorizationSecondaryKey = buildAuthorization(subscriptionCode, apiKeys.getSecondaryKey(), institution, false, delegationInfoResponse); this.authorizerConfigClient.createAuthorization(authorizationSecondaryKey); } @@ -199,15 +226,6 @@ public InstitutionApiKeysResource createSubscriptionKeys(String institutionId, S .build(); } - - private List getDelegationResponse(String institutionId, Subscription subscriptionCode) { - if (Boolean.TRUE.equals(subscriptionCode.getAuthDelegations())) { - return this.externalApiClient.getBrokerDelegation( - null, institutionId, "prod-pagopa", "FULL", null); - } - return new ArrayList<>(); - } - /** * Regenerate the primary subscription key to the specified subscription for the given institution. *

@@ -244,35 +262,94 @@ public void regenerateSecondaryKey(@NotNull String institutionId, @NotNull Strin } } - private void updateAuthorization(String institutionId, String subscriptionId, String subscriptionPrefixId, boolean isPrimaryKey) { + /** + * Updates authorizer config for all broker's API keys that require delegations configuration. + * Retrieves the updated list of creditor institution and the relative list of segregation codes associated to + * broker's station and use this list to update segregation codes metadata in authorizer configuration. + * + * @param institutionId broker's institution id + * @param ciTaxCode broker's tax code + */ + public void updateBrokerAuthorizerSegregationCodesMetadata( + String institutionId, + String ciTaxCode + ) { + List apiKeys = this.apimClient.getApiSubscriptions(institutionId).parallelStream() + .filter(this::checkIfAPIKeyHasAuthDelegations) + .toList(); + + CreditorInstitutionStationSegregationCodesList ciSegregationCodes = + this.apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(ciTaxCode); + + apiKeys.parallelStream().forEach( + apiKey -> { + String prefixId = apiKey.getId().split("-")[0] + "-"; + updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, true); + updateAuthorizerConfigMetadata(institutionId, prefixId, ciSegregationCodes, false); + } + ); + } + + private boolean checkIfAPIKeyHasAuthDelegations(InstitutionApiKeys institutionApiKeys) { + try { + String prefixId = institutionApiKeys.getId().split("-")[0] + "-"; + return Subscription.fromPrefix(prefixId).getAuthDelegations(); + } catch (Exception e) { + return false; + } + } + + private void updateAuthorization( + String institutionId, + String subscriptionId, + String subscriptionPrefixId, + boolean isPrimaryKey + ) { InstitutionApiKeys apiKeys = this.apimClient.getApiSubscriptions(institutionId).stream() .filter(institutionApiKeys -> institutionApiKeys.getId().equals(subscriptionId)) .findFirst() .orElseThrow(() -> new AppException(AppError.APIM_KEY_NOT_FOUND, institutionId)); + Subscription subscription = Subscription.fromPrefix(subscriptionPrefixId); Authorization authorization; try { String authorizationId = createAuthorizationId(subscriptionPrefixId, institutionId, isPrimaryKey); authorization = this.authorizerConfigClient.getAuthorization(authorizationId); - this.authorizerConfigClient.deleteAuthorization(authorization.getId()); authorization.setSubscriptionKey(isPrimaryKey ? apiKeys.getPrimaryKey() : apiKeys.getSecondaryKey()); - InstitutionResponse institution = - getInstitutionResponse(institutionId); - List delegationResponse = getDelegationResponse(institutionId, Subscription.fromPrefix(subscriptionPrefixId)); - authorization.setAuthorizedEntities(getAuthorizationEntities(institution, delegationResponse)); + InstitutionResponse institution = getInstitutionResponse(institutionId); + DelegationInfo delegationInfoResponse = getDelegationInfo(institutionId, subscription.getAuthDelegations(), institution.getTaxCode()); + + authorization.setAuthorizedEntities(getAuthorizationEntities(institution, delegationInfoResponse.delegationResponse)); + authorization.setOtherMetadata(getAuthorizationMetadataList(delegationInfoResponse.ciSegregationCodes, authorization.getOtherMetadata())); + this.authorizerConfigClient.deleteAuthorization(authorization.getId()); this.authorizerConfigClient.createAuthorization(authorization); } catch (FeignException.NotFound e) { - createSubscriptionKeys(institutionId, Subscription.fromPrefix(subscriptionPrefixId)); + log.error("An error occurred while updating API key authorizer configuration for institution {} and subscription {}, proceed to recreate the API key", + sanitizeLogParam(institutionId), sanitizeLogParam(subscription.getDisplayName()), e); + createSubscriptionKeys(institutionId, subscription); } } + private List getAuthorizationMetadataList( + CreditorInstitutionStationSegregationCodesList ciSegregationCodes, + List otherMetadata + ) { + AuthorizationMetadata authorizationMetadata = buildAuthorizationMetadata(ciSegregationCodes); + if (otherMetadata != null) { + List newOtherMetadata = new ArrayList<>(otherMetadata); + newOtherMetadata.removeIf(metadata -> metadata.getShortKey().equals(AUTHORIZER_SEGREGATION_CODES_METADATA_SHORT_KEY)); + newOtherMetadata.add(authorizationMetadata); + return newOtherMetadata; + } + return Collections.singletonList(authorizationMetadata); + } + private InstitutionResponse getInstitutionResponse(String institutionId) { - InstitutionResponse institution = - this.externalApiClient.getInstitution(institutionId); + InstitutionResponse institution = this.externalApiClient.getInstitution(institutionId); if (institution == null) { throw new AppException(AppError.APIM_USER_NOT_FOUND, institutionId); } @@ -280,29 +357,32 @@ private InstitutionResponse getInstitutionResponse(String institutionId) { } private Authorization buildAuthorization( - String domain, - String subscriptionPrefixId, + Subscription subscription, String subscriptionKey, InstitutionResponse institution, boolean isPrimaryKey, - List delegationResponse + DelegationInfo delegationInfo ) { + String authDomain = subscription.getAuthDomain(); return Authorization.builder() - .id(createAuthorizationId(subscriptionPrefixId, institution.getId(), isPrimaryKey)) - .domain(domain) + .id(createAuthorizationId(subscription.getPrefixId(), institution.getId(), isPrimaryKey)) + .domain(authDomain) .subscriptionKey(subscriptionKey) - .description(String.format("%s key configuration for %s", isPrimaryKey ? PRIMARY : SECONDARY, domain)) + .description(String.format("%s key configuration for %s", isPrimaryKey ? PRIMARY : SECONDARY, authDomain)) .owner(AuthorizationOwner.builder() .id(institution.getTaxCode()) .name(institution.getDescription()) .type(getOwnerType(institution)) .build()) - .authorizedEntities(getAuthorizationEntities(institution, delegationResponse)) - .otherMetadata(Collections.emptyList()) + .authorizedEntities(getAuthorizationEntities(institution, delegationInfo.delegationResponse)) + .otherMetadata(Collections.singletonList(buildAuthorizationMetadata(delegationInfo.ciSegregationCodes))) .build(); } - private static List getAuthorizationEntities(InstitutionResponse institution, List delegationResponse) { + private List getAuthorizationEntities( + InstitutionResponse institution, + List delegationResponse + ) { List authorizedEntities = new ArrayList<>(); if (delegationResponse != null && !delegationResponse.isEmpty()) { @@ -329,8 +409,10 @@ private String createAuthorizationId(String subscriptionPrefixId, String institu return String.format("%s%s_%s", subscriptionPrefixId, institutionId, isPrimaryKey ? PRIMARY : SECONDARY); } - private void createUserIfNotExist(String institutionId, - InstitutionResponse institution) { + private void createUserIfNotExist( + String institutionId, + InstitutionResponse institution + ) { try { this.apimClient.getInstitution(institutionId); } catch (IllegalArgumentException e) { @@ -346,5 +428,66 @@ private void createUserIfNotExist(String institutionId, private char getEnvironment() { return environment.toLowerCase().charAt(0); } + + private void updateAuthorizerConfigMetadata( + String institutionId, + String prefixId, + CreditorInstitutionStationSegregationCodesList ciSegregationCodes, + boolean isPrimaryKey + ) { + Subscription subscription = Subscription.fromPrefix(prefixId); + try { + String authorizationId = createAuthorizationId(prefixId, institutionId, isPrimaryKey); + Authorization authorization = this.authorizerConfigClient.getAuthorization(authorizationId); + + authorization.setOtherMetadata(getAuthorizationMetadataList(ciSegregationCodes, authorization.getOtherMetadata())); + + this.authorizerConfigClient.deleteAuthorization(authorization.getId()); + this.authorizerConfigClient.createAuthorization(authorization); + } catch (FeignException.NotFound e) { + log.error("An error occurred while updating API key authorizer configuration for institution {} and subscription {}, proceed to recreate the API key", + sanitizeLogParam(institutionId), sanitizeLogParam(subscription.getDisplayName()), e); + createSubscriptionKeys(institutionId, subscription); + } + } + + private AuthorizationMetadata buildAuthorizationMetadata(CreditorInstitutionStationSegregationCodesList ciStationCodesList) { + List genericKeyValues = + ciStationCodesList.getCiStationCodes().parallelStream() + .map(elem -> + AuthorizationGenericKeyValue.builder() + .key(elem.getCiTaxCode()) + .values(elem.getSegregationCodes()) + .build() + ) + .toList(); + + return AuthorizationMetadata.builder() + .name("Segregation codes") + .shortKey(AUTHORIZER_SEGREGATION_CODES_METADATA_SHORT_KEY) + .content(genericKeyValues) + .build(); + } + + private DelegationInfo getDelegationInfo( + String institutionId, + Boolean hasAuthDelegations, + String institutionTaxCode + ) { + List delegationResponse = new ArrayList<>(); + CreditorInstitutionStationSegregationCodesList ciSegregationCodes = new CreditorInstitutionStationSegregationCodesList(new ArrayList<>()); + if (Boolean.TRUE.equals(hasAuthDelegations)) { + delegationResponse = this.externalApiClient + .getBrokerDelegation(null, institutionId, "prod-pagopa", "FULL", null); + ciSegregationCodes = + this.apiConfigSelfcareIntegrationClient + .getCreditorInstitutionsSegregationCodeAssociatedToBroker(institutionTaxCode); + } + return new DelegationInfo(delegationResponse, ciSegregationCodes); + } + + private record DelegationInfo(List delegationResponse, + CreditorInstitutionStationSegregationCodesList ciSegregationCodes) { + } } diff --git a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java index 11c65d0c3..4290f48b4 100644 --- a/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java +++ b/src/main/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionService.java @@ -64,18 +64,22 @@ public class CreditorInstitutionService { private final ModelMapper modelMapper; + private final ApiManagementService apiManagementService; + @Autowired public CreditorInstitutionService( ApiConfigClient apiConfigClient, ApiConfigSelfcareIntegrationClient apiConfigSelfcareIntegrationClient, TavoloOpRepository operativeTableRepository, - ExternalApiClient externalApiClient, ModelMapper modelMapper + ExternalApiClient externalApiClient, ModelMapper modelMapper, + ApiManagementService apiManagementService ) { this.apiConfigClient = apiConfigClient; this.apiConfigSelfcareIntegrationClient = apiConfigSelfcareIntegrationClient; this.operativeTableRepository = operativeTableRepository; this.externalApiClient = externalApiClient; this.modelMapper = modelMapper; + this.apiManagementService = apiManagementService; } /** @@ -120,36 +124,86 @@ public AvailableCodes getCreditorInstitutionSegregationCodes(String ciTaxCode, S return this.apiConfigSelfcareIntegrationClient.getCreditorInstitutionSegregationCodes(ciTaxCode, targetCITaxCode); } + /** + * Associate the provided creditor institution to the given station. + *

+ * Check if the provided tax code is a creditor institution tax code and if so, associates it to the given station and + * updates the authorizer config for each broker's api keys by adding the specified segregation code + * + * @param ciTaxCode creditor institution's tax code + * @param institutionId broker's institution id + * @param brokerTaxCode broker's tax code + * @param dto creditor institution - station association info + * @return the creditor institution - station association info + */ public CreditorInstitutionStationEditResource associateStationToCreditorInstitution( - String ecCode, + String ciTaxCode, + String institutionId, + String brokerTaxCode, @NotNull CreditorInstitutionStationDto dto ) { + checkIfIsCITaxCodeFailOtherwise(ciTaxCode); + CreditorInstitutionStationEdit station = this.mapper.fromDto(dto); + CreditorInstitutionStationEdit ecStation = this.apiConfigClient.createCreditorInstitutionStationRelationship(ciTaxCode, station); try { - apiConfigClient.getCreditorInstitutionDetails(ecCode); - } catch (FeignException e) { - throw new AppException(AppError.CREDITOR_INSTITUTION_NOT_FOUND, ecCode); + this.apiManagementService.updateBrokerAuthorizerSegregationCodesMetadata(institutionId, brokerTaxCode); + } catch (Exception e) { + log.error("Failed to update broker API key authorizations, revert associate station to CI operation"); + this.apiConfigClient.deleteCreditorInstitutionStationRelationship(ciTaxCode, ecStation.getStationCode()); + throw e; } - CreditorInstitutionStationEdit station = mapper.fromDto(dto); - CreditorInstitutionStationEdit ecStation = apiConfigClient.createCreditorInstitutionStationRelationship(ecCode, station); - return mapper.toResource(ecStation); + return this.mapper.toResource(ecStation); } + /** + * Updates the association between creditor institution and station. + *

+ * Check if the provided tax code is a creditor institution tax code and if so, updates the association to the given + * station with the provided info + * + * @param ciTaxCode creditor institution's tax code + * @param dto creditor institution - station association info + * @return the updated creditor institution - station association info + */ public CreditorInstitutionStationEditResource updateStationAssociationToCreditorInstitution( - String ecCode, + String ciTaxCode, @NotNull CreditorInstitutionStationDto dto ) { - try { - apiConfigClient.getCreditorInstitutionDetails(ecCode); - } catch (FeignException e) { - throw new AppException(AppError.CREDITOR_INSTITUTION_NOT_FOUND, ecCode); - } - CreditorInstitutionStationEdit station = mapper.fromDto(dto); - CreditorInstitutionStationEdit ecStation = apiConfigClient.updateCreditorInstitutionStationRelationship(ecCode, station.getStationCode(), station); - return mapper.toResource(ecStation); + checkIfIsCITaxCodeFailOtherwise(ciTaxCode); + CreditorInstitutionStationEdit station = this.mapper.fromDto(dto); + CreditorInstitutionStationEdit ecStation = this.apiConfigClient.updateCreditorInstitutionStationRelationship(ciTaxCode, station.getStationCode(), station); + return this.mapper.toResource(ecStation); } - public void deleteCreditorInstitutionStationRelationship(String ecCode, String stationCode) { - apiConfigClient.deleteCreditorInstitutionStationRelationship(ecCode, stationCode); + /** + * Removes the association between creditor institution and station. + *

+ * Removes the association and updates the authorizer config for each broker's api keys by removing + * the segregation code of the association + * + * @param ciTaxCode creditor institution's tax code + * @param institutionId broker's institution id + * @param brokerTaxCode broker's tax code + */ + public void deleteCreditorInstitutionStationRelationship( + String ciTaxCode, + String stationCode, + String institutionId, + String brokerTaxCode + ) { + this.apiConfigClient.deleteCreditorInstitutionStationRelationship(ciTaxCode, stationCode); + try { + this.apiManagementService.updateBrokerAuthorizerSegregationCodesMetadata(institutionId, brokerTaxCode); + } catch (Exception e) { + log.error("Failed to update broker API key authorizations, revert dissociate station to CI operation"); + CreditorInstitutions creditorInstitutions = + this.apiConfigClient.getCreditorInstitutionsByStation(stationCode, 1, 0, ciTaxCode); + CreditorInstitutionStationEdit dto = + this.modelMapper.map(creditorInstitutions.getCreditorInstitutionList().get(0), CreditorInstitutionStationEdit.class); + dto.setStationCode(stationCode); + this.apiConfigClient.createCreditorInstitutionStationRelationship(ciTaxCode, dto); + throw e; + } } @@ -327,4 +381,11 @@ private boolean brokerCanBeAddedToDelegation( && delegationExternals.stream().noneMatch(delegationExternal -> delegationExternal.getTaxCode().equals(broker.getTaxCode())); } + private void checkIfIsCITaxCodeFailOtherwise(String ciTaxCode) { + try { + this.apiConfigClient.getCreditorInstitutionDetails(ciTaxCode); + } catch (FeignException e) { + throw new AppException(AppError.CREDITOR_INSTITUTION_NOT_FOUND, ciTaxCode); + } + } } diff --git a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionControllerTest.java b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionControllerTest.java index 3bf17b4fe..66fc82cff 100644 --- a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionControllerTest.java +++ b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/controller/CreditorInstitutionControllerTest.java @@ -83,9 +83,11 @@ void getCreditorInstitutionSegregationCodes() throws Exception { @Test void associateStationToCreditorInstitution() throws Exception { String url = "/creditor-institutions/12345678900/station"; - when(ciService.associateStationToCreditorInstitution(anyString(), any(CreditorInstitutionStationDto.class))) + when(ciService.associateStationToCreditorInstitution(anyString(), anyString(), anyString(), any(CreditorInstitutionStationDto.class))) .thenReturn(TestUtil.fileToObject("response/service/post_creditor_institution_station_association_ok.json", CreditorInstitutionStationEditResource.class)); mvc.perform(post(url) + .param("institutionId", "institutionId") + .param("brokerTaxCode", "brokerTaxCode") .content(TestUtil.readJsonFromFile("request/post_creditor_institution_station_association.json")) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) @@ -107,8 +109,10 @@ void updateStationAssociationToCreditorInstitution() throws Exception { @Test void deleteCreditorInstitutionStationRelationship() throws Exception { String url = "/creditor-institutions/12345678900/station/00000000000_01"; - doNothing().when(ciService).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); - mvc.perform(delete(url).contentType(MediaType.APPLICATION_JSON)) + doNothing().when(ciService).deleteCreditorInstitutionStationRelationship(anyString(), anyString(), anyString(), anyString()); + mvc.perform(delete(url).contentType(MediaType.APPLICATION_JSON) + .param("institutionId", "institutionId") + .param("brokerTaxCode", "brokerTaxCode")) .andExpect(status().isOk()); } diff --git a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java index a20255352..e813cea26 100644 --- a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java +++ b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/ApiManagementServiceTest.java @@ -1,12 +1,18 @@ package it.pagopa.selfcare.pagopa.backoffice.service; import com.azure.spring.cloud.feature.management.FeatureManager; +import feign.FeignException; import it.pagopa.selfcare.pagopa.backoffice.TestUtil; +import it.pagopa.selfcare.pagopa.backoffice.client.ApiConfigSelfcareIntegrationClient; import it.pagopa.selfcare.pagopa.backoffice.client.AuthorizerConfigClient; import it.pagopa.selfcare.pagopa.backoffice.client.AzureApiManagerClient; import it.pagopa.selfcare.pagopa.backoffice.client.ExternalApiClient; import it.pagopa.selfcare.pagopa.backoffice.config.MappingsConfiguration; import it.pagopa.selfcare.pagopa.backoffice.model.authorization.Authorization; +import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationGenericKeyValue; +import it.pagopa.selfcare.pagopa.backoffice.model.authorization.AuthorizationMetadata; +import it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client.CreditorInstitutionStationSegregationCodes; +import it.pagopa.selfcare.pagopa.backoffice.model.creditorinstituions.client.CreditorInstitutionStationSegregationCodesList; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.*; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.client.InstitutionApiKeys; import it.pagopa.selfcare.pagopa.backoffice.model.institutions.client.InstitutionInfo; @@ -18,6 +24,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -32,6 +39,7 @@ class ApiManagementServiceTest { private final String INSTITUTION_ID = "INSTITUTION_ID"; private final String SUBSCRIPTION_ID = "SUBSCRIPTION_ID"; private final String BROKER_ID = "BROKER_ID"; + private static final String CI_TAX_CODE = "ciTaxCode"; @MockBean private AzureApiManagerClient apimClient; @@ -45,6 +53,9 @@ class ApiManagementServiceTest { @MockBean private AuthorizerConfigClient authorizerConfigClient; + @MockBean + private ApiConfigSelfcareIntegrationClient apiConfigSelfcareIntegrationClient; + @Autowired private ApiManagementService service; @@ -158,6 +169,8 @@ void createSubscriptionKeys() throws IOException { verify(apimClient).createInstitutionSubscription(any(), any(), any(), any(), any()); verify(externalApiClient).getInstitution(INSTITUTION_ID); verify(authorizerConfigClient, never()).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -179,6 +192,8 @@ void createSubscriptionKeysWithoutAPIMUser() throws IOException { verify(apimClient).createInstitutionSubscription(any(), any(), any(), any(), any()); verify(externalApiClient).getInstitution(INSTITUTION_ID); verify(authorizerConfigClient, never()).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -202,6 +217,8 @@ void createSubscriptionKeysForBOExtEC() throws IOException { verify(apimClient).createInstitutionSubscription(any(), any(), any(), any(), any()); verify(externalApiClient).getInstitution(INSTITUTION_ID); verify(authorizerConfigClient, times(2)).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -213,6 +230,10 @@ void createSubscriptionKeysForFdrPsp() throws IOException { when(externalApiClient.getInstitution(any())).thenReturn(institutionResponse); when(apimClient.getApiSubscriptions(any())).thenReturn(Collections.singletonList(institutionApiKeys)); + when(externalApiClient.getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null)) + .thenReturn(createDelegations()); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn(buildCreditorInstitutionStationSegregationCodesList()); InstitutionApiKeysResource result = service.createSubscriptionKeys(INSTITUTION_ID, Subscription.FDR_PSP); @@ -237,6 +258,10 @@ void regeneratePrimaryKey() throws IOException { .id("auth-id") .build()); when(externalApiClient.getInstitution(any())).thenReturn(institutionResponse); + when(externalApiClient.getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null)) + .thenReturn(createDelegations()); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn(buildCreditorInstitutionStationSegregationCodesList()); assertDoesNotThrow(() -> service.regeneratePrimaryKey(INSTITUTION_ID, "gdp-123456")); @@ -246,6 +271,34 @@ void regeneratePrimaryKey() throws IOException { verify(authorizerConfigClient).createAuthorization(any()); } + @Test + void regeneratePrimaryKeyFailOnAuthorizerConfigUpdateTriggerAPIKeyRecreation() throws IOException { + InstitutionResponse institutionResponse = TestUtil.fileToObject( + "response/externalapi/institution_response.json", InstitutionResponse.class); + InstitutionApiKeys institutionApiKeys = buildInstitutionApiKeys("gdp-aTaxCode"); + when(apimClient.getApiSubscriptions(anyString())) + .thenReturn(Collections.singletonList(institutionApiKeys)) + .thenReturn(Collections.singletonList(institutionApiKeys)); + when(authorizerConfigClient.getAuthorization(anyString())) + .thenThrow(FeignException.NotFound.class) + .thenReturn(Authorization.builder().id("auth-id").build()); + when(externalApiClient.getInstitution(any())).thenReturn(institutionResponse); + when(externalApiClient.getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null)) + .thenReturn(createDelegations()); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn(buildCreditorInstitutionStationSegregationCodesList()); + + assertDoesNotThrow(() -> service.regeneratePrimaryKey(INSTITUTION_ID, "gdp-aTaxCode")); + + verify(apimClient).regeneratePrimaryKey("gdp-aTaxCode"); + verify(apimClient, times(2)).getApiSubscriptions(INSTITUTION_ID); + verify(apimClient).getInstitution(INSTITUTION_ID); + verify(apimClient, never()).createInstitution(anyString(), any()); + verify(apimClient).createInstitutionSubscription(any(), any(), any(), any(), any()); + verify(authorizerConfigClient, times(2)).createAuthorization(any()); + verify(authorizerConfigClient, never()).deleteAuthorization(anyString()); + } + @Test void regeneratePrimaryKeyForBOExtEC() throws IOException { InstitutionResponse institutionResponse = TestUtil.fileToObject( @@ -263,6 +316,8 @@ void regeneratePrimaryKeyForBOExtEC() throws IOException { verify(apimClient).getApiSubscriptions(INSTITUTION_ID); verify(authorizerConfigClient).deleteAuthorization(anyString()); verify(authorizerConfigClient).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -282,6 +337,8 @@ void regeneratePrimaryKeyForBOExtPSP() throws IOException { verify(apimClient).getApiSubscriptions(INSTITUTION_ID); verify(authorizerConfigClient).deleteAuthorization(anyString()); verify(authorizerConfigClient).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -295,6 +352,10 @@ void regenerateSecondaryKey() throws IOException { when(authorizerConfigClient.getAuthorization(anyString())).thenReturn(Authorization.builder() .id("auth-id") .build()); + when(externalApiClient.getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null)) + .thenReturn(createDelegations()); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn(buildCreditorInstitutionStationSegregationCodesList()); assertDoesNotThrow(() -> service.regenerateSecondaryKey(INSTITUTION_ID, "gdp-123456")); @@ -321,6 +382,8 @@ void regenerateSecondaryKeyForBOExtEC() throws IOException { verify(apimClient).getApiSubscriptions(INSTITUTION_ID); verify(authorizerConfigClient).deleteAuthorization(anyString()); verify(authorizerConfigClient).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); } @Test @@ -340,6 +403,48 @@ void regenerateSecondaryKeyForBOExtPSP() throws IOException { verify(apimClient).getApiSubscriptions(INSTITUTION_ID); verify(authorizerConfigClient).deleteAuthorization(anyString()); verify(authorizerConfigClient).createAuthorization(any()); + verify(externalApiClient, never()).getBrokerDelegation(null, INSTITUTION_ID, "prod-pagopa", "FULL", null); + verify(apiConfigSelfcareIntegrationClient, never()).getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString()); + } + + @Test + void updateBrokerAuthorizerSegregationCodesMetadataSuccess() { + String subscriptionId = String.format("%s%s", Subscription.GPD.getPrefixId(), CI_TAX_CODE); + InstitutionApiKeys institutionApiKeys1 = buildInstitutionApiKeys(subscriptionId); + InstitutionApiKeys institutionApiKeys2 = buildInstitutionApiKeys("not from BO API key"); + + when(apimClient.getApiSubscriptions(INSTITUTION_ID)).thenReturn(List.of(institutionApiKeys1, institutionApiKeys2)); + when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionsSegregationCodeAssociatedToBroker(anyString())) + .thenReturn(buildCreditorInstitutionStationSegregationCodesList()); + when(authorizerConfigClient.getAuthorization(anyString())).thenReturn( + buildAuthorizationWithSegregationCodes(CI_TAX_CODE), + buildAuthorizationWithSegregationCodes("pippo") + ); + + assertDoesNotThrow(() -> service.updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, CI_TAX_CODE)); + + verify(apimClient).getApiSubscriptions(INSTITUTION_ID); + verify(authorizerConfigClient, times(2)).deleteAuthorization(anyString()); + verify(authorizerConfigClient, times(2)).createAuthorization(any()); + } + + private Authorization buildAuthorizationWithSegregationCodes(String ciTaxCode) { + List keyValues = new ArrayList<>(); + keyValues.add( + AuthorizationGenericKeyValue.builder() + .key(ciTaxCode) + .values(Collections.singletonList("02")) + .build()); + List metadata = new ArrayList<>(); + metadata.add(AuthorizationMetadata.builder() + .name("Segregation codes") + .shortKey("_seg") + .content(keyValues) + .build()); + return Authorization.builder() + .id("auth-id") + .otherMetadata(metadata) + .build(); } private InstitutionApiKeys buildInstitutionApiKeys(String subscriptionId) { @@ -383,4 +488,14 @@ public List createDelegations() { return delegationExternals; } + private CreditorInstitutionStationSegregationCodesList buildCreditorInstitutionStationSegregationCodesList() { + return CreditorInstitutionStationSegregationCodesList.builder() + .ciStationCodes(Arrays.asList( + CreditorInstitutionStationSegregationCodes.builder() + .ciTaxCode(CI_TAX_CODE) + .segregationCodes(List.of("01", "14")) + .build() + )) + .build(); + } } diff --git a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java index 586f27c64..ff1cf31df 100644 --- a/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java +++ b/src/test/java/it/pagopa/selfcare/pagopa/backoffice/service/CreditorInstitutionServiceTest.java @@ -12,6 +12,7 @@ import it.pagopa.selfcare.pagopa.backoffice.model.connector.broker.Brokers; import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.ApiConfigCreditorInstitutionsOrderBy; import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.AvailableCodes; +import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.CreditorInstitution; import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.CreditorInstitutionDetails; import it.pagopa.selfcare.pagopa.backoffice.model.connector.creditorinstitution.CreditorInstitutions; import it.pagopa.selfcare.pagopa.backoffice.model.connector.station.CreditorInstitutionStationEdit; @@ -61,7 +62,6 @@ import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -76,6 +76,10 @@ class CreditorInstitutionServiceTest { private static final String STATION_CODE = "stationCode"; private static final String CI_TAX_CODE_1 = "12345677"; private static final String CI_TAX_CODE_2 = "12345666"; + private static final String INSTITUTION_ID = "institutionId"; + private static final String BROKER_TAX_CODE = "brokerTaxCode"; + private static final String CI_TAX_CODE = "12345678900"; + private static final String STATION_CODE1 = "00000000000_01"; @MockBean private ApiConfigClient apiConfigClient; @@ -89,6 +93,9 @@ class CreditorInstitutionServiceTest { @MockBean private ExternalApiClient externalApiClient; + @MockBean + private ApiManagementService apiManagementService; + @Autowired private CreditorInstitutionService service; @@ -168,7 +175,7 @@ void getCreditorInstitutionDetails_ok() throws IOException { when(apiConfigClient.getCreditorInstitutionDetails(anyString())) .thenReturn(TestUtil.fileToObject("response/apiconfig/get_creditor_institution_details_ok.json", CreditorInstitutionDetails.class)); - CreditorInstitutionDetailsResource result = service.getCreditorInstitutionDetails("12345678900"); + CreditorInstitutionDetailsResource result = service.getCreditorInstitutionDetails(CI_TAX_CODE); assertNotNull(result); } @@ -178,7 +185,7 @@ void getCreditorInstitutionDetails_ko() { FeignException feignException = mock(FeignException.InternalServerError.class); when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(feignException); - assertThrows(FeignException.class, () -> service.getCreditorInstitutionDetails("12345678900")); + assertThrows(FeignException.class, () -> service.getCreditorInstitutionDetails(CI_TAX_CODE)); } @Test @@ -186,7 +193,7 @@ void getCreditorInstitutionSegregationCodes_ok() { when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionSegregationCodes(anyString(), anyString())) .thenReturn(AvailableCodes.builder().availableCodeList(Collections.singletonList("2")).build()); - AvailableCodes result = assertDoesNotThrow(() -> service.getCreditorInstitutionSegregationCodes("12345678900", "111111")); + AvailableCodes result = assertDoesNotThrow(() -> service.getCreditorInstitutionSegregationCodes(CI_TAX_CODE, "111111")); assertNotNull(result); } @@ -196,7 +203,7 @@ void getCreditorInstitutionSegregationCodes_ko() { FeignException feignException = mock(FeignException.InternalServerError.class); when(apiConfigSelfcareIntegrationClient.getCreditorInstitutionSegregationCodes(anyString(), anyString())).thenThrow(feignException); - assertThrows(FeignException.class, () -> service.getCreditorInstitutionSegregationCodes("12345678900", "111111")); + assertThrows(FeignException.class, () -> service.getCreditorInstitutionSegregationCodes(CI_TAX_CODE, "111111")); } @Test @@ -206,19 +213,41 @@ void associateStationToCreditorInstitution_ok() throws IOException { .thenReturn(TestUtil.fileToObject("response/apiconfig/post_creditor_institution_station_association_ok.json", CreditorInstitutionStationEdit.class)); CreditorInstitutionStationDto dto = TestUtil.fileToObject("request/post_creditor_institution_station_association.json", CreditorInstitutionStationDto.class); - CreditorInstitutionStationEditResource result = service.associateStationToCreditorInstitution("12345678900", dto); + CreditorInstitutionStationEditResource result = service.associateStationToCreditorInstitution(CI_TAX_CODE, INSTITUTION_ID, BROKER_TAX_CODE, dto); assertNotNull(result); + + verify(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, BROKER_TAX_CODE); } @Test void associateStationToCreditorInstitution_ko() throws IOException { - FeignException feignException = mock(FeignException.InternalServerError.class); - when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(feignException); + when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(FeignException.InternalServerError.class); CreditorInstitutionStationDto dto = TestUtil.fileToObject("request/post_creditor_institution_station_association.json", CreditorInstitutionStationDto.class); - assertThrows(AppException.class, () -> service.associateStationToCreditorInstitution("12345678900", dto)); - verify(apiConfigClient, times(0)).createCreditorInstitutionStationRelationship(anyString(), any(CreditorInstitutionStationEdit.class)); + assertThrows(AppException.class, () -> service.associateStationToCreditorInstitution(CI_TAX_CODE, INSTITUTION_ID, BROKER_TAX_CODE, dto)); + + verify(apiConfigClient, never()).createCreditorInstitutionStationRelationship(anyString(), any(CreditorInstitutionStationEdit.class)); + verify(apiManagementService, never()).updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, BROKER_TAX_CODE); + } + + @Test + void associateStationToCreditorInstitutionFailOnAuthorizerUpdateExpectRollback() throws IOException { + when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenReturn(new CreditorInstitutionDetails()); + when(apiConfigClient.createCreditorInstitutionStationRelationship(anyString(), any(CreditorInstitutionStationEdit.class))) + .thenReturn( + TestUtil.fileToObject( + "response/apiconfig/post_creditor_institution_station_association_ok.json", + CreditorInstitutionStationEdit.class) + ); + doThrow(AppException.class).when(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(anyString(), anyString()); + + CreditorInstitutionStationDto dto = + TestUtil.fileToObject("request/post_creditor_institution_station_association.json", CreditorInstitutionStationDto.class); + assertThrows(AppException.class, () -> service.associateStationToCreditorInstitution(CI_TAX_CODE, INSTITUTION_ID, BROKER_TAX_CODE, dto)); + + verify(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, BROKER_TAX_CODE); + verify(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); } @Test @@ -228,34 +257,48 @@ void updateStationAssociationToCreditorInstitution_ok() throws IOException { .thenReturn(TestUtil.fileToObject("response/apiconfig/post_creditor_institution_station_association_ok.json", CreditorInstitutionStationEdit.class)); CreditorInstitutionStationDto dto = TestUtil.fileToObject("request/post_creditor_institution_station_association.json", CreditorInstitutionStationDto.class); - CreditorInstitutionStationEditResource result = service.updateStationAssociationToCreditorInstitution("12345678900", dto); + CreditorInstitutionStationEditResource result = service.updateStationAssociationToCreditorInstitution(CI_TAX_CODE, dto); assertNotNull(result); } @Test - void updateStationAssociationToCreditorInstitutio_ko() throws IOException { + void updateStationAssociationToCreditorInstitution_ko() throws IOException { FeignException feignException = mock(FeignException.InternalServerError.class); when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(feignException); CreditorInstitutionStationDto dto = TestUtil.fileToObject("request/post_creditor_institution_station_association.json", CreditorInstitutionStationDto.class); - assertThrows(AppException.class, () -> service.updateStationAssociationToCreditorInstitution("12345678900", dto)); + assertThrows(AppException.class, () -> service.updateStationAssociationToCreditorInstitution(CI_TAX_CODE, dto)); verify(apiConfigClient, times(0)).updateCreditorInstitutionStationRelationship(anyString(), anyString(),any(CreditorInstitutionStationEdit.class)); } @Test void deleteCreditorInstitutionStationRelationship_ok() { - doNothing().when(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); + assertDoesNotThrow(() -> service.deleteCreditorInstitutionStationRelationship(CI_TAX_CODE, STATION_CODE1, INSTITUTION_ID, BROKER_TAX_CODE)); - assertDoesNotThrow(() -> service.deleteCreditorInstitutionStationRelationship("12345678900", "00000000000_01")); + verify(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); + verify(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(INSTITUTION_ID, BROKER_TAX_CODE); } @Test void deleteCreditorInstitutionStationRelationship_ko() { - FeignException feignException = mock(FeignException.InternalServerError.class); - doThrow(feignException).when(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); + doThrow(FeignException.InternalServerError.class).when(apiConfigClient) + .deleteCreditorInstitutionStationRelationship(anyString(), anyString()); - assertThrows(FeignException.class, () -> service.deleteCreditorInstitutionStationRelationship("12345678900", "00000000000_01")); + assertThrows(FeignException.class, () -> + service.deleteCreditorInstitutionStationRelationship(CI_TAX_CODE, STATION_CODE1, INSTITUTION_ID, BROKER_TAX_CODE)); + } + + @Test + void deleteCreditorInstitutionStationRelationshipFailOnAuthorizerUpdateExpectRollback() { + doThrow(AppException.class).when(apiManagementService).updateBrokerAuthorizerSegregationCodesMetadata(anyString(), anyString()); + when(apiConfigClient.getCreditorInstitutionsByStation(STATION_CODE1, 1, 0, CI_TAX_CODE)) + .thenReturn(buildCreditorInstitutions()); + assertThrows(AppException.class, () -> + service.deleteCreditorInstitutionStationRelationship(CI_TAX_CODE, STATION_CODE1, INSTITUTION_ID, BROKER_TAX_CODE)); + + verify(apiConfigClient).deleteCreditorInstitutionStationRelationship(anyString(), anyString()); + verify(apiConfigClient).createCreditorInstitutionStationRelationship(anyString(), any()); } @Test @@ -307,7 +350,7 @@ void updateCreditorInstitution_ok() throws IOException { .thenReturn(TestUtil.fileToObject("response/apiconfig/post_creditor_institution_ok.json", CreditorInstitutionDetails.class)); UpdateCreditorInstitutionDto dto = TestUtil.fileToObject("request/post_creditor_institution.json", UpdateCreditorInstitutionDto.class); - CreditorInstitutionDetailsResource result = service.updateCreditorInstitutionDetails("12345678900", dto); + CreditorInstitutionDetailsResource result = service.updateCreditorInstitutionDetails(CI_TAX_CODE, dto); assertNotNull(result); } @@ -318,7 +361,7 @@ void updateCreditorInstitution_ko() throws IOException { when(apiConfigClient.updateCreditorInstitutionDetails(anyString(), any(CreditorInstitutionDetails.class))).thenThrow(feignException); UpdateCreditorInstitutionDto dto = TestUtil.fileToObject("request/post_creditor_institution.json", UpdateCreditorInstitutionDto.class); - assertThrows(FeignException.class, () -> service.updateCreditorInstitutionDetails("12345678900", dto)); + assertThrows(FeignException.class, () -> service.updateCreditorInstitutionDetails(CI_TAX_CODE, dto)); } @ParameterizedTest @@ -331,7 +374,7 @@ void getBrokerAndEcDetails_ok(String existsBroker, String existsCI) throws IOExc FeignException feignException = mock(FeignException.NotFound.class); boolean isBrokerExistent = "true".equals(existsBroker); boolean isCIExistent = "true".equals(existsCI); - String brokerCode = "12345678900"; + String brokerCode = CI_TAX_CODE; if (isBrokerExistent) { when(apiConfigClient.getBrokersEC(1, 0, brokerCode, null, null, "ASC")) @@ -346,7 +389,7 @@ void getBrokerAndEcDetails_ok(String existsBroker, String existsCI) throws IOExc when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(feignException); } - BrokerAndEcDetailsResource result = service.getBrokerAndEcDetails("12345678900"); + BrokerAndEcDetailsResource result = service.getBrokerAndEcDetails(CI_TAX_CODE); assertNotNull(result); if (isBrokerExistent) { @@ -367,7 +410,7 @@ void getBrokerAndEcDetails_ko() { when(apiConfigClient.getBrokersEC(anyInt(), anyInt(), anyString(), anyString(), anyString(), anyString())).thenThrow(feignException); when(apiConfigClient.getCreditorInstitutionDetails(anyString())).thenThrow(feignException); - assertThrows(AppException.class, () -> service.getBrokerAndEcDetails("12345678900")); + assertThrows(AppException.class, () -> service.getBrokerAndEcDetails(CI_TAX_CODE)); } @Test @@ -376,14 +419,14 @@ void getCreditorInstitutionContactsSuccess() { InstitutionProductUsers users = buildInstitutionProductUsers(); when(operativeTableRepository.findByTaxCode("ciTaxCode")).thenReturn(Optional.of(entity)); when(externalApiClient.getInstitutionProductUsers( - "institutionId", + INSTITUTION_ID, null, null, Collections.singletonList(SelfcareProductUser.ADMIN.getProductUser())) ).thenReturn(Collections.singletonList(users)); CreditorInstitutionContactsResource result = assertDoesNotThrow(() -> - service.getCreditorInstitutionContacts("ciTaxCode", "institutionId")); + service.getCreditorInstitutionContacts("ciTaxCode", INSTITUTION_ID)); assertNotNull(result); assertNotNull(result.getOperativeTable()); @@ -405,14 +448,14 @@ void getCreditorInstitutionContactsWithOperativeTableNotFound() { InstitutionProductUsers users = buildInstitutionProductUsers(); when(operativeTableRepository.findByTaxCode("ciTaxCode")).thenReturn(Optional.empty()); when(externalApiClient.getInstitutionProductUsers( - "institutionId", + INSTITUTION_ID, null, null, Collections.singletonList(SelfcareProductUser.ADMIN.getProductUser())) ).thenReturn(Collections.singletonList(users)); CreditorInstitutionContactsResource result = assertDoesNotThrow(() -> - service.getCreditorInstitutionContacts("ciTaxCode", "institutionId")); + service.getCreditorInstitutionContacts("ciTaxCode", INSTITUTION_ID)); assertNotNull(result); assertNull(result.getOperativeTable()); @@ -677,4 +720,23 @@ private DelegationExternal buildDelegation(String institutionType, String taxCod private InstitutionResponse buildInstitutionResponse(InstitutionType institutionType, String taxCode) { return InstitutionResponse.builder().description("Broker").taxCode(taxCode).institutionType(institutionType).build(); } + + private CreditorInstitutions buildCreditorInstitutions() { + return CreditorInstitutions.builder() + .creditorInstitutionList(Collections.singletonList( + CreditorInstitution.builder() + .aca(true) + .standIn(true) + .creditorInstitutionCode(CI_TAX_CODE) + .mod4(false) + .applicationCode(null) + .segregationCode(2L) + .auxDigit(null) + .broadcast(false) + .enabled(true) + .cbillCode("cbill") + .build() + )) + .build(); + } } diff --git a/src/test/resources/response/apiconfig/get_creditor_institution_details_ok.json b/src/test/resources/response/apiconfig/get_creditor_institution_details_ok.json index d97786d7c..2690cd44f 100644 --- a/src/test/resources/response/apiconfig/get_creditor_institution_details_ok.json +++ b/src/test/resources/response/apiconfig/get_creditor_institution_details_ok.json @@ -3,10 +3,10 @@ "enabled": true, "business_name": "Comune XYZ", "cbill_code": "COXYZ", - "application_code": "01", - "aux_digit": "03", - "segregation_code": "02", - "mod4": "x", + "application_code": 1, + "aux_digit": 3, + "segregation_code": 2, + "mod4": false, "broadcast": false, "address": { "location": "via Roma 1", diff --git a/src/test/resources/response/apiconfig/post_creditor_institution_ok.json b/src/test/resources/response/apiconfig/post_creditor_institution_ok.json index d97786d7c..2690cd44f 100644 --- a/src/test/resources/response/apiconfig/post_creditor_institution_ok.json +++ b/src/test/resources/response/apiconfig/post_creditor_institution_ok.json @@ -3,10 +3,10 @@ "enabled": true, "business_name": "Comune XYZ", "cbill_code": "COXYZ", - "application_code": "01", - "aux_digit": "03", - "segregation_code": "02", - "mod4": "x", + "application_code": 1, + "aux_digit": 3, + "segregation_code": 2, + "mod4": false, "broadcast": false, "address": { "location": "via Roma 1",