All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.imunity.scim.group.GroupRetrievalService Maven / Gradle / Ivy
/*
* Copyright (c) 2021 Bixbit - Krzysztof Benedyczak. All rights reserved.
* See LICENCE.txt file for licensing information.
*/
package io.imunity.scim.group;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import io.imunity.scim.MembershipGroupsUtils;
import io.imunity.scim.config.SCIMEndpointDescription;
import io.imunity.scim.group.GroupAuthzService.SCIMGroupAuthzServiceFactory;
import io.imunity.scim.group.GroupMember.Builder;
import io.imunity.scim.group.GroupMember.MemberType;
import pl.edu.icm.unity.MessageSource;
import pl.edu.icm.unity.base.utils.Log;
import pl.edu.icm.unity.engine.api.GroupsManagement;
import pl.edu.icm.unity.engine.api.attributes.AttributeSupport;
import pl.edu.icm.unity.engine.api.bulk.BulkGroupQueryService;
import pl.edu.icm.unity.engine.api.bulk.EntityInGroupData;
import pl.edu.icm.unity.engine.api.bulk.GroupStructuralData;
import pl.edu.icm.unity.exceptions.EngineException;
import pl.edu.icm.unity.stdext.identity.PersistentIdentity;
import pl.edu.icm.unity.stdext.utils.EntityNameMetadataProvider;
import pl.edu.icm.unity.types.basic.AttributeExt;
import pl.edu.icm.unity.types.basic.AttributeType;
import pl.edu.icm.unity.types.basic.Group;
import pl.edu.icm.unity.types.basic.GroupContents;
import pl.edu.icm.unity.types.basic.Identity;
class GroupRetrievalService
{
static final String DEFAULT_META_VERSION = "v1";
private static final Logger log = Log.getLogger(Log.U_SERVER_SCIM, GroupRetrievalService.class);
private final GroupAuthzService authzMan;
private final MessageSource msg;
private final GroupsManagement groupsMan;
private final BulkGroupQueryService bulkService;
private final AttributeSupport attrSupport;
private final SCIMEndpointDescription configuration;
GroupRetrievalService(MessageSource msg, GroupAuthzService authzMan, GroupsManagement groupMan,
BulkGroupQueryService bulkService, AttributeSupport attrSupport, SCIMEndpointDescription configuration)
{
this.msg = msg;
this.authzMan = authzMan;
this.groupsMan = groupMan;
this.bulkService = bulkService;
this.configuration = configuration;
this.attrSupport = attrSupport;
}
GroupData getGroup(GroupId groupId) throws EngineException
{
authzMan.checkReadGroups();
GroupStructuralData bulkStructuralData = bulkService.getBulkStructuralData("/");
Map allGroupsWithSubgroups = bulkService.getGroupAndSubgroups(bulkStructuralData);
List effectiveMembershipGroups = MembershipGroupsUtils.getEffectiveMembershipGroups(
configuration.membershipGroups, configuration.excludedMembershipGroups, allGroupsWithSubgroups.values()
.stream().collect(Collectors.toMap(g -> g.getGroup().getPathEncoded(), g -> g.getGroup())));
assertIsMembershipGroup(groupId.id, effectiveMembershipGroups);
if (!authzMan.getFilter().test(groupId.id))
{
throw new GroupNotFoundException("Invalid group " + groupId.id);
}
Map membershipInfo = bulkService
.getMembershipInfo(bulkService.getBulkMembershipData(groupId.id));
Map attributesInfo = bulkService
.getMembershipInfo(bulkService.getBulkMembershipData(configuration.rootGroup));
Map groupAndSubgroups = bulkService.getGroupAndSubgroups(bulkStructuralData, groupId.id);
GroupContents main = groupAndSubgroups.get(groupId.id);
Optional nameAttribute = getNameAttribute();
List members = new ArrayList<>();
membershipInfo.values().forEach(m -> members
.add(mapToUserMember(m, Optional.ofNullable(attributesInfo.get(m.entity.getId())), nameAttribute)));
groupAndSubgroups.values().stream()
.filter(g -> !g.equals(main) && effectiveMembershipGroups.contains(g.getGroup().getPathEncoded()))
.forEach(g -> members.add(mapToGroupMemeber(g)));
return GroupData.builder().withDisplayName(main.getGroup().getDisplayedNameShort(msg).getValue(msg))
.withId(main.getGroup().getPathEncoded()).withMembers(members).build();
}
private Optional getNameAttribute() throws EngineException
{
AttributeType attributeTypeWithSingeltonMetadata = attrSupport
.getAttributeTypeWithSingeltonMetadata(EntityNameMetadataProvider.NAME);
return Optional.ofNullable(
attributeTypeWithSingeltonMetadata != null ? attributeTypeWithSingeltonMetadata.getName() : null);
}
List getGroups() throws EngineException
{
authzMan.checkReadGroups();
List groups = new ArrayList<>();
Map membershipInfo = bulkService
.getMembershipInfo(bulkService.getBulkMembershipData("/"));
Optional nameAttribute = getNameAttribute();
Map attributesInfo = bulkService
.getMembershipInfo(bulkService.getBulkMembershipData(configuration.rootGroup));
Map allGroupsWithSubgroups = bulkService
.getGroupAndSubgroups(bulkService.getBulkStructuralData("/"));
Predicate filter = authzMan.getFilter();
List effectiveMembershipGroups = MembershipGroupsUtils.getEffectiveMembershipGroups(
configuration.membershipGroups, configuration.excludedMembershipGroups, allGroupsWithSubgroups.values()
.stream().collect(Collectors.toMap(g -> g.getGroup().getPathEncoded(), g -> g.getGroup())));
for (String configuredMemebershipGroup : effectiveMembershipGroups.stream().filter(filter).sorted()
.collect(Collectors.toList()))
{
GroupContents main = allGroupsWithSubgroups.get(configuredMemebershipGroup);
if (main == null)
{
log.warn("Can not get configured membership group " + configuredMemebershipGroup);
continue;
}
fillMembersAndAddGroupResource(main, allGroupsWithSubgroups, nameAttribute, membershipInfo, attributesInfo,
effectiveMembershipGroups, groups);
}
return groups;
}
private void fillMembersAndAddGroupResource(GroupContents group, Map groupAndSubgroups,
Optional nameAttribute, Map membershipInfo,
Map membershipInfoForAttr, List effectiveMembershipGroups,
List groups)
{
List members = new ArrayList<>();
membershipInfo.values().stream().filter(e -> e.groups.contains(group.getGroup().getPathEncoded()))
.forEach(e -> members.add(mapToUserMember(e,
Optional.ofNullable(membershipInfoForAttr.get(e.entity.getId())), nameAttribute)));
groupAndSubgroups.values().stream()
.filter(g -> Group.isDirectChild(g.getGroup().getPathEncoded(), group.getGroup().getPathEncoded())
&& effectiveMembershipGroups.contains(g.getGroup().getPathEncoded()))
.forEach(g ->
{
members.add(mapToGroupMemeber(g));
});
groups.add(GroupData.builder().withDisplayName(group.getGroup().getDisplayedNameShort(msg).getValue(msg))
.withId(group.getGroup().getPathEncoded()).withMembers(members).build());
}
private GroupMember mapToGroupMemeber(GroupContents group)
{
return GroupMember.builder().withValue(group.getGroup().getPathEncoded()).withType(MemberType.Group)
.withDisplayName(group.getGroup().getDisplayedNameShort(msg).getValue(msg)).build();
}
private GroupMember mapToUserMember(EntityInGroupData entityInGroupData,
Optional entityInGroupDataForAttr, Optional nameAttribute)
{
Identity persistence = entityInGroupData.entity.getIdentities().stream()
.filter(i -> i.getTypeId().equals(PersistentIdentity.ID)).findFirst().get();
Builder userMember = GroupMember.builder().withValue(persistence.getComparableValue())
.withType(MemberType.User);
if (nameAttribute.isPresent() && entityInGroupDataForAttr.isPresent())
{
AttributeExt displayedName = entityInGroupDataForAttr.get().groupAttributesByName.get(nameAttribute.get());
if (displayedName != null && displayedName.getValues().size() > 0)
{
userMember.withDisplayName(displayedName.getValues().get(0));
}
}
return userMember.build();
}
private void assertIsMembershipGroup(String group, List effectiveMembershipGroups) throws EngineException
{
if (groupsMan.isPresent(group))
{
if (effectiveMembershipGroups.stream().anyMatch(g -> g.equals(group)))
{
return;
}
}
log.error("Group " + group + " is out of range for configured membership groups");
throw new GroupNotFoundException("Invalid group " + group);
}
@Component
static class SCIMGroupRetrievalServiceFactory
{
private final GroupsManagement groupMan;
private final BulkGroupQueryService bulkService;
private final SCIMGroupAuthzServiceFactory authzManFactory;
private final MessageSource msg;
private final AttributeSupport attrSupport;
@Autowired
SCIMGroupRetrievalServiceFactory(MessageSource msg, @Qualifier("insecure") GroupsManagement groupMan,
@Qualifier("insecure") BulkGroupQueryService bulkService, SCIMGroupAuthzServiceFactory authzManFactory,
AttributeSupport attrSupport)
{
this.groupMan = groupMan;
this.bulkService = bulkService;
this.authzManFactory = authzManFactory;
this.msg = msg;
this.attrSupport = attrSupport;
}
GroupRetrievalService getService(SCIMEndpointDescription configuration)
{
return new GroupRetrievalService(msg, authzManFactory.getService(configuration), groupMan, bulkService,
attrSupport, configuration);
}
}
}