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