1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.document.rule;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.membership.MemberType;
20 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
21 import org.kuali.rice.core.api.uif.RemotableAttributeError;
22 import org.kuali.rice.core.api.util.RiceKeyConstants;
23 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
24 import org.kuali.rice.kim.api.KimConstants;
25 import org.kuali.rice.kim.api.identity.IdentityService;
26 import org.kuali.rice.kim.api.identity.principal.Principal;
27 import org.kuali.rice.kim.api.permission.Permission;
28 import org.kuali.rice.kim.api.responsibility.Responsibility;
29 import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
30 import org.kuali.rice.kim.api.role.Role;
31 import org.kuali.rice.kim.api.role.RoleService;
32 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
33 import org.kuali.rice.kim.api.type.KimAttributeField;
34 import org.kuali.rice.kim.api.type.KimType;
35 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
36 import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission;
37 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
38 import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility;
39 import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibilityAction;
40 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
41 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
42 import org.kuali.rice.kim.document.IdentityManagementRoleDocument;
43 import org.kuali.rice.kim.framework.role.RoleTypeService;
44 import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator;
45 import org.kuali.rice.kim.framework.type.KimTypeService;
46 import org.kuali.rice.kim.impl.common.attribute.KimAttributeBo;
47 import org.kuali.rice.kim.impl.responsibility.AddResponsibilityEvent;
48 import org.kuali.rice.kim.impl.responsibility.AddResponsibilityRule;
49 import org.kuali.rice.kim.impl.responsibility.KimDocumentResponsibilityRule;
50 import org.kuali.rice.kim.impl.responsibility.ResponsibilityBo;
51 import org.kuali.rice.kim.impl.responsibility.ResponsibilityInternalService;
52 import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
53 import org.kuali.rice.kim.impl.type.KimTypeLookupableHelperServiceImpl;
54 import org.kuali.rice.kim.rule.event.ui.AddDelegationEvent;
55 import org.kuali.rice.kim.rule.event.ui.AddDelegationMemberEvent;
56 import org.kuali.rice.kim.rule.event.ui.AddMemberEvent;
57 import org.kuali.rice.kim.rule.event.ui.AddPermissionEvent;
58 import org.kuali.rice.kim.rule.ui.AddDelegationMemberRule;
59 import org.kuali.rice.kim.rule.ui.AddDelegationRule;
60 import org.kuali.rice.kim.rule.ui.AddMemberRule;
61 import org.kuali.rice.kim.rule.ui.AddPermissionRule;
62 import org.kuali.rice.kim.rules.ui.KimDocumentMemberRule;
63 import org.kuali.rice.kim.rules.ui.KimDocumentPermissionRule;
64 import org.kuali.rice.kim.rules.ui.RoleDocumentDelegationMemberRule;
65 import org.kuali.rice.kim.rules.ui.RoleDocumentDelegationRule;
66 import org.kuali.rice.kns.kim.type.DataDictionaryTypeServiceHelper;
67 import org.kuali.rice.krad.document.Document;
68 import org.kuali.rice.kns.rules.TransactionalDocumentRuleBase;
69 import org.kuali.rice.krad.service.BusinessObjectService;
70 import org.kuali.rice.krad.service.KRADServiceLocator;
71 import org.kuali.rice.krad.util.GlobalVariables;
72 import org.kuali.rice.krad.util.KRADConstants;
73 import org.kuali.rice.krad.util.MessageMap;
74
75 import javax.xml.namespace.QName;
76 import java.sql.Timestamp;
77 import java.util.ArrayList;
78 import java.util.Collections;
79 import java.util.HashMap;
80 import java.util.HashSet;
81 import java.util.List;
82 import java.util.Map;
83 import java.util.Set;
84
85
86
87
88 public class IdentityManagementRoleDocumentRule extends TransactionalDocumentRuleBase implements AddPermissionRule, AddResponsibilityRule, AddMemberRule, AddDelegationRule, AddDelegationMemberRule {
89
90
91 public static final int PRIORITY_NUMBER_MIN_VALUE = 1;
92 public static final int PRIORITY_NUMBER_MAX_VALUE = 11;
93
94 protected AddResponsibilityRule addResponsibilityRule;
95 protected AddPermissionRule addPermissionRule;
96 protected AddMemberRule addMemberRule;
97 protected AddDelegationRule addDelegationRule;
98 protected AddDelegationMemberRule addDelegationMemberRule;
99 protected BusinessObjectService businessObjectService;
100 protected ResponsibilityService responsibilityService;
101 protected Class<? extends AddResponsibilityRule> addResponsibilityRuleClass = KimDocumentResponsibilityRule.class;
102 protected Class<? extends AddPermissionRule> addPermissionRuleClass = KimDocumentPermissionRule.class;
103 protected Class<? extends AddMemberRule> addMemberRuleClass = KimDocumentMemberRule.class;
104 protected Class<? extends AddDelegationRule> addDelegationRuleClass = RoleDocumentDelegationRule.class;
105 protected Class<? extends AddDelegationMemberRule> addDelegationMemberRuleClass = RoleDocumentDelegationMemberRule.class;
106
107 protected IdentityService identityService;
108 private static ResponsibilityInternalService responsibilityInternalService;
109
110 protected AttributeValidationHelper attributeValidationHelper = new AttributeValidationHelper();
111
112
113 protected ActiveRoleMemberHelper activeRoleMemberHelper = new ActiveRoleMemberHelper();
114
115 public IdentityService getIdentityService() {
116 if ( identityService == null) {
117 identityService = KimApiServiceLocator.getIdentityService();
118 }
119 return identityService;
120 }
121
122 @Override
123 protected boolean processCustomSaveDocumentBusinessRules(Document document) {
124 if (!(document instanceof IdentityManagementRoleDocument)) {
125 return false;
126 }
127
128 IdentityManagementRoleDocument roleDoc = (IdentityManagementRoleDocument)document;
129
130 boolean valid = true;
131 boolean validateRoleAssigneesAndDelegations = !KimTypeLookupableHelperServiceImpl
132 .hasDerivedRoleTypeService(roleDoc.getKimType());
133 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
134 valid &= validDuplicateRoleName(roleDoc);
135 valid &= validPermissions(roleDoc);
136 valid &= validResponsibilities(roleDoc);
137
138 valid &= validRoleMemberPrincipalIDs(roleDoc.getModifiedMembers());
139 getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document, getMaxDictionaryValidationDepth(), true, false);
140 validateRoleAssigneesAndDelegations &= validAssignRole(roleDoc);
141 if(validateRoleAssigneesAndDelegations){
142
143
144
145
146
147 List<KimDocumentRoleMember> activeRoleMembers = activeRoleMemberHelper.getActiveRoleMembers(roleDoc.getMembers());
148 List<KimDocumentRoleMember> newActiveRoleMembers = activeRoleMemberHelper.getActiveRoleMembers(roleDoc.getModifiedMembers());
149 List<RoleDocumentDelegationMember> activeRoleDelegationMembers = activeRoleMemberHelper.getActiveDelegationRoleMembers(roleDoc.getDelegationMembers());
150
151 valid &= validateRoleQualifier(newActiveRoleMembers, roleDoc.getKimType());
152 valid &= validRoleMemberActiveDates(roleDoc.getModifiedMembers());
153 valid &= validateDelegationMemberRoleQualifier(newActiveRoleMembers, activeRoleDelegationMembers, roleDoc.getKimType(), activeRoleMembers);
154 valid &= validDelegationMemberActiveDates(roleDoc.getDelegationMembers());
155 valid &= validRoleMembersResponsibilityActions(roleDoc.getModifiedMembers());
156 }
157 valid &= validRoleResponsibilitiesActions(roleDoc.getResponsibilities());
158 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
159
160 return valid;
161 }
162
163 protected boolean validAssignRole(IdentityManagementRoleDocument document){
164 boolean rulePassed = true;
165 Map<String,String> additionalPermissionDetails = new HashMap<String,String>();
166 additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace());
167 additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName());
168 if((document.getMembers()!=null && document.getMembers().size()>0) ||
169 (document.getDelegationMembers()!=null && document.getDelegationMembers().size()>0)){
170 if(!getDocumentDictionaryService().getDocumentAuthorizer(document).isAuthorizedByTemplate(
171 document, KimConstants.NAMESPACE_CODE, KimConstants.PermissionTemplateNames.ASSIGN_ROLE,
172 GlobalVariables.getUserSession().getPrincipalId(), additionalPermissionDetails, null)){
173 rulePassed = false;
174 }
175 }
176 return rulePassed;
177 }
178
179 protected boolean validRoleMemberPrincipalIDs(List<KimDocumentRoleMember> roleMembers) {
180 boolean valid = true;
181 List<String> principalIds = new ArrayList<String>();
182 for(KimDocumentRoleMember roleMember: roleMembers) {
183 if (StringUtils.equals(roleMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode()) ) {
184 principalIds.add(roleMember.getMemberId());
185 }
186 }
187 if(!principalIds.isEmpty()) {
188 List<Principal> validPrincipals = getIdentityService().getPrincipals(principalIds);
189 for(KimDocumentRoleMember roleMember: roleMembers) {
190 if (StringUtils.equals(roleMember.getMemberTypeCode(), MemberType.PRINCIPAL.getCode()) ) {
191 boolean validPrincipalId = false;
192 if(validPrincipals != null && !validPrincipals.isEmpty()) {
193 for(Principal validPrincipal: validPrincipals) {
194 if(roleMember.getMemberId().equals(validPrincipal.getPrincipalId())) {
195 validPrincipalId = true;
196 }
197 }
198 }
199 if(!validPrincipalId) {
200 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH,
201 new String[] {roleMember.getMemberId()});
202 valid = false;
203 }
204 }
205 }
206 }
207 return valid;
208 }
209
210 @SuppressWarnings("unchecked")
211 protected boolean validDuplicateRoleName(IdentityManagementRoleDocument roleDoc){
212 Role role = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(roleDoc.getRoleNamespace(),
213 roleDoc.getRoleName());
214 boolean rulePassed = true;
215 if(role!=null){
216 if(role.getId().equals(roleDoc.getRoleId())) {
217 rulePassed = true;
218 }
219 else{
220 GlobalVariables.getMessageMap().putError("document.roleName",
221 RiceKeyConstants.ERROR_DUPLICATE_ENTRY, new String[] {"Role Name"});
222 rulePassed = false;
223 }
224 }
225 return rulePassed;
226 }
227
228 protected boolean validRoleMemberActiveDates(List<KimDocumentRoleMember> roleMembers) {
229 boolean valid = true;
230 int i = 0;
231 for(KimDocumentRoleMember roleMember: roleMembers) {
232 valid &= validateActiveDate("document.members["+i+"].activeToDate", roleMember.getActiveFromDate(), roleMember.getActiveToDate());
233 i++;
234 }
235 return valid;
236 }
237
238 protected boolean validDelegationMemberActiveDates(List<RoleDocumentDelegationMember> delegationMembers) {
239 boolean valid = true;
240 int i = 0;
241 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
242 valid &= validateActiveDate("document.delegationMembers[" + i + "].activeToDate",
243 delegationMember.getActiveFromDate(), delegationMember.getActiveToDate());
244 i++;
245 }
246 return valid;
247 }
248
249 protected boolean validPermissions(IdentityManagementRoleDocument document){
250 Permission kimPermissionInfo;
251 boolean valid = true;
252 int i = 0;
253 for(KimDocumentRolePermission permission: document.getPermissions()){
254 kimPermissionInfo = permission.getPermission();
255 if(!permission.isActive() && !hasPermissionToGrantPermission(permission.getPermission(), document)){
256 GlobalVariables.getMessageMap().putError("permissions["+i+"].active", RiceKeyConstants.ERROR_ASSIGN_PERMISSION,
257 new String[] {kimPermissionInfo.getNamespaceCode(), kimPermissionInfo.getTemplate().getName()});
258 valid = false;
259 }
260 i++;
261 }
262 return valid;
263 }
264
265 protected boolean validResponsibilities(IdentityManagementRoleDocument document){
266 ResponsibilityBo kimResponsibilityImpl;
267 boolean valid = true;
268 int i = 0;
269 for(KimDocumentRoleResponsibility responsibility: document.getResponsibilities()){
270 kimResponsibilityImpl = responsibility.getKimResponsibility();
271 if(!responsibility.isActive() && !hasPermissionToGrantResponsibility(ResponsibilityBo.to(responsibility.getKimResponsibility()), document)){
272 GlobalVariables.getMessageMap().putError("responsibilities["+i+"].active", RiceKeyConstants.ERROR_ASSIGN_RESPONSIBILITY,
273 new String[] {kimResponsibilityImpl.getNamespaceCode(), kimResponsibilityImpl.getTemplate().getName()});
274 valid = false;
275 }
276 i++;
277 }
278 return valid;
279 }
280
281 protected boolean validRoleResponsibilitiesActions(List<KimDocumentRoleResponsibility> roleResponsibilities){
282 int i = 0;
283 boolean rulePassed = true;
284 for(KimDocumentRoleResponsibility roleResponsibility: roleResponsibilities){
285 if(!getResponsibilityInternalService().areActionsAtAssignmentLevelById(roleResponsibility.getResponsibilityId())) {
286 validateRoleResponsibilityAction("document.responsibilities["+i+"].roleRspActions[0].priorityNumber", roleResponsibility.getRoleRspActions().get(0));
287 }
288 i++;
289 }
290 return rulePassed;
291 }
292
293 protected boolean validRoleMembersResponsibilityActions(List<KimDocumentRoleMember> roleMembers){
294 int i = 0;
295 int j;
296 boolean rulePassed = true;
297 for(KimDocumentRoleMember roleMember: roleMembers){
298 j = 0;
299 if(roleMember.getRoleRspActions()!=null && !roleMember.getRoleRspActions().isEmpty()){
300 for(KimDocumentRoleResponsibilityAction roleRspAction: roleMember.getRoleRspActions()){
301 validateRoleResponsibilityAction("document.members["+i+"].roleRspActions["+j+"].priorityNumber", roleRspAction);
302 j++;
303 }
304 }
305 i++;
306 }
307 return rulePassed;
308 }
309
310 protected boolean validateRoleResponsibilityAction(String errorPath, KimDocumentRoleResponsibilityAction roleRspAction){
311 boolean rulePassed = true;
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327 if(roleRspAction.getPriorityNumber()!=null &&
328 (roleRspAction.getPriorityNumber()<PRIORITY_NUMBER_MIN_VALUE
329 || roleRspAction.getPriorityNumber()>PRIORITY_NUMBER_MAX_VALUE)){
330 GlobalVariables.getMessageMap().putError(errorPath,
331 RiceKeyConstants.ERROR_PRIORITY_NUMBER_RANGE, new String[] {PRIORITY_NUMBER_MIN_VALUE+"", PRIORITY_NUMBER_MAX_VALUE+""});
332 rulePassed = false;
333 }
334
335 return rulePassed;
336 }
337
338 protected boolean validateRoleQualifier(List<KimDocumentRoleMember> roleMembers, KimType kimType){
339 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
340
341 int memberCounter = 0;
342 int roleMemberCount = 0;
343 List<RemotableAttributeError> errorsTemp;
344 Map<String, String> mapToValidate;
345 KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(kimType);
346 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
347 final List<KimAttributeField> attributeDefinitions = kimTypeService.getAttributeDefinitions(kimType.getId());
348 final Set<String> uniqueAttributeNames = figureOutUniqueQualificationSet(roleMembers, attributeDefinitions);
349
350 for(KimDocumentRoleMember roleMember: roleMembers) {
351 errorsTemp = Collections.emptyList();
352 mapToValidate = attributeValidationHelper.convertQualifiersToMap(roleMember.getQualifiers());
353 RoleTypeService roleTypeService = getRoleTypeService(kimType);
354 boolean shouldNotValidate = true;
355 if (roleTypeService != null) {
356 shouldNotValidate = roleTypeService.shouldValidateQualifiersForMemberType( MemberType.fromCode(roleMember.getMemberTypeCode()));
357 }
358
359 if(!shouldNotValidate){
360 errorsTemp = kimTypeService.validateAttributes(kimType.getId(), mapToValidate);
361 validationErrors.addAll(attributeValidationHelper.convertErrorsForMappedFields(
362 "members[" + memberCounter + "]", errorsTemp));
363 memberCounter++;
364 }
365 if (uniqueAttributeNames.size() > 0) {
366 validateUniquePersonRoleQualifiersUniqueForRoleMembership(roleMember, roleMemberCount, roleMembers, uniqueAttributeNames, validationErrors);
367 }
368
369 roleMemberCount += 1;
370 }
371
372 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
373
374 if (validationErrors.isEmpty()) {
375 return true;
376 }
377 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
378 return false;
379 }
380
381
382
383
384
385
386
387
388 protected Set<String> figureOutUniqueQualificationSet(List<KimDocumentRoleMember> memberships, List<KimAttributeField> attributeDefinitions) {
389 Set<String> uniqueAttributeIds = new HashSet<String>();
390
391 if (memberships != null && memberships.size() > 1) {
392 KimDocumentRoleMember membership = memberships.get(0);
393
394 for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
395 if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
396 final KimAttributeField relatedDefinition = DataDictionaryTypeServiceHelper.findAttributeField(
397 qualifier.getKimAttribute().getAttributeName(), attributeDefinitions);
398
399 if (relatedDefinition != null && relatedDefinition.isUnique()) {
400 uniqueAttributeIds.add(qualifier.getKimAttrDefnId());
401 }
402 }
403 }
404 }
405
406 return uniqueAttributeIds;
407 }
408
409
410
411
412
413
414
415
416
417 protected boolean validateUniquePersonRoleQualifiersUniqueForRoleMembership(KimDocumentRoleMember membershipToCheck, int membershipToCheckIndex, List<KimDocumentRoleMember> memberships, Set<String> uniqueQualifierIds, List<RemotableAttributeError> validationErrors) {
418 boolean foundError = false;
419 int count = 0;
420
421 for (KimDocumentRoleMember membership : memberships) {
422 if (membershipToCheckIndex != count) {
423 if (sameMembership(membershipToCheck, membership)) {
424 if (sameUniqueMembershipQualifications(membershipToCheck, membership, uniqueQualifierIds)) {
425 foundError = true;
426
427 int qualifierCount = 0;
428
429 for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
430 if (qualifier != null && uniqueQualifierIds.contains(qualifier.getKimAttrDefnId())) {
431
432
433 KimAttributeBo attr = qualifier.getKimAttribute();
434 String attrName = "<unknown>";
435 if (attr == null && qualifier.getKimAttrDefnId() != null) {
436 attr = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(KimAttributeBo.class, qualifier.getKimAttrDefnId());
437 }
438 if (attr != null) {
439 attrName = attr.getAttributeName();
440 }
441 validationErrors.add(RemotableAttributeError.Builder.create("document.members["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+membership.getMemberId()+";"+attrName+";"+qualifier.getAttrVal()).build());
442 }
443 qualifierCount += 1;
444 }
445 }
446 }
447 }
448 count += 1;
449 }
450
451 return foundError;
452 }
453
454
455
456
457
458
459
460
461 protected boolean sameMembership(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB) {
462 if (!StringUtils.isBlank(membershipA.getMemberTypeCode()) && !StringUtils.isBlank(membershipB.getMemberTypeCode()) && !StringUtils.isBlank(membershipA.getMemberId()) && !StringUtils.isBlank(membershipB.getMemberId())) {
463 return membershipA.getMemberTypeCode().equals(membershipB.getMemberTypeCode()) && membershipA.getMemberId().equals(membershipB.getMemberId());
464 }
465 return false;
466 }
467
468
469
470
471
472
473
474
475
476 protected boolean sameUniqueMembershipQualifications(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB, Set<String> uniqueAttributeIds) {
477 boolean equalSoFar = true;
478 for (String kimAttributeDefinitionId : uniqueAttributeIds) {
479 final KimDocumentRoleQualifier qualifierA = membershipA.getQualifier(kimAttributeDefinitionId);
480 final KimDocumentRoleQualifier qualifierB = membershipB.getQualifier(kimAttributeDefinitionId);
481
482 if (qualifierA != null && qualifierB != null) {
483 equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
484 }
485 }
486 return equalSoFar;
487 }
488
489 protected KimDocumentRoleMember getRoleMemberForDelegation(
490 List<KimDocumentRoleMember> roleMembers, RoleDocumentDelegationMember delegationMember, List<KimDocumentRoleMember> modifiedRoleMembers) {
491 if((roleMembers==null && modifiedRoleMembers==null) || delegationMember==null || delegationMember.getRoleMemberId()==null) { return null; }
492 for(KimDocumentRoleMember roleMember: modifiedRoleMembers){
493 if(delegationMember.getRoleMemberId().equals(roleMember.getRoleMemberId())) {
494 return roleMember;
495 }
496 }
497 for(KimDocumentRoleMember roleMember: roleMembers){
498 if(delegationMember.getRoleMemberId().equals(roleMember.getRoleMemberId())) {
499 return roleMember;
500 }
501 }
502 return null;
503 }
504
505 protected boolean validateDelegationMemberRoleQualifier(List<KimDocumentRoleMember> modifiedRoleMembers,
506 List<RoleDocumentDelegationMember> delegationMembers, KimType kimType, List<KimDocumentRoleMember> nonModifiedRoleMembers){
507 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
508 boolean valid;
509 int memberCounter = 0;
510 List<RemotableAttributeError> errorsTemp;
511 Map<String, String> mapToValidate;
512 KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(kimType);
513 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
514 KimDocumentRoleMember roleMember;
515 String errorPath;
516 final List<KimAttributeField> attributeDefinitions = kimTypeService.getAttributeDefinitions(kimType.getId());
517 final Set<String> uniqueQualifierAttributes = figureOutUniqueQualificationSetForDelegation(delegationMembers, attributeDefinitions);
518
519 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
520 errorPath = "delegationMembers["+memberCounter+"]";
521 mapToValidate = attributeValidationHelper.convertQualifiersToMap(delegationMember.getQualifiers());
522 if(!delegationMember.isRole()){
523 errorsTemp = kimTypeService.validateAttributes(kimType.getId(), mapToValidate);
524 validationErrors.addAll(
525 attributeValidationHelper.convertErrorsForMappedFields(errorPath, errorsTemp));
526 }
527 roleMember = getRoleMemberForDelegation(nonModifiedRoleMembers, delegationMember, modifiedRoleMembers);
528 if(roleMember==null){
529 valid = false;
530 GlobalVariables.getMessageMap().putError("document.delegationMembers["+memberCounter+"]", RiceKeyConstants.ERROR_DELEGATE_ROLE_MEMBER_ASSOCIATION, new String[]{});
531 } else{
532 errorsTemp = kimTypeService.validateUnmodifiableAttributes(
533 kimType.getId(),
534 attributeValidationHelper.convertQualifiersToMap(roleMember.getQualifiers()),
535 mapToValidate);
536 validationErrors.addAll(
537 attributeValidationHelper.convertErrorsForMappedFields(errorPath, errorsTemp) );
538 }
539 if (uniqueQualifierAttributes.size() > 0) {
540 validateUniquePersonRoleQualifiersUniqueForRoleDelegation(delegationMember, memberCounter, delegationMembers, uniqueQualifierAttributes, validationErrors);
541 }
542 memberCounter++;
543 }
544 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
545 if (validationErrors.isEmpty()) {
546 valid = true;
547 } else {
548 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
549 valid = false;
550 }
551 return valid;
552 }
553
554
555
556
557
558
559
560
561 protected Set<String> figureOutUniqueQualificationSetForDelegation(List<RoleDocumentDelegationMember> memberships, List<KimAttributeField> attributeDefinitions) {
562 Set<String> uniqueAttributeIds = new HashSet<String>();
563
564 if (memberships != null && memberships.size() > 1) {
565 RoleDocumentDelegationMember membership = memberships.get(0);
566
567 for (RoleDocumentDelegationMemberQualifier qualifier : membership.getQualifiers()) {
568 if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
569 final KimAttributeField relatedDefinition = DataDictionaryTypeServiceHelper.findAttributeField(
570 qualifier.getKimAttribute().getAttributeName(), attributeDefinitions);
571
572 if (relatedDefinition.isUnique()) {
573 uniqueAttributeIds.add(qualifier.getKimAttrDefnId());
574 }
575 }
576 }
577 }
578
579 return uniqueAttributeIds;
580 }
581
582
583
584
585
586
587
588
589
590 protected boolean validateUniquePersonRoleQualifiersUniqueForRoleDelegation(RoleDocumentDelegationMember delegationMembershipToCheck, int membershipToCheckIndex, List<RoleDocumentDelegationMember> delegationMemberships, Set<String> uniqueQualifierIds, List<RemotableAttributeError> validationErrors) {
591 boolean foundError = false;
592 int count = 0;
593
594 for (RoleDocumentDelegationMember delegationMembership : delegationMemberships) {
595 if (membershipToCheckIndex != count) {
596 if (sameDelegationMembership(delegationMembershipToCheck, delegationMembership)) {
597 if (sameUniqueDelegationMembershipQualifications(delegationMembershipToCheck, delegationMembership, uniqueQualifierIds)) {
598 foundError = true;
599
600 int qualifierCount = 0;
601
602 for (RoleDocumentDelegationMemberQualifier qualifier : delegationMembership.getQualifiers()) {
603 if (qualifier != null && uniqueQualifierIds.contains(qualifier.getKimAttrDefnId())) {
604 validationErrors.add(RemotableAttributeError.Builder.create("document.delegationMembers["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+qualifier.getKimAttribute().getAttributeName()+";"+qualifier.getAttrVal()).build());
605 }
606 qualifierCount += 1;
607 }
608 }
609 }
610 }
611 count += 1;
612 }
613
614 return foundError;
615 }
616
617
618
619
620
621
622
623
624 protected boolean sameDelegationMembership(RoleDocumentDelegationMember membershipA, RoleDocumentDelegationMember membershipB) {
625 if (!StringUtils.isBlank(membershipA.getMemberTypeCode()) && !StringUtils.isBlank(membershipB.getMemberTypeCode()) && !StringUtils.isBlank(membershipA.getMemberId()) && !StringUtils.isBlank(membershipB.getMemberId())) {
626 return membershipA.getMemberTypeCode().equals(membershipB.getMemberTypeCode()) && membershipA.getMemberId().equals(membershipB.getMemberId());
627 }
628 return false;
629 }
630
631
632
633
634
635
636
637
638
639 protected boolean sameUniqueDelegationMembershipQualifications(RoleDocumentDelegationMember membershipA, RoleDocumentDelegationMember membershipB, Set<String> uniqueAttributeIds) {
640 boolean equalSoFar = true;
641 for (String kimAttributeDefinitionId : uniqueAttributeIds) {
642 final RoleDocumentDelegationMemberQualifier qualifierA = membershipA.getQualifier(kimAttributeDefinitionId);
643 final RoleDocumentDelegationMemberQualifier qualifierB = membershipB.getQualifier(kimAttributeDefinitionId);
644
645 if (qualifierA != null && qualifierB != null) {
646 equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
647 }
648 }
649 return equalSoFar;
650 }
651
652 protected boolean validateActiveDate(String errorPath, Timestamp activeFromDate, Timestamp activeToDate) {
653
654 boolean valid = true;
655 if (activeFromDate != null && activeToDate !=null && activeToDate.before(activeFromDate)) {
656 MessageMap errorMap = GlobalVariables.getMessageMap();
657 errorMap.putError(errorPath, RiceKeyConstants.ERROR_ACTIVE_TO_DATE_BEFORE_FROM_DATE);
658 valid = false;
659
660 }
661 return valid;
662 }
663
664
665
666
667
668
669
670
671
672
673 protected boolean checkForCircularRoleMembership(AddMemberEvent addMemberEvent)
674 {
675 KimDocumentRoleMember newMember = addMemberEvent.getMember();
676 if (newMember == null || StringUtils.isBlank(newMember.getMemberId())){
677 MessageMap errorMap = GlobalVariables.getMessageMap();
678 errorMap.putError("member.memberId", RiceKeyConstants.ERROR_INVALID_ROLE, new String[] {""});
679 return false;
680 }
681 Set<String> roleMemberIds = null;
682
683
684 if (newMember.isRole()){
685
686 RoleService roleService = KimApiServiceLocator.getRoleService();
687 roleMemberIds = roleService.getRoleTypeRoleMemberIds(newMember.getMemberId());
688
689
690 IdentityManagementRoleDocument document = (IdentityManagementRoleDocument)addMemberEvent.getDocument();
691 if (roleMemberIds.contains(document.getRoleId())){
692 MessageMap errorMap = GlobalVariables.getMessageMap();
693 errorMap.putError("member.memberId", RiceKeyConstants.ERROR_ASSIGN_ROLE_MEMBER_CIRCULAR, new String[] {newMember.getMemberId()});
694 return false;
695 }
696 }
697 return true;
698 }
699
700
701
702
703 public AddResponsibilityRule getAddResponsibilityRule() {
704 if(addResponsibilityRule == null){
705 try {
706 addResponsibilityRule = addResponsibilityRuleClass.newInstance();
707 } catch ( Exception ex ) {
708 throw new RuntimeException( "Unable to create AddResponsibilityRule instance using class: " + addResponsibilityRuleClass, ex );
709 }
710 }
711 return addResponsibilityRule;
712 }
713
714
715
716
717 public AddPermissionRule getAddPermissionRule() {
718 if(addPermissionRule == null){
719 try {
720 addPermissionRule = addPermissionRuleClass.newInstance();
721 } catch ( Exception ex ) {
722 throw new RuntimeException( "Unable to create AddPermissionRule instance using class: " + addPermissionRuleClass, ex );
723 }
724 }
725 return addPermissionRule;
726 }
727
728
729
730
731 public AddMemberRule getAddMemberRule() {
732 if(addMemberRule == null){
733 try {
734 addMemberRule = addMemberRuleClass.newInstance();
735 } catch ( Exception ex ) {
736 throw new RuntimeException( "Unable to create AddMemberRule instance using class: " + addMemberRuleClass, ex );
737 }
738 }
739 return addMemberRule;
740 }
741
742
743
744
745 public AddDelegationRule getAddDelegationRule() {
746 if(addDelegationRule == null){
747 try {
748 addDelegationRule = addDelegationRuleClass.newInstance();
749 } catch ( Exception ex ) {
750 throw new RuntimeException( "Unable to create AddDelegationRule instance using class: " + addDelegationRuleClass, ex );
751 }
752 }
753 return addDelegationRule;
754 }
755
756
757
758
759 public AddDelegationMemberRule getAddDelegationMemberRule() {
760 if(addDelegationMemberRule == null){
761 try {
762 addDelegationMemberRule = addDelegationMemberRuleClass.newInstance();
763 } catch ( Exception ex ) {
764 throw new RuntimeException( "Unable to create AddDelegationMemberRule instance using class: " + addDelegationMemberRuleClass, ex );
765 }
766 }
767 return addDelegationMemberRule;
768 }
769
770 public boolean processAddPermission(AddPermissionEvent addPermissionEvent) {
771 return getAddPermissionRule().processAddPermission(addPermissionEvent);
772 }
773
774 public boolean hasPermissionToGrantPermission(Permission kimPermissionInfo , IdentityManagementRoleDocument document){
775 return getAddPermissionRule().hasPermissionToGrantPermission(kimPermissionInfo, document);
776 }
777
778 public boolean processAddResponsibility(AddResponsibilityEvent addResponsibilityEvent) {
779 return getAddResponsibilityRule().processAddResponsibility(addResponsibilityEvent);
780 }
781
782 public boolean hasPermissionToGrantResponsibility(Responsibility kimResponsibilityInfo, IdentityManagementRoleDocument document) {
783 return getAddResponsibilityRule().hasPermissionToGrantResponsibility(kimResponsibilityInfo, document);
784 }
785
786 public boolean processAddMember(AddMemberEvent addMemberEvent) {
787 boolean success = new KimDocumentMemberRule().processAddMember(addMemberEvent);
788 success &= validateActiveDate("member.activeFromDate", addMemberEvent.getMember().getActiveFromDate(), addMemberEvent.getMember().getActiveToDate());
789 success &= checkForCircularRoleMembership(addMemberEvent);
790 return success;
791 }
792
793 public boolean processAddDelegation(AddDelegationEvent addDelegationEvent) {
794 return getAddDelegationRule().processAddDelegation(addDelegationEvent);
795 }
796
797 public boolean processAddDelegationMember(AddDelegationMemberEvent addDelegationMemberEvent) {
798 boolean success = new RoleDocumentDelegationMemberRule().processAddDelegationMember(addDelegationMemberEvent);
799 RoleDocumentDelegationMember roleDocumentDelegationMember = addDelegationMemberEvent.getDelegationMember();
800 success &= validateActiveDate("delegationMember.activeFromDate", roleDocumentDelegationMember.getActiveFromDate(), roleDocumentDelegationMember.getActiveToDate());
801 return success;
802 }
803
804 public ResponsibilityService getResponsibilityService() {
805 if(responsibilityService == null){
806 responsibilityService = KimApiServiceLocator.getResponsibilityService();
807 }
808 return responsibilityService;
809 }
810
811 public ResponsibilityInternalService getResponsibilityInternalService() {
812 if ( responsibilityInternalService == null ) {
813 responsibilityInternalService = KimImplServiceLocator.getResponsibilityInternalService();
814 }
815 return responsibilityInternalService;
816 }
817
818
819
820
821
822 public BusinessObjectService getBusinessObjectService() {
823 if(businessObjectService == null){
824 businessObjectService = KRADServiceLocator.getBusinessObjectService();
825 }
826 return businessObjectService;
827 }
828
829
830 protected RoleTypeService getRoleTypeService(KimType typeInfo) {
831 String serviceName = typeInfo.getServiceName();
832 if (serviceName != null) {
833 try {
834 KimTypeService service = (KimTypeService) GlobalResourceLoader.getService(QName.valueOf(serviceName));
835 if (service != null && service instanceof RoleTypeService) {
836 return (RoleTypeService) service;
837 }
838 return (RoleTypeService) KimImplServiceLocator.getService("kimNoMembersRoleTypeService");
839 } catch (Exception ex) {
840 return (RoleTypeService) KimImplServiceLocator.getService("kimNoMembersRoleTypeService");
841 }
842 }
843 return null;
844 }
845
846 }