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