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