Skip to content

Commit

Permalink
PIN-4999 BKE - Auth process - SECURITY role is not allowed to delete …
Browse files Browse the repository at this point in the history
…keys if it is not longer a client member
  • Loading branch information
nttdata-rtorsoli committed Jun 20, 2024
1 parent 0ea8adc commit 9261839
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ object ClientApiHandlers extends AkkaResponses {
result match {
case Success(s) => success(s)
case Failure(ex: OrganizationNotAllowedOnClient) => forbidden(ex, logMessage)
case Failure(ex: KeyOperationNotAllowedOnClient) => forbidden(ex, logMessage)
case Failure(ex: ClientKeyNotFound) => notFound(ex, logMessage)
case Failure(ex) => internalServerError(ex, logMessage)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import it.pagopa.interop.agreementmanagement.model.agreement.{
Suspended
}
import it.pagopa.interop.authorizationmanagement.client.{model => AuthorizationManagementDependency}
import it.pagopa.interop.authorizationmanagement.model.client.PersistentClient
import it.pagopa.interop.authorizationprocess.api.ClientApiService
import it.pagopa.interop.authorizationprocess.api.impl.ClientApiHandlers._
import it.pagopa.interop.authorizationprocess.common.Adapters._
Expand Down Expand Up @@ -229,9 +230,19 @@ final case class ClientApiServiceImpl(
val operationLabel: String = s"Deleting Key $keyId of Client $clientId"
logger.info(operationLabel)

def checkRole(client: PersistentClient): Future[Unit] = for {
roles <- getUserRolesFuture(contexts)
requesterUserId <- getUidFutureUUID(contexts)
_ <-
if (roles.contains(SECURITY_ROLE) && client.users.filter(_ == requesterUserId).isEmpty)
Future.failed(KeyOperationNotAllowedOnClient(client.id))
else Future.unit
} yield ()

val result: Future[Unit] = for {
clientUuid <- clientId.toFutureUUID
client <- authorizationManagementService.getClient(clientUuid)
_ <- checkRole(client)
_ <- assertIsClientConsumer(client).toFuture
_ <- authorizationManagementService.deleteKey(clientUuid, keyId)(contexts)
} yield ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@ object AuthorizationProcessErrors {
"0024",
s"The number of the keys ${size.toString} for the client ${clientId.toString} exceed maximun allowed"
)

final case class KeyOperationNotAllowedOnClient(clientId: UUID)
extends ComponentError(
"0025",
s"Role is not allowed to perform operation on the key for the client ${clientId.toString}"
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,15 @@ class KeyOperationSpec

"Delete key" should {
"succeed" in {
val kid = "some-kid"
implicit val contexts: Seq[(String, String)] =
Seq(
"bearer" -> bearerToken,
USER_ROLES -> ADMIN_ROLE,
"organizationId" -> consumerId.toString,
"uid" -> userId.toString,
"selfcareId" -> selfcareId.toString
)
val kid = "some-kid"

(mockAuthorizationManagementService
.getClient(_: UUID)(_: ExecutionContext, _: ReadModelService))
Expand All @@ -297,6 +305,55 @@ class KeyOperationSpec
}
}

"succeed if role is Security" in {
implicit val contexts: Seq[(String, String)] =
Seq(
"bearer" -> bearerToken,
USER_ROLES -> SECURITY_ROLE,
"organizationId" -> consumerId.toString,
"uid" -> userId.toString,
"selfcareId" -> selfcareId.toString
)
val kid = "some-kid"

(mockAuthorizationManagementService
.getClient(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(*, *, *)
.once()
.returns(Future.successful(persistentClient.copy(users = Set(userId))))

(mockAuthorizationManagementService
.deleteKey(_: UUID, _: String)(_: Seq[(String, String)]))
.expects(client.id, kid, *)
.once()
.returns(Future.successful(()))

Get() ~> service.deleteClientKeyById(client.id.toString, kid) ~> check {
status shouldEqual StatusCodes.NoContent
}
}
"fail if role is Security and UID is not a member" in {
implicit val contexts: Seq[(String, String)] =
Seq(
"bearer" -> bearerToken,
USER_ROLES -> SECURITY_ROLE,
"organizationId" -> consumerId.toString,
"uid" -> userId.toString,
"selfcareId" -> selfcareId.toString
)
val kid = "some-kid"

(mockAuthorizationManagementService
.getClient(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(*, *, *)
.once()
.returns(Future.successful(persistentClient))

Get() ~> service.deleteClientKeyById(client.id.toString, kid) ~> check {
status shouldEqual StatusCodes.Forbidden
}
}

"fail if client or key do not exist" in {
val kid = "some-kid"
(mockAuthorizationManagementService
Expand Down

0 comments on commit 9261839

Please sign in to comment.