Skip to content
Snippets Groups Projects
Commit eb8cdf17 authored by OZGCloud's avatar OZGCloud
Browse files

OZG-2653 RoleMapping in Mapper umgezogen

parent ba6d5d14
No related branches found
No related tags found
No related merge requests found
package de.itvsh.kop.user;
import java.util.Date;
import java.util.GregorianCalendar;
import org.keycloak.representations.idm.UserRepresentation;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
public interface UserRepresentationMapper {
@Mapping(target = "externalId", source = "id")
@Mapping(target = "organisationsEinheitIds", ignore = true)
@Mapping(target = "roles", ignore = true)
@Mapping(target = "lastSyncTimestamp", ignore = true)
User toKopUser(UserRepresentation userRep);
default Date map(Long createdAt) {
var calendar = new GregorianCalendar();
calendar.setTimeInMillis(createdAt);
return calendar.getTime();
}
default Long map(Date createdAt) {
return createdAt != null ? createdAt.getTime() : null;
}
}
package de.itvsh.kop.user;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
......@@ -30,7 +34,7 @@ public abstract class UserResourceMapper {
@Mapping(target = "roles", expression = "java(mapRoles(userRes))")
@Mapping(target = "lastSyncTimestamp", ignore = true)
@Mapping(target = "deleted", ignore = true)
abstract User toKopUser(UserResource userRes);
public abstract User toKopUser(UserResource userRes);
Date mapCreatedAt(UserResource userRes) {
var createdAt = userRes.toRepresentation().getCreatedTimestamp();
......@@ -49,7 +53,14 @@ public abstract class UserResourceMapper {
}
List<String> mapRoles(UserResource userRes) {
return List.of();
var roleRepresentation = Optional.ofNullable(userRes.roles().getAll().getClientMappings())
.filter(Objects::nonNull)
.filter(map -> map.containsKey(properties.client()))
.map(map -> map.get(properties.client()))
.map(ClientMappingsRepresentation::getMappings)
.orElseGet(Collections::emptyList);
return roleRepresentation.stream().map(RoleRepresentation::getName).toList();
}
String mapId(UserResource userRes) {
......
package de.itvsh.kop.user.keycloak;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
......@@ -14,14 +10,9 @@ import javax.ws.rs.ProcessingException;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import de.itvsh.kop.user.User;
import de.itvsh.kop.user.UserRepresentationMapper;
import de.itvsh.kop.user.UserResourceMapper;
import de.itvsh.kop.user.common.errorhandling.KeycloakClientException;
import de.itvsh.kop.user.common.errorhandling.KeycloakUnavailableException;
......@@ -31,7 +22,7 @@ class KeycloakApiService {
@Inject
private RealmResource realmResource;
@Inject
private UserRepresentationMapper mapper;
private UserResourceMapper mapper;
@Inject
private KeycloakApiProperties properties;
......@@ -41,43 +32,10 @@ class KeycloakApiService {
public Stream<User> findAllUser() {
return handlingKeycloakException(() -> {
var users = realmResource.users();
return users.list().stream().map(userRep -> toUser(users.get(userRep.getId())));
return users.list().stream().map(userRep -> mapper.toKopUser(users.get(userRep.getId())));
});
}
private User toUser(UserResource userResource) {
User user = toUser(userResource.toRepresentation());
return user.toBuilder()
.roles(getClientRoles(userResource))
.organisationsEinheitIds(getOrganisationsEinheitIds(userResource)).build();
}
// TOOD in den Mapper verschieben
List<String> getClientRoles(UserResource userResource) {
var roleRepresentation = Optional.ofNullable(userResource.roles().getAll().getClientMappings())
.filter(map -> map.containsKey(properties.client()))
.map(map -> map.get(properties.client()))
.map(ClientMappingsRepresentation::getMappings)
.orElseGet(Collections::emptyList);
return roleRepresentation.stream().map(RoleRepresentation::getName).toList();
}
// TOOD in den Mapper verschieben
List<String> getOrganisationsEinheitIds(UserResource userResource) {
return userResource.groups().stream()
.map(GroupRepresentation::getAttributes)
.filter(Objects::nonNull)
.map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey()))
.filter(Objects::nonNull)
.map(attributeValues -> attributeValues.get(0))
.toList();
}
private User toUser(UserRepresentation userRepresentation) {
return mapper.toKopUser(userRepresentation);
}
private <T> T handlingKeycloakException(Supplier<T> runnable) {
try {
return runnable.get();
......
......@@ -23,5 +23,4 @@ usermanager:
realm: sh-kiel-dev
organisations-einheit-id-key: organisationseinheitId
ldap-id-key: LDAP_ID
organisations-einheit-id-key: organisationseinheitId
client: sh-kiel-dev-goofy
\ No newline at end of file
......@@ -8,10 +8,12 @@ import javax.ws.rs.core.Response;
import org.keycloak.admin.client.resource.RoleMappingResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
......@@ -208,7 +210,12 @@ class StubUserResource implements UserResource {
@Override
public MappingsRepresentation getAll() {
return null;
var rep = new MappingsRepresentation();
var clientMapRep = new ClientMappingsRepresentation();
var roleRep = new RoleRepresentation(UserRepresentationTestFactory.ROLE, "Test role", false);
clientMapRep.setMappings(List.of(roleRep));
rep.setClientMappings(Map.of("sh-kiel-dev-goofy", clientMapRep));
return rep;
}
@Override
......
package de.itvsh.kop.user;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
class UserRepresenstationMapperTest {
private UserRepresentationMapper mapper = Mappers.getMapper(UserRepresentationMapper.class);
@Nested
class TestMapping {
@Test
void shouldMapToUser() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user).isNotNull();
}
@Test
void shouldMapEmail() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user.getEmail()).isEqualTo(UserRepresentationTestFactory.EMAIL);
}
@Test
void shouldMapExternalId() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID);
}
@Test
void shouldMapFirstName() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user.getFirstName()).isEqualTo(UserRepresentationTestFactory.FIRST_NAME);
}
@Test
void shouldMapLastName() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user.getLastName()).isEqualTo(UserRepresentationTestFactory.LAST_NAME);
}
@Test
void shouldMapUserName() {
User user = mapper.toKopUser(UserRepresentationTestFactory.create());
assertThat(user.getUsername()).isEqualTo(UserRepresentationTestFactory.USER_NAME);
}
}
}
......@@ -6,7 +6,6 @@ import static org.mockito.Mockito.*;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
......@@ -29,6 +28,7 @@ class UserResourceMapperTest {
void init() {
when(apiProperties.ldapIdKey()).thenReturn("LDAP_ID");
when(apiProperties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId");
when(apiProperties.client()).thenReturn("sh-kiel-dev-goofy");
}
@Test
......@@ -88,7 +88,6 @@ class UserResourceMapperTest {
}
@Test
@Disabled
void shouldMapRoles() {
User user = mapper.toKopUser(UserResourceTestFactory.create());
......
package de.itvsh.kop.user.keycloak;
import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.resource.RoleMappingResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.assertj.core.api.Assertions.*;
class KeycloakApiServiceTest {
@InjectMocks
private KeycloakApiService service;
@Mock
private KeycloakApiProperties properties;
@Mock
private UserResource userResource;
@DisplayName("Get organisationsEinheit ids")
@Nested
class TestGetOrganisationsEinheitIds {
private static final String ORGANISATIONS_EINHEIT_ID = "7899554";
private static final String ORGANISATIONS_EINHEIT_ID_KEY = "testIdentifier";
@Mock
private GroupRepresentation groupRepresentation;
@BeforeEach
void init() {
when(userResource.groups()).thenReturn(List.of(groupRepresentation));
when(properties.organisationsEinheitIdKey()).thenReturn(ORGANISATIONS_EINHEIT_ID_KEY);
when(groupRepresentation.getAttributes()).thenReturn(Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID)));
}
@Test
void shouldMap() {
var ids = service.getOrganisationsEinheitIds(userResource);
assertThat(ids).isNotEmpty();
assertThat(ids.get(0)).isEqualTo(ORGANISATIONS_EINHEIT_ID);
}
}
@DisplayName("Get client roles")
@Nested
class TestGetClientRoles {
private static final String ROLE_NAME = "roleName";
private static final String CLIENT_NAME = "clientName";
@Mock
private RoleMappingResource roleMappingResource;
@Mock
private RoleScopeResource roleScopeResource;
@Mock
private MappingsRepresentation mappingsRepresentation;
@Mock
private Map<String, ClientMappingsRepresentation> clientMappingsRepresentation;
@Mock
private ClientMappingsRepresentation clientMappingRepresentation;
@BeforeEach
void init() {
when(userResource.roles()).thenReturn(roleMappingResource);
when(roleMappingResource.getAll()).thenReturn(mappingsRepresentation);
}
@DisplayName("on existing roles")
@Nested
class TestOnAssignedRoles {
@BeforeEach
void init() {
when(properties.client()).thenReturn(CLIENT_NAME);
when(mappingsRepresentation.getClientMappings()).thenReturn(clientMappingsRepresentation);
when(clientMappingsRepresentation.containsKey(CLIENT_NAME)).thenReturn(true);
when(clientMappingsRepresentation.get(CLIENT_NAME)).thenReturn(clientMappingRepresentation);
when(clientMappingRepresentation.getMappings()).thenReturn(List.of(createRoleRepresentation()));
}
private RoleRepresentation createRoleRepresentation() {
var roleRepresentation = new RoleRepresentation();
roleRepresentation.setName(ROLE_NAME);
return roleRepresentation;
}
@Test
void shouldReturnRolesIfExists() {
var roles = service.getClientRoles(userResource);
assertThat(roles).isNotEmpty();
assertThat(roles.get(0)).isEqualTo(ROLE_NAME);
}
}
@Nested
class TestOnNonExistingClient {
@BeforeEach
void init() {
when(properties.client()).thenReturn(CLIENT_NAME);
when(mappingsRepresentation.getClientMappings()).thenReturn(Collections.emptyMap());
}
@Test
void shouldReturnEmptyListIfNoRolesAttached() {
var roles = service.getClientRoles(userResource);
assertThat(roles).isEmpty();
}
}
@Nested
class TestNullClientMappings {
@BeforeEach
void init() {
when(mappingsRepresentation.getClientMappings()).thenReturn(null);
}
@Test
void shouldReturnEmptyListIfNoRolesAttached() {
var roles = service.getClientRoles(userResource);
assertThat(roles).isEmpty();
}
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment