use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceBase method getRoleMembersByExactQualifierMatch.
protected List<RoleMember> getRoleMembersByExactQualifierMatch(RoleContract role, String memberId, RoleDaoAction daoActionToTake, Map<String, String> qualifier) {
List<RoleMember> rms = new ArrayList<>();
RoleTypeService roleTypeService = getRoleTypeService(role.getId());
if (roleTypeService != null) {
List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
switch(daoActionToTake) {
case ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS:
// Search for group role members only.
rms = getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(role.getId()), Collections.singletonList(memberId), populateQualifiersForExactMatch(qualifier, attributesForExactMatch));
break;
case ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS:
// Search for principal role members only.
rms = getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collections.singletonList(role.getId()), memberId, populateQualifiersForExactMatch(qualifier, attributesForExactMatch));
break;
case ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS:
// Search for roles as role members only.
List<RoleMember> allRoleMembers = getStoredRoleMembershipsForRoleIdsAsMembers(Collections.singletonList(role.getId()), populateQualifiersForExactMatch(qualifier, attributesForExactMatch));
for (RoleMember rm : allRoleMembers) {
if (rm.getMemberId().equals(memberId)) {
rms.add(rm);
}
}
break;
default:
// The daoActionToTake parameter is invalid; throw an exception.
throw new IllegalArgumentException("The 'daoActionToTake' parameter cannot refer to a " + "non-role-member-related value!");
}
}
}
return rms;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method matchesOnDelegation.
/**
* Support method for principalHasRole. Checks delegations on the passed in roles for the given principal and
* groups. (It's assumed that the principal belongs to the given groups.)
* <p>
* Delegation checks are mostly the same as role checks except that the delegateType itself is qualified against the
* original role (like a RolePrincipal or RoleGroup.) And then, the members of that delegateType may have additional
* qualifiers which are not part of the original role qualifiers.
* <p>
* For example:
* <p>
* A role could be qualified by organization. So, there is a person in the organization with primary authority for
* that org. But, then they delegate authority for that organization (not their authority - the delegateType is
* attached to the org.) So, in this case the delegateType has a qualifier of the organization when it is attached
* to the role.
* <p>
* The principals then attached to that delegateType (which is specific to the organization), may have additional
* qualifiers.
* For Example: dollar amount range, effective dates, document types.
* As a subsequent step, those qualifiers are checked against the qualification passed in from the client.
*/
protected boolean matchesOnDelegation(Set<String> allRoleIds, String principalId, List<String> principalGroupIds, Map<String, String> qualification, Context context) {
// get the list of delegations for the roles
Map<String, DelegateType> delegations = getStoredDelegationImplMapFromRoleIds(allRoleIds);
// roles do not have dynamic membership
if (delegations.isEmpty()) {
for (String roleId : allRoleIds) {
RoleLite role = loadRole(roleId);
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
if (!context.isDerivedRoleType(role.getKimTypeId()) || roleTypeService == null || !roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) {
putPrincipalHasRoleInCache(false, principalId, roleId, qualification, true);
}
}
return false;
}
// Build a map from a role ID to the delegations for that role ID
Map<String, List<DelegateType>> roleToDelegations = new HashMap<>();
for (DelegateType delegation : delegations.values()) {
List<DelegateType> roleDelegations = roleToDelegations.computeIfAbsent(delegation.getRoleId(), k -> new ArrayList<>());
roleDelegations.add(delegation);
}
// Iterate through each role and check its delegations to determine if the principal has one of the roles
for (String roleId : roleToDelegations.keySet()) {
boolean matchesOnRoleDelegation = false;
RoleLite role = getRoleWithoutMembers(roleId);
RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId());
// delegation
for (DelegateType delegation : roleToDelegations.get(roleId)) {
// If the delegation isn't active skip it
if (!delegation.isActive()) {
continue;
}
// principal
for (DelegateMember delegateMember : delegation.getMembers()) {
// If the membership isn't active skip the rest of the checks
if (!delegateMember.isActive(new Timestamp(new Date().getTime()))) {
continue;
}
// principal ID
if (MemberType.PRINCIPAL.equals(delegateMember.getType()) && !delegateMember.getMemberId().equals(principalId)) {
continue;
}
// of groups the principal belongs to
if (MemberType.GROUP.equals(delegateMember.getType()) && !principalGroupIds.contains(delegateMember.getMemberId())) {
continue;
}
// principal is a member of that role
if (MemberType.ROLE.equals(delegateMember.getType()) && !principalHasRole(principalId, Collections.singletonList(delegateMember.getMemberId()), qualification, false)) {
continue;
}
// it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, delegateMember.getQualifier())) {
continue;
}
} catch (Exception ex) {
LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for " + "role Id: " + delegation.getRoleId() + " / " + qualification + " / " + delegateMember.getQualifier(), ex);
continue;
}
// role service matches this qualifier
// now try the delegateType service
DelegationTypeService delegationTypeService = getDelegationTypeService(delegateMember.getDelegationId());
// QUESTION: does the qualifier map need to be merged with the main delegateType qualification?
if (delegationTypeService != null && !delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegateMember.getQualifier())) {
continue;
}
// if so, check that the original role member would match the given qualifiers
if (StringUtils.isNotBlank(delegateMember.getRoleMemberId())) {
RoleMember rm = getRoleMember(delegateMember.getRoleMemberId());
if (rm != null) {
// membership
if (!rm.isActive(new Timestamp(new Date().getTime()))) {
continue;
}
Map<String, String> roleQualifier = rm.getAttributes();
// catch this possibility.
try {
if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, roleQualifier)) {
continue;
}
} catch (Exception ex) {
LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type " + "service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + roleQualifier, ex);
continue;
}
} else {
LOG.warn("Unknown role member ID cited in the delegateType member table:");
LOG.warn(" assignedToId: " + delegateMember.getDelegationMemberId() + " / roleMemberId: " + delegateMember.getRoleMemberId());
}
}
// If we've made it here then all of the tests pass so the principal must belong to this
// delegation so set the flag to true and break out of this loop
matchesOnRoleDelegation = true;
break;
}
// If we've found a match for one of the delegations break out of this loop
if (matchesOnRoleDelegation) {
break;
}
}
// through one of these delegations
if (!context.isDerivedRoleType(role.getKimTypeId()) || roleTypeService == null || !roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) {
putPrincipalHasRoleInCache(matchesOnRoleDelegation, principalId, roleId, qualification, true);
}
// If we've found a matching delegation skip processing the rest of the roles
if (matchesOnRoleDelegation) {
return true;
}
}
// If we get here we didn't find a matching delegation so return false
return false;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method getDelegationTypeService.
protected DelegationTypeService getDelegationTypeService(String delegationId) {
DelegationTypeService service = null;
DelegateType delegateType = getKimDelegationImpl(delegationId);
KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(delegateType.getKimTypeId());
if (kimType != null) {
KimTypeService tempService = KimFrameworkServiceLocator.getKimTypeService(kimType);
if (tempService instanceof DelegationTypeService) {
service = (DelegationTypeService) tempService;
} else {
LOG.error("Service returned for type " + kimType + "(" + kimType.getName() + ") was not a DelegationTypeService. Was a " + (tempService != null ? tempService.getClass() : "(null)"));
}
} else {
// delegateType has no type - default to role type if possible
RoleTypeService roleTypeService = getRoleTypeService(delegateType.getRoleId());
if (roleTypeService instanceof DelegationTypeService) {
service = (DelegationTypeService) roleTypeService;
}
}
return service;
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method getNestedRoleQualifiersForPrincipalByRoleIds.
@Override
public List<Map<String, String>> getNestedRoleQualifiersForPrincipalByRoleIds(String principalId, List<String> roleIds, Map<String, String> qualification) throws IllegalStateException {
incomingParamCheck(principalId, "principalId");
incomingParamCheck(roleIds, "roleIds");
List<Map<String, String>> results = new ArrayList<>();
Map<String, RoleLite> rolesById = getRoleLiteMap(roleIds);
// get the person's groups
List<String> groupIds = getGroupService().getGroupIdsByPrincipalId(principalId);
List<RoleMember> roleMembers = getStoredRoleMembersUsingExactMatchOnQualification(principalId, groupIds, roleIds, qualification);
Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<>();
for (RoleMember roleMember : roleMembers) {
RoleTypeService roleTypeService = getRoleTypeService(roleMember.getRoleId());
// gather up the qualifier sets and the service they go with
if (MemberType.PRINCIPAL.equals(roleMember.getType()) || MemberType.GROUP.equals(roleMember.getType())) {
if (roleTypeService != null) {
List<RoleMembership> las = roleIdToMembershipMap.computeIfAbsent(roleMember.getRoleId(), k -> new ArrayList<>());
RoleMembership mi = RoleMembership.Builder.create(roleMember.getRoleId(), roleMember.getId(), roleMember.getMemberId(), roleMember.getType(), roleMember.getAttributes()).build();
las.add(mi);
} else {
results.add(roleMember.getAttributes());
}
} else if (MemberType.ROLE.equals(roleMember.getType())) {
// find out if the user has the role
// need to convert qualification using this role's service
Map<String, String> nestedQualification = qualification;
if (roleTypeService != null) {
RoleLite roleLite = rolesById.get(roleMember.getRoleId());
// pulling from here as the nested role is not necessarily (and likely is not)
// in the rolesById Map created earlier
RoleLite nestedRole = getRoleLite(roleMember.getMemberId());
// it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
nestedQualification = roleTypeService.convertQualificationForMemberRoles(roleLite.getNamespaceCode(), roleLite.getName(), nestedRole.getNamespaceCode(), nestedRole.getName(), qualification);
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleLite.getId(), ex);
}
}
List<String> nestedRoleId = new ArrayList<>(1);
nestedRoleId.add(roleMember.getMemberId());
// originally queries role
if (getProxiedRoleService().principalHasRole(principalId, nestedRoleId, nestedQualification, false)) {
results.add(roleMember.getAttributes());
}
}
}
for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) {
RoleTypeService roleTypeService = getRoleTypeService(entry.getKey());
// guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue());
for (RoleMembership roleMembership : matchingMembers) {
results.add(roleMembership.getQualifier());
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex);
}
}
return Collections.unmodifiableList(results);
}
use of org.kuali.kfs.kim.framework.role.RoleTypeService in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method getRoleMembers.
protected List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification, boolean followDelegations, Set<String> foundRoleTypeMembers) {
List<RoleMembership> results = new ArrayList<>();
Set<String> allRoleIds = new HashSet<>();
for (String roleId : roleIds) {
if (getProxiedRoleService().isRoleActive(roleId)) {
allRoleIds.add(roleId);
}
}
// short-circuit if no roles match
if (allRoleIds.isEmpty()) {
return Collections.emptyList();
}
Set<String> matchingRoleIds = new HashSet<>(allRoleIds.size());
// for efficiency, retrieve all roles and store in a map
Map<String, RoleLite> roles = getRoleLiteMap(allRoleIds);
List<String> copyRoleIds = new ArrayList<>(allRoleIds);
List<RoleMember> rms = new ArrayList<>();
for (String roleId : allRoleIds) {
RoleTypeService roleTypeService = getRoleTypeService(roleId);
if (roleTypeService != null) {
List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch();
if (CollectionUtils.isNotEmpty(attributesForExactMatch)) {
copyRoleIds.remove(roleId);
rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), null, populateQualifiersForExactMatch(qualification, attributesForExactMatch)));
}
}
}
if (CollectionUtils.isNotEmpty(copyRoleIds)) {
rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIds, null, null));
}
// build a map of role ID to membership information
// this will be used for later qualification checks
Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<>();
for (RoleMember roleMember : rms) {
RoleMembership mi = RoleMembership.Builder.create(roleMember.getRoleId(), roleMember.getId(), roleMember.getMemberId(), roleMember.getType(), roleMember.getAttributes()).build();
// if the qualification check does not need to be made, just add the result
if (qualification == null || qualification.isEmpty()) {
if (MemberType.ROLE.equals(roleMember.getType())) {
// if a role member type, do a non-recursive role member check to obtain the group and principal
// members of that role given the qualification
Map<String, String> nestedRoleQualification = qualification;
RoleTypeService roleTypeService = getRoleTypeService(roleMember.getRoleId());
if (roleTypeService != null) {
// get the member role object
RoleLite memberRole = getRoleLite(mi.getMemberId());
nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(roles.get(roleMember.getRoleId()).getNamespaceCode(), roles.get(roleMember.getRoleId()).getName(), memberRole.getNamespaceCode(), memberRole.getName(), qualification);
}
if (getProxiedRoleService().isRoleActive(roleMember.getRoleId())) {
Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, mi, foundRoleTypeMembers);
if (!nestedRoleMembers.isEmpty()) {
results.addAll(nestedRoleMembers);
matchingRoleIds.add(roleMember.getRoleId());
}
}
} else {
results.add(mi);
matchingRoleIds.add(roleMember.getRoleId());
}
matchingRoleIds.add(roleMember.getRoleId());
} else {
List<RoleMembership> lrmi = roleIdToMembershipMap.computeIfAbsent(mi.getRoleId(), k -> new ArrayList<>());
lrmi.add(mi);
}
}
// entries
if (!roleIdToMembershipMap.isEmpty()) {
// for evaluation, the service will return those which match
for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) {
// can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
RoleTypeService roleTypeService = getRoleTypeService(entry.getKey());
List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue());
// loop over the matching entries, adding them to the results
for (RoleMembership roleMemberships : matchingMembers) {
if (MemberType.ROLE.equals(roleMemberships.getType())) {
// if a role member type, do a non-recursive role member check to obtain the group and
// principal members of that role given the qualification get the member role object
RoleLite memberRole = getRoleLite(roleMemberships.getMemberId());
if (memberRole.isActive()) {
Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles(roles.get(roleMemberships.getRoleId()).getNamespaceCode(), roles.get(roleMemberships.getRoleId()).getName(), memberRole.getNamespaceCode(), memberRole.getName(), qualification);
Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, roleMemberships, foundRoleTypeMembers);
if (!nestedRoleMembers.isEmpty()) {
results.addAll(nestedRoleMembers);
matchingRoleIds.add(roleMemberships.getRoleId());
}
}
} else {
results.add(roleMemberships);
matchingRoleIds.add(roleMemberships.getRoleId());
}
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex);
}
}
}
// handle derived roles
for (String roleId : allRoleIds) {
RoleTypeService roleTypeService = getRoleTypeService(roleId);
RoleLite role = roles.get(roleId);
// check if a derived role
try {
if (isDerivedRoleType(roleTypeService)) {
// for each derived role, get the list of principals and groups which are in that role given the
// qualification (per the role type service)
List<RoleMembership> roleMembers = roleTypeService.getRoleMembersFromDerivedRole(role.getNamespaceCode(), role.getName(), qualification);
if (!roleMembers.isEmpty()) {
matchingRoleIds.add(roleId);
}
for (RoleMembership rm : roleMembers) {
RoleMembership.Builder builder = RoleMembership.Builder.create(rm);
builder.setRoleId(roleId);
builder.setId("*");
results.add(builder.build());
}
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
}
}
if (followDelegations && !matchingRoleIds.isEmpty()) {
// we have a list of RoleMembershipInfo objects
// need to get delegations for distinct list of roles in that list
Map<String, DelegateType> delegationIdToDelegationMap = getStoredDelegationImplMapFromRoleIds(matchingRoleIds);
if (!delegationIdToDelegationMap.isEmpty()) {
List<RoleMembership.Builder> membershipsWithDelegations = applyDelegationsToRoleMembers(results, delegationIdToDelegationMap.values(), qualification);
resolveDelegationMemberRoles(membershipsWithDelegations, qualification, foundRoleTypeMembers);
results = ModelObjectUtils.buildImmutableCopy(membershipsWithDelegations);
}
}
// all the matching role members
if (results.size() > 1) {
// if a single role: easy case
if (matchingRoleIds.size() == 1) {
String roleId = matchingRoleIds.iterator().next();
RoleTypeService roleTypeService = getRoleTypeService(roleId);
// can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
if (roleTypeService != null) {
results = roleTypeService.sortRoleMembers(results);
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
}
} else if (matchingRoleIds.size() > 1) {
// if more than one, check if there is only a single role type service
String prevServiceName = null;
boolean multipleServices = false;
for (String roleId : matchingRoleIds) {
String serviceName = KimApiServiceLocator.getKimTypeInfoService().getKimType(getRoleWithoutMembers(roleId).getKimTypeId()).getServiceName();
if (prevServiceName != null && !StringUtils.equals(prevServiceName, serviceName)) {
multipleServices = true;
break;
}
prevServiceName = serviceName;
}
if (!multipleServices) {
String roleId = matchingRoleIds.iterator().next();
// it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility.
try {
RoleTypeService kimRoleTypeService = getRoleTypeService(roleId);
if (kimRoleTypeService != null) {
results = kimRoleTypeService.sortRoleMembers(results);
}
} catch (Exception ex) {
LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex);
}
} else {
LOG.warn("Did not sort role members - multiple role type services found. Role Ids: " + matchingRoleIds);
}
}
}
return Collections.unmodifiableList(results);
}
Aggregations