Skip to content

Commit

Permalink
Merge branch '1.0.x' into PIN-3515
Browse files Browse the repository at this point in the history
  • Loading branch information
nttdata-rtorsoli committed Nov 8, 2023
2 parents 98823dd + 8292ba4 commit 4d6e265
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/main/resources/application-standalone.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ authorization-process {
selfcare-v2-client = "a_secret_key"
}

max-keys-per-client = 100
jwt {
audience = ${ACCEPTED_AUDIENCES}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ authorization-process {
selfcare-v2-client = ${SELFCARE_V2_API_KEY}
}

max-keys-per-client = ${MAX_KEYS_PER_CLIENT}
jwt {
audience = ${ACCEPTED_AUDIENCES}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ object ClientApiHandlers extends AkkaResponses {
result match {
case Success(s) => success(s)
case Failure(ex: CreateKeysBadRequest) => badRequest(ex, logMessage)
case Failure(ex: TooManyKeysPerClient) => badRequest(ex, logMessage)
case Failure(ex: OrganizationNotAllowedOnClient) => forbidden(ex, logMessage)
case Failure(ex: UserNotFound) => forbidden(ex, logMessage)
case Failure(ex: ClientNotFound) => notFound(ex, logMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import akka.http.scaladsl.server.Directives.{complete, onComplete}
import akka.http.scaladsl.server.Route
import cats.syntax.all._
import com.typesafe.scalalogging.{Logger, LoggerTakingImplicit}
import it.pagopa.interop.authorizationprocess.common.system.ApplicationConfiguration
import it.pagopa.interop._
import it.pagopa.interop.agreementmanagement.model.agreement.{
Active,
Expand Down Expand Up @@ -245,6 +246,11 @@ final case class ClientApiServiceImpl(
val operationLabel: String = s"Creating keys for client $clientId"
logger.info(operationLabel)

def assertKeyIsBelowThreshold(clientId: UUID, size: Int): Future[Unit] =
if (size > ApplicationConfiguration.maxKeysPerClient)
Future.failed(TooManyKeysPerClient(clientId, size))
else Future.unit

val result: Future[Keys] = for {
clientUuid <- clientId.toFutureUUID
selfcareId <- getSelfcareIdFutureUUID(contexts)
Expand All @@ -253,6 +259,8 @@ final case class ClientApiServiceImpl(
client <- authorizationManagementService
.getClient(clientUuid)
.ensureOr(client => OrganizationNotAllowedOnClient(clientId, client.consumerId))(_.consumerId == requesterOrgId)
keys <- authorizationManagementService.getClientKeys(clientUuid)
_ <- assertKeyIsBelowThreshold(clientUuid, keys.size + keysSeeds.size)
_ <- client.users.find(_ == requesterUserId).toFuture(UserNotFound(selfcareId, requesterUserId))
_ <- assertSecurityUser(selfcareId, requesterOrgId, requesterUserId)
seeds = keysSeeds.map(_.toDependency(requesterUserId, dateTimeSupplier.get()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ object ApplicationConfiguration {

require(jwtAudience.nonEmpty, "Audience cannot be empty")

val maxKeysPerClient: Int = config.getInt("authorization-process.max-keys-per-client")

val readModelConfig: ReadModelConfig = {
val connectionString: String = config.getString("authorization-process.read-model.db.connection-string")
val dbName: String = config.getString("authorization-process.read-model.db.name")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,11 @@ object AuthorizationProcessErrors {

final case class UserNotFound(selfcareId: UUID, userId: UUID)
extends ComponentError("0023", s"User $userId not found for selfcare institution $selfcareId")

final case class TooManyKeysPerClient(clientId: UUID, size: Int)
extends ComponentError(
"0024",
s"The number of the keys ${size.toString} for the client ${clientId.toString} exceed maximun allowed"
)

}
1 change: 1 addition & 0 deletions src/test/resources/application-test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ authorization-process {
selfcare-v2-client = "selfcare-v2-client-key"
}

max-keys-per-client = 5
jwt {
audience = "audience"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ class KeyOperationSpec
.once()
.returns(Future.successful(persistentClient.copy(users = Set(userId))))

(mockAuthorizationManagementService
.getClientKeys(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(persistentClient.id, *, *)
.once()
.returns(Future.successful(Seq(persistentKey.copy(userId = Some(userId)))))

val results: Seq[UserResource] = Seq(userResource)

(mockSelfcareV2ClientService
Expand Down Expand Up @@ -216,9 +222,43 @@ class KeyOperationSpec
.once()
.returns(Future.successful(persistentClient))

(mockAuthorizationManagementService
.getClientKeys(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(client.id, *, *)
.once()
.returns(Future.successful(Seq(persistentKey.copy(userId = Some(userId)))))

Get() ~> service.createKeys(client.id.toString, keySeeds) ~> check {
status shouldEqual StatusCodes.Forbidden
entityAs[Problem].errors.head.code shouldBe "007-0023"

}
}

"fail if the keys exceed the maximum allowed" in {
val keySeeds: Seq[KeySeed] = Seq(
KeySeed(key = "key1", use = KeyUse.SIG, alg = "123", name = "test"),
KeySeed(key = "key2", use = KeyUse.SIG, alg = "123", name = "test"),
KeySeed(key = "key3", use = KeyUse.SIG, alg = "123", name = "test"),
KeySeed(key = "key4", use = KeyUse.SIG, alg = "123", name = "test"),
KeySeed(key = "key5", use = KeyUse.SIG, alg = "123", name = "test")
)

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

(mockAuthorizationManagementService
.getClientKeys(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(client.id, *, *)
.once()
.returns(Future.successful(Seq(persistentKey.copy(userId = Some(userId)))))

Get() ~> service.createKeys(client.id.toString, keySeeds) ~> check {
status shouldEqual StatusCodes.BadRequest
entityAs[Problem].errors.head.code shouldBe "007-0024"
}
}

Expand Down Expand Up @@ -259,7 +299,6 @@ class KeyOperationSpec

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

(mockAuthorizationManagementService
.getClient(_: UUID)(_: ExecutionContext, _: ReadModelService))
.expects(*, *, *)
Expand Down

0 comments on commit 4d6e265

Please sign in to comment.