diff --git a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java index b38218f6504b5dc1c0d26f17109151f56695f0c5..2d8faf3a74bc794c4fd229a53a5f7424d7d752bd 100644 --- a/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java +++ b/ozgcloud-keycloak-operator/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java @@ -24,7 +24,10 @@ package de.ozgcloud.operator.keycloak.user; import java.util.Arrays; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; import org.keycloak.admin.client.CreatedResponseUtil; import org.keycloak.admin.client.Keycloak; @@ -79,16 +82,25 @@ class KeycloakUserRemoteService { } void addClientRoles(String userId, RealmResource realmResource, String namespace, UserRepresentation user) { - user.getClientRoles().keySet().forEach(clientId -> { + getClientNamesOfUser(user).forEach(clientId -> { + var realmClient = getRealmClient(realmResource, clientId); user.getClientRoles().get(clientId).stream() - .map(clientRoleName -> keycloakGenericRemoteService.getClientRole(clientRoleName, realmClient.getId(), namespace) - .orElseThrow(() -> new KeycloakException( - "Role " + clientRoleName + " not found for client with clientId " + clientId + " in realm " + namespace))) + .map(clientRoleName -> getClientRole(namespace, clientId, realmClient, clientRoleName)) .forEach(clientRole -> addClientRoleToUser(clientRole, realmResource, userId, realmClient)); }); } + Stream<String> getClientNamesOfUser(UserRepresentation user) { + return Optional.ofNullable(user.getClientRoles()).map(Map::keySet).map(Set::stream).orElse(Stream.empty()); + } + + RoleRepresentation getClientRole(String namespace, String clientId, ClientRepresentation realmClient, String clientRoleName) { + return keycloakGenericRemoteService.getClientRole(clientRoleName, realmClient.getId(), namespace) + .orElseThrow(() -> new KeycloakException( + "Role " + clientRoleName + " not found for client with clientId " + clientId + " in realm " + namespace)); + } + ClientRepresentation getRealmClient(RealmResource realmResource, String clientId) { return realmResource.clients() .findByClientId(clientId).stream().findFirst() diff --git a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java index 908127e31ffda460e4ad538a63f51ba3d8e9ab8d..67693d1cd2b589a37f2872e316f404ae17806c5a 100644 --- a/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java +++ b/ozgcloud-keycloak-operator/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java @@ -61,6 +61,7 @@ class KeycloakUserRemoteServiceTest { private final static String REALM = "TestRealm"; private final static String USERID = "UserId"; private final static String CLIENT_ID = "ClientId"; + private final static String CLIENT_ROLE_NAME = "ClientRoleName"; @Spy @InjectMocks @@ -173,7 +174,6 @@ class KeycloakUserRemoteServiceTest { @Test void shouldThrowOnMissingClientRole() { var user = UserRepresentationTestFactory.create(); - userRemoteService.addClientRoles(USERID, realmResource, REALM, userRepresentation); when(genericRemoteService.getClientRole(any(), any(), any())).thenReturn(Optional.empty()); assertThrows(KeycloakException.class, @@ -181,6 +181,69 @@ class KeycloakUserRemoteServiceTest { } } + @Nested + class TestAddClientRolesUserWithoutRoles { + + @Test + void shouldNotThrowOnUserWithoutRoles() { + UserRepresentation user = createUserWithNullRoles(); + + assertDoesNotThrow(() -> userRemoteService.addClientRoles(USERID, realmResource, REALM, user)); + } + + private UserRepresentation createUserWithNullRoles() { + UserRepresentation user = UserRepresentationTestFactory.create(); + user.setClientRoles(null); + return user; + } + } + + @Nested + class TestGetRealmClientNamesOfUser { + + @Test + void shouldReturnClientNames() { + UserRepresentation user = UserRepresentationTestFactory.create(); + + List<String> clientNames = userRemoteService.getClientNamesOfUser(user).toList(); + + assertThat(clientNames).contains(UserRepresentationTestFactory.CLIENT_NAME); + } + } + + @Nested + class TestGetClientRole { + + @Spy + @InjectMocks + private KeycloakUserRemoteService userRemoteService; + + @Mock + private KeycloakGenericRemoteService keycloakGenericRemoteService; + + @BeforeEach + void init() { + when(clientRepresentation.getId()).thenReturn(CLIENT_ID); + } + + @Test + void shouldReturnClientRole() { + when(keycloakGenericRemoteService.getClientRole(CLIENT_ROLE_NAME, CLIENT_ID, REALM)).thenReturn(Optional.of(roleRepresentation)); + + RoleRepresentation role = userRemoteService.getClientRole(REALM, CLIENT_ID, clientRepresentation, CLIENT_ROLE_NAME); + + assertThat(role).isEqualTo(roleRepresentation); + } + + @Test + void shouldThrowOnMissingRole() { + when(keycloakGenericRemoteService.getClientRole(CLIENT_ROLE_NAME, CLIENT_ID, REALM)).thenReturn(Optional.empty()); + + assertThrows(KeycloakException.class, + () -> userRemoteService.getClientRole(REALM, CLIENT_ID, clientRepresentation, CLIENT_ROLE_NAME)); + } + } + @Nested class TestAddClientRoleToUser {