diff --git a/src/Resource/Users.php b/src/Resource/Users.php index bd278ac..2c0788b 100644 --- a/src/Resource/Users.php +++ b/src/Resource/Users.php @@ -9,7 +9,6 @@ use Fschmtt\Keycloak\Collection\RoleCollection; use Fschmtt\Keycloak\Collection\UserCollection; use Fschmtt\Keycloak\Http\Command; -use Fschmtt\Keycloak\Http\ContentType; use Fschmtt\Keycloak\Http\Criteria; use Fschmtt\Keycloak\Http\Method; use Fschmtt\Keycloak\Http\Query; @@ -205,6 +204,69 @@ public function removeRealmRoles(string $realm, string $userId, RoleCollection $ ); } + + public function retrieveClientRoles(string $realm, string $userId, string $clientUuid): RoleCollection + { + return $this->queryExecutor->executeQuery( + new Query( + '/admin/realms/{realm}/users/{userId}/role-mappings/clients/{clientUuid}', + RoleCollection::class, + [ + 'realm' => $realm, + 'userId' => $userId, + 'clientUuid' => $clientUuid, + ], + ), + ); + } + + public function retrieveAvailableClientRoles(string $realm, string $userId, string $clientUuid): RoleCollection + { + return $this->queryExecutor->executeQuery( + new Query( + '/admin/realms/{realm}/users/{userId}/role-mappings/clients/{clientUuid}/available', + RoleCollection::class, + [ + 'realm' => $realm, + 'userId' => $userId, + 'clientUuid' => $clientUuid, + ], + ), + ); + } + + public function addClientRoles(string $realm, string $userId, RoleCollection $roles, string $clientUuid): void + { + $this->commandExecutor->executeCommand( + new Command( + '/admin/realms/{realm}/users/{userId}/role-mappings/clients/{clientUuid}', + Method::POST, + [ + 'realm' => $realm, + 'userId' => $userId, + 'clientUuid' => $clientUuid, + ], + $roles, + ), + ); + } + + public function removeClientRoles(string $realm, string $userId, RoleCollection $roles, string $clientUuid): void + { + $this->commandExecutor->executeCommand( + new Command( + '/admin/realms/{realm}/users/{userId}/role-mappings/clients/{clientUuid}', + Method::DELETE, + [ + 'realm' => $realm, + 'userId' => $userId, + 'clientUuid' => $clientUuid, + ], + $roles, + ), + ); + } + /** * @param list|null $actions */ diff --git a/tests/Integration/Resource/UsersTest.php b/tests/Integration/Resource/UsersTest.php index 9d9042f..4569c53 100644 --- a/tests/Integration/Resource/UsersTest.php +++ b/tests/Integration/Resource/UsersTest.php @@ -155,6 +155,56 @@ public function testAddRemoveRealmRoleUser(): void } } + public function testAddRemoveClientRoleUser(): void + { + $users = $this->getKeycloak()->users(); + $user = $users->all('master')->first(); + static::assertInstanceOf(User::class, $user); + + $clients = $this->getKeycloak()->clients()->all('master'); + + $clientWithAvailableRole = null; + $availableRoles = null; + + foreach ($clients as $client) { + $available = $users->retrieveAvailableClientRoles('master', $user->getId(), $client->getId()); + if ($available->count() > 0) { + $clientWithAvailableRole = $client; + $availableRoles = $available; + break; + } + } + + static::assertNotNull($clientWithAvailableRole); + static::assertNotNull($availableRoles); + + $roles = $users->retrieveClientRoles('master', $user->getId(), $clientWithAvailableRole->getId()); + $rolesCount = $roles->count(); + + $availableRolesCount = $availableRoles->count(); + static::assertGreaterThanOrEqual(1, $availableRolesCount); + $role = $availableRoles->first(); + static::assertInstanceOf(Role::class, $role); + + $users->addClientRoles('master', $user->getId(), new RoleCollection([$role]), $clientWithAvailableRole->getId()); + + $roles = $users->retrieveClientRoles('master', $user->getId(), $clientWithAvailableRole->getId()); + static::assertEquals($rolesCount + 1, $roles->count()); + static::assertContainsEquals($role, $roles); + + $availableRoles = $users->retrieveAvailableClientRoles('master', $user->getId(), $clientWithAvailableRole->getId()); + static::assertEquals($availableRolesCount - 1, $availableRoles->count()); + + $users->removeClientRoles('master', $user->getId(), new RoleCollection([$role]), $clientWithAvailableRole->getId()); + + $roles = $users->retrieveClientRoles('master', $user->getId(), $clientWithAvailableRole->getId()); + static::assertEquals($rolesCount, $roles->count()); + static::assertNotContainsEquals($role, $roles); + + $availableRoles = $users->retrieveAvailableClientRoles('master', $user->getId(), $clientWithAvailableRole->getId()); + static::assertEquals($availableRolesCount, $availableRoles->count()); + } + public function testCreateUserWithPasswordCredential(): void { $users = $this->getKeycloak()->users();