Skip to content
Snippets Groups Projects
UserResourceMapper.java 6 KiB
Newer Older
  • Learn to ignore specific revisions
  •  * 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.
     */
    
    package de.ozgcloud.user;
    
    import java.util.Collections;
    
    import java.util.Date;
    import java.util.List;
    
    import java.util.Objects;
    
    import java.util.Optional;
    
    import java.util.stream.Collectors;
    
    import java.util.stream.Stream;
    
    OZGCloud's avatar
    OZGCloud committed
    import jakarta.inject.Inject;
    
    
    Lukas Malte Monnerjahn's avatar
    Lukas Malte Monnerjahn committed
    import org.apache.commons.lang3.StringUtils;
    
    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;
    
    
    	@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))")
    
    OZGCloud's avatar
    OZGCloud committed
    	@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();
    
    
    		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)
    				)
    
    Lukas Malte Monnerjahn's avatar
    Lukas Malte Monnerjahn committed
    				.filter(StringUtils::isNotBlank)
    
    				.collect(Collectors.toSet());
    
    	private Stream<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) {
    
    				.filter(Objects::nonNull)
    				.map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey()))
    
    	private Stream<String> getOrganisationsEinheitIdsFromUser(UserResource userRes) {
    
    Lukas Malte Monnerjahn's avatar
    Lukas Malte Monnerjahn committed
    		return getUserAttributes(userRes)
    				.map(attributes -> attributes.get(properties.organisationsEinheitIdKey()))
    
    				.orElse(Collections.emptyList())
    
    	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();
    
    OZGCloud's avatar
    OZGCloud committed
    
    		return Optional.ofNullable(userRepresentation.getAttributes())
    				.map(attributes -> attributes.get(properties.ldapIdKey()))
    
    Lukas Malte Monnerjahn's avatar
    Lukas Malte Monnerjahn committed
    				.map(List::getFirst)
    
    				.orElseGet(userRepresentation::getId);
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    	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();
    	}
    
    OZGCloud's avatar
    OZGCloud committed
    	String mapFullName(UserResource userRes) {
    		return String.join(" ", Stream.of(userRes.toRepresentation().getFirstName(), userRes.toRepresentation().getLastName())
    				.filter(Objects::nonNull).toArray(String[]::new));
    
    OZGCloud's avatar
    OZGCloud committed
    	String mapFullNameReversed(UserResource userRes) {
    		return String.join(" ", Stream.of(userRes.toRepresentation().getLastName(), userRes.toRepresentation().getFirstName())
    				.filter(Objects::nonNull).toArray(String[]::new));
    
    Lukas Malte Monnerjahn's avatar
    Lukas Malte Monnerjahn committed
    	private Optional<Map<String, List<String>>> getUserAttributes(UserResource userResource) {
    		return Optional.ofNullable(userResource.toRepresentation().getAttributes());