use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method getStoredRoleGroupsUsingExactMatchOnQualification.
private List<RoleMember> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, Set<String> roleIds, Map<String, String> qualification) {
List<String> copyRoleIds = new ArrayList<>(roleIds);
List<RoleMember> roleMembers = new ArrayList<>();
for (String roleId : roleIds) {
RoleTypeService roleTypeService = getRoleTypeService(roleId);
if (roleTypeService != null) {
try {
List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
copyRoleIds.remove(roleId);
roleMembers.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(roleId), groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
}
} catch (Exception e) {
LOG.warn("Caught exception when attempting to invoke a role type service for role " + roleId, e);
}
}
}
if (CollectionUtils.isNotEmpty(copyRoleIds)) {
roleMembers.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(copyRoleIds, groupIds, null));
}
return roleMembers;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method applyDelegationsToRoleMembers.
/**
* Checks each of the result records to determine if there are potentially applicable delegation members for that
* role membership. If there are, applicable delegations and members will be linked to the RoleMemberships in the
* given list. An updated list will be returned from this method which includes the appropriate linked delegations.
*/
protected List<RoleMembership.Builder> applyDelegationsToRoleMembers(List<RoleMembership> roleMemberships, Collection<DelegateType> delegations, Map<String, String> qualification) {
MultiValueMap<String, String> roleIdToRoleMembershipIds = new LinkedMultiValueMap<>();
Map<String, RoleMembership.Builder> roleMembershipIdToBuilder = new HashMap<>();
List<RoleMembership.Builder> roleMembershipBuilders = new ArrayList<>();
// builders
for (RoleMembership roleMembership : roleMemberships) {
roleIdToRoleMembershipIds.add(roleMembership.getRoleId(), roleMembership.getId());
RoleMembership.Builder builder = RoleMembership.Builder.create(roleMembership);
roleMembershipBuilders.add(builder);
roleMembershipIdToBuilder.put(roleMembership.getId(), builder);
}
for (DelegateType delegation : delegations) {
// determine the candidate role memberships where this delegation can be mapped
List<String> candidateRoleMembershipIds = roleIdToRoleMembershipIds.get(delegation.getRoleId());
if (CollectionUtils.isNotEmpty(candidateRoleMembershipIds)) {
DelegationTypeService delegationTypeService = getDelegationTypeService(delegation.getDelegationId());
for (DelegateMember delegationMember : delegation.getMembers()) {
// Make sure that the delegation member is active
if (delegationMember.isActive(DateTime.now()) && (delegationTypeService == null || delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegationMember.getQualifier()))) {
// memberships on the role
if (StringUtils.isBlank(delegationMember.getRoleMemberId())) {
RoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId());
for (String roleMembershipId : candidateRoleMembershipIds) {
RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(roleMembershipId);
if (roleTypeService == null || roleTypeService.doesRoleQualifierMatchQualification(roleMembershipBuilder.getQualifier(), delegationMember.getQualifier())) {
linkDelegateToRoleMembership(delegation, delegationMember, roleMembershipBuilder);
}
}
} else if (candidateRoleMembershipIds.contains(delegationMember.getRoleMemberId())) {
RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(delegationMember.getRoleMemberId());
linkDelegateToRoleMembership(delegation, delegationMember, roleMembershipBuilder);
}
}
}
}
}
return roleMembershipBuilders;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method getStoredRoleMembersUsingExactMatchOnQualification.
private List<RoleMember> getStoredRoleMembersUsingExactMatchOnQualification(String principalId, List<String> groupIds, List<String> roleIds, Map<String, String> qualification) {
List<String> copyRoleIds = new ArrayList<>(roleIds);
List<RoleMember> roleMemberList = new ArrayList<>();
for (String roleId : roleIds) {
RoleTypeService roleTypeService = getRoleTypeService(roleId);
if (roleTypeService != null) {
try {
List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
copyRoleIds.remove(roleId);
roleMemberList.addAll(getStoredRoleMembersForRoleIdsWithFilters(Collections.singletonList(roleId), principalId, groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
}
} catch (Exception e) {
LOG.warn("Caught exception when attempting to invoke a role type service for role " + roleId, e);
}
}
}
if (CollectionUtils.isNotEmpty(copyRoleIds)) {
roleMemberList.addAll(getStoredRoleMembersForRoleIdsWithFilters(copyRoleIds, principalId, groupIds, null));
}
return roleMemberList;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method isDynamicRoleMembership.
@Cacheable(value = Role.CACHE_NAME, key = "'{isDynamicRoleMembership}' + 'roleId=' + #p0")
@Override
public boolean isDynamicRoleMembership(String roleId) {
incomingParamCheck(roleId, "roleId");
RoleTypeService service = getRoleTypeService(roleId);
try {
return dynamicRoleMembership(service, getRoleWithoutMembers(roleId));
} catch (Exception e) {
LOG.warn("Caught exception while invoking a role type service for role " + roleId, e);
// Returning true so the role won't be cached
return true;
}
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method principalHasRole.
protected boolean principalHasRole(Context context, String principalId, List<String> roleIds, Map<String, String> qualification, boolean checkDelegations) {
/*
* This method uses a multi-phase approach to determining if the given principal of any of the roles given
* based on the qualification map that is passed.
*
* Phase 1: Check the cache to find if it's already been determined that the principal is a member of any of
* the roles with the given ids.
* Phase 2: Perform exact database-level matching. This can be done for all roles if the given qualification
* map is null or empty since that means qualification matching does not need to be performed. It can
* also be done for roles who's RoleTypeService defines qualifiers for exact match.
* Phase 3: Use RoleTypeService matching for roles which have not already been checked. Will need to determine
* which role memberships match the given principal then delegate to the appropriate RoleTypeService
* to execute matching logic.
* Phase 4: Check nested roles.
* Phase 5: For any cases where derived roles are used, determine if the principal is a member of those
* derived roles.
* Phase 6: If checkDelegations is true, check if any delegations match
*/
try {
// Phase 1: first check if any of the role membership is cached, only proceed with checking the role ids
// that aren't already cached
List<String> roleIdsToCheck = new ArrayList<>(roleIds.size());
for (String roleId : roleIds) {
Boolean hasRole = getPrincipalHasRoleFromCache(principalId, roleId, qualification, checkDelegations);
if (hasRole != null) {
if (hasRole) {
return true;
}
} else {
roleIdsToCheck.add(roleId);
}
}
// load the roles, this will also filter out inactive roles!
List<RoleLite> roles = loadRoles(roleIdsToCheck);
// short-circuit if no roles match
if (roles.isEmpty()) {
return false;
}
// Phase 2: If they didn't pass any qualifications or they are using exact qualifier matching, we can go
// straight to the database
Set<String> rolesCheckedForExactMatch = new HashSet<>();
for (RoleLite role : roles) {
Map<String, String> qualificationForExactMatch = null;
if (qualification == null || qualification.isEmpty()) {
qualificationForExactMatch = new HashMap<>();
} else {
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
if (roleTypeService != null) {
List<String> attributesForExactMatch = getQualifiersForExactMatch(role.getKimTypeId(), roleTypeService);
if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
qualificationForExactMatch = populateQualifiersForExactMatch(qualification, attributesForExactMatch);
if (qualificationForExactMatch.isEmpty()) {
// go onto the next role.
continue;
}
}
}
}
if (qualificationForExactMatch != null) {
rolesCheckedForExactMatch.add(role.getId());
List<RoleMember> matchingRoleMembers = getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collections.singletonList(role.getId()), principalId, qualificationForExactMatch);
// if a role member matched our principal, we're good to go
if (CollectionUtils.isNotEmpty(matchingRoleMembers)) {
return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
// now check groups
if (!context.getPrincipalGroupIds().isEmpty()) {
List<RoleMember> matchingRoleGroupMembers = getStoredRoleGroupsUsingExactMatchOnQualification(context.getPrincipalGroupIds(), role.getId(), qualification);
if (CollectionUtils.isNotEmpty(matchingRoleGroupMembers)) {
return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
}
// if we drop to this point, either we didn't match or the role has nested or derived role
// membership, we'll check that later
}
}
for (RoleLite role : roles) {
// if we didn't do an exact match, we need to do a manual match
if (!rolesCheckedForExactMatch.contains(role.getId())) {
List<RoleMember> matchingPrincipalRoleMembers = getRoleMembersForPrincipalId(role.getId(), principalId);
List<RoleMember> matchingGroupRoleMembers = getRoleMembersForGroupIds(role.getId(), context.getPrincipalGroupIds());
List<RoleMembership> roleMemberships = convertToRoleMemberships(matchingPrincipalRoleMembers, matchingGroupRoleMembers);
for (RoleMembership roleMembership : roleMemberships) {
try {
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
if (!roleTypeService.getMatchingRoleMemberships(qualification, roleMemberships).isEmpty()) {
return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
} catch (Exception ex) {
LOG.warn("Unable to find role type service with id: " + role.getKimTypeId());
}
}
}
}
// Phase 4: If we have nested roles, execute a recursive check on those
// first, check that the qualifiers on the role membership match then, perform a principalHasRole on the
// embedded role
Map<String, RoleLite> roleIndex = new HashMap<>();
for (RoleLite role : roles) {
roleIndex.put(role.getId(), role);
}
List<RoleMember> roleMembers = getStoredRoleMembersForRoleIds(new ArrayList<>(roleIndex.keySet()), MemberType.ROLE.getCode(), null);
for (RoleMember roleMember : roleMembers) {
RoleLite role = roleIndex.get(roleMember.getRoleId());
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
if (roleTypeService != null) {
// it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
if (roleTypeService.doesRoleQualifierMatchQualification(qualification, roleMember.getAttributes())) {
RoleLite memberRole = getRoleLite(roleMember.getMemberId());
Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(role.getNamespaceCode(), role.getName(), memberRole.getNamespaceCode(), memberRole.getName(), qualification);
if (principalHasRole(context, principalId, Collections.singletonList(roleMember.getMemberId()), nestedRoleQualification, true)) {
return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleMember.getRoleId(), ex);
}
} else {
// no role type service, so can't convert qualification - just pass as is
if (principalHasRole(context, principalId, Collections.singletonList(roleMember.getMemberId()), qualification, true)) {
return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
}
}
// external system (application)
for (RoleLite role : roles) {
// to catch this possibility.
try {
boolean isDerivedRoleType = context.isDerivedRoleType(role.getKimTypeId());
if (isDerivedRoleType) {
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
if (roleTypeService.hasDerivedRole(principalId, context.getPrincipalGroupIds(), role.getNamespaceCode(), role.getName(), qualification)) {
if (!roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) {
putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations);
}
return true;
}
} else {
if (!checkDelegations) {
putPrincipalHasRoleInCache(false, principalId, role.getId(), qualification, false);
}
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + role.getId(), ex);
}
}
if (checkDelegations) {
if (matchesOnDelegation(roleIndex.keySet(), principalId, context.getPrincipalGroupIds(), qualification, context)) {
return true;
}
}
} catch (Exception e) {
LOG.warn("Caught exception during a principalHasRole check", e);
}
return false;
}
Aggregations