Coverage Report - org.kuali.rice.kim.document.rule.IdentityManagementRoleDocumentRule
 
Classes in this File Line Coverage Branch Coverage Complexity
IdentityManagementRoleDocumentRule
0%
0/299
0%
0/230
4.368
 
 1  
 /*
 2  
  * Copyright 2007-2009 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kim.document.rule;
 17  
 
 18  
 import java.sql.Timestamp;
 19  
 import java.util.HashMap;
 20  
 import java.util.HashSet;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 import java.util.Set;
 24  
 
 25  
 import org.apache.commons.lang.StringUtils;
 26  
 import org.kuali.rice.core.util.RiceKeyConstants;
 27  
 import org.kuali.rice.core.xml.dto.AttributeSet;
 28  
 import org.kuali.rice.kim.bo.impl.RoleImpl;
 29  
 import org.kuali.rice.kim.bo.role.dto.KimPermissionInfo;
 30  
 import org.kuali.rice.kim.bo.role.dto.KimResponsibilityInfo;
 31  
 import org.kuali.rice.kim.bo.role.impl.KimResponsibilityImpl;
 32  
 import org.kuali.rice.kim.bo.types.dto.AttributeDefinitionMap;
 33  
 import org.kuali.rice.kim.bo.types.dto.KimTypeInfo;
 34  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember;
 35  
 import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission;
 36  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier;
 37  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility;
 38  
 import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibilityAction;
 39  
 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember;
 40  
 import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier;
 41  
 import org.kuali.rice.kim.document.IdentityManagementRoleDocument;
 42  
 import org.kuali.rice.kim.lookup.KimTypeLookupableHelperServiceImpl;
 43  
 import org.kuali.rice.kim.rule.event.ui.AddDelegationEvent;
 44  
 import org.kuali.rice.kim.rule.event.ui.AddDelegationMemberEvent;
 45  
 import org.kuali.rice.kim.rule.event.ui.AddMemberEvent;
 46  
 import org.kuali.rice.kim.rule.event.ui.AddPermissionEvent;
 47  
 import org.kuali.rice.kim.rule.event.ui.AddResponsibilityEvent;
 48  
 import org.kuali.rice.kim.rule.ui.AddDelegationMemberRule;
 49  
 import org.kuali.rice.kim.rule.ui.AddDelegationRule;
 50  
 import org.kuali.rice.kim.rule.ui.AddMemberRule;
 51  
 import org.kuali.rice.kim.rule.ui.AddPermissionRule;
 52  
 import org.kuali.rice.kim.rule.ui.AddResponsibilityRule;
 53  
 import org.kuali.rice.kim.rules.ui.KimDocumentMemberRule;
 54  
 import org.kuali.rice.kim.rules.ui.KimDocumentPermissionRule;
 55  
 import org.kuali.rice.kim.rules.ui.KimDocumentResponsibilityRule;
 56  
 import org.kuali.rice.kim.rules.ui.RoleDocumentDelegationMemberRule;
 57  
 import org.kuali.rice.kim.rules.ui.RoleDocumentDelegationRule;
 58  
 import org.kuali.rice.kim.service.*;
 59  
 import org.kuali.rice.kim.service.impl.RoleServiceBase;
 60  
 import org.kuali.rice.kim.service.support.KimTypeService;
 61  
 import org.kuali.rice.kim.util.KimConstants;
 62  
 import org.kuali.rice.kns.datadictionary.AttributeDefinition;
 63  
 import org.kuali.rice.kns.document.Document;
 64  
 import org.kuali.rice.kns.rules.TransactionalDocumentRuleBase;
 65  
 import org.kuali.rice.kns.service.BusinessObjectService;
 66  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 67  
 import org.kuali.rice.kns.util.GlobalVariables;
 68  
 import org.kuali.rice.kns.util.KNSConstants;
 69  
 import org.kuali.rice.kns.util.MessageMap;
 70  
 
 71  
 /**
 72  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 73  
  */
 74  0
 public class IdentityManagementRoleDocumentRule extends TransactionalDocumentRuleBase implements AddPermissionRule, AddResponsibilityRule, AddMemberRule, AddDelegationRule, AddDelegationMemberRule {
 75  
 //        protected static final Logger LOG = Logger.getLogger( IdentityManagementRoleDocumentRule.class );
 76  
                         
 77  
     public static final int PRIORITY_NUMBER_MIN_VALUE = 1;
 78  
     public static final int PRIORITY_NUMBER_MAX_VALUE = 11;
 79  
 
 80  
         protected AddResponsibilityRule addResponsibilityRule;
 81  
         protected AddPermissionRule  addPermissionRule;
 82  
         protected AddMemberRule  addMemberRule;
 83  
         protected AddDelegationRule addDelegationRule;
 84  
         protected AddDelegationMemberRule addDelegationMemberRule;
 85  
         protected BusinessObjectService businessObjectService;
 86  
         protected ResponsibilityService responsibilityService;
 87  0
         protected Class<? extends AddResponsibilityRule> addResponsibilityRuleClass = KimDocumentResponsibilityRule.class;
 88  0
         protected Class<? extends AddPermissionRule> addPermissionRuleClass = KimDocumentPermissionRule.class;
 89  0
         protected Class<? extends AddMemberRule> addMemberRuleClass = KimDocumentMemberRule.class;
 90  0
         protected Class<? extends AddDelegationRule> addDelegationRuleClass = RoleDocumentDelegationRule.class;
 91  0
         protected Class<? extends AddDelegationMemberRule> addDelegationMemberRuleClass = RoleDocumentDelegationMemberRule.class;
 92  
 
 93  
         protected IdentityService identityService;
 94  
         
 95  0
         protected AttributeValidationHelper attributeValidationHelper = new AttributeValidationHelper();
 96  
         
 97  
         // KULRICE-4153
 98  0
         protected ActiveRoleMemberHelper activeRoleMemberHelper = new ActiveRoleMemberHelper();
 99  
         
 100  
     public IdentityService getIdentityService() {
 101  0
         if ( identityService == null) {
 102  0
             identityService = KIMServiceLocator.getIdentityService();
 103  
         }
 104  0
         return identityService;
 105  
     }
 106  
 
 107  
     @Override
 108  
     protected boolean processCustomSaveDocumentBusinessRules(Document document) {
 109  0
         if (!(document instanceof IdentityManagementRoleDocument))
 110  0
             return false;
 111  
 
 112  0
         IdentityManagementRoleDocument roleDoc = (IdentityManagementRoleDocument)document;
 113  
 
 114  0
         boolean valid = true;
 115  0
         boolean validateRoleAssigneesAndDelegations = !KimTypeLookupableHelperServiceImpl.hasDerivedRoleTypeService(roleDoc.getKimType());
 116  0
         GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 117  0
         valid &= validDuplicateRoleName(roleDoc);
 118  0
         valid &= validPermissions(roleDoc);
 119  0
         valid &= validResponsibilities(roleDoc);
 120  0
         getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document, getMaxDictionaryValidationDepth(), true, false);
 121  0
         validateRoleAssigneesAndDelegations &= validAssignRole(roleDoc);
 122  0
         if(validateRoleAssigneesAndDelegations){
 123  
                 //valid &= validAssignRole(roleDoc);
 124  
                 // KULRICE-4153 & KULRICE-4818
 125  
                 // Use the Active Role Member Helper to retrieve only those Role Members & Delegation member that are active
 126  
                 // If a member or delegation is active on a Role, and they have an inactive Role Qualifier, Role Qualifier validation will fail
 127  
                 // If a member or delegation is inactive on a Role, and they have an inactive Role Qualifier, Role Qualifier validation will pass
 128  0
                 List<KimDocumentRoleMember> activeRoleMembers = activeRoleMemberHelper.getActiveRoleMembers(roleDoc.getMembers());
 129  0
                 List<RoleDocumentDelegationMember> activeRoleDelegationMembers = activeRoleMemberHelper.getActiveDelegationRoleMembers(roleDoc.getDelegationMembers());
 130  
                 
 131  0
                 valid &= validateRoleQualifier(activeRoleMembers, roleDoc.getKimType());
 132  0
                 valid &= validRoleMemberActiveDates(roleDoc.getMembers());
 133  0
                 valid &= validateDelegationMemberRoleQualifier(activeRoleMembers, activeRoleDelegationMembers, roleDoc.getKimType());
 134  0
                 valid &= validDelegationMemberActiveDates(roleDoc.getDelegationMembers());
 135  0
                 valid &= validRoleMembersResponsibilityActions(roleDoc.getMembers());
 136  
         }
 137  0
         valid &= validRoleResponsibilitiesActions(roleDoc.getResponsibilities());
 138  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 139  
 
 140  0
         return valid;
 141  
     }
 142  
     
 143  
         protected boolean validAssignRole(IdentityManagementRoleDocument document){
 144  0
         boolean rulePassed = true;
 145  0
         Map<String,String> additionalPermissionDetails = new HashMap<String,String>();
 146  0
         additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace());
 147  0
         additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName());
 148  0
                 if((document.getMembers()!=null && document.getMembers().size()>0) ||
 149  
                                 (document.getDelegationMembers()!=null && document.getDelegationMembers().size()>0)){
 150  0
                         if(!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate(
 151  
                                         document, KimConstants.NAMESPACE_CODE, KimConstants.PermissionTemplateNames.ASSIGN_ROLE, 
 152  
                                         GlobalVariables.getUserSession().getPrincipalId(), additionalPermissionDetails, null)){
 153  0
                     rulePassed = false;
 154  
                         }
 155  
                 }
 156  0
                 return rulePassed;
 157  
         }
 158  
 
 159  
     @SuppressWarnings("unchecked")
 160  
         protected boolean validDuplicateRoleName(IdentityManagementRoleDocument roleDoc){
 161  0
             Map<String, String> criteria = new HashMap<String, String>();
 162  0
             criteria.put("roleName", roleDoc.getRoleName());
 163  0
             criteria.put("namespaceCode", roleDoc.getRoleNamespace());
 164  0
             List<RoleImpl> roleImpls = (List<RoleImpl>)getBusinessObjectService().findMatching(RoleImpl.class, criteria);
 165  0
             boolean rulePassed = true;
 166  0
             if(roleImpls!=null && roleImpls.size()>0){
 167  0
                     if(roleImpls.size()==1 && roleImpls.get(0).getRoleId().equals(roleDoc.getRoleId()))
 168  0
                             rulePassed = true;
 169  
                     else{
 170  0
                             GlobalVariables.getMessageMap().putError("document.roleName", 
 171  
                                             RiceKeyConstants.ERROR_DUPLICATE_ENTRY, new String[] {"Role Name"});
 172  0
                             rulePassed = false;
 173  
                     }
 174  
             }
 175  0
             return rulePassed;
 176  
     }
 177  
     
 178  
     protected boolean validRoleMemberActiveDates(List<KimDocumentRoleMember> roleMembers) {
 179  0
             boolean valid = true;
 180  0
                 int i = 0;
 181  0
             for(KimDocumentRoleMember roleMember: roleMembers) {
 182  0
                            valid &= validateActiveDate("document.members["+i+"].activeToDate", roleMember.getActiveFromDate(), roleMember.getActiveToDate());
 183  0
                     i++;
 184  
             }
 185  0
             return valid;
 186  
     }
 187  
 
 188  
     protected boolean validDelegationMemberActiveDates(List<RoleDocumentDelegationMember> delegationMembers) {
 189  0
             boolean valid = true;
 190  0
                 int i = 0;
 191  0
             for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
 192  0
                            valid &= validateActiveDate("document.delegationMembers["+i+"].activeToDate", 
 193  
                                            delegationMember.getActiveFromDate(), delegationMember.getActiveToDate());
 194  0
                     i++;
 195  
             }
 196  0
             return valid;
 197  
     }
 198  
 
 199  
     protected boolean validPermissions(IdentityManagementRoleDocument document){
 200  
             KimPermissionInfo kimPermissionInfo;
 201  0
             boolean valid = true;
 202  0
             int i = 0;
 203  0
             for(KimDocumentRolePermission permission: document.getPermissions()){
 204  0
                     kimPermissionInfo = permission.getKimPermission();
 205  0
                     if(!permission.isActive() && !hasPermissionToGrantPermission(permission.getKimPermission(), document)){
 206  0
                     GlobalVariables.getMessageMap().putError("permissions["+i+"].active", RiceKeyConstants.ERROR_ASSIGN_PERMISSION, 
 207  
                                     new String[] {kimPermissionInfo.getNamespaceCode(), kimPermissionInfo.getTemplate().getName()});
 208  0
                     valid = false;
 209  
                     }
 210  0
                     i++;
 211  
             }
 212  0
             return valid;
 213  
     }
 214  
 
 215  
     protected boolean validResponsibilities(IdentityManagementRoleDocument document){
 216  
             KimResponsibilityImpl kimResponsibilityImpl;
 217  0
             boolean valid = true;
 218  0
             int i = 0;
 219  0
             for(KimDocumentRoleResponsibility responsibility: document.getResponsibilities()){
 220  0
                     kimResponsibilityImpl = responsibility.getKimResponsibility();
 221  0
                     if(!responsibility.isActive() && !hasPermissionToGrantResponsibility(responsibility.getKimResponsibility().toSimpleInfo(), document)){
 222  0
                     GlobalVariables.getMessageMap().putError("responsibilities["+i+"].active", RiceKeyConstants.ERROR_ASSIGN_RESPONSIBILITY, 
 223  
                                     new String[] {kimResponsibilityImpl.getNamespaceCode(), kimResponsibilityImpl.getTemplate().getName()});
 224  0
                     valid = false;
 225  
                     }
 226  0
                     i++;
 227  
             }
 228  0
             return valid;
 229  
     }
 230  
     
 231  
     protected boolean validRoleResponsibilitiesActions(List<KimDocumentRoleResponsibility> roleResponsibilities){
 232  0
         int i = 0;
 233  0
         boolean rulePassed = true;
 234  0
             for(KimDocumentRoleResponsibility roleResponsibility: roleResponsibilities){
 235  0
                     if(!getResponsibilityService().areActionsAtAssignmentLevelById(roleResponsibility.getResponsibilityId()))
 236  0
                             validateRoleResponsibilityAction("document.responsibilities["+i+"].roleRspActions[0].priorityNumber", roleResponsibility.getRoleRspActions().get(0));
 237  0
                 i++;
 238  
             }
 239  0
             return rulePassed;
 240  
     }
 241  
 
 242  
     protected boolean validRoleMembersResponsibilityActions(List<KimDocumentRoleMember> roleMembers){
 243  0
         int i = 0;
 244  
         int j;
 245  0
         boolean rulePassed = true;
 246  0
             for(KimDocumentRoleMember roleMember: roleMembers){
 247  0
                     j = 0;
 248  0
                     if(roleMember.getRoleRspActions()!=null && !roleMember.getRoleRspActions().isEmpty()){
 249  0
                             for(KimDocumentRoleResponsibilityAction roleRspAction: roleMember.getRoleRspActions()){
 250  0
                                     validateRoleResponsibilityAction("document.members["+i+"].roleRspActions["+j+"].priorityNumber", roleRspAction);
 251  0
                                 j++;
 252  
                             }
 253  
                     }
 254  0
                     i++;
 255  
             }
 256  0
             return rulePassed;
 257  
     }
 258  
 
 259  
     protected boolean validateRoleResponsibilityAction(String errorPath, KimDocumentRoleResponsibilityAction roleRspAction){
 260  0
             boolean rulePassed = true;
 261  
             /*if(StringUtils.isBlank(roleRspAction.getActionPolicyCode())){
 262  
                     GlobalVariables.getErrorMap().putError(errorPath, 
 263  
                                     RiceKeyConstants.ERROR_EMPTY_ENTRY, new String[] {"Action Policy Code"});
 264  
                     rulePassed = false;
 265  
             }
 266  
             if(roleRspAction.getPriorityNumber()==null){
 267  
                     GlobalVariables.getErrorMap().putError(errorPath, 
 268  
                                     RiceKeyConstants.ERROR_EMPTY_ENTRY, new String[] {"Priority Number"});
 269  
                     rulePassed = false;
 270  
             }
 271  
             if(StringUtils.isBlank(roleRspAction.getActionTypeCode())){
 272  
                     GlobalVariables.getErrorMap().putError(errorPath, 
 273  
                                     RiceKeyConstants.ERROR_EMPTY_ENTRY, new String[] {"Action Type Code"});
 274  
                     rulePassed = false;
 275  
             }*/
 276  0
             if(roleRspAction.getPriorityNumber()!=null && 
 277  
                             (roleRspAction.getPriorityNumber()<PRIORITY_NUMBER_MIN_VALUE 
 278  
                                             || roleRspAction.getPriorityNumber()>PRIORITY_NUMBER_MAX_VALUE)){
 279  0
                     GlobalVariables.getMessageMap().putError(errorPath, 
 280  
                                    RiceKeyConstants.ERROR_PRIORITY_NUMBER_RANGE, new String[] {PRIORITY_NUMBER_MIN_VALUE+"", PRIORITY_NUMBER_MAX_VALUE+""});
 281  0
                     rulePassed = false;
 282  
             }
 283  
 
 284  0
             return rulePassed;
 285  
     }
 286  
 
 287  
     protected boolean validateRoleQualifier(List<KimDocumentRoleMember> roleMembers, KimTypeInfo kimType){
 288  0
                 AttributeSet validationErrors = new AttributeSet();
 289  
 
 290  0
                 int memberCounter = 0;
 291  0
                 int roleMemberCount = 0;
 292  
                 AttributeSet errorsTemp;
 293  
                 AttributeSet attributeSetToValidate;
 294  0
         KimTypeService kimTypeService = KIMServiceLocatorWeb.getKimTypeService(kimType);
 295  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 296  0
         final AttributeDefinitionMap attributeDefinitions = kimTypeService.getAttributeDefinitions(kimType.getKimTypeId());
 297  0
         final Set<String> uniqueAttributeNames = figureOutUniqueQualificationSet(roleMembers, attributeDefinitions);
 298  
         
 299  0
                 for(KimDocumentRoleMember roleMember: roleMembers) {
 300  0
                         errorsTemp = new AttributeSet();
 301  0
                         attributeSetToValidate = attributeValidationHelper.convertQualifiersToMap(roleMember.getQualifiers());
 302  0
                         if(!roleMember.isRole()){
 303  0
                                 errorsTemp = kimTypeService.validateAttributes(kimType.getKimTypeId(), attributeSetToValidate);
 304  0
                                 validationErrors.putAll( 
 305  
                                                 attributeValidationHelper.convertErrorsForMappedFields("document.members["+memberCounter+"]", errorsTemp) );
 306  0
                         memberCounter++;
 307  
                         }
 308  0
                         if (uniqueAttributeNames.size() > 0) {
 309  0
                                 validateUniquePersonRoleQualifiersUniqueForRoleMembership(roleMember, roleMemberCount, roleMembers, uniqueAttributeNames, validationErrors);
 310  
                         }
 311  
                         
 312  0
                         roleMemberCount += 1;
 313  
             }
 314  
 
 315  0
                 GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 316  
                 
 317  0
             if (validationErrors.isEmpty()) {
 318  0
                     return true;
 319  
             } 
 320  0
             attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
 321  0
             return false;
 322  
     }
 323  
     
 324  
     /**
 325  
      * Finds the names of the unique qualification attributes which this role should be checking against
 326  
      * 
 327  
      * @param memberships the memberships (we take the qualification from the first)
 328  
      * @param attributeDefinitions information about the attributeDefinitions
 329  
      * @return a Set of unique attribute ids (with their indices, for error reporting)
 330  
      */
 331  
     protected Set<String> figureOutUniqueQualificationSet(List<KimDocumentRoleMember> memberships, AttributeDefinitionMap attributeDefinitions) {
 332  0
             Set<String> uniqueAttributeIds = new HashSet<String>();
 333  
             
 334  0
             if (memberships != null && memberships.size() > 1) { // if there aren't two or more members, doing this whole check is kinda silly
 335  0
                     KimDocumentRoleMember membership = memberships.get(0);
 336  
                     
 337  0
                     for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
 338  0
                         if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
 339  0
                                 final AttributeDefinition relatedDefinition = attributeDefinitions.getByAttributeName(qualifier.getKimAttribute().getAttributeName());
 340  
                                 
 341  0
                                 if (relatedDefinition != null && relatedDefinition.getUnique() != null && relatedDefinition.getUnique().booleanValue()) {
 342  0
                                         uniqueAttributeIds.add(qualifier.getKimAttrDefnId()); // it's unique - add it to the Set
 343  
                                 }
 344  0
                         }
 345  
                     }
 346  
             }
 347  
             
 348  0
             return uniqueAttributeIds;
 349  
     }
 350  
     
 351  
     /**
 352  
      * Checks all the qualifiers for the given membership, so that all qualifiers which should be unique are guaranteed to be unique
 353  
      * 
 354  
      * @param membership the membership to check
 355  
      * @param attributeDefinitions the Map of attribute definitions used by the role
 356  
      * @param memberIndex the index of the person's membership in the role (for error reporting purposes)
 357  
      * @param validationErrors AttributeSet of errors to report
 358  
      * @return true if all unique values are indeed unique, false otherwise
 359  
      */
 360  
     protected boolean validateUniquePersonRoleQualifiersUniqueForRoleMembership(KimDocumentRoleMember membershipToCheck, int membershipToCheckIndex, List<KimDocumentRoleMember> memberships, Set<String> uniqueQualifierIds, AttributeSet validationErrors) {
 361  0
             boolean foundError = false;
 362  0
             int count = 0;
 363  
             
 364  0
             for (KimDocumentRoleMember membership : memberships) {
 365  0
                     if (membershipToCheckIndex != count) {
 366  0
                             if (sameMembership(membershipToCheck, membership)) {
 367  0
                                     if (sameUniqueMembershipQualifications(membershipToCheck, membership, uniqueQualifierIds)) {
 368  0
                                             foundError = true;
 369  
                                             // add error to each qualifier which is supposed to be unique
 370  0
                                             int qualifierCount = 0;
 371  
                                             
 372  0
                                             for (KimDocumentRoleQualifier qualifier : membership.getQualifiers()) {
 373  0
                                                     if (qualifier != null && uniqueQualifierIds.contains(qualifier.getKimAttrDefnId())) {
 374  0
                                                             validationErrors.put("document.members["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+qualifier.getKimAttribute().getAttributeName()+";"+qualifier.getAttrVal());
 375  
                                                     }
 376  0
                                                     qualifierCount += 1;
 377  
                                             }
 378  
                                     }
 379  
                             }
 380  
                     }
 381  0
                     count += 1;
 382  
             }
 383  
             
 384  0
             return foundError;
 385  
     }
 386  
     
 387  
     /**
 388  
      * Determines if two memberships represent the same member being added: that is, the two memberships have the same type code and id
 389  
      * 
 390  
      * @param membershipA the first membership to check
 391  
      * @param membershipB the second membership to check
 392  
      * @return true if the two memberships represent the same member; false if they do not, or if it could not be profitably determined if the members were the same
 393  
      */
 394  
     protected boolean sameMembership(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB) {
 395  0
             if (!StringUtils.isBlank(membershipA.getMemberTypeCode()) && !StringUtils.isBlank(membershipB.getMemberTypeCode()) && !StringUtils.isBlank(membershipA.getMemberId()) && !StringUtils.isBlank(membershipB.getMemberId())) {
 396  0
                     return membershipA.getMemberTypeCode().equals(membershipB.getMemberTypeCode()) && membershipA.getMemberId().equals(membershipB.getMemberId());
 397  
             }
 398  0
             return false;
 399  
     }
 400  
     
 401  
     /**
 402  
      * Given two memberships which represent the same member, do they share qualifications?
 403  
      * 
 404  
      * @param membershipA the first membership to check
 405  
      * @param membershipB the second membership to check
 406  
      * @param uniqueAttributeIds the Set of attribute definition ids which should be unique
 407  
      * @return
 408  
      */
 409  
     protected boolean sameUniqueMembershipQualifications(KimDocumentRoleMember membershipA, KimDocumentRoleMember membershipB, Set<String> uniqueAttributeIds) {
 410  0
             boolean equalSoFar = true;
 411  0
             for (String kimAttributeDefinitionId : uniqueAttributeIds) {
 412  0
                     final KimDocumentRoleQualifier qualifierA = membershipA.getQualifier(kimAttributeDefinitionId);
 413  0
                     final KimDocumentRoleQualifier qualifierB = membershipB.getQualifier(kimAttributeDefinitionId);
 414  
                     
 415  0
                     if (qualifierA != null && qualifierB != null) {
 416  0
                             equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
 417  
                     }
 418  0
             }
 419  0
             return equalSoFar;
 420  
     }
 421  
     
 422  
     protected KimDocumentRoleMember getRoleMemberForDelegation(
 423  
                     List<KimDocumentRoleMember> roleMembers, RoleDocumentDelegationMember delegationMember){
 424  0
             if(roleMembers==null || delegationMember==null || delegationMember.getRoleMemberId()==null) return null;
 425  0
             for(KimDocumentRoleMember roleMember: roleMembers){
 426  0
                     if(delegationMember.getRoleMemberId().equals(roleMember.getRoleMemberId()))
 427  0
                             return roleMember;
 428  
             }
 429  0
             return null;
 430  
     }
 431  
 
 432  
     protected boolean validateDelegationMemberRoleQualifier(List<KimDocumentRoleMember> roleMembers, 
 433  
                     List<RoleDocumentDelegationMember> delegationMembers, KimTypeInfo kimType){
 434  0
                 AttributeSet validationErrors = new AttributeSet();
 435  
                 boolean valid;
 436  0
                 int memberCounter = 0;
 437  
                 AttributeSet errorsTemp;
 438  
                 AttributeSet attributeSetToValidate;
 439  0
         KimTypeService kimTypeService = KIMServiceLocatorWeb.getKimTypeService(kimType);
 440  0
         GlobalVariables.getMessageMap().removeFromErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 441  
         KimDocumentRoleMember roleMember;
 442  
         String errorPath;
 443  0
         final AttributeDefinitionMap attributeDefinitions = kimTypeService.getAttributeDefinitions(kimType.getKimTypeId());
 444  0
         final Set<String> uniqueQualifierAttributes = figureOutUniqueQualificationSetForDelegation(delegationMembers, attributeDefinitions);
 445  
         
 446  0
                 for(RoleDocumentDelegationMember delegationMember: delegationMembers) {
 447  0
                         errorPath = "delegationMembers["+memberCounter+"]";
 448  0
                         errorsTemp = new AttributeSet();
 449  0
                         attributeSetToValidate = attributeValidationHelper.convertQualifiersToMap(delegationMember.getQualifiers());
 450  0
                         if(!delegationMember.isRole()){
 451  0
                                 errorsTemp = kimTypeService.validateAttributes(kimType.getKimTypeId(), attributeSetToValidate);
 452  0
                                 validationErrors.putAll(
 453  
                                                 attributeValidationHelper.convertErrorsForMappedFields(errorPath, errorsTemp));
 454  
                         }
 455  0
                         roleMember = getRoleMemberForDelegation(roleMembers, delegationMember);
 456  0
                         if(roleMember==null){
 457  0
                                 valid = false;
 458  0
                                 GlobalVariables.getMessageMap().putError("document.delegationMembers["+memberCounter+"]", RiceKeyConstants.ERROR_DELEGATE_ROLE_MEMBER_ASSOCIATION, new String[]{});
 459  
                         } else{
 460  0
                                 errorsTemp = kimTypeService.validateUnmodifiableAttributes(
 461  
                                                                 kimType.getKimTypeId(), 
 462  
                                                                 attributeValidationHelper.convertQualifiersToMap(roleMember.getQualifiers()), 
 463  
                                                                 attributeSetToValidate);
 464  0
                                 validationErrors.putAll(
 465  
                                                 attributeValidationHelper.convertErrorsForMappedFields(errorPath, errorsTemp) );
 466  
                         }
 467  0
                         if (uniqueQualifierAttributes.size() > 0) {
 468  0
                                 validateUniquePersonRoleQualifiersUniqueForRoleDelegation(delegationMember, memberCounter, delegationMembers, uniqueQualifierAttributes, validationErrors);
 469  
                         }
 470  0
                 memberCounter++;
 471  
             }
 472  0
                 GlobalVariables.getMessageMap().addToErrorPath(KNSConstants.DOCUMENT_PROPERTY_NAME);
 473  0
             if (validationErrors.isEmpty()) {
 474  0
                     valid = true;
 475  
             } else {
 476  0
                     attributeValidationHelper.moveValidationErrorsToErrorMap(validationErrors);
 477  0
                     valid = false;
 478  
             }
 479  0
             return valid;
 480  
     }
 481  
     
 482  
     /**
 483  
      * Finds the names of the unique qualification attributes which this role should be checking against
 484  
      * 
 485  
      * @param memberships the memberships (we take the qualification from the first)
 486  
      * @param attributeDefinitions information about the attributeDefinitions
 487  
      * @return a Set of unique attribute ids (with their indices, for error reporting)
 488  
      */
 489  
     protected Set<String> figureOutUniqueQualificationSetForDelegation(List<RoleDocumentDelegationMember> memberships, AttributeDefinitionMap attributeDefinitions) {
 490  0
             Set<String> uniqueAttributeIds = new HashSet<String>();
 491  
             
 492  0
             if (memberships != null && memberships.size() > 1) { // if there aren't two or more members, doing this whole check is kinda silly
 493  0
                     RoleDocumentDelegationMember membership = memberships.get(0);
 494  
                     
 495  0
                     for (RoleDocumentDelegationMemberQualifier qualifier : membership.getQualifiers()) {
 496  0
                         if (qualifier != null && qualifier.getKimAttribute() != null && !StringUtils.isBlank(qualifier.getKimAttribute().getAttributeName())) {
 497  0
                                 final AttributeDefinition relatedDefinition = attributeDefinitions.getByAttributeName(qualifier.getKimAttribute().getAttributeName());
 498  
                                 
 499  0
                                 if (relatedDefinition.getUnique() != null && relatedDefinition.getUnique().booleanValue()) {
 500  0
                                         uniqueAttributeIds.add(qualifier.getKimAttrDefnId()); // it's unique - add it to the Set
 501  
                                 }
 502  0
                         }
 503  
                     }
 504  
             }
 505  
             
 506  0
             return uniqueAttributeIds;
 507  
     }
 508  
     
 509  
     /**
 510  
      * Checks all the qualifiers for the given membership, so that all qualifiers which should be unique are guaranteed to be unique
 511  
      * 
 512  
      * @param membership the membership to check
 513  
      * @param attributeDefinitions the Map of attribute definitions used by the role
 514  
      * @param memberIndex the index of the person's membership in the role (for error reporting purposes)
 515  
      * @param validationErrors AttributeSet of errors to report
 516  
      * @return true if all unique values are indeed unique, false otherwise
 517  
      */
 518  
     protected boolean validateUniquePersonRoleQualifiersUniqueForRoleDelegation(RoleDocumentDelegationMember delegationMembershipToCheck, int membershipToCheckIndex, List<RoleDocumentDelegationMember> delegationMemberships, Set<String> uniqueQualifierIds, AttributeSet validationErrors) {
 519  0
             boolean foundError = false;
 520  0
             int count = 0;
 521  
             
 522  0
             for (RoleDocumentDelegationMember delegationMembership : delegationMemberships) {
 523  0
                     if (membershipToCheckIndex != count) {
 524  0
                             if (sameDelegationMembership(delegationMembershipToCheck, delegationMembership)) {
 525  0
                                     if (sameUniqueDelegationMembershipQualifications(delegationMembershipToCheck, delegationMembership, uniqueQualifierIds)) {
 526  0
                                             foundError = true;
 527  
                                             // add error to each qualifier which is supposed to be unique
 528  0
                                             int qualifierCount = 0;
 529  
                                             
 530  0
                                             for (RoleDocumentDelegationMemberQualifier qualifier : delegationMembership.getQualifiers()) {
 531  0
                                                     if (qualifier != null && uniqueQualifierIds.contains(qualifier.getKimAttrDefnId())) {
 532  0
                                                             validationErrors.put("document.delegationMembers["+membershipToCheckIndex+"].qualifiers["+qualifierCount+"].attrVal", RiceKeyConstants.ERROR_DOCUMENT_IDENTITY_MANAGEMENT_PERSON_QUALIFIER_VALUE_NOT_UNIQUE+":"+qualifier.getKimAttribute().getAttributeName()+";"+qualifier.getAttrVal());
 533  
                                                     }
 534  0
                                                     qualifierCount += 1;
 535  
                                             }
 536  
                                     }
 537  
                             }
 538  
                     }
 539  0
                     count += 1;
 540  
             }
 541  
             
 542  0
             return foundError;
 543  
     }
 544  
     
 545  
     /**
 546  
      * Determines if two memberships represent the same member being added: that is, the two memberships have the same type code and id
 547  
      * 
 548  
      * @param membershipA the first membership to check
 549  
      * @param membershipB the second membership to check
 550  
      * @return true if the two memberships represent the same member; false if they do not, or if it could not be profitably determined if the members were the same
 551  
      */
 552  
     protected boolean sameDelegationMembership(RoleDocumentDelegationMember membershipA, RoleDocumentDelegationMember membershipB) {
 553  0
             if (!StringUtils.isBlank(membershipA.getMemberTypeCode()) && !StringUtils.isBlank(membershipB.getMemberTypeCode()) && !StringUtils.isBlank(membershipA.getMemberId()) && !StringUtils.isBlank(membershipB.getMemberId())) {
 554  0
                     return membershipA.getMemberTypeCode().equals(membershipB.getMemberTypeCode()) && membershipA.getMemberId().equals(membershipB.getMemberId());
 555  
             }
 556  0
             return false;
 557  
     }
 558  
     
 559  
     /**
 560  
      * Given two memberships which represent the same member, do they share qualifications?
 561  
      * 
 562  
      * @param membershipA the first membership to check
 563  
      * @param membershipB the second membership to check
 564  
      * @param uniqueAttributeIds the Set of attribute definition ids which should be unique
 565  
      * @return
 566  
      */
 567  
     protected boolean sameUniqueDelegationMembershipQualifications(RoleDocumentDelegationMember membershipA, RoleDocumentDelegationMember membershipB, Set<String> uniqueAttributeIds) {
 568  0
             boolean equalSoFar = true;
 569  0
             for (String kimAttributeDefinitionId : uniqueAttributeIds) {
 570  0
                     final RoleDocumentDelegationMemberQualifier qualifierA = membershipA.getQualifier(kimAttributeDefinitionId);
 571  0
                     final RoleDocumentDelegationMemberQualifier qualifierB = membershipB.getQualifier(kimAttributeDefinitionId);
 572  
                     
 573  0
                     if (qualifierA != null && qualifierB != null) {
 574  0
                             equalSoFar &= (qualifierA.getAttrVal() == null && qualifierB.getAttrVal() == null) || (qualifierA.getAttrVal() == null || qualifierA.getAttrVal().equals(qualifierB.getAttrVal()));
 575  
                     }
 576  0
             }
 577  0
             return equalSoFar;
 578  
     }
 579  
     
 580  
         protected boolean validateActiveDate(String errorPath, Timestamp activeFromDate, Timestamp activeToDate) {
 581  
                 // TODO : do not have detail bus rule yet, so just check this for now.
 582  0
                 boolean valid = true;
 583  0
                 if (activeFromDate != null && activeToDate !=null && activeToDate.before(activeFromDate)) {
 584  0
                 MessageMap errorMap = GlobalVariables.getMessageMap();
 585  0
             errorMap.putError(errorPath, RiceKeyConstants.ERROR_ACTIVE_TO_DATE_BEFORE_FROM_DATE);
 586  0
             valid = false;
 587  
                         
 588  
                 }
 589  0
                 return valid;
 590  
         }
 591  
         
 592  
         /**
 593  
          *
 594  
          * This method checks to see if adding a role to role membership
 595  
          * creates a circular reference.
 596  
          * 
 597  
          * @param addMemberEvent
 598  
          * @return true  - ok to assign, no circular references
 599  
          *         false - do not make assignment, will create circular reference.
 600  
          */
 601  
         protected boolean checkForCircularRoleMembership(AddMemberEvent addMemberEvent)
 602  
         {
 603  0
                 KimDocumentRoleMember newMember = addMemberEvent.getMember();
 604  0
                 if (newMember == null || StringUtils.isBlank(newMember.getMemberId())){
 605  0
                         MessageMap errorMap = GlobalVariables.getMessageMap();
 606  0
                         errorMap.putError("member.memberId", RiceKeyConstants.ERROR_INVALID_ROLE, new String[] {""});
 607  0
                         return false;
 608  
                 } 
 609  0
                 Set<String> roleMemberIds = null;
 610  
                 // if the role member is a role, check to make sure we won't be creating a circular reference.
 611  
                 // Verify that the new role is not already related to the role either directly or indirectly
 612  0
                 if (newMember.isRole()){
 613  
                         // get all nested role member ids that are of type role
 614  0
                         RoleService roleService = KIMServiceLocator.getRoleService();
 615  0
                         roleMemberIds = ((RoleServiceBase) roleService).getRoleTypeRoleMemberIds(newMember.getMemberId());
 616  
 
 617  
                         // check to see if the document role is not a member of the new member role
 618  0
                         IdentityManagementRoleDocument document = (IdentityManagementRoleDocument)addMemberEvent.getDocument();
 619  0
                         if (roleMemberIds.contains(document.getRoleId())){
 620  0
                                 MessageMap errorMap = GlobalVariables.getMessageMap();
 621  0
                                 errorMap.putError("member.memberId", RiceKeyConstants.ERROR_ASSIGN_ROLE_MEMBER_CIRCULAR, new String[] {newMember.getMemberId()});                
 622  0
                                 return false;
 623  
                         }
 624  
                 }
 625  0
                 return true;
 626  
         }
 627  
         
 628  
         /**
 629  
          * @return the addResponsibilityRule
 630  
          */
 631  
         public AddResponsibilityRule getAddResponsibilityRule() {
 632  0
                 if(addResponsibilityRule == null){
 633  
                         try {
 634  0
                                 addResponsibilityRule = addResponsibilityRuleClass.newInstance();
 635  0
                         } catch ( Exception ex ) {
 636  0
                                 throw new RuntimeException( "Unable to create AddResponsibilityRule instance using class: " + addResponsibilityRuleClass, ex );
 637  0
                         }
 638  
                 }
 639  0
                 return addResponsibilityRule;
 640  
         }
 641  
 
 642  
         /**
 643  
          * @return the addPermissionRule
 644  
          */
 645  
         public AddPermissionRule getAddPermissionRule() {
 646  0
                 if(addPermissionRule == null){
 647  
                         try {
 648  0
                                 addPermissionRule = addPermissionRuleClass.newInstance();
 649  0
                         } catch ( Exception ex ) {
 650  0
                                 throw new RuntimeException( "Unable to create AddPermissionRule instance using class: " + addPermissionRuleClass, ex );
 651  0
                         }
 652  
                 }
 653  0
                 return addPermissionRule;
 654  
         }
 655  
         
 656  
         /**
 657  
          * @return the addMemberRule
 658  
          */
 659  
         public AddMemberRule getAddMemberRule() {
 660  0
                 if(addMemberRule == null){
 661  
                         try {
 662  0
                                 addMemberRule = addMemberRuleClass.newInstance();
 663  0
                         } catch ( Exception ex ) {
 664  0
                                 throw new RuntimeException( "Unable to create AddMemberRule instance using class: " + addMemberRuleClass, ex );
 665  0
                         }
 666  
                 }
 667  0
                 return addMemberRule;
 668  
         }
 669  
 
 670  
         /**
 671  
          * @return the addDelegationRule
 672  
          */
 673  
         public AddDelegationRule getAddDelegationRule() {
 674  0
                 if(addDelegationRule == null){
 675  
                         try {
 676  0
                                 addDelegationRule = addDelegationRuleClass.newInstance();
 677  0
                         } catch ( Exception ex ) {
 678  0
                                 throw new RuntimeException( "Unable to create AddDelegationRule instance using class: " + addDelegationRuleClass, ex );
 679  0
                         }
 680  
                 }
 681  0
                 return addDelegationRule;
 682  
         }
 683  
 
 684  
         /**
 685  
          * @return the addDelegationMemberRule
 686  
          */
 687  
         public AddDelegationMemberRule getAddDelegationMemberRule() {
 688  0
                 if(addDelegationMemberRule == null){
 689  
                         try {
 690  0
                                 addDelegationMemberRule = addDelegationMemberRuleClass.newInstance();
 691  0
                         } catch ( Exception ex ) {
 692  0
                                 throw new RuntimeException( "Unable to create AddDelegationMemberRule instance using class: " + addDelegationMemberRuleClass, ex );
 693  0
                         }
 694  
                 }
 695  0
                 return addDelegationMemberRule;
 696  
         }
 697  
         
 698  
     public boolean processAddPermission(AddPermissionEvent addPermissionEvent) {
 699  0
         return getAddPermissionRule().processAddPermission(addPermissionEvent);    
 700  
     }
 701  
 
 702  
     public boolean hasPermissionToGrantPermission(KimPermissionInfo kimPermissionInfo , IdentityManagementRoleDocument document){
 703  0
         return getAddPermissionRule().hasPermissionToGrantPermission(kimPermissionInfo, document);    
 704  
     }
 705  
 
 706  
     public boolean processAddResponsibility(AddResponsibilityEvent addResponsibilityEvent) {
 707  0
         return getAddResponsibilityRule().processAddResponsibility(addResponsibilityEvent);    
 708  
     }
 709  
 
 710  
     public boolean hasPermissionToGrantResponsibility(KimResponsibilityInfo kimResponsibilityInfo, IdentityManagementRoleDocument document) {
 711  0
         return getAddResponsibilityRule().hasPermissionToGrantResponsibility(kimResponsibilityInfo, document);    
 712  
     }
 713  
     
 714  
     public boolean processAddMember(AddMemberEvent addMemberEvent) {
 715  0
         boolean success = new KimDocumentMemberRule().processAddMember(addMemberEvent);
 716  0
         success &= validateActiveDate("member.activeFromDate", addMemberEvent.getMember().getActiveFromDate(), addMemberEvent.getMember().getActiveToDate());
 717  0
         success &= checkForCircularRoleMembership(addMemberEvent);
 718  0
         return success;
 719  
     }
 720  
 
 721  
     public boolean processAddDelegation(AddDelegationEvent addDelegationEvent) {
 722  0
         return getAddDelegationRule().processAddDelegation(addDelegationEvent);    
 723  
     }
 724  
 
 725  
     public boolean processAddDelegationMember(AddDelegationMemberEvent addDelegationMemberEvent) {
 726  0
         boolean success = new RoleDocumentDelegationMemberRule().processAddDelegationMember(addDelegationMemberEvent);
 727  0
         RoleDocumentDelegationMember roleDocumentDelegationMember = addDelegationMemberEvent.getDelegationMember();
 728  0
         success &= validateActiveDate("delegationMember.activeFromDate", roleDocumentDelegationMember.getActiveFromDate(), roleDocumentDelegationMember.getActiveToDate());
 729  0
         return success;
 730  
     }
 731  
 
 732  
         public ResponsibilityService getResponsibilityService() {
 733  0
                 if(responsibilityService == null){
 734  0
                         responsibilityService = KIMServiceLocator.getResponsibilityService();
 735  
                 }
 736  0
                 return responsibilityService;
 737  
         }
 738  
 
 739  
 
 740  
         /**
 741  
          * @return the businessObjectService
 742  
          */
 743  
         public BusinessObjectService getBusinessObjectService() {
 744  0
                 if(businessObjectService == null){
 745  0
                         businessObjectService = KNSServiceLocator.getBusinessObjectService();
 746  
                 }
 747  0
                 return businessObjectService;
 748  
         }
 749  
 }