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