From 4c3975392385ebe89fcb4a80cdd4e842614d03b0 Mon Sep 17 00:00:00 2001 From: Pat Losoponkul Date: Tue, 14 Nov 2023 17:17:25 +0700 Subject: [PATCH] test: add multi-tenant wallet admin test cases Signed-off-by: Pat Losoponkul --- .../core/EntityPermissionManagementSpec.scala | 1 - ...cloakPermissionManagementServiceSpec.scala | 80 +++++++++++++++++++ .../service/WalletManagementServiceSpec.scala | 58 ++++++++++++-- 3 files changed, 133 insertions(+), 6 deletions(-) diff --git a/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/core/EntityPermissionManagementSpec.scala b/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/core/EntityPermissionManagementSpec.scala index aae3e29b5f..90c4658b6d 100644 --- a/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/core/EntityPermissionManagementSpec.scala +++ b/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/core/EntityPermissionManagementSpec.scala @@ -82,7 +82,6 @@ object EntityPermissionManagementSpec extends ZIOSpecDefault, PostgresTestContai exit <- permissionService .revokeWalletFromUser(wallet1.id, entity) .provide(ZLayer.succeed(WalletAdministrationContext.Admin())) - .debug("revokeWallet") .exit } yield assert(exit)(fails(isSubtype[ServiceError](anything))) } diff --git a/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/keycloak/admin/KeycloakPermissionManagementServiceSpec.scala b/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/keycloak/admin/KeycloakPermissionManagementServiceSpec.scala index f851699759..8b71fda85a 100644 --- a/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/keycloak/admin/KeycloakPermissionManagementServiceSpec.scala +++ b/prism-agent/service/server/src/test/scala/io/iohk/atala/iam/authorization/keycloak/admin/KeycloakPermissionManagementServiceSpec.scala @@ -16,6 +16,7 @@ import io.iohk.atala.iam.authentication.oidc.{ } import io.iohk.atala.iam.authorization.core.PermissionManagement import io.iohk.atala.iam.authorization.core.PermissionManagement.Error.WalletNotFoundById +import io.iohk.atala.iam.authorization.core.PermissionManagement.Error.UnexpectedError import io.iohk.atala.shared.models.WalletAdministrationContext import io.iohk.atala.shared.models.{WalletAccessContext, WalletId} import io.iohk.atala.sharedtest.containers.PostgresTestContainerSupport @@ -125,6 +126,17 @@ object KeycloakPermissionManagementServiceSpec entity = KeycloakEntity(id = UUID.randomUUID()) exit <- permissionService.grantWalletToUser(WalletId.random, entity).exit } yield assert(exit)(fails(isSubtype[WalletNotFoundById](anything))) + }, + test("grant wallet access to the user with invalid user id") { + for { + client <- ZIO.service[KeycloakClient] + authenticator <- ZIO.service[KeycloakAuthenticator] + walletService <- ZIO.service[WalletManagementService] + wallet <- walletService.createWallet(Wallet("test_1")) + entity = KeycloakEntity(id = UUID.randomUUID()) + permissionService <- ZIO.service[PermissionManagement.Service[KeycloakEntity]] + exit <- permissionService.grantWalletToUser(wallet.id, entity).exit + } yield assert(exit)(fails(isSubtype[UnexpectedError](anything))) } ).provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())) @@ -157,6 +169,42 @@ object KeycloakPermissionManagementServiceSpec permittedWallet <- authenticator.authorize(entity) } yield assert(wallet.id)(equalTo(permittedWallet.walletId)) }, + test("revoke wallet access from the user by self-service") { + for { + client <- ZIO.service[KeycloakClient] + authenticator <- ZIO.service[KeycloakAuthenticator] + walletService <- ZIO.service[WalletManagementService] + + wallet <- walletService + .createWallet(Wallet("test_2")) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())) + + randomId = UUID.randomUUID().toString + username = "user_" + randomId + password = randomId + user <- createUser(username = username, password = password) + entity = KeycloakEntity(id = UUID.fromString(user.getId)) + + permissionService <- ZIO.service[PermissionManagement.Service[KeycloakEntity]] + _ <- permissionService + .grantWalletToUser(wallet.id, entity) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())) + + token <- client.getAccessToken(username, password).map(_.access_token) + + entity <- authenticator.authenticate(token) + permittedWallet <- authenticator.authorize(entity) + + _ <- permissionService + .revokeWalletFromUser(wallet.id, entity) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.SelfService(Seq(wallet.id)))) + + token2 <- client.getAccessToken(username, password).map(_.access_token) + entity2 <- authenticator.authenticate(token) + permittedWallet2 <- authenticator.authorize(entity).exit + + } yield assert(permittedWallet2)(fails(isSubtype[ResourceNotPermitted](anything))) + }, test("grant wallet access to non-permitted wallet by self-service is not allowed") { val walletId = WalletId.random for { @@ -180,6 +228,38 @@ object KeycloakPermissionManagementServiceSpec .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.SelfService(Seq(walletId)))) .exit } yield assert(exit)(fails(isSubtype[WalletNotFoundById](anything))) + }, + test("revoke wallet access from non-permitted wallet by self-service is not allowed") { + for { + client <- ZIO.service[KeycloakClient] + authenticator <- ZIO.service[KeycloakAuthenticator] + walletService <- ZIO.service[WalletManagementService] + + wallet <- walletService + .createWallet(Wallet("test_2")) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())) + + randomId = UUID.randomUUID().toString + username = "user_" + randomId + password = randomId + user <- createUser(username = username, password = password) + entity = KeycloakEntity(id = UUID.fromString(user.getId)) + + permissionService <- ZIO.service[PermissionManagement.Service[KeycloakEntity]] + _ <- permissionService + .grantWalletToUser(wallet.id, entity) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())) + + token <- client.getAccessToken(username, password).map(_.access_token) + + entity <- authenticator.authenticate(token) + permittedWallet <- authenticator.authorize(entity) + + exit <- permissionService + .revokeWalletFromUser(wallet.id, entity) + .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.SelfService(Seq(WalletId.random)))) + .exit + } yield assert(exit)(fails(isSubtype[WalletNotFoundById](anything))) } ) } diff --git a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala index 6814e2c249..c7c08e3c06 100644 --- a/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala +++ b/prism-agent/service/wallet-api/src/test/scala/io/iohk/atala/agent/walletapi/service/WalletManagementServiceSpec.scala @@ -28,8 +28,9 @@ object WalletManagementServiceSpec override def spec = { def testSuite(name: String) = suite(name)( - createWalletSpec, - getWalletSpec, + createWalletSpec.provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())), + getWalletSpec.provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin())), + multitenantSpec ) @@ TestAspect.before(DBTestUtils.runMigrationAgentDB) @@ TestAspect.sequential val suite1 = testSuite("jdbc as secret storage") @@ -40,7 +41,6 @@ object WalletManagementServiceSpec contextAwareTransactorLayer, pgContainerLayer, apolloLayer, - ZLayer.succeed(WalletAdministrationContext.Admin()) ) val suite2 = testSuite("vault as secret storage") @@ -52,7 +52,6 @@ object WalletManagementServiceSpec pgContainerLayer, apolloLayer, vaultKvClientLayer, - ZLayer.succeed(WalletAdministrationContext.Admin()) ) suite("WalletManagementService")(suite1, suite2) @@ -135,7 +134,7 @@ object WalletManagementServiceSpec exit <- svc.createWallet(Wallet("wallet-2"), Some(seed)).exit } yield assert(exit)(fails(isSubtype[DuplicatedWalletSeed](anything))) }, - test("cannot create new wallet for self-service context if already have permitted wallet") { + test("cannot create new wallet for self-service if already have permitted wallet") { val walletId = WalletId.random for { svc <- ZIO.service[WalletManagementService] @@ -147,4 +146,53 @@ object WalletManagementServiceSpec } ) + private def multitenantSpec = suite("multitenant spec")( + test("get all wallets for admin") { + for { + svc <- ZIO.service[WalletManagementService] + wallet1 <- svc.createWallet(Wallet("wallet-1")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet2 <- svc.createWallet(Wallet("wallet-2")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet3 <- svc.createWallet(Wallet("wallet-3")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + walletIds = Seq(wallet1, wallet2, wallet3).map(_.id) + wallets1 <- svc.getWallets(walletIds).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallets2 <- svc + .listWallets() + .map(_._1) + .provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + } yield assert(wallets1.map(_.id))(equalTo(walletIds)) && + assert(wallets2.map(_.id))(equalTo(walletIds)) + }, + test("get only permitted wallet for self-service") { + for { + svc <- ZIO.service[WalletManagementService] + wallet1 <- svc.createWallet(Wallet("wallet-1")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet2 <- svc.createWallet(Wallet("wallet-2")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet3 <- svc.createWallet(Wallet("wallet-3")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + walletIds = Seq(wallet1, wallet2, wallet3).map(_.id) + permittedWalletIds = Seq(wallet1, wallet2).map(_.id) + wallets1 <- svc + .getWallets(walletIds) + .provide(ZLayer.succeed(WalletAdministrationContext.SelfService(permittedWalletIds))) + wallets2 <- svc + .listWallets() + .map(_._1) + .provide(ZLayer.succeed(WalletAdministrationContext.SelfService(permittedWalletIds))) + } yield assert(wallets1.map(_.id))(equalTo(permittedWalletIds)) && + assert(wallets2.map(_.id))(equalTo(permittedWalletIds)) + }, + test("cannot get wallet by self-service that is not permitted") { + for { + svc <- ZIO.service[WalletManagementService] + wallet1 <- svc.createWallet(Wallet("wallet-1")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet2 <- svc.createWallet(Wallet("wallet-2")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + wallet3 <- svc.createWallet(Wallet("wallet-3")).provide(ZLayer.succeed(WalletAdministrationContext.Admin())) + walletIds = Seq(wallet1, wallet2, wallet3).map(_.id) + permittedWalletIds = Seq(wallet1, wallet2).map(_.id) + maybeWallet3 <- svc + .getWallet(wallet3.id) + .provide(ZLayer.succeed(WalletAdministrationContext.SelfService(permittedWalletIds))) + } yield assert(maybeWallet3)(isNone) + } + ) + }