Search in sources :

Example 6 with RoleTypeService

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;
}
Also used : RoleTypeService(org.kuali.kfs.kim.framework.role.RoleTypeService) ArrayList(java.util.ArrayList)

Example 7 with RoleTypeService

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;
}
Also used : LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap) HashMap(java.util.HashMap) DelegationTypeService(org.kuali.kfs.kim.framework.common.delegate.DelegationTypeService) ArrayList(java.util.ArrayList) RoleTypeService(org.kuali.kfs.kim.framework.role.RoleTypeService) DelegateMember(org.kuali.kfs.kim.impl.common.delegate.DelegateMember) RoleMembership(org.kuali.kfs.kim.api.role.RoleMembership) DelegateType(org.kuali.kfs.kim.impl.common.delegate.DelegateType)

Example 8 with RoleTypeService

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;
}
Also used : RoleTypeService(org.kuali.kfs.kim.framework.role.RoleTypeService) ArrayList(java.util.ArrayList)

Example 9 with RoleTypeService

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;
    }
}
Also used : RoleTypeService(org.kuali.kfs.kim.framework.role.RoleTypeService) Cacheable(org.springframework.cache.annotation.Cacheable)

Example 10 with RoleTypeService

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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RoleTypeService(org.kuali.kfs.kim.framework.role.RoleTypeService) RoleMembership(org.kuali.kfs.kim.api.role.RoleMembership) HashSet(java.util.HashSet)

Aggregations

RoleTypeService (org.kuali.kfs.kim.framework.role.RoleTypeService)10 ArrayList (java.util.ArrayList)8 HashMap (java.util.HashMap)5 RoleMembership (org.kuali.kfs.kim.api.role.RoleMembership)4 DelegateType (org.kuali.kfs.kim.impl.common.delegate.DelegateType)4 List (java.util.List)3 DelegationTypeService (org.kuali.kfs.kim.framework.common.delegate.DelegationTypeService)3 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)3 HashSet (java.util.HashSet)2 Map (java.util.Map)2 DelegateMember (org.kuali.kfs.kim.impl.common.delegate.DelegateMember)2 MultiValueMap (org.springframework.util.MultiValueMap)2 Timestamp (java.sql.Timestamp)1 Date (java.util.Date)1 KimTypeService (org.kuali.kfs.kim.framework.type.KimTypeService)1 KimType (org.kuali.kfs.kim.impl.type.KimType)1 Cacheable (org.springframework.cache.annotation.Cacheable)1