Skip to content

Commit

Permalink
PIN-4023 Implemented Delete Risk Analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
nttdata-rtorsoli committed Sep 27, 2023
1 parent b54154b commit 506d9cd
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 3 deletions.
45 changes: 44 additions & 1 deletion src/main/resources/interface-specification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,50 @@ paths:
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
$ref: '#/components/schemas/Problem'
delete:
security:
- bearerAuth: []
tags:
- process
summary: Delete an e-service risk analysis
operationId: deleteRiskAnalysis
parameters:
- name: eServiceId
in: path
description: the eservice id
required: true
schema:
type: string
format: uuid
- name: riskAnalysisId
in: path
description: the eservice id
required: true
schema:
type: string
format: uuid
responses:
'204':
description: EService Risk Analysis deleted.
'403':
description: Bad request
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'404':
description: EService not found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'400':
description: Bad request
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
/status:
get:
security: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,26 @@ final case class ProcessApiServiceImpl(
updateRiskAnalysisResponse[Unit](operationLabel)(_ => updateRiskAnalysis204)
}
}

override def deleteRiskAnalysis(eServiceId: String, riskAnalysisId: String)(implicit
contexts: Seq[(String, String)],
toEntityMarshallerProblem: ToEntityMarshaller[Problem]
): Route = authorize(ADMIN_ROLE, API_ROLE) {
val operationLabel = s"Delete a Risk Analysis $riskAnalysisId for EService $eServiceId"
logger.info(operationLabel)

val result = for {
eServiceUuid <- eServiceId.toFutureUUID
riskAnalysisUuid <- riskAnalysisId.toFutureUUID
catalogItem <- catalogManagementService.getEServiceById(eServiceUuid)
_ <- isDraftEService(catalogItem)
_ <- catalogManagementService.deleteRiskAnalysis(eServiceUuid, riskAnalysisUuid)
} yield ()

onComplete(result) {
deleteRiskAnalysisResponse[Unit](operationLabel)(_ => deleteRiskAnalysis204)
}
}
}

object ProcessApiServiceImpl {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ object ResponseHandlers extends AkkaResponses {
case Failure(ex) => internalServerError(ex, logMessage)
}

def deleteRiskAnalysisResponse[T](logMessage: String)(
success: T => Route
)(result: Try[T])(implicit contexts: Seq[(String, String)], logger: LoggerTakingImplicit[ContextFieldsToLog]): Route =
result match {
case Success(s) => success(s)
case Failure(ex: EServiceNotFound) => notFound(ex, logMessage)
case Failure(ex: EServiceRiskAnalysisNotFound) => notFound(ex, logMessage)
case Failure(ex: EServiceNotInDraftState) => badRequest(ex, logMessage)
case Failure(ex) => internalServerError(ex, logMessage)
}

def updateEServiceByIdResponse[T](logMessage: String)(
success: T => Route
)(result: Try[T])(implicit contexts: Seq[(String, String)], logger: LoggerTakingImplicit[ContextFieldsToLog]): Route =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,6 @@ trait CatalogManagementService {
def updateRiskAnalysis(eServiceId: UUID, riskAnalysisId: UUID, riskAnalysisSeed: RiskAnalysisSeed)(implicit
contexts: Seq[(String, String)]
): Future[EServiceRiskAnalysis]

def deleteRiskAnalysis(eServiceId: UUID, riskAnalysisId: UUID)(implicit contexts: Seq[(String, String)]): Future[Unit]
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,23 @@ final case class CatalogManagementServiceImpl(invoker: CatalogManagementInvoker,
}
}

override def deleteRiskAnalysis(eServiceId: UUID, riskAnalysisId: UUID)(implicit
contexts: Seq[(String, String)]
): Future[Unit] = withHeaders { (bearerToken, correlationId, ip) =>
val request = api.deleteRiskAnalysis(
xCorrelationId = correlationId,
eServiceId = eServiceId,
riskAnalysisId = riskAnalysisId,
xForwardedFor = ip
)(BearerToken(bearerToken))
invoker
.invoke(request, s"Delete Risk Analysis $riskAnalysisId for E-Services $eServiceId")
.recoverWith {
case err: ApiError[_] if err.code == 404 =>
Future.failed(EServiceRiskAnalysisNotFound(eServiceId, riskAnalysisId))
}
}

private def getDocument(eService: CatalogItem, descriptorId: UUID, documentId: UUID): Option[CatalogDocument] = {

def lookup(catalogDescriptor: CatalogDescriptor): Option[CatalogDocument] = {
Expand Down
3 changes: 2 additions & 1 deletion src/test/resources/authz.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
},
{ "route": "deleteEService", "roles": ["admin", "api"], "verb": "DELETE" },
{ "route": "createRiskAnalysis", "roles": ["admin", "api"], "verb": "POST" },
{ "route": "updateRiskAnalysis", "roles": ["admin", "api"], "verb": "POST" }
{ "route": "updateRiskAnalysis", "roles": ["admin", "api"], "verb": "POST" },
{ "route": "deleteRiskAnalysis", "roles": ["admin", "api"], "verb": "DELETE" }
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2830,4 +2830,135 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR
}
}
}
"Risk Analysis delete" should {
"succeed" in {
val requesterId = UUID.randomUUID()
val riskAnalysisId = UUID.randomUUID()
val riskAnalysisFormId = UUID.randomUUID()
val single = UUID.randomUUID()
val multi = UUID.randomUUID()

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString)

val createdDate = OffsetDateTimeSupplier.get()

val descriptor =
SpecData.catalogDescriptor.copy(state = Draft)

val eService = SpecData.catalogItem.copy(
descriptors = Seq(descriptor),
producerId = requesterId,
riskAnalysis = Seq(
CatalogRiskAnalysis(
id = riskAnalysisId,
name = "OldName",
riskAnalysisForm = CatalogRiskAnalysisForm(
id = riskAnalysisFormId,
version = "3.0",
singleAnswers =
Seq(CatalogRiskAnalysisSingleAnswer(id = single, key = "purpose", value = Some("INSTITUTIONAL"))),
multiAnswers =
Seq(CatalogRiskAnalysisMultiAnswer(id = multi, key = "personalDataTypes", values = Seq("OTHER")))
),
createdAt = createdDate
)
),
mode = Receive
)

(mockCatalogManagementService
.getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(eService.id, *, *)
.once()
.returns(Future.successful(eService))

(mockCatalogManagementService
.deleteRiskAnalysis(_: UUID, _: UUID)(_: Seq[(String, String)]))
.expects(eService.id, riskAnalysisId, *)
.returning(Future.successful(()))
.once()

Post() ~> service.deleteRiskAnalysis(eService.id.toString, riskAnalysisId.toString) ~> check {
status shouldEqual StatusCodes.NoContent
}
}

"fail if Risk Analysis does not exists on EService" in {
val requesterId = UUID.randomUUID()
val riskAnalysisId = UUID.randomUUID()
val riskAnalysisFormId = UUID.randomUUID()
val single = UUID.randomUUID()
val multi = UUID.randomUUID()

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString)

val createdDate = OffsetDateTimeSupplier.get()

val descriptor =
SpecData.catalogDescriptor.copy(state = Draft)

val eService = SpecData.catalogItem.copy(
descriptors = Seq(descriptor),
producerId = requesterId,
riskAnalysis = Seq(
CatalogRiskAnalysis(
id = UUID.randomUUID(),
name = "OldName",
riskAnalysisForm = CatalogRiskAnalysisForm(
id = riskAnalysisFormId,
version = "3.0",
singleAnswers =
Seq(CatalogRiskAnalysisSingleAnswer(id = single, key = "purpose", value = Some("INSTITUTIONAL"))),
multiAnswers =
Seq(CatalogRiskAnalysisMultiAnswer(id = multi, key = "personalDataTypes", values = Seq("OTHER")))
),
createdAt = createdDate
)
),
mode = Receive
)

(mockCatalogManagementService
.getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(eService.id, *, *)
.once()
.returns(Future.successful(eService))

(mockCatalogManagementService
.deleteRiskAnalysis(_: UUID, _: UUID)(_: Seq[(String, String)]))
.expects(eService.id, riskAnalysisId, *)
.returning(Future.failed(EServiceRiskAnalysisNotFound(eService.id, riskAnalysisId)))
.once()

Post() ~> service.deleteRiskAnalysis(eService.id.toString, riskAnalysisId.toString) ~> check {
status shouldEqual StatusCodes.NotFound
}
}
"fail if descriptor is not DRAFT" in {
val requesterId = UUID.randomUUID()

implicit val context: Seq[(String, String)] =
Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString)

val descriptor =
SpecData.catalogDescriptor.copy(state = Published)

val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId, mode = Receive)

(mockCatalogManagementService
.getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(eService.id, *, *)
.once()
.returns(Future.successful(eService))

Post() ~> service.deleteRiskAnalysis(eService.id.toString, UUID.randomUUID().toString) ~> check {
status shouldEqual StatusCodes.BadRequest
val problem = responseAs[Problem]
problem.status shouldBe StatusCodes.BadRequest.intValue
problem.errors.head.code shouldBe "009-0012"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,5 +234,15 @@ class ProcessApiAuthzSpec extends AnyWordSpecLike with BeforeAndAfterAll with Au
}
)
}

"accept authorized roles for deleteRiskAnalysis" in {
val endpoint = AuthorizedRoutes.endpoints("deleteRiskAnalysis")
validateAuthorization(
endpoint,
{ implicit c: Seq[(String, String)] =>
service.deleteRiskAnalysis(UUID.randomUUID().toString, UUID.randomUUID().toString)
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,11 @@ object FakeDependencies {
)
)
)
}

override def deleteRiskAnalysis(eServiceId: UUID, riskAnalysisId: UUID)(implicit
contexts: Seq[(String, String)]
): Future[Unit] = Future.successful(())
}
class FakeAuthorizationManagementService extends AuthorizationManagementService {
override def updateStateOnClients(
eServiceId: UUID,
Expand Down

0 comments on commit 506d9cd

Please sign in to comment.