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.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.uif.RemotableAttributeError;
21 import org.kuali.rice.core.api.util.RiceKeyConstants;
22 import org.kuali.rice.kim.api.identity.IdentityService;
23 import org.kuali.rice.kim.api.identity.entity.EntityDefault;
24 import org.kuali.rice.kim.api.identity.principal.Principal;
25 import org.kuali.rice.kim.api.role.RoleService;
26 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
27 import org.kuali.rice.kim.api.type.KimAttributeField;
28 import org.kuali.rice.kim.api.type.KimType;
29 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
30 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
31 import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation;
32 import org.kuali.rice.kim.bo.ui.PersonDocumentBoDefaultBase;
33 import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo;
34 import org.kuali.rice.kim.bo.ui.PersonDocumentGroup;
35 import org.kuali.rice.kim.bo.ui.PersonDocumentName;
36 import org.kuali.rice.kim.bo.ui.PersonDocumentRole;
37 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
38 import org.kuali.rice.kim.document.IdentityManagementPersonDocument;
39 import org.kuali.rice.kim.document.authorization.IdentityManagementKimDocumentAuthorizer;
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.KIMPropertyConstants;
43 import org.kuali.rice.kim.impl.identity.principal.PrincipalBo;
44 import org.kuali.rice.kim.impl.role.RoleMemberBo;
45 import org.kuali.rice.kim.impl.type.KimTypeBo;
46 import org.kuali.rice.kim.rule.event.ui.AddGroupEvent;
47 import org.kuali.rice.kim.rule.event.ui.AddPersonDelegationMemberEvent;
48 import org.kuali.rice.kim.rule.event.ui.AddRoleEvent;
49 import org.kuali.rice.kim.rule.ui.AddGroupRule;
50 import org.kuali.rice.kim.rule.ui.AddPersonDelegationMemberRule;
51 import org.kuali.rice.kim.rule.ui.AddPersonDocumentRoleQualifierRule;
52 import org.kuali.rice.kim.rule.ui.AddRoleRule;
53 import org.kuali.rice.kim.rules.ui.PersonDocumentDelegationMemberRule;
54 import org.kuali.rice.kim.rules.ui.PersonDocumentGroupRule;
55 import org.kuali.rice.kim.rules.ui.PersonDocumentRoleRule;
56 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
57 import org.kuali.rice.kim.service.UiDocumentService;
58 import org.kuali.rice.kns.kim.type.DataDictionaryTypeServiceHelper;
59 import org.kuali.rice.kns.rules.TransactionalDocumentRuleBase;
60 import org.kuali.rice.krad.document.Document;
61 import org.kuali.rice.krad.service.BusinessObjectService;
62 import org.kuali.rice.krad.service.KRADServiceLocator;
63 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
64 import org.kuali.rice.krad.util.GlobalVariables;
65 import org.kuali.rice.krad.util.KRADConstants;
66 import org.kuali.rice.krad.util.ObjectUtils;
67
68 import java.sql.Timestamp;
69 import java.util.ArrayList;
70 import java.util.HashMap;
71 import java.util.HashSet;
72 import java.util.List;
73 import java.util.Map;
74 import java.util.Set;
75
76
77
78
79
80
81
82 public class IdentityManagementPersonDocumentRule extends TransactionalDocumentRuleBase implements AddGroupRule, AddRoleRule, AddPersonDocumentRoleQualifierRule, AddPersonDelegationMemberRule {
83
84
85
86 protected AddGroupRule addGroupRule;
87 protected AddRoleRule addRoleRule;
88 protected AddPersonDelegationMemberRule addPersonDelegationMemberRule;
89 protected IdentityManagementKimDocumentAuthorizer authorizer;
90 protected BusinessObjectService businessObjectService;
91 protected IdentityService identityService;
92 protected RoleService roleService;
93 protected UiDocumentService uiDocumentService;
94 protected Class<? extends AddGroupRule> addGroupRuleClass = PersonDocumentGroupRule.class;
95 protected Class<? extends AddRoleRule> addRoleRuleClass = PersonDocumentRoleRule.class;
96 protected Class<? extends AddPersonDelegationMemberRule> addPersonDelegationMemberRuleClass = PersonDocumentDelegationMemberRule.class;
97 protected ActiveRoleMemberHelper activeRoleMemberHelper = new ActiveRoleMemberHelper();
98 protected AttributeValidationHelper attributeValidationHelper = new AttributeValidationHelper();
99
100 @Override
101 protected boolean processCustomSaveDocumentBusinessRules(Document document) {
102 if (!(document instanceof IdentityManagementPersonDocument)) {
103 return false;
104 }
105
106 IdentityManagementPersonDocument personDoc = (IdentityManagementPersonDocument)document;
107 boolean valid = true;
108
109 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
110
111
112 getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document, getMaxDictionaryValidationDepth(), true, false);
113 valid &= validDuplicatePrincipalName(personDoc);
114 EntityDefault origEntity = getIdentityService().getEntityDefault(personDoc.getEntityId());
115 boolean isCreatingNew = origEntity==null?true:false;
116 if(getUIDocumentService().canModifyEntity(GlobalVariables.getUserSession().getPrincipalId(), personDoc.getPrincipalId()) || isCreatingNew) {
117 valid &= validateEntityInformation(isCreatingNew, personDoc);
118 }
119
120 valid &= validateRoleQualifier (personDoc.getRoles());
121 valid &= validateDelegationMemberRoleQualifier(personDoc.getDelegationMembers());
122 if (StringUtils.isNotBlank(personDoc.getPrincipalName())) {
123 valid &= doesPrincipalNameExist (personDoc.getPrincipalName(), personDoc.getPrincipalId());
124 }
125
126 valid &= validActiveDatesForRole (personDoc.getRoles());
127 valid &= validActiveDatesForGroup (personDoc.getGroups());
128 valid &= validActiveDatesForDelegations (personDoc.getDelegationMembers());
129
130
131
132
133
134
135 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
136
137 return valid;
138 }
139
140 protected boolean validateEntityInformation(boolean isCreatingNew, IdentityManagementPersonDocument personDoc){
141 boolean valid = true;
142 boolean canOverridePrivacyPreferences = getUIDocumentService().canOverrideEntityPrivacyPreferences(GlobalVariables.getUserSession().getPrincipalId(), personDoc.getPrincipalId());
143 valid &= checkMultipleDefault (personDoc.getAffiliations(), "affiliations");
144 if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressName()) {
145 valid &= checkMultipleDefault (personDoc.getNames(), "names");
146 }
147 if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressAddress()) {
148 valid &= checkMultipleDefault (personDoc.getAddrs(), "addrs");
149 }
150 if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressPhone()) {
151 valid &= checkMultipleDefault (personDoc.getPhones(), "phones");
152 }
153 if(isCreatingNew || canOverridePrivacyPreferences || !personDoc.getPrivacy().isSuppressEmail()) {
154 valid &= checkMultipleDefault (personDoc.getEmails(), "emails");
155 }
156 valid &= checkPrimaryEmploymentInfo (personDoc.getAffiliations());
157 valid &= validEmployeeIDForAffiliation(personDoc.getAffiliations());
158 valid &= checkAffiliationTypeChange (personDoc.getAffiliations());
159 valid &= checkUniqueAffiliationTypePerCampus(personDoc.getAffiliations());
160 return valid;
161 }
162
163 @SuppressWarnings("unchecked")
164 protected boolean validDuplicatePrincipalName(IdentityManagementPersonDocument personDoc){
165 Map<String, String> criteria = new HashMap<String, String>();
166 criteria.put("principalName", personDoc.getPrincipalName());
167 List<PrincipalBo> prncplImpls = (List<PrincipalBo>)getBusinessObjectService().findMatching(PrincipalBo.class, criteria);
168 boolean rulePassed = true;
169 if(prncplImpls!=null && prncplImpls.size()>0){
170 if(prncplImpls.size()==1 && prncplImpls.get(0).getPrincipalId().equals(personDoc.getPrincipalId())) {
171 rulePassed = true;
172 }
173 else{
174 GlobalVariables.getMessageMap().putError("document.principalName",
175 RiceKeyConstants.ERROR_DUPLICATE_ENTRY, new String[] {"Principal Name"});
176 rulePassed = false;
177 }
178 }
179 return rulePassed;
180 }
181
182 protected boolean checkUnassignableRoles(IdentityManagementPersonDocument document) {
183 boolean valid = true;
184 Map<String,Set<String>> unassignableRoles = getAuthorizer( document ).getUnassignableRoles(document, GlobalVariables.getUserSession().getPerson());
185 for (String namespaceCode : unassignableRoles.keySet()) {
186 for (String roleName : unassignableRoles.get(namespaceCode)) {
187 int i = 0;
188 for (PersonDocumentRole role : document.getRoles()) {
189 if (role.isEditable() && namespaceCode.endsWith(role.getNamespaceCode()) && roleName.equals(role.getRoleName())) {
190 GlobalVariables.getMessageMap().putError("roles["+i+"].roleId", RiceKeyConstants.ERROR_ASSIGN_ROLE, new String[] {namespaceCode, roleName});
191 valid = false;
192 }
193 i++;
194 }
195 }
196 }
197 return valid;
198 }
199
200 protected boolean checkUnpopulatableGroups(IdentityManagementPersonDocument document) {
201 boolean valid = true;
202 Map<String,Set<String>> unpopulatableGroups = getAuthorizer( document ).getUnpopulateableGroups(document, GlobalVariables.getUserSession().getPerson());
203 for (String namespaceCode : unpopulatableGroups.keySet()) {
204 for (String groupName : unpopulatableGroups.get(namespaceCode)) {
205 int i = 0;
206 for (PersonDocumentGroup group : document.getGroups()) {
207 if ( (group.getNamespaceCode() != null && namespaceCode.endsWith(group.getNamespaceCode())) && (group.getGroupName() != null && groupName.equals(group.getGroupName()))) {
208 GlobalVariables.getMessageMap().putError("groups["+i+"].groupId", RiceKeyConstants.ERROR_POPULATE_GROUP, new String[] {namespaceCode, groupName});
209 }
210 i++;
211 }
212 }
213 valid = false;
214 }
215 return valid;
216 }
217
218 @Override
219 protected boolean processCustomRouteDocumentBusinessRules(Document document) {
220 super.processCustomRouteDocumentBusinessRules(document);
221 IdentityManagementPersonDocument personDoc = (IdentityManagementPersonDocument)document;
222 boolean valid = true;
223 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
224 valid &= validateAffiliationAndName( personDoc );
225 valid &= checkAffiliationEithOneEMpInfo (personDoc.getAffiliations());
226 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
227
228 return valid;
229 }
230
231
232 protected boolean checkMultipleDefault (List <? extends PersonDocumentBoDefaultBase> boList, String listName) {
233 boolean valid = true;
234 boolean isDefaultSet = false;
235 int i = 0;
236 for (PersonDocumentBoDefaultBase item : boList) {
237 if (item.isDflt()) {
238 if (isDefaultSet) {
239 GlobalVariables.getMessageMap().putError(listName+"[" + i + "].dflt",RiceKeyConstants.ERROR_MULTIPLE_DEFAULT_SELETION);
240 valid = false;
241 } else {
242 isDefaultSet = true;
243 }
244 }
245 i++;
246 }
247 if (!boList.isEmpty() && !isDefaultSet) {
248 GlobalVariables.getMessageMap().putError(listName+"[0].dflt",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
249 }
250 return valid;
251 }
252
253 protected boolean checkPrimaryEmploymentInfo (List <PersonDocumentAffiliation> affiliations) {
254 boolean valid = true;
255 int i = 0;
256 int firstAfflnCounter = -1;
257 boolean isPrimarySet = false;
258 for (PersonDocumentAffiliation affiliation : affiliations) {
259 int j = 0;
260 for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
261 if(firstAfflnCounter==-1) {
262 firstAfflnCounter = i;
263 }
264 if (empInfo.isPrimary()) {
265 if (isPrimarySet) {
266
267 GlobalVariables.getMessageMap().putError("affiliations[" + i + "].empInfos["+ j +"].primary",RiceKeyConstants.ERROR_MULTIPLE_PRIMARY_EMPLOYMENT);
268 valid = false;
269 } else {
270 isPrimarySet = true;
271 }
272 j++;
273 }
274 }
275 i++;
276 }
277 if(!isPrimarySet && firstAfflnCounter!=-1){
278 GlobalVariables.getMessageMap().putError("affiliations[" + firstAfflnCounter + "].empInfos[0].primary",RiceKeyConstants.ERROR_NO_PRIMARY_EMPLOYMENT);
279 valid = false;
280 }
281 return valid;
282 }
283
284 protected boolean checkAffiliationTypeChange (List <PersonDocumentAffiliation> affiliations) {
285 boolean valid = true;
286 int i = 0;
287 for (PersonDocumentAffiliation affiliation : affiliations) {
288 if (affiliation.getAffiliationType() != null && !affiliation.getAffiliationTypeCode().equals(affiliation.getAffiliationType().getCode())) {
289 PersonDocumentAffiliation copiedAffiliation = (PersonDocumentAffiliation)ObjectUtils.deepCopy(affiliation);
290 copiedAffiliation.refreshReferenceObject("affiliationType");
291 if (!copiedAffiliation.getAffiliationType().isEmploymentAffiliationType() && affiliation.getAffiliationType().isEmploymentAffiliationType() && !copiedAffiliation.getEmpInfos().isEmpty()) {
292 GlobalVariables.getMessageMap().putError("affiliations[" + i + "].affiliationTypeCode",RiceKeyConstants.ERROR_NOT_EMPLOYMENT_AFFILIATION_TYPE,new String[] {affiliation.getAffiliationType().getName(), copiedAffiliation.getAffiliationType().getName()});
293 valid = false;
294 }
295 }
296 i++;
297 }
298 return valid;
299 }
300
301 protected boolean validEmployeeIDForAffiliation(List <PersonDocumentAffiliation> affiliations) {
302 boolean valid = true;
303 int i = 0;
304 int j = 0;
305 for(PersonDocumentAffiliation affiliation : affiliations) {
306 if(affiliation.getAffiliationType() != null && affiliation.getAffiliationType().isEmploymentAffiliationType()){
307 if(affiliation.getEmpInfos()!=null){
308 j = 0;
309 for (PersonDocumentEmploymentInfo empInfo : affiliation.getEmpInfos()) {
310 if (StringUtils.isEmpty(empInfo.getEmployeeId())) {
311 GlobalVariables.getMessageMap().putError("affiliations[" + i + "].empInfos["+ j +"].employeeId", RiceKeyConstants.ERROR_REQUIRED_CONDITIONALLY, new String[] {"Employee ID", "an employee"});
312 valid = false;
313 j++;
314 }
315 }
316 }
317 }
318 i++;
319 }
320 return valid;
321 }
322
323 protected boolean isPersonAnEmployee(List<PersonDocumentAffiliation> affiliations){
324 boolean isEmployee = false;
325 for (PersonDocumentAffiliation affiliation : affiliations){
326 if (affiliation.getAffiliationType() != null && affiliation.getAffiliationType().isEmploymentAffiliationType()){
327 isEmployee = true;
328 break;
329 }
330 }
331 return isEmployee;
332 }
333
334 protected boolean checkUniqueAffiliationTypePerCampus (List <PersonDocumentAffiliation> affiliations) {
335 boolean valid = true;
336 int i = 0;
337 for (PersonDocumentAffiliation affiliation : affiliations) {
338 int j = 0;
339 for (PersonDocumentAffiliation affiliation1 : affiliations) {
340 if (j > i && affiliation.getAffiliationTypeCode() .equals(affiliation1.getAffiliationTypeCode()) && affiliation.getCampusCode().equals(affiliation1.getCampusCode())) {
341 GlobalVariables.getMessageMap().putError("affiliations[" + j + "].affiliationTypeCode",RiceKeyConstants.ERROR_NOT_UNIQUE_AFFILIATION_TYPE_PER_CAMPUE, affiliation.getAffiliationType().getName());
342 valid = false;
343 }
344 j++;
345 }
346 i++;
347 }
348 return valid;
349 }
350
351 protected boolean checkAffiliationEithOneEMpInfo (List <PersonDocumentAffiliation> affiliations) {
352 boolean valid = true;
353 int i = 0;
354 for (PersonDocumentAffiliation affiliation : affiliations) {
355 if (affiliation.getAffiliationType() .isEmploymentAffiliationType() && affiliation.getEmpInfos().isEmpty()) {
356 GlobalVariables.getMessageMap().putError("affiliations[" + i + "].affiliationTypeCode",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "Employment Information");
357 valid = false;
358 }
359 i++;
360 }
361 return valid;
362 }
363
364
365
366
367 protected boolean validateAffiliationAndName(IdentityManagementPersonDocument personDoc) {
368 boolean valid = true;
369 if (personDoc.getAffiliations().isEmpty()) {
370 GlobalVariables.getMessageMap().putError("affiliations[0]",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "affiliation");
371 valid = false;
372 }
373 if (personDoc.getNames().isEmpty()) {
374 GlobalVariables.getMessageMap().putError("names[0]",RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "name");
375 valid = false;
376 } else{
377 boolean activeExists = false;
378 for(PersonDocumentName name: personDoc.getNames()){
379 if(name.isActive()){
380 activeExists = true;
381 }
382 }
383 if(!activeExists){
384 GlobalVariables.getMessageMap().putError("names[0]", RiceKeyConstants.ERROR_ONE_ACTIVE_ITEM_REQUIRED, "name");
385 valid = false;
386 }
387 return valid;
388
389 }
390 return valid;
391 }
392
393 protected boolean doesPrincipalNameExist (String principalName, String principalId) {
394 Principal principal = getIdentityService().getPrincipalByPrincipalName(principalName);
395 if (principal != null && (StringUtils.isBlank(principalId) || !principal.getPrincipalId().equals(principalId))) {
396 GlobalVariables.getMessageMap().putError(KIMPropertyConstants.Person.PRINCIPAL_NAME,RiceKeyConstants.ERROR_EXIST_PRINCIPAL_NAME, principalName);
397 return false;
398 }
399 return true;
400 }
401
402 protected boolean validateRoleQualifier( List<PersonDocumentRole> roles ) {
403 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
404 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
405 int i = 0;
406 for(PersonDocumentRole role : roles ) {
407 KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(KimTypeBo.to(
408 role.getKimRoleType()));
409 if(CollectionUtils.isEmpty(role.getRolePrncpls()) && !role.getDefinitions().isEmpty()){
410 KimType kimTypeInfo = KimApiServiceLocator.getKimTypeInfoService().getKimType(role.getKimRoleType().getId());
411 Map<String, String> blankQualifiers = attributeValidationHelper.getBlankValueQualifiersMap(kimTypeInfo.getAttributeDefinitions());
412 List<RemotableAttributeError> localErrors = kimTypeService.validateAttributes(
413 role.getKimRoleType().getId(), blankQualifiers);
414 if(localErrors!=null && !localErrors.isEmpty()){
415 GlobalVariables.getMessageMap().putError("document.roles["+i+"].newRolePrncpl.qualifiers[0].attrVal",
416 RiceKeyConstants.ERROR_ONE_ITEM_REQUIRED, "Role Qualifier");
417 return false;
418 }
419 }
420
421 final List<KimAttributeField> attributeDefinitions = role.getDefinitions();
422 final Set<String> uniqueQualifierAttributes = findUniqueQualificationAttributes(role, attributeDefinitions);
423
424 if ( kimTypeService != null ) {
425 int j = 0;
426
427 for ( KimDocumentRoleMember rolePrincipal : activeRoleMemberHelper.getActiveRoleMembers(role.getRolePrncpls()) ) {
428 List<RemotableAttributeError> localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), attributeValidationHelper.convertQualifiersToMap( rolePrincipal.getQualifiers() ) );
429 validationErrors.addAll( attributeValidationHelper.convertErrors(
430 "roles[" + i + "].rolePrncpls[" + j + "]",
431 attributeValidationHelper.convertQualifiersToAttrIdxMap(rolePrincipal.getQualifiers()),
432 localErrors));
433
434 if (uniqueQualifierAttributes.size() > 0) {
435 validateUniquePersonRoleQualifiersUniqueForMembership(role, rolePrincipal, j, uniqueQualifierAttributes, i, validationErrors);
436 }
437
438 j++;
439 }
440 }
441 i++;
442 }
443 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
444 if (validationErrors.isEmpty()) {
445 return true;
446 } else {
447 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
448 return false;
449 }
450 }
451
452
453
454
455
456
457
458
459 protected boolean validateUniquePersonRoleQualifiersUniqueForMembership(PersonDocumentRole role, KimDocumentRoleMember membershipToCheck, int membershipToCheckIndex, Set<String> uniqueQualifierAttributes, int roleIndex, List<RemotableAttributeError> validationErrors) {
460 boolean foundError = false;
461 int count = 0;
462
463 for (KimDocumentRoleMember membership : role.getRolePrncpls()) {
464 if (sameMembershipQualifications(membershipToCheck, membership, uniqueQualifierAttributes)) {
465 if (count == 0 ) {
466 count +=1;
467 } else {
468 count += 1;
469 foundError = true;
470
471 int qualifierCount = 0;
472
473 for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
474 if (qualifier != null && uniqueQualifierAttributes.contains(qualifier.getKimAttrDefnId())) {
475 validationErrors.add(RemotableAttributeError.Builder.create("document.roles["+roleIndex+"].rolePrncpls["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+qualifier.getKimAttribute().getAttributeName()+";"+qualifier.getAttrVal()).build());
476 }
477 qualifierCount += 1;
478 }
479 }
480 }
481 }
482 return foundError;
483 }
484
485
486
487
488
489
490
491
492 protected boolean sameMembershipQualifications(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB, Set<String> uniqueQualifierAttributes) {
493 boolean equalSoFar = true;
494 for (String uniqueQualifierAttributeDefinitionId : uniqueQualifierAttributes) {
495 final KimDocumentRoleQualifier qualifierA = membershipA.getQualifier(uniqueQualifierAttributeDefinitionId);
496 final KimDocumentRoleQualifier qualifierB = membershipB.getQualifier(uniqueQualifierAttributeDefinitionId);
497
498 if (qualifierA != null && qualifierB != null) {
499 equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
500 }
501 }
502 return equalSoFar;
503 }
504
505
506
507
508
509
510
511
512 public Set<String> findUniqueQualificationAttributes(PersonDocumentRole role, List<KimAttributeField> attributeDefinitions) {
513 Set<String> uniqueQualifications = new HashSet<String>();
514
515 if (role.getRolePrncpls() != null && role.getRolePrncpls().size() > 1) {
516 final KimDocumentRoleMember membership = role.getRolePrncpls().get(0);
517 for (KimDocumentRoleQualifier qualifier: membership.getQualifiers()) {
518 if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
519 final KimAttributeField relatedDefinition = DataDictionaryTypeServiceHelper.findAttributeField(
520 qualifier.getKimAttribute().getAttributeName(), attributeDefinitions);
521
522 if (relatedDefinition != null && relatedDefinition.isUnique()) {
523 uniqueQualifications.add(qualifier.getKimAttrDefnId());
524 }
525 }
526 }
527 }
528
529 return uniqueQualifications;
530 }
531
532 protected boolean validActiveDatesForRole (List<PersonDocumentRole> roles ) {
533 boolean valid = true;
534 int i = 0;
535 for(PersonDocumentRole role : roles ) {
536 int j = 0;
537 for (KimDocumentRoleMember principal : role.getRolePrncpls()) {
538 valid &= validateActiveDate("roles["+i+"].rolePrncpls["+j+"].activeToDate",principal.getActiveFromDate(), principal.getActiveToDate());
539 j++;
540 }
541 i++;
542 }
543 return valid;
544 }
545
546 protected boolean validActiveDatesForGroup (List<PersonDocumentGroup> groups ) {
547 boolean valid = true;
548 int i = 0;
549 for(PersonDocumentGroup group : groups ) {
550 valid &= validateActiveDate("groups["+i+"].activeToDate",group.getActiveFromDate(), group.getActiveToDate());
551 i++;
552 }
553 return valid;
554 }
555
556 protected boolean validActiveDatesForDelegations(List<RoleDocumentDelegationMember> delegationMembers) {
557 boolean valid = true;
558 int i = 0;
559 for(RoleDocumentDelegationMember delegationMember: delegationMembers){
560 valid &= validateActiveDate("delegationMembers["+i+"].activeToDate", delegationMember.getActiveFromDate(), delegationMember.getActiveToDate());
561 i++;
562 }
563 return valid;
564 }
565
566 protected boolean validateActiveDate(String errorPath, Timestamp activeFromDate, Timestamp activeToDate) {
567
568 boolean valid = true;
569 if (activeFromDate != null && activeToDate !=null && activeToDate.before(activeFromDate)) {
570 GlobalVariables.getMessageMap().putError(errorPath, RiceKeyConstants.ERROR_ACTIVE_TO_DATE_BEFORE_FROM_DATE);
571 valid = false;
572 }
573 return valid;
574 }
575
576 public boolean processAddGroup(AddGroupEvent addGroupEvent) {
577 return getAddGroupRule().processAddGroup(addGroupEvent);
578 }
579
580 public boolean processAddRole(AddRoleEvent addRoleEvent) {
581 return getAddRoleRule().processAddRole(addRoleEvent);
582 }
583
584 public boolean processAddPersonDelegationMember(AddPersonDelegationMemberEvent addPersonDelegationMemberEvent){
585 return getAddPersonDelegationMemberRule().processAddPersonDelegationMember(addPersonDelegationMemberEvent);
586 }
587
588 public IdentityService getIdentityService() {
589 if ( identityService == null ) {
590 identityService = KimApiServiceLocator.getIdentityService();
591 }
592 return identityService;
593 }
594
595 public RoleService getRoleService() {
596 if ( roleService == null ) {
597 roleService = KimApiServiceLocator.getRoleService();
598 }
599 return roleService;
600 }
601
602 public UiDocumentService getUIDocumentService() {
603 if ( uiDocumentService == null ) {
604 uiDocumentService = KIMServiceLocatorInternal.getUiDocumentService();
605 }
606 return uiDocumentService;
607 }
608
609 public IdentityManagementKimDocumentAuthorizer getAuthorizer(IdentityManagementPersonDocument document) {
610 if ( authorizer == null ) {
611 authorizer = (IdentityManagementKimDocumentAuthorizer) KRADServiceLocatorWeb.getDocumentDictionaryService().getDocumentAuthorizer(document);
612 }
613 return authorizer;
614 }
615
616
617
618
619
620
621 public Class<? extends AddGroupRule> getAddGroupRuleClass() {
622 return this.addGroupRuleClass;
623 }
624
625
626
627
628
629
630
631
632 public void setAddGroupRuleClass(Class<? extends AddGroupRule> addGroupRuleClass) {
633 this.addGroupRuleClass = addGroupRuleClass;
634 }
635
636
637
638
639
640
641 public Class<? extends AddRoleRule> getAddRoleRuleClass() {
642 return this.addRoleRuleClass;
643 }
644
645
646
647
648
649
650
651
652 public void setAddRoleRuleClass(Class<? extends AddRoleRule> addRoleRuleClass) {
653 this.addRoleRuleClass = addRoleRuleClass;
654 }
655
656
657
658
659
660
661 public AddGroupRule getAddGroupRule() {
662 if ( addGroupRule == null ) {
663 try {
664 addGroupRule = addGroupRuleClass.newInstance();
665 } catch ( Exception ex ) {
666 throw new RuntimeException( "Unable to create AddGroupRule instance using class: " + addGroupRuleClass, ex );
667 }
668 }
669 return addGroupRule;
670 }
671
672
673
674
675
676
677 public AddRoleRule getAddRoleRule() {
678 if ( addRoleRule == null ) {
679 try {
680 addRoleRule = addRoleRuleClass.newInstance();
681 } catch ( Exception ex ) {
682 throw new RuntimeException( "Unable to create AddRoleRule instance using class: " + addRoleRuleClass, ex );
683 }
684 }
685 return addRoleRule;
686 }
687
688
689
690
691 public AddPersonDelegationMemberRule getAddPersonDelegationMemberRule() {
692 if(addPersonDelegationMemberRule == null){
693 try {
694 addPersonDelegationMemberRule = addPersonDelegationMemberRuleClass.newInstance();
695 } catch ( Exception ex ) {
696 throw new RuntimeException( "Unable to create AddPersonDelegationMemberRuleClass instance using class: " + addPersonDelegationMemberRuleClass, ex );
697 }
698 }
699 return addPersonDelegationMemberRule;
700 }
701
702
703
704
705 public BusinessObjectService getBusinessObjectService() {
706 if ( businessObjectService == null ) {
707 businessObjectService = KRADServiceLocator.getBusinessObjectService();
708 }
709 return businessObjectService;
710 }
711
712 public boolean processAddPersonDocumentRoleQualifier(IdentityManagementPersonDocument document, PersonDocumentRole role, KimDocumentRoleMember kimDocumentRoleMember, int selectedRoleIdx) {
713 boolean dateValidationSuccess = validateActiveDate("document.roles[" + selectedRoleIdx + "].newRolePrncpl.activeFromDate", kimDocumentRoleMember.getActiveFromDate(), kimDocumentRoleMember.getActiveToDate());
714 String errorPath = "roles[" + selectedRoleIdx + "].newRolePrncpl";
715 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
716 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
717 KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(KimTypeBo.to(role.getKimRoleType()));
718
719 List<RemotableAttributeError> errorsAttributesAgainstExisting;
720 int i = 0;
721 boolean rulePassed = true;
722 Map<String, String> newMemberQualifiers = attributeValidationHelper.convertQualifiersToMap(kimDocumentRoleMember.getQualifiers());
723 Map<String, String> oldMemberQualifiers;
724 List<String> roleIds = new ArrayList<String>();
725 roleIds.add(role.getRoleId());
726 for(KimDocumentRoleMember member: role.getRolePrncpls()){
727 oldMemberQualifiers = member.getQualifierAsMap();
728 errorsAttributesAgainstExisting = kimTypeService.validateUniqueAttributes(
729 role.getKimRoleType().getId(), newMemberQualifiers, oldMemberQualifiers);
730 validationErrors.addAll(
731 attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper
732 .convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()),
733 errorsAttributesAgainstExisting));
734 i++;
735 }
736
737 if ( kimTypeService != null ) {
738 List<RemotableAttributeError> localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), newMemberQualifiers );
739 validationErrors.addAll( attributeValidationHelper.convertErrors(errorPath,
740 attributeValidationHelper.convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()),
741 localErrors));
742 }
743
744 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
745 if (validationErrors.isEmpty()) {
746 rulePassed = dateValidationSuccess;
747 } else {
748 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
749 rulePassed = false;
750 }
751 return rulePassed;
752 }
753
754 protected boolean validateDelegationMemberRoleQualifier(List<RoleDocumentDelegationMember> delegationMembers){
755 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
756 boolean valid;
757 int memberCounter = 0;
758 List<RemotableAttributeError> errorsTemp;
759 Map<String, String> mapToValidate;
760 KimTypeService kimTypeService;
761 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
762 RoleMemberBo roleMember;
763 String errorPath;
764 ArrayList<String> roleIds;
765 KimType kimType;
766 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
767 kimType = KimTypeBo.to(delegationMember.getRoleBo().getKimRoleType());
768 kimTypeService = KimFrameworkServiceLocator.getKimTypeService(kimType);
769 roleIds = new ArrayList<String>();
770 roleIds.add(delegationMember.getRoleBo().getId());
771 errorPath = "delegationMembers["+memberCounter+"]";
772 mapToValidate = attributeValidationHelper.convertQualifiersToMap(delegationMember.getQualifiers());
773 errorsTemp = kimTypeService.validateAttributes(kimType.getId(), mapToValidate);
774 validationErrors.addAll(
775 attributeValidationHelper.convertErrors(errorPath,
776 attributeValidationHelper.convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()),
777 errorsTemp));
778
779 roleMember = getUIDocumentService().getRoleMember(delegationMember.getRoleMemberId());
780 if(roleMember==null){
781 valid = false;
782 GlobalVariables.getMessageMap().putError("document."+errorPath, RiceKeyConstants.ERROR_DELEGATE_ROLE_MEMBER_ASSOCIATION, new String[]{});
783 } else{
784 kimTypeService.validateUnmodifiableAttributes(kimType.getId(), roleMember.getAttributes(), mapToValidate);
785 validationErrors.addAll(
786 attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper
787 .convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()), errorsTemp));
788 }
789 memberCounter++;
790 }
791 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
792 if (validationErrors.isEmpty()) {
793 valid = true;
794 } else {
795 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
796 valid = false;
797 }
798 return valid;
799 }
800
801 }