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
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 for ( KimDocumentRoleMember rolePrincipal : role.getRolePrncpls() ) {
427 List<RemotableAttributeError> localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), attributeValidationHelper.convertQualifiersToMap( rolePrincipal.getQualifiers() ) );
428 validationErrors.addAll( attributeValidationHelper.convertErrors(
429 "roles[" + i + "].rolePrncpls[" + j + "]",
430 attributeValidationHelper.convertQualifiersToAttrIdxMap(rolePrincipal.getQualifiers()),
431 localErrors));
432
433 if (uniqueQualifierAttributes.size() > 0) {
434 validateUniquePersonRoleQualifiersUniqueForMembership(role, rolePrincipal, j, uniqueQualifierAttributes, i, validationErrors);
435 }
436
437 j++;
438 }
439 }
440 i++;
441 }
442 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
443 if (validationErrors.isEmpty()) {
444 return true;
445 } else {
446 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
447 return false;
448 }
449 }
450
451
452
453
454
455
456
457
458 protected boolean validateUniquePersonRoleQualifiersUniqueForMembership(PersonDocumentRole role, KimDocumentRoleMember membershipToCheck, int membershipToCheckIndex, Set<String> uniqueQualifierAttributes, int roleIndex, List<RemotableAttributeError> validationErrors) {
459 boolean foundError = false;
460 int count = 0;
461
462 for (KimDocumentRoleMember membership : role.getRolePrncpls()) {
463 if (membershipToCheckIndex != count) {
464 if (sameMembershipQualifications(membershipToCheck, membership, uniqueQualifierAttributes)) {
465 foundError = true;
466
467 int qualifierCount = 0;
468
469 for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
470 if (qualifier != null && uniqueQualifierAttributes.contains(qualifier.getKimAttrDefnId())) {
471 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());
472 }
473 qualifierCount += 1;
474 }
475 }
476 }
477
478 count += 1;
479 }
480 return foundError;
481 }
482
483
484
485
486
487
488
489
490 protected boolean sameMembershipQualifications(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB, Set<String> uniqueQualifierAttributes) {
491 boolean equalSoFar = true;
492 for (String uniqueQualifierAttributeDefinitionId : uniqueQualifierAttributes) {
493 final KimDocumentRoleQualifier qualifierA = membershipA.getQualifier(uniqueQualifierAttributeDefinitionId);
494 final KimDocumentRoleQualifier qualifierB = membershipB.getQualifier(uniqueQualifierAttributeDefinitionId);
495
496 if (qualifierA != null && qualifierB != null) {
497 equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
498 }
499 }
500 return equalSoFar;
501 }
502
503
504
505
506
507
508
509
510 public Set<String> findUniqueQualificationAttributes(PersonDocumentRole role, List<KimAttributeField> attributeDefinitions) {
511 Set<String> uniqueQualifications = new HashSet<String>();
512
513 if (role.getRolePrncpls() != null && role.getRolePrncpls().size() > 1) {
514 final KimDocumentRoleMember membership = role.getRolePrncpls().get(0);
515 for (KimDocumentRoleQualifier qualifier: membership.getQualifiers()) {
516 if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
517 final KimAttributeField relatedDefinition = DataDictionaryTypeServiceHelper.findAttributeField(
518 qualifier.getKimAttribute().getAttributeName(), attributeDefinitions);
519
520 if (relatedDefinition != null && relatedDefinition.isUnique()) {
521 uniqueQualifications.add(qualifier.getKimAttrDefnId());
522 }
523 }
524 }
525 }
526
527 return uniqueQualifications;
528 }
529
530 protected boolean validActiveDatesForRole (List<PersonDocumentRole> roles ) {
531 boolean valid = true;
532 int i = 0;
533 for(PersonDocumentRole role : roles ) {
534 int j = 0;
535 for (KimDocumentRoleMember principal : role.getRolePrncpls()) {
536 valid &= validateActiveDate("roles["+i+"].rolePrncpls["+j+"].activeToDate",principal.getActiveFromDate(), principal.getActiveToDate());
537 j++;
538 }
539 i++;
540 }
541 return valid;
542 }
543
544 protected boolean validActiveDatesForGroup (List<PersonDocumentGroup> groups ) {
545 boolean valid = true;
546 int i = 0;
547 for(PersonDocumentGroup group : groups ) {
548 valid &= validateActiveDate("groups["+i+"].activeToDate",group.getActiveFromDate(), group.getActiveToDate());
549 i++;
550 }
551 return valid;
552 }
553
554 protected boolean validActiveDatesForDelegations(List<RoleDocumentDelegationMember> delegationMembers) {
555 boolean valid = true;
556 int i = 0;
557 for(RoleDocumentDelegationMember delegationMember: delegationMembers){
558 valid &= validateActiveDate("delegationMembers["+i+"].activeToDate", delegationMember.getActiveFromDate(), delegationMember.getActiveToDate());
559 i++;
560 }
561 return valid;
562 }
563
564 protected boolean validateActiveDate(String errorPath, Timestamp activeFromDate, Timestamp activeToDate) {
565
566 boolean valid = true;
567 if (activeFromDate != null && activeToDate !=null && activeToDate.before(activeFromDate)) {
568 GlobalVariables.getMessageMap().putError(errorPath, RiceKeyConstants.ERROR_ACTIVE_TO_DATE_BEFORE_FROM_DATE);
569 valid = false;
570 }
571 return valid;
572 }
573
574 public boolean processAddGroup(AddGroupEvent addGroupEvent) {
575 return getAddGroupRule().processAddGroup(addGroupEvent);
576 }
577
578 public boolean processAddRole(AddRoleEvent addRoleEvent) {
579 return getAddRoleRule().processAddRole(addRoleEvent);
580 }
581
582 public boolean processAddPersonDelegationMember(AddPersonDelegationMemberEvent addPersonDelegationMemberEvent){
583 return getAddPersonDelegationMemberRule().processAddPersonDelegationMember(addPersonDelegationMemberEvent);
584 }
585
586 public IdentityService getIdentityService() {
587 if ( identityService == null ) {
588 identityService = KimApiServiceLocator.getIdentityService();
589 }
590 return identityService;
591 }
592
593 public RoleService getRoleService() {
594 if ( roleService == null ) {
595 roleService = KimApiServiceLocator.getRoleService();
596 }
597 return roleService;
598 }
599
600 public UiDocumentService getUIDocumentService() {
601 if ( uiDocumentService == null ) {
602 uiDocumentService = KIMServiceLocatorInternal.getUiDocumentService();
603 }
604 return uiDocumentService;
605 }
606
607 public IdentityManagementKimDocumentAuthorizer getAuthorizer(IdentityManagementPersonDocument document) {
608 if ( authorizer == null ) {
609 authorizer = (IdentityManagementKimDocumentAuthorizer) KRADServiceLocatorWeb.getDocumentDictionaryService().getDocumentAuthorizer(document);
610 }
611 return authorizer;
612 }
613
614
615
616
617
618
619 public Class<? extends AddGroupRule> getAddGroupRuleClass() {
620 return this.addGroupRuleClass;
621 }
622
623
624
625
626
627
628
629
630 public void setAddGroupRuleClass(Class<? extends AddGroupRule> addGroupRuleClass) {
631 this.addGroupRuleClass = addGroupRuleClass;
632 }
633
634
635
636
637
638
639 public Class<? extends AddRoleRule> getAddRoleRuleClass() {
640 return this.addRoleRuleClass;
641 }
642
643
644
645
646
647
648
649
650 public void setAddRoleRuleClass(Class<? extends AddRoleRule> addRoleRuleClass) {
651 this.addRoleRuleClass = addRoleRuleClass;
652 }
653
654
655
656
657
658
659 public AddGroupRule getAddGroupRule() {
660 if ( addGroupRule == null ) {
661 try {
662 addGroupRule = addGroupRuleClass.newInstance();
663 } catch ( Exception ex ) {
664 throw new RuntimeException( "Unable to create AddGroupRule instance using class: " + addGroupRuleClass, ex );
665 }
666 }
667 return addGroupRule;
668 }
669
670
671
672
673
674
675 public AddRoleRule getAddRoleRule() {
676 if ( addRoleRule == null ) {
677 try {
678 addRoleRule = addRoleRuleClass.newInstance();
679 } catch ( Exception ex ) {
680 throw new RuntimeException( "Unable to create AddRoleRule instance using class: " + addRoleRuleClass, ex );
681 }
682 }
683 return addRoleRule;
684 }
685
686
687
688
689 public AddPersonDelegationMemberRule getAddPersonDelegationMemberRule() {
690 if(addPersonDelegationMemberRule == null){
691 try {
692 addPersonDelegationMemberRule = addPersonDelegationMemberRuleClass.newInstance();
693 } catch ( Exception ex ) {
694 throw new RuntimeException( "Unable to create AddPersonDelegationMemberRuleClass instance using class: " + addPersonDelegationMemberRuleClass, ex );
695 }
696 }
697 return addPersonDelegationMemberRule;
698 }
699
700
701
702
703 public BusinessObjectService getBusinessObjectService() {
704 if ( businessObjectService == null ) {
705 businessObjectService = KRADServiceLocator.getBusinessObjectService();
706 }
707 return businessObjectService;
708 }
709
710 public boolean processAddPersonDocumentRoleQualifier(IdentityManagementPersonDocument document, PersonDocumentRole role, KimDocumentRoleMember kimDocumentRoleMember, int selectedRoleIdx) {
711 boolean dateValidationSuccess = validateActiveDate("document.roles[" + selectedRoleIdx + "].newRolePrncpl.activeFromDate", kimDocumentRoleMember.getActiveFromDate(), kimDocumentRoleMember.getActiveToDate());
712 String errorPath = "roles[" + selectedRoleIdx + "].newRolePrncpl";
713 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
714 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
715 KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(KimTypeBo.to(role.getKimRoleType()));
716
717 List<RemotableAttributeError> errorsAttributesAgainstExisting;
718 int i = 0;
719 boolean rulePassed = true;
720 Map<String, String> newMemberQualifiers = attributeValidationHelper.convertQualifiersToMap(kimDocumentRoleMember.getQualifiers());
721 Map<String, String> oldMemberQualifiers;
722 List<String> roleIds = new ArrayList<String>();
723 roleIds.add(role.getRoleId());
724 for(KimDocumentRoleMember member: role.getRolePrncpls()){
725 oldMemberQualifiers = member.getQualifierAsMap();
726 errorsAttributesAgainstExisting = kimTypeService.validateUniqueAttributes(
727 role.getKimRoleType().getId(), newMemberQualifiers, oldMemberQualifiers);
728 validationErrors.addAll(
729 attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper
730 .convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()),
731 errorsAttributesAgainstExisting));
732 i++;
733 }
734
735 if ( kimTypeService != null ) {
736 List<RemotableAttributeError> localErrors = kimTypeService.validateAttributes( role.getKimRoleType().getId(), newMemberQualifiers );
737 validationErrors.addAll( attributeValidationHelper.convertErrors(errorPath,
738 attributeValidationHelper.convertQualifiersToAttrIdxMap(kimDocumentRoleMember.getQualifiers()),
739 localErrors));
740 }
741
742 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
743 if (validationErrors.isEmpty()) {
744 rulePassed = dateValidationSuccess;
745 } else {
746 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
747 rulePassed = false;
748 }
749 return rulePassed;
750 }
751
752 protected boolean validateDelegationMemberRoleQualifier(List<RoleDocumentDelegationMember> delegationMembers){
753 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
754 boolean valid;
755 int memberCounter = 0;
756 List<RemotableAttributeError> errorsTemp;
757 Map<String, String> mapToValidate;
758 KimTypeService kimTypeService;
759 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
760 RoleMemberBo roleMember;
761 String errorPath;
762 ArrayList<String> roleIds;
763 KimType kimType;
764 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
765 kimType = KimTypeBo.to(delegationMember.getRoleBo().getKimRoleType());
766 kimTypeService = KimFrameworkServiceLocator.getKimTypeService(kimType);
767 roleIds = new ArrayList<String>();
768 roleIds.add(delegationMember.getRoleBo().getId());
769 errorPath = "delegationMembers["+memberCounter+"]";
770 mapToValidate = attributeValidationHelper.convertQualifiersToMap(delegationMember.getQualifiers());
771 errorsTemp = kimTypeService.validateAttributes(kimType.getId(), mapToValidate);
772 validationErrors.addAll(
773 attributeValidationHelper.convertErrors(errorPath,
774 attributeValidationHelper.convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()),
775 errorsTemp));
776
777 roleMember = getUIDocumentService().getRoleMember(delegationMember.getRoleMemberId());
778 if(roleMember==null){
779 valid = false;
780 GlobalVariables.getMessageMap().putError("document."+errorPath, RiceKeyConstants.ERROR_DELEGATE_ROLE_MEMBER_ASSOCIATION, new String[]{});
781 } else{
782 kimTypeService.validateUnmodifiableAttributes(kimType.getId(), roleMember.getAttributes(), mapToValidate);
783 validationErrors.addAll(
784 attributeValidationHelper.convertErrors(errorPath, attributeValidationHelper
785 .convertQualifiersToAttrIdxMap(delegationMember.getQualifiers()), errorsTemp));
786 }
787 memberCounter++;
788 }
789 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
790 if (validationErrors.isEmpty()) {
791 valid = true;
792 } else {
793 attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
794 valid = false;
795 }
796 return valid;
797 }
798
799 }