use of org.kuali.kfs.kim.impl.common.delegate.DelegateMember 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.impl.common.delegate.DelegateMember in project cu-kfs by CU-CommunityApps.
the class RoleServiceImpl method updateDelegateMember.
@CacheEvict(value = { Role.CACHE_NAME, RoleMembership.CACHE_NAME, RoleMember.CACHE_NAME, DelegateMember.CACHE_NAME, RoleResponsibility.CACHE_NAME, DelegateType.CACHE_NAME }, allEntries = true)
@Override
public DelegateMember updateDelegateMember(DelegateMember delegateMember) throws IllegalArgumentException, IllegalStateException {
// check delegateMember not empty
incomingParamCheck(delegateMember, "delegateMember");
// check delegate exists
String delegationId = delegateMember.getDelegationId();
incomingParamCheck(delegationId, "delegationId");
DelegateType delegate = getKimDelegationImpl(delegationId);
DelegateMember originalDelegateMember = null;
String delegationMemberId = delegateMember.getDelegationMemberId();
if (StringUtils.isNotEmpty(delegationMemberId)) {
originalDelegateMember = getDelegateMember(delegateMember.getDelegationMemberId());
}
if (delegate == null) {
throw new IllegalStateException("the delegate does not exist: " + delegationId);
}
// save the delegateMember (actually updates)
String kimTypeId = getRoleLite(delegate.getRoleId()).getKimTypeId();
List<DelegateMemberAttributeData> attrBos = KimAttributeData.createFrom(DelegateMemberAttributeData.class, delegateMember.getAttributes(), kimTypeId);
List<DelegateMemberAttributeData> updateAttrBos = new ArrayList<>();
boolean matched = false;
if (originalDelegateMember != null) {
delegateMember.setVersionNumber(originalDelegateMember.getVersionNumber());
for (DelegateMemberAttributeData newDelegateMemberAttrData : attrBos) {
for (DelegateMemberAttributeData oldDelegateMemberAttrData : originalDelegateMember.getAttributeDetails()) {
if (newDelegateMemberAttrData.getKimTypeId().equals(oldDelegateMemberAttrData.getKimTypeId()) && newDelegateMemberAttrData.getKimAttributeId().equals(oldDelegateMemberAttrData.getKimAttributeId())) {
newDelegateMemberAttrData.setAssignedToId(oldDelegateMemberAttrData.getAssignedToId());
newDelegateMemberAttrData.setVersionNumber(oldDelegateMemberAttrData.getVersionNumber());
newDelegateMemberAttrData.setId(oldDelegateMemberAttrData.getId());
updateAttrBos.add(newDelegateMemberAttrData);
matched = true;
break;
}
}
if (!matched) {
updateAttrBos.add(newDelegateMemberAttrData);
} else {
matched = false;
}
}
}
delegateMember.setAttributeDetails(updateAttrBos);
return getResponsibilityInternalService().saveDelegateMember(delegateMember);
}
use of org.kuali.kfs.kim.impl.common.delegate.DelegateMember 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.impl.common.delegate.DelegateMember in project cu-kfs by CU-CommunityApps.
the class OrgReviewRoleServiceImpl method populateOrgReviewRoleFromDelegationMember.
@Override
public void populateOrgReviewRoleFromDelegationMember(OrgReviewRole orr, String roleMemberId, String delegationMemberId) {
RoleMember roleMember = null;
if (StringUtils.isNotBlank(roleMemberId)) {
roleMember = getRoleMemberFromKimRoleService(roleMemberId);
}
RoleService roleService = KimApiServiceLocator.getRoleService();
DelegateMember delegationMember = roleService.getDelegationMemberById(delegationMemberId);
DelegateType delegation = roleService.getDelegateTypeByDelegationId(delegationMember.getDelegationId());
orr.setDelegationTypeCode(delegation.getDelegationType().getCode());
orr.setDelegateMember(roleMember, delegationMember);
orr.setRoleRspActions(roleService.getRoleMemberResponsibilityActions(delegationMember.getRoleMemberId()));
populateObjectExtras(orr);
}
use of org.kuali.kfs.kim.impl.common.delegate.DelegateMember in project cu-kfs by CU-CommunityApps.
the class OrgReviewRoleServiceImpl method saveDelegateMemberToKim.
protected void saveDelegateMemberToKim(OrgReviewRole orr) {
if (LOG.isDebugEnabled()) {
LOG.debug("Saving delegate member from OrgReviewRole: " + orr);
}
RoleService roleService = KimApiServiceLocator.getRoleService();
// Save delegation(s)
List<KfsKimDocDelegateMember> delegationMembers = getDelegationMembersToSave(orr);
for (KfsKimDocDelegateMember dm : delegationMembers) {
// retrieve the delegate type so it can be updated
DelegationType delegationType = dm.getDelegationType();
DelegateType delegateType = roleService.getDelegateTypeByRoleIdAndDelegateTypeCode(orr.getRoleId(), delegationType);
if (shouldCreateNewDelegateType(delegateType)) {
DelegateType newDelegateType = new DelegateType();
newDelegateType.setRoleId(orr.getRoleId());
newDelegateType.setDelegationType(delegationType);
newDelegateType.setDelegationMembers(new ArrayList<>(1));
// ensure this is set (for new delegation types)
newDelegateType.setKimTypeId(orr.getKimTypeId());
delegateType = roleService.createDelegateType(newDelegateType);
if (LOG.isDebugEnabled()) {
LOG.debug("No DelegateType in KIM. Created new one: " + delegateType);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Pulled DelegateType from KIM: " + delegateType);
}
}
boolean foundExistingMember = false;
DelegateMember addedMember = null;
// check for an existing delegation member given its unique ID if found, update that record
if (StringUtils.isNotBlank(dm.getDelegationMemberId())) {
DelegateMember member = roleService.getDelegationMemberById(dm.getDelegationMemberId());
if (member != null) {
foundExistingMember = true;
if (LOG.isDebugEnabled()) {
LOG.debug("Found existing delegate member - updating existing record. " + member);
}
// KFSMI-9628 : fixing issue with the delegate switch from primary to secondary
// IN this case, we need to delete the member from the "other" delegate type
// need to determine what the "existing" type was
DelegateType originalDelegateType = roleService.getDelegateTypeByDelegationId(member.getDelegationId());
// if they are the same, we can just update the existing record
if (originalDelegateType.getDelegationType().equals(dm.getDelegationType())) {
updateDelegateMemberFromDocDelegateMember(member, dm);
addedMember = roleService.updateDelegateMember(member);
} else {
// Otherwise, we need to remove the old one and add a new one
// Remove old
roleService.removeDelegateMembers(Collections.singletonList(member));
// add new
DelegateMember newMember = new DelegateMember();
newMember.setDelegationId(delegateType.getDelegationId());
updateDelegateMemberFromDocDelegateMember(newMember, dm);
addedMember = roleService.createDelegateMember(newMember);
}
}
}
// if we did not find one, then we need to create a new member
if (!foundExistingMember) {
if (LOG.isDebugEnabled()) {
LOG.debug("No existing delegate member found, adding as a new delegate: " + dm);
}
DelegateMember newMember = new DelegateMember();
newMember.setDelegationId(delegateType.getDelegationId());
updateDelegateMemberFromDocDelegateMember(newMember, dm);
addedMember = roleService.createDelegateMember(newMember);
}
if (addedMember != null) {
orr.setDelegationMemberId(addedMember.getDelegationMemberId());
}
}
}
Aggregations