diff --git a/src/main/resources/interface-specification.yml b/src/main/resources/interface-specification.yml index 043bb19e..fb5aae3a 100644 --- a/src/main/resources/interface-specification.yml +++ b/src/main/resources/interface-specification.yml @@ -714,10 +714,12 @@ paths: required: true schema: type: string - - name: tenantKind + - name: eserviceId in: query + required: true schema: - $ref: '#/components/schemas/TenantKind' + type: string + format: uuid get: tags: - purpose diff --git a/src/main/scala/it/pagopa/interop/purposeprocess/api/impl/PurposeApiServiceImpl.scala b/src/main/scala/it/pagopa/interop/purposeprocess/api/impl/PurposeApiServiceImpl.scala index b253fa09..984dbced 100644 --- a/src/main/scala/it/pagopa/interop/purposeprocess/api/impl/PurposeApiServiceImpl.scala +++ b/src/main/scala/it/pagopa/interop/purposeprocess/api/impl/PurposeApiServiceImpl.scala @@ -655,8 +655,7 @@ final case class PurposeApiServiceImpl( } } - override def retrieveRiskAnalysisConfigurationByVersion(tenantKind: Option[String], riskAnalysisVersion: String)( - implicit + override def retrieveRiskAnalysisConfigurationByVersion(eserviceId: String, riskAnalysisVersion: String)(implicit contexts: Seq[(String, String)], toEntityMarshallerRiskAnalysisFormConfigResponse: ToEntityMarshaller[RiskAnalysisFormConfigResponse], toEntityMarshallerProblem: ToEntityMarshaller[Problem] @@ -665,12 +664,14 @@ final case class PurposeApiServiceImpl( logger.info(operationLabel) val result: Future[RiskAnalysisFormConfigResponse] = for { - organizationId <- getOrganizationIdFutureUUID(contexts) - tenant <- tenantManagementService.getTenantById(organizationId) - tenantKindParam <- tenantKind.traverse(TenantKind.fromValue).toFuture - kind <- tenantKindParam.fold(tenant.kind.toFuture(TenantKindNotFound(tenant.id)))(kind => - Future.successful(kind.toPersistent) - ) + organizationId <- getOrganizationIdFutureUUID(contexts) + eserviceId <- eserviceId.toFutureUUID + eservice <- catalogManagementService.getEServiceById(eserviceId) + tenant <- eservice.mode match { + case Deliver => tenantManagementService.getTenantById(organizationId) + case Receive => tenantManagementService.getTenantById(eservice.producerId) + } + kind <- tenant.kind.fold(tenant.kind.toFuture(TenantKindNotFound(tenant.id)))(kind => Future.successful(kind)) kindConfig <- RiskAnalysisService .riskAnalysisForms() .get(kind.toTemplate) diff --git a/src/test/scala/it/pagopa/interop/purposeprocess/PurposeApiServiceSpec.scala b/src/test/scala/it/pagopa/interop/purposeprocess/PurposeApiServiceSpec.scala index 5ae369d9..537ada91 100644 --- a/src/test/scala/it/pagopa/interop/purposeprocess/PurposeApiServiceSpec.scala +++ b/src/test/scala/it/pagopa/interop/purposeprocess/PurposeApiServiceSpec.scala @@ -12,7 +12,8 @@ import it.pagopa.interop.purposeprocess.error.PurposeProcessErrors.{ EServiceNotFound, PurposeNotFound, PurposeVersionDocumentNotFound, - PurposeVersionNotFound + PurposeVersionNotFound, + TenantNotFound } import it.pagopa.interop.purposeprocess.model._ import org.scalatest.concurrent.ScalaFutures @@ -2509,62 +2510,235 @@ class PurposeApiServiceSpec extends AnyWordSpecLike with SpecHelper with Scalate } "Purpose Risk Analysis Configuration for retrieving a specified version " should { - "succeed when Tenant kind is PA" in { + "succeed when Tenant kind is PA and eService is Receive" in { val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> UUID.randomUUID().toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns(Future.successful(SpecData.eService.copy(id = eServiceId, producerId = producerId, mode = Receive))) + + (mockTenantManagementService + .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(producerId, *, *) + .once() + .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.PA.some))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "2.0") ~> check { + status shouldEqual StatusCodes.OK + responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "2.0" + } + } + + "succeed when Tenant kind is PRIVATE and eService is Receive" in { + + val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> UUID.randomUUID().toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns(Future.successful(SpecData.eService.copy(id = eServiceId, producerId = producerId, mode = Receive))) + + (mockTenantManagementService + .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(producerId, *, *) + .once() + .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.PRIVATE.some))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { + status shouldEqual StatusCodes.OK + responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "1.0" + } + } + + "succeed when Tenant kind is GSP and eService is Receive" in { + + val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> UUID.randomUUID().toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns(Future.successful(SpecData.eService.copy(id = eServiceId, producerId = producerId, mode = Receive))) + + (mockTenantManagementService + .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(producerId, *, *) + .once() + .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.GSP.some))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { + status shouldEqual StatusCodes.OK + responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "1.0" + } + } + "succeed when Tenant kind is PA and eService is Deliver" in { + + val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> producerId.toString) + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns( + Future.successful(SpecData.eService.copy(id = eServiceId, producerId = UUID.randomUUID(), mode = Deliver)) + ) + (mockTenantManagementService .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) .expects(producerId, *, *) .once() .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.PA.some))) - Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(Some("PA"), "2.0") ~> check { + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "2.0") ~> check { status shouldEqual StatusCodes.OK responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "2.0" } } - "succeed when Tenant kind is PRIVATE" in { + "succeed when Tenant kind is PRIVATE and eService is Deliver" in { val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> producerId.toString) + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns( + Future.successful(SpecData.eService.copy(id = eServiceId, producerId = UUID.randomUUID(), mode = Deliver)) + ) + (mockTenantManagementService .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) .expects(producerId, *, *) .once() .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.PRIVATE.some))) - Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(None, "1.0") ~> check { + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { status shouldEqual StatusCodes.OK responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "1.0" } } - "succeed when Tenant kind is GSP" in { + "succeed when Tenant kind is GSP and eService is Deliver" in { val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> producerId.toString) + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns( + Future.successful(SpecData.eService.copy(id = eServiceId, producerId = UUID.randomUUID(), mode = Deliver)) + ) + (mockTenantManagementService .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) .expects(producerId, *, *) .once() .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = PersistentTenantKind.GSP.some))) - Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(None, "1.0") ~> check { + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { status shouldEqual StatusCodes.OK responseAs[RiskAnalysisFormConfigResponse].version shouldEqual "1.0" } } + "fail when eService is not found" in { + + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> UUID.randomUUID().toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns(Future.failed(EServiceNotFound(eServiceId))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { + status shouldEqual StatusCodes.InternalServerError + } + } + "fail when Tenant not found" in { + + val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> producerId.toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns( + Future.successful(SpecData.eService.copy(id = eServiceId, producerId = UUID.randomUUID(), mode = Deliver)) + ) + + (mockTenantManagementService + .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(producerId, *, *) + .once() + .returns(Future.failed(TenantNotFound(producerId))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { + status shouldEqual StatusCodes.InternalServerError + } + } + "fail when Tenant kind not found" in { + + val producerId: UUID = UUID.randomUUID() + val eServiceId: UUID = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> producerId.toString) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eServiceId, *, *) + .once() + .returns( + Future.successful(SpecData.eService.copy(id = eServiceId, producerId = UUID.randomUUID(), mode = Deliver)) + ) + + (mockTenantManagementService + .getTenantById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(producerId, *, *) + .once() + .returns(Future.successful(SpecData.tenant.copy(id = producerId, kind = None))) + + Get() ~> service.retrieveRiskAnalysisConfigurationByVersion(eServiceId.toString, "1.0") ~> check { + status shouldEqual StatusCodes.InternalServerError + } + } } "Purpose Risk Analysis Document" should { diff --git a/src/test/scala/it/pagopa/interop/purposeprocess/authz/PurposeApiAuthzSpec.scala b/src/test/scala/it/pagopa/interop/purposeprocess/authz/PurposeApiAuthzSpec.scala index 92507628..e94d45bd 100644 --- a/src/test/scala/it/pagopa/interop/purposeprocess/authz/PurposeApiAuthzSpec.scala +++ b/src/test/scala/it/pagopa/interop/purposeprocess/authz/PurposeApiAuthzSpec.scala @@ -217,7 +217,9 @@ class PurposeApiAuthzSpec extends AnyWordSpecLike with BeforeAndAfterAll with Au val endpoint = AuthorizedRoutes.endpoints("retrieveRiskAnalysisConfigurationByVersion") validateAuthorization( endpoint, - { implicit c: Seq[(String, String)] => service.retrieveRiskAnalysisConfigurationByVersion(None, "fake") } + { implicit c: Seq[(String, String)] => + service.retrieveRiskAnalysisConfigurationByVersion(UUID.randomUUID().toString, "fake") + } ) }