Skip to content
Snippets Groups Projects
Commit bb4f77b1 authored by Lukas Malte Monnerjahn's avatar Lukas Malte Monnerjahn
Browse files

Merge pull request 'OZG-6897 Get OrganisationseinheitIds from Groups and...

Merge pull request 'OZG-6897 Get OrganisationseinheitIds from Groups and Property on User' (#133) from OZG-6897-get-oeids-from-groups-and-property-on-user into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/user-manager/pulls/133


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents 35e60737 3a6c3195
No related branches found
No related tags found
No related merge requests found
...@@ -23,18 +23,20 @@ ...@@ -23,18 +23,20 @@
*/ */
package de.ozgcloud.user; package de.ozgcloud.user;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation; import org.keycloak.representations.idm.ClientMappingsRepresentation;
...@@ -78,18 +80,27 @@ public abstract class UserResourceMapper { ...@@ -78,18 +80,27 @@ public abstract class UserResourceMapper {
Set<String> mapOrganisationsEinheitIds(UserResource userRes) { Set<String> mapOrganisationsEinheitIds(UserResource userRes) {
var groups = userRes.groups(); var groups = userRes.groups();
var organisationsEinheitIds = getOrganisationsEinheitIdsFromGroups(groups); return Stream.concat(
return new HashSet<>(organisationsEinheitIds); getOrganisationsEinheitIdsFromGroups(groups),
getOrganisationsEinheitIdsFromUser(userRes)
)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
} }
private List<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) { private Stream<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) {
return groups.stream() return groups.stream()
.map(this::mapGroup) .map(this::mapGroup)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey())) .map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey()))
.filter(Objects::nonNull) .flatMap(Collection::stream);
.map(attributeValues -> attributeValues.get(0)) }
.toList();
private Stream<String> getOrganisationsEinheitIdsFromUser(UserResource userRes) {
return getUserAttributes(userRes)
.map(attributes -> attributes.get(properties.organisationsEinheitIdKey()))
.orElse(Collections.emptyList())
.stream();
} }
private Map<String, List<String>> mapGroup(GroupRepresentation group) { private Map<String, List<String>> mapGroup(GroupRepresentation group) {
...@@ -113,7 +124,7 @@ public abstract class UserResourceMapper { ...@@ -113,7 +124,7 @@ public abstract class UserResourceMapper {
return Optional.ofNullable(userRepresentation.getAttributes()) return Optional.ofNullable(userRepresentation.getAttributes())
.map(attributes -> attributes.get(properties.ldapIdKey())) .map(attributes -> attributes.get(properties.ldapIdKey()))
.map(id -> id.get(0)) .map(List::getFirst)
.orElseGet(userRepresentation::getId); .orElseGet(userRepresentation::getId);
} }
...@@ -147,4 +158,8 @@ public abstract class UserResourceMapper { ...@@ -147,4 +158,8 @@ public abstract class UserResourceMapper {
return String.join(" ", Stream.of(userRes.toRepresentation().getLastName(), userRes.toRepresentation().getFirstName()) return String.join(" ", Stream.of(userRes.toRepresentation().getLastName(), userRes.toRepresentation().getFirstName())
.filter(Objects::nonNull).toArray(String[]::new)); .filter(Objects::nonNull).toArray(String[]::new));
} }
private Optional<Map<String, List<String>>> getUserAttributes(UserResource userResource) {
return Optional.ofNullable(userResource.toRepresentation().getAttributes());
}
} }
...@@ -35,12 +35,12 @@ class GroupRepresentationTestFactory { ...@@ -35,12 +35,12 @@ class GroupRepresentationTestFactory {
return group; return group;
} }
public static GroupRepresentation createByPathAndOrganisationEinheitId(String groupPath, String organisationEinheitId) { public static GroupRepresentation createByPathAndOrganisationEinheitIds(String groupPath, String... organisationEinheitIds) {
var groupRepresentation = new GroupRepresentation(); var groupRepresentation = new GroupRepresentation();
groupRepresentation.setName(groupPath); groupRepresentation.setName(groupPath);
groupRepresentation.setPath(groupPath); groupRepresentation.setPath(groupPath);
groupRepresentation.setAttributes(Map.of(UserResourceMapperTest.ORGANISATIONS_EINHEIT_ID_KEY, groupRepresentation.setAttributes(Map.of(UserResourceMapperTest.ORGANISATIONS_EINHEIT_ID_KEY,
List.of(organisationEinheitId))); List.of(organisationEinheitIds)));
return groupRepresentation; return groupRepresentation;
} }
} }
...@@ -29,6 +29,7 @@ import static org.mockito.Mockito.*; ...@@ -29,6 +29,7 @@ import static org.mockito.Mockito.*;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
...@@ -36,14 +37,15 @@ import org.junit.jupiter.api.Nested; ...@@ -36,14 +37,15 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.admin.client.resource.RoleMappingResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.ClientMappingsRepresentation; import org.keycloak.representations.idm.ClientMappingsRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation; import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.RoleRepresentation;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.user.keycloak.KeycloakApiProperties; import de.ozgcloud.user.keycloak.KeycloakApiProperties;
...@@ -55,9 +57,7 @@ class UserResourceMapperTest { ...@@ -55,9 +57,7 @@ class UserResourceMapperTest {
static final String GROUP_1_PATH = "/group1"; static final String GROUP_1_PATH = "/group1";
static final String GROUP_2_PATH = "/group2"; static final String GROUP_2_PATH = "/group2";
static final Map<String, List<String>> ATTRIBUTES_1 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1)); @Spy
static final Map<String, List<String>> ATTRIBUTES_2 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_2));
@InjectMocks @InjectMocks
UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class); UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class);
...@@ -67,6 +67,8 @@ class UserResourceMapperTest { ...@@ -67,6 +67,8 @@ class UserResourceMapperTest {
@Mock @Mock
RealmResource realm; RealmResource realm;
final Set<String> organisationsEinheitIds = Set.of(ORGANISATIONS_EINHEIT_ID_1);
@DisplayName("To kop user") @DisplayName("To kop user")
@Nested @Nested
class TestToKopUser { class TestToKopUser {
...@@ -74,13 +76,8 @@ class UserResourceMapperTest { ...@@ -74,13 +76,8 @@ class UserResourceMapperTest {
@BeforeEach @BeforeEach
void init() { void init() {
when(properties.ldapIdKey()).thenReturn("LDAP_ID"); when(properties.ldapIdKey()).thenReturn("LDAP_ID");
when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId");
when(properties.client()).thenReturn("alfa");
when(realm.getGroupByPath(GROUP_1_PATH))
.thenReturn(GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1));
when(properties.ldapIdKey()).thenReturn("LDAP_ID");
when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId");
when(properties.client()).thenReturn("alfa"); when(properties.client()).thenReturn("alfa");
doReturn(organisationsEinheitIds).when(mapper).mapOrganisationsEinheitIds(any());
} }
@Test @Test
...@@ -139,26 +136,9 @@ class UserResourceMapperTest { ...@@ -139,26 +136,9 @@ class UserResourceMapperTest {
@Test @Test
void shouldMapOrganisationsEinheitIds() { void shouldMapOrganisationsEinheitIds() {
var user = toKopUser(); var result = toKopUser();
assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().contains(ORGANISATIONS_EINHEIT_ID_1);
}
@Test
void shouldMapMultipleOrganisationsEinheitIds() {
var groupRepresentation = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_2_PATH,
ORGANISATIONS_EINHEIT_ID_2);
when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(groupRepresentation);
var user = toKopUser(buildUserResourceWithGroups());
assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().hasSize(2).contains(ORGANISATIONS_EINHEIT_ID_2); assertThat(result.getOrganisationsEinheitIds()).hasSameElementsAs(organisationsEinheitIds);
}
private UserResource buildUserResourceWithGroups() {
return UserResourceTestFactory.createWithGroups(List.of(
GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_1_PATH),
GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_2_PATH)));
} }
@Test @Test
...@@ -198,6 +178,65 @@ class UserResourceMapperTest { ...@@ -198,6 +178,65 @@ class UserResourceMapperTest {
} }
} }
@DisplayName("Map organisations einheit ids")
@Nested
class TestMapOrganisationsEinheitIds {
static final String ORGANISATIONS_EINHEIT_ID_3 = "6287";
private final GroupRepresentation group1 = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitIds(
GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_3);
private final GroupRepresentation group2 = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitIds(
GROUP_2_PATH, ORGANISATIONS_EINHEIT_ID_2);
@BeforeEach
void beforeEach() {
when(properties.organisationsEinheitIdKey()).thenReturn(ORGANISATIONS_EINHEIT_ID_KEY);
}
@Test
void shouldMapOrganisationsEinheitIdsFromSingleGroup() {
var userResource = UserResourceTestFactory.createWithGroups(group1);
when(realm.getGroupByPath(GROUP_1_PATH)).thenReturn(group1);
var result = mapper.mapOrganisationsEinheitIds(userResource);
assertThat(result).containsExactlyInAnyOrder(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_3);
}
@Test
void shouldMapOrganisationsEinheitIdsFromGroups() {
var userResource = UserResourceTestFactory.createWithGroups(group1, group2);
when(realm.getGroupByPath(GROUP_1_PATH)).thenReturn(group1);
when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(group2);
var result = mapper.mapOrganisationsEinheitIds(userResource);
assertThat(result).containsExactlyInAnyOrder(
ORGANISATIONS_EINHEIT_ID_1,
ORGANISATIONS_EINHEIT_ID_2,
ORGANISATIONS_EINHEIT_ID_3
);
}
@Test
void shouldMapOrganisationsEinheitIdsFromUser() {
var attributes = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_2));
var userResource = UserResourceTestFactory.createWithAttributes(attributes);
var result = mapper.mapOrganisationsEinheitIds(userResource);
assertThat(result).containsExactlyInAnyOrder(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_2);
}
@Test
void shouldReturnEmptyIfNoOrganisationsEinheitIds() {
var userResource = UserResourceTestFactory.create();
var result = mapper.mapOrganisationsEinheitIds(userResource);
assertThat(result).isEmpty();
}
}
@DisplayName("Get client roles") @DisplayName("Get client roles")
@Nested @Nested
class TestGetClientRoles { class TestGetClientRoles {
...@@ -208,8 +247,6 @@ class UserResourceMapperTest { ...@@ -208,8 +247,6 @@ class UserResourceMapperTest {
@Mock @Mock
RoleMappingResource roleMappingResource; RoleMappingResource roleMappingResource;
@Mock @Mock
RoleScopeResource roleScopeResource;
@Mock
MappingsRepresentation mappingsRepresentation; MappingsRepresentation mappingsRepresentation;
@Mock @Mock
Map<String, ClientMappingsRepresentation> clientMappingsRepresentation; Map<String, ClientMappingsRepresentation> clientMappingsRepresentation;
......
...@@ -39,7 +39,7 @@ public class UserResourceTestFactory { ...@@ -39,7 +39,7 @@ public class UserResourceTestFactory {
return new UserResourceStub(attributes); return new UserResourceStub(attributes);
} }
public static UserResource createWithGroups(List<GroupRepresentation> groups) { public static UserResource createWithGroups(GroupRepresentation... groups) {
return new UserResourceStub(groups); return new UserResourceStub(List.of(groups));
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment