Newer
Older
* Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
import java.util.Collection;
import java.util.Date;
import java.util.List;

OZGCloud
committed
import java.util.Map;
import java.util.Set;
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.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
import de.ozgcloud.user.keycloak.KeycloakApiProperties;
@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
public abstract class UserResourceMapper {
@Inject
KeycloakApiProperties properties;
@Inject
RealmResource realm;
@Mapping(target = "createdAt", expression = "java(mapCreatedAt(userRes))")
@Mapping(target = "email", expression = "java(mapEmail(userRes))")
@Mapping(target = "firstName", expression = "java(mapFirstName(userRes))")
@Mapping(target = "lastName", expression = "java(mapLastName(userRes))")
@Mapping(target = "fullName", expression = "java(mapFullName(userRes))")
@Mapping(target = "fullNameReversed", expression = "java(mapFullNameReversed(userRes))")
@Mapping(target = "username", expression = "java(mapUsername(userRes))")
@Mapping(target = "externalId", expression = "java(mapId(userRes))")
@Mapping(target = "keycloakUserId", expression = "java(mapKeycloakUserId(userRes))")
@Mapping(target = "organisationsEinheitIds", expression = "java(mapOrganisationsEinheitIds(userRes))")
@Mapping(target = "roles", expression = "java(mapRoles(userRes))")
@Mapping(target = "lastSyncTimestamp", ignore = true)
@Mapping(target = "deleted", ignore = true)
public abstract User toKopUser(UserResource userRes);
Date mapCreatedAt(UserResource userRes) {
var createdAt = userRes.toRepresentation().getCreatedTimestamp();

OZGCloud
committed
return Optional.ofNullable(createdAt).map(Date::new).orElse(new Date());
Set<String> mapOrganisationsEinheitIds(UserResource userRes) {
var groups = userRes.groups();
return Stream.concat(
getOrganisationsEinheitIdsFromGroups(groups),
getOrganisationsEinheitIdsFromUser(userRes)
)
private Stream<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) {
return groups.stream()

OZGCloud
committed
.map(this::mapGroup)
.filter(Objects::nonNull)
.map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey()))
.filter(Objects::nonNull)
.flatMap(Collection::stream);
private Stream<String> getOrganisationsEinheitIdsFromUser(UserResource userRes) {
return getUserAttributes(userRes)
.map(attributes -> attributes.get(properties.organisationsEinheitIdKey()))
.stream();

OZGCloud
committed
private Map<String, List<String>> mapGroup(GroupRepresentation group) {
var groupFromRealm = realm.getGroupByPath(group.getPath());
return Optional.ofNullable(groupFromRealm).map(GroupRepresentation::getAttributes).orElse(null);
}
List<String> mapRoles(UserResource userRes) {
var roleRepresentation = Optional.ofNullable(userRes.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();
}
String mapId(UserResource userRes) {
var userRepresentation = userRes.toRepresentation();
return Optional.ofNullable(userRepresentation.getAttributes())
.map(attributes -> attributes.get(properties.ldapIdKey()))
.orElseGet(userRepresentation::getId);
String mapKeycloakUserId(UserResource userRes) {
return userRes.toRepresentation().getId();
}
String mapEmail(UserResource userRes) {
return userRes.toRepresentation().getEmail();
}
String mapFirstName(UserResource userRes) {
return userRes.toRepresentation().getFirstName();
}
String mapLastName(UserResource userRes) {
return userRes.toRepresentation().getLastName();
}
String mapUsername(UserResource userRes) {
return userRes.toRepresentation().getUsername();
}
String mapFullName(UserResource userRes) {
return String.join(" ", Stream.of(userRes.toRepresentation().getFirstName(), userRes.toRepresentation().getLastName())
.filter(Objects::nonNull).toArray(String[]::new));
String mapFullNameReversed(UserResource userRes) {
return String.join(" ", Stream.of(userRes.toRepresentation().getLastName(), userRes.toRepresentation().getFirstName())
.filter(Objects::nonNull).toArray(String[]::new));
private Optional<Map<String, List<String>>> getUserAttributes(UserResource userResource) {
return Optional.ofNullable(userResource.toRepresentation().getAttributes());