From 3a5b6e1d25d630c8a9c39a197ecf35ad8729c4c1 Mon Sep 17 00:00:00 2001 From: Simone Camito Date: Tue, 12 Nov 2024 16:00:06 +0100 Subject: [PATCH 1/3] add attribute check on delegate and delegator --- .../src/api/catalogApiConverter.ts | 10 ++++++--- .../src/services/catalogService.ts | 22 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/backend-for-frontend/src/api/catalogApiConverter.ts b/packages/backend-for-frontend/src/api/catalogApiConverter.ts index a04d60189f..6449b47a3b 100644 --- a/packages/backend-for-frontend/src/api/catalogApiConverter.ts +++ b/packages/backend-for-frontend/src/api/catalogApiConverter.ts @@ -92,7 +92,7 @@ export function toBffCatalogDescriptorEService( descriptor: catalogApi.EServiceDescriptor, producerTenant: tenantApi.Tenant, agreement: agreementApi.Agreement | undefined, - requesterTenant: tenantApi.Tenant + requesterTenants: tenantApi.Tenant[] ): bffApi.CatalogDescriptorEService { const activeDescriptor = getLatestActiveDescriptor(eservice); return { @@ -107,8 +107,12 @@ export function toBffCatalogDescriptorEService( technology: eservice.technology, descriptors: getNotDraftDescriptor(eservice).map(toCompactDescriptor), agreement: agreement && toBffCompactAgreement(agreement, eservice), - isMine: isRequesterEserviceProducer(requesterTenant.id, eservice), - hasCertifiedAttributes: hasCertifiedAttributes(descriptor, requesterTenant), + isMine: requesterTenants.some((t) => + isRequesterEserviceProducer(t.id, eservice) + ), + hasCertifiedAttributes: requesterTenants.some((t) => + hasCertifiedAttributes(descriptor, t) + ), isSubscribed: isAgreementSubscribed(agreement), activeDescriptor: activeDescriptor ? toCompactDescriptor(activeDescriptor) diff --git a/packages/backend-for-frontend/src/services/catalogService.ts b/packages/backend-for-frontend/src/services/catalogService.ts index 468a8d66dd..a23c3d1a86 100644 --- a/packages/backend-for-frontend/src/services/catalogService.ts +++ b/packages/backend-for-frontend/src/services/catalogService.ts @@ -62,6 +62,10 @@ import { assertNotDelegatedEservice, assertRequesterIsProducer, } from "./validators.js"; +import { + getAllDelegations, + getTenantsFromDelegation, +} from "./delegationService.js"; export type CatalogService = ReturnType; @@ -528,12 +532,16 @@ export function catalogServiceBuilder( descriptor ); - const requesterTenant = await tenantProcessClient.tenant.getTenant({ - headers, - params: { - id: requesterId, - }, - }); + const requesterTenants = await getTenantsFromDelegation( + tenantProcessClient, + await getAllDelegations(delegationProcessClient, headers, { + delegateIds: [requesterId], + delegationStates: ["ACTIVE"], + kind: "DELEGATED_CONSUMER", + eserviceIds: [eserviceId], + }), + headers + ); const producerTenant = await tenantProcessClient.tenant.getTenant({ headers, params: { @@ -571,7 +579,7 @@ export function catalogServiceBuilder( descriptor, producerTenant, agreement, - requesterTenant + Array.from(requesterTenants, ([, tenant]) => tenant) ), }; }, From eb1452fccb824503740a5da8db020dcfc8b28039 Mon Sep 17 00:00:00 2001 From: Simone Camito Date: Thu, 21 Nov 2024 17:16:12 +0100 Subject: [PATCH 2/3] fix review comments --- packages/api-clients/open-api/bffApi.yml | 5 ++++ .../src/api/catalogApiConverter.ts | 15 ++++++---- .../src/services/catalogService.ts | 29 ++++++++++++++++--- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/api-clients/open-api/bffApi.yml b/packages/api-clients/open-api/bffApi.yml index 2c9ab3e0e7..162fbe47e2 100644 --- a/packages/api-clients/open-api/bffApi.yml +++ b/packages/api-clients/open-api/bffApi.yml @@ -13172,6 +13172,11 @@ components: type: boolean hasCertifiedAttributes: type: boolean + description: > + True in case: + - the requester has the certified attributes required to consume the eservice, or + - the requester is the delegated consumer for the eservice and + the delegator has the certified attributes required to consume the eservice isSubscribed: type: boolean activeDescriptor: diff --git a/packages/backend-for-frontend/src/api/catalogApiConverter.ts b/packages/backend-for-frontend/src/api/catalogApiConverter.ts index 6449b47a3b..b6290bbb74 100644 --- a/packages/backend-for-frontend/src/api/catalogApiConverter.ts +++ b/packages/backend-for-frontend/src/api/catalogApiConverter.ts @@ -92,7 +92,8 @@ export function toBffCatalogDescriptorEService( descriptor: catalogApi.EServiceDescriptor, producerTenant: tenantApi.Tenant, agreement: agreementApi.Agreement | undefined, - requesterTenants: tenantApi.Tenant[] + requesterTenant: tenantApi.Tenant, + consumerDelegators: tenantApi.Tenant[] ): bffApi.CatalogDescriptorEService { const activeDescriptor = getLatestActiveDescriptor(eservice); return { @@ -107,11 +108,13 @@ export function toBffCatalogDescriptorEService( technology: eservice.technology, descriptors: getNotDraftDescriptor(eservice).map(toCompactDescriptor), agreement: agreement && toBffCompactAgreement(agreement, eservice), - isMine: requesterTenants.some((t) => - isRequesterEserviceProducer(t.id, eservice) - ), - hasCertifiedAttributes: requesterTenants.some((t) => - hasCertifiedAttributes(descriptor, t) + isMine: isRequesterEserviceProducer(requesterTenant.id, eservice), + hasCertifiedAttributes: [requesterTenant, ...consumerDelegators].some( + (t) => hasCertifiedAttributes(descriptor, t) + /* True in case: + - the requester has the certified attributes required to consume the eservice, or + - the requester is the delegated consumer for the eservice and + the delegator has the certified attributes required to consume the eservice */ ), isSubscribed: isAgreementSubscribed(agreement), activeDescriptor: activeDescriptor diff --git a/packages/backend-for-frontend/src/services/catalogService.ts b/packages/backend-for-frontend/src/services/catalogService.ts index a23c3d1a86..93d4aed7ea 100644 --- a/packages/backend-for-frontend/src/services/catalogService.ts +++ b/packages/backend-for-frontend/src/services/catalogService.ts @@ -3,7 +3,12 @@ /* eslint-disable functional/immutable-data */ import { randomUUID } from "crypto"; import AdmZip from "adm-zip"; -import { bffApi, catalogApi, tenantApi } from "pagopa-interop-api-clients"; +import { + bffApi, + catalogApi, + delegationApi, + tenantApi, +} from "pagopa-interop-api-clients"; import { FileManager, WithLogger, @@ -26,6 +31,7 @@ import { invalidZipStructure, missingDescriptorInClonedEservice, noDescriptorInEservice, + tenantNotFound, } from "../model/errors.js"; import { getLatestActiveDescriptor } from "../model/modelMappingUtils.js"; import { @@ -536,12 +542,26 @@ export function catalogServiceBuilder( tenantProcessClient, await getAllDelegations(delegationProcessClient, headers, { delegateIds: [requesterId], - delegationStates: ["ACTIVE"], - kind: "DELEGATED_CONSUMER", + delegationStates: [delegationApi.DelegationState.Values.ACTIVE], + kind: delegationApi.DelegationKind.Values.DELEGATED_CONSUMER, eserviceIds: [eserviceId], }), headers ); + + const delegationTenants = Array.from(requesterTenants.values()); + const requesterTenant = delegationTenants.find( + (t) => t.id === requesterId + ); + + if (!requesterTenant) { + throw tenantNotFound(requesterId); + } + + const consumerDelegators = delegationTenants.filter( + (t) => t.id !== requesterId + ); + const producerTenant = await tenantProcessClient.tenant.getTenant({ headers, params: { @@ -579,7 +599,8 @@ export function catalogServiceBuilder( descriptor, producerTenant, agreement, - Array.from(requesterTenants, ([, tenant]) => tenant) + requesterTenant, + consumerDelegators ), }; }, From 3d2fb190757d29d4991c461428fa57867eccc926 Mon Sep 17 00:00:00 2001 From: Simone Camito Date: Tue, 26 Nov 2024 15:07:09 +0100 Subject: [PATCH 3/3] fix bug in case of missing delegation --- .../src/services/catalogService.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/backend-for-frontend/src/services/catalogService.ts b/packages/backend-for-frontend/src/services/catalogService.ts index 93d4aed7ea..e6594db0be 100644 --- a/packages/backend-for-frontend/src/services/catalogService.ts +++ b/packages/backend-for-frontend/src/services/catalogService.ts @@ -538,7 +538,17 @@ export function catalogServiceBuilder( descriptor ); - const requesterTenants = await getTenantsFromDelegation( + const requesterTenant = await tenantProcessClient.tenant.getTenant({ + headers, + params: { + id: requesterId, + }, + }); + if (!requesterTenant) { + throw tenantNotFound(requesterId); + } + + const delegationTenantsSet = await getTenantsFromDelegation( tenantProcessClient, await getAllDelegations(delegationProcessClient, headers, { delegateIds: [requesterId], @@ -549,15 +559,7 @@ export function catalogServiceBuilder( headers ); - const delegationTenants = Array.from(requesterTenants.values()); - const requesterTenant = delegationTenants.find( - (t) => t.id === requesterId - ); - - if (!requesterTenant) { - throw tenantNotFound(requesterId); - } - + const delegationTenants = Array.from(delegationTenantsSet.values()); const consumerDelegators = delegationTenants.filter( (t) => t.id !== requesterId );