001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kim.impl.role; 017 018import org.apache.commons.collections.CollectionUtils; 019import org.apache.commons.lang.StringUtils; 020import org.apache.commons.lang.exception.ExceptionUtils; 021import org.apache.log4j.Logger; 022import org.joda.time.DateTime; 023import org.kuali.rice.core.api.cache.CacheKeyUtils; 024import org.kuali.rice.core.api.criteria.CriteriaLookupService; 025import org.kuali.rice.core.api.criteria.GenericQueryResults; 026import org.kuali.rice.core.api.criteria.LookupCustomizer; 027import org.kuali.rice.core.api.criteria.QueryByCriteria; 028import org.kuali.rice.core.api.delegation.DelegationType; 029import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 030import org.kuali.rice.core.api.exception.RiceIllegalStateException; 031import org.kuali.rice.core.api.membership.MemberType; 032import org.kuali.rice.core.api.mo.ModelObjectUtils; 033import org.kuali.rice.kim.api.KimConstants; 034import org.kuali.rice.kim.api.common.delegate.DelegateMember; 035import org.kuali.rice.kim.api.common.delegate.DelegateType; 036import org.kuali.rice.kim.api.identity.principal.Principal; 037import org.kuali.rice.kim.api.role.DelegateMemberQueryResults; 038import org.kuali.rice.kim.api.role.Role; 039import org.kuali.rice.kim.api.role.RoleMember; 040import org.kuali.rice.kim.api.role.RoleMemberQueryResults; 041import org.kuali.rice.kim.api.role.RoleMembership; 042import org.kuali.rice.kim.api.role.RoleMembershipQueryResults; 043import org.kuali.rice.kim.api.role.RoleQueryResults; 044import org.kuali.rice.kim.api.role.RoleResponsibility; 045import org.kuali.rice.kim.api.role.RoleResponsibilityAction; 046import org.kuali.rice.kim.api.role.RoleService; 047import org.kuali.rice.kim.api.services.KimApiServiceLocator; 048import org.kuali.rice.kim.api.type.KimType; 049import org.kuali.rice.kim.framework.common.delegate.DelegationTypeService; 050import org.kuali.rice.kim.framework.role.RoleTypeService; 051import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator; 052import org.kuali.rice.kim.framework.type.KimTypeService; 053import org.kuali.rice.kim.impl.common.attribute.AttributeTransform; 054import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo; 055import org.kuali.rice.kim.impl.common.delegate.DelegateMemberAttributeDataBo; 056import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo; 057import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo; 058import org.kuali.rice.kim.impl.services.KimImplServiceLocator; 059import org.kuali.rice.krad.service.BusinessObjectService; 060import org.kuali.rice.krad.service.KRADServiceLocator; 061import org.springframework.cache.Cache; 062import org.springframework.cache.CacheManager; 063import org.springframework.cache.support.NoOpCacheManager; 064import org.springframework.util.LinkedMultiValueMap; 065import org.springframework.util.MultiValueMap; 066 067import javax.jws.WebParam; 068import java.sql.Timestamp; 069import java.util.ArrayList; 070import java.util.Collection; 071import java.util.Collections; 072import java.util.Date; 073import java.util.HashMap; 074import java.util.HashSet; 075import java.util.List; 076import java.util.Map; 077import java.util.Set; 078 079import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 080 081public class RoleServiceImpl extends RoleServiceBase implements RoleService { 082 private static final Logger LOG = Logger.getLogger(RoleServiceImpl.class); 083 084 private static final Map<String, RoleDaoAction> memberTypeToRoleDaoActionMap = populateMemberTypeToRoleDaoActionMap(); 085 086 private static Map<String, RoleDaoAction> populateMemberTypeToRoleDaoActionMap() { 087 Map<String, RoleDaoAction> map = new HashMap<String, RoleDaoAction>(); 088 map.put(MemberType.GROUP.getCode(), RoleDaoAction.ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS); 089 map.put(MemberType.PRINCIPAL.getCode(), RoleDaoAction.ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS); 090 map.put(MemberType.ROLE.getCode(), RoleDaoAction.ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS); 091 return Collections.unmodifiableMap(map); 092 } 093 094 private RoleService proxiedRoleService; 095 private CacheManager cacheManager; 096 097 public RoleServiceImpl() { 098 this.cacheManager = new NoOpCacheManager(); 099 } 100 101 @Override 102 public Role createRole(final Role role) throws RiceIllegalArgumentException, RiceIllegalStateException { 103 incomingParamCheck(role, "role"); 104 105 if (StringUtils.isNotBlank(role.getId()) && getRole(role.getId()) != null) { 106 throw new RiceIllegalStateException("the role to create already exists: " + role); 107 } 108 RoleBo bo = RoleBo.from(role); 109 return RoleBo.to(getBusinessObjectService().save(bo)); 110 } 111 112 @Override 113 public Role updateRole(final Role role) throws RiceIllegalArgumentException, RiceIllegalStateException { 114 incomingParamCheck(role, "role"); 115 116 RoleBoLite originalRole = getRoleBoLite(role.getId()); 117 if (StringUtils.isBlank(role.getId()) || originalRole == null) { 118 throw new RiceIllegalStateException("the role does not exist: " + role); 119 } 120 121 RoleBo bo = RoleBo.from(role); 122 123 RoleBo updatedRole = getBusinessObjectService().save(bo); 124 if (originalRole.isActive() 125 && !updatedRole.isActive()) { 126 KimImplServiceLocator.getRoleInternalService().roleInactivated(updatedRole.getId()); 127 } 128 return RoleBo.to(updatedRole); 129 } 130 131 /** 132 * This method tests to see if assigning a roleBo to another roleBo will create a circular reference. 133 * The Role is checked to see if it is a member (direct or nested) of the roleBo to be assigned as a member. 134 * 135 * @param newMemberId 136 * @param roleBo 137 * @return true - assignment is allowed, no circular reference will be created. 138 * false - illegal assignment, it will create a circular membership 139 */ 140 protected boolean checkForCircularRoleMembership(String newMemberId, RoleBo roleBo) { 141 // get all nested roleBo members that are of type roleBo 142 Set<String> newRoleMemberIds = getRoleTypeRoleMemberIds(newMemberId); 143 return !newRoleMemberIds.contains(roleBo.getId()); 144 } 145 146 protected RoleMember findRoleMember(String roleMemberId) { 147 final List<RoleMember> roleMembers = findRoleMembers(QueryByCriteria.Builder.fromPredicates(equal(KimConstants.PrimaryKeyConstants.ID, roleMemberId))).getResults(); 148 if (roleMembers != null && !roleMembers.isEmpty()) { 149 return roleMembers.get(0); 150 } 151 return null; 152 } 153 154 @Override 155 public RoleMemberQueryResults findRoleMembers(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 156 incomingParamCheck(queryByCriteria, "queryByCriteria"); 157 158 //KULRICE-8972 lookup customizer for attribute transform 159 LookupCustomizer.Builder<RoleMemberBo> lc = LookupCustomizer.Builder.create(); 160 lc.setPredicateTransform(AttributeTransform.getInstance()); 161 162 GenericQueryResults<RoleMemberBo> results = getCriteriaLookupService().lookup(RoleMemberBo.class, queryByCriteria, lc.build()); 163 164 RoleMemberQueryResults.Builder builder = RoleMemberQueryResults.Builder.create(); 165 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 166 builder.setTotalRowCount(results.getTotalRowCount()); 167 168 final List<RoleMember.Builder> ims = new ArrayList<RoleMember.Builder>(); 169 for (RoleMemberBo bo : results.getResults()) { 170 ims.add(RoleMember.Builder.create(bo)); 171 } 172 173 builder.setResults(ims); 174 return builder.build(); 175 176 } 177 178 179 180 @Override 181 public Set<String> getRoleTypeRoleMemberIds(String roleId) throws RiceIllegalArgumentException { 182 incomingParamCheck(roleId, "roleId"); 183 184 Set<String> results = new HashSet<String>(); 185 getNestedRoleTypeMemberIds(roleId, results); 186 return Collections.unmodifiableSet(results); 187 } 188 189 @Override 190 public List<String> getMemberParentRoleIds(String memberType, String memberId) throws RiceIllegalStateException { 191 incomingParamCheck(memberType, "memberType"); 192 incomingParamCheck(memberId, "memberId"); 193 194 List<RoleMemberBo> parentRoleMembers = getRoleDao().getRoleMembershipsForMemberId(memberType, memberId, 195 Collections.<String, String>emptyMap()); 196 197 List<String> parentRoleIds = new ArrayList<String>(parentRoleMembers.size()); 198 for (RoleMemberBo parentRoleMember : parentRoleMembers) { 199 parentRoleIds.add(parentRoleMember.getRoleId()); 200 } 201 202 return parentRoleIds; 203 } 204 205 @Override 206 public List<RoleResponsibilityAction> getRoleMemberResponsibilityActions(String roleMemberId) throws RiceIllegalStateException { 207 incomingParamCheck(roleMemberId, "roleMemberId"); 208 209 Map<String, String> criteria = new HashMap<String, String>(1); 210 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId); 211 212 List<RoleResponsibilityActionBo> responsibilityActionBoList = (List<RoleResponsibilityActionBo>) 213 getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria); 214 215 List<RoleResponsibilityAction> roleResponsibilityActionsList = new ArrayList<RoleResponsibilityAction>(); 216 for (RoleResponsibilityActionBo roleResponsibilityActionBo : responsibilityActionBoList) { 217 RoleResponsibilityAction roleResponsibility = RoleResponsibilityActionBo.to(roleResponsibilityActionBo); 218 roleResponsibilityActionsList.add(roleResponsibility); 219 } 220 return roleResponsibilityActionsList; 221 } 222 223 @Override 224 public DelegateMemberQueryResults findDelegateMembers(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 225 incomingParamCheck(queryByCriteria, "queryByCriteria"); 226 227 //KULRICE-8972 lookup customizer for attribute transform 228 LookupCustomizer.Builder<DelegateMemberBo> lc = LookupCustomizer.Builder.create(); 229 lc.setPredicateTransform(AttributeTransform.getInstance()); 230 231 GenericQueryResults<DelegateMemberBo> results = getCriteriaLookupService().lookup(DelegateMemberBo.class, queryByCriteria, lc.build()); 232 233 DelegateMemberQueryResults.Builder builder = DelegateMemberQueryResults.Builder.create(); 234 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 235 builder.setTotalRowCount(results.getTotalRowCount()); 236 237 final List<DelegateMember.Builder> ims = new ArrayList<DelegateMember.Builder>(); 238 for (DelegateMemberBo bo : results.getResults()) { 239 ims.add(DelegateMember.Builder.create(bo)); 240 } 241 242 builder.setResults(ims); 243 return builder.build(); 244 } 245 246 @Override 247 public Role getRole(String roleId) throws RiceIllegalStateException { 248 incomingParamCheck(roleId, "roleId"); 249 return loadRole(roleId); 250 } 251 252 /** 253 * Loads the role with the given id, leveraging the cache where possible and querying the database 254 * if role not already in the cache. If the role is not in the cache, then it will be placed in 255 * the cache once it is loaded. 256 */ 257 protected Role loadRole(String roleId) { 258 Role role = getRoleFromCache(roleId); 259 if (role == null) { 260 RoleBoLite roleBo = getRoleBoLite(roleId); 261 if (roleBo != null) { 262 role = RoleBoLite.to(roleBo); 263 putRoleInCache(role); 264 } 265 } 266 return role; 267 } 268 269 protected Role getRoleFromCache(String id) { 270 Cache cache = cacheManager.getCache(Role.Cache.NAME); 271 Cache.ValueWrapper cachedValue = cache.get("id=" + id); 272 if (cachedValue != null) { 273 return (Role)cachedValue.get(); 274 } 275 return null; 276 } 277 278 protected Role getRoleFromCache(String namespaceCode, String name) { 279 Cache cache = cacheManager.getCache(Role.Cache.NAME); 280 Cache.ValueWrapper cachedValue = cache.get("namespaceCode=" + namespaceCode + "|name=" + name); 281 if (cachedValue != null) { 282 return (Role)cachedValue.get(); 283 } 284 return null; 285 } 286 287 protected void putRoleInCache(Role role) { 288 if (role != null) { 289 Cache cache = cacheManager.getCache(Role.Cache.NAME); 290 String idKey = "id=" + role.getId(); 291 String nameKey = "namespaceCode=" + role.getNamespaceCode() + "|name=" + role.getName(); 292 cache.put(idKey, role); 293 cache.put(nameKey, role); 294 } 295 } 296 297 protected Map<String, RoleBoLite> getRoleBoLiteMap(Collection<String> roleIds) { 298 Map<String, RoleBoLite> result; 299 // check for a non-null result in the cache, return it if found 300 if (roleIds.size() == 1) { 301 String roleId = roleIds.iterator().next(); 302 RoleBoLite bo = getRoleBoLite(roleId); 303 if (bo == null) { 304 return Collections.<String, RoleBoLite>emptyMap(); 305 } 306 result = bo.isActive() ? Collections.singletonMap(roleId, bo) : Collections.<String, RoleBoLite>emptyMap(); 307 } else { 308 result = new HashMap<String, RoleBoLite>(roleIds.size()); 309 for (String roleId : roleIds) { 310 RoleBoLite bo = getRoleBoLite(roleId); 311 if (bo != null && bo.isActive()) { 312 result.put(roleId, bo); 313 } 314 } 315 } 316 return result; 317 } 318 319 @Override 320 public List<Role> getRoles(List<String> roleIds) throws RiceIllegalStateException { 321 if (CollectionUtils.isEmpty(roleIds)) { 322 throw new RiceIllegalArgumentException("roleIds is null or empty"); 323 } 324 return Collections.unmodifiableList(loadRoles(roleIds)); 325 } 326 327 /** 328 * Loads the roles with the given ids, leveraging the cache where possible and querying the database 329 * for role ids not already in the cache. If the role is not in the cache, then it will be placed in 330 * the cache once it is loaded. 331 */ 332 protected List<Role> loadRoles(List<String> roleIds) { 333 List<String> remainingRoleIds = new ArrayList<String>(); 334 Map<String, Role> roleMap = new HashMap<String, Role>(roleIds.size()); 335 for (String roleId : roleIds) { 336 Role role = getRoleFromCache(roleId); 337 if (role != null) { 338 roleMap.put(roleId, role); 339 } else { 340 remainingRoleIds.add(roleId); 341 } 342 } 343 if (!remainingRoleIds.isEmpty()) { 344 Map<String, RoleBoLite> roleBoMap = getRoleBoLiteMap(remainingRoleIds); 345 for (String roleId : roleBoMap.keySet()) { 346 RoleBoLite roleBo = roleBoMap.get(roleId); 347 if (roleBo != null) { 348 Role role = RoleBoLite.to(roleBo); 349 roleMap.put(roleId, role); 350 putRoleInCache(role); 351 } 352 } 353 } 354 List<Role> roles = new ArrayList<Role>(roleMap.values()); 355 return roles; 356 } 357 358 @Override 359 public Role getRoleByNamespaceCodeAndName(String namespaceCode, String roleName) throws RiceIllegalStateException { 360 incomingParamCheck(namespaceCode, "namespaceCode"); 361 incomingParamCheck(roleName, "roleName"); 362 return loadRoleByName(namespaceCode, roleName); 363 } 364 365 /** 366 * Loads the role with the given name, leveraging the cache where possible and querying the database 367 * if role not already in the cache. If the role is not in the cache, then it will be placed in 368 * the cache once it is loaded. 369 */ 370 protected Role loadRoleByName(String namespaceCode, String roleName) { 371 Role role = getRoleFromCache(namespaceCode, roleName); 372 if (role == null) { 373 RoleBoLite roleBo = getRoleBoLiteByName(namespaceCode, roleName); 374 if (roleBo != null) { 375 role = getRoleFromCache(roleBo.getId()); 376 if (role == null) { 377 role = RoleBoLite.to(roleBo); 378 } 379 putRoleInCache(role); 380 } 381 } 382 return role; 383 } 384 385 @Override 386 public String getRoleIdByNamespaceCodeAndName(String namespaceCode, String roleName) throws RiceIllegalStateException { 387 incomingParamCheck(namespaceCode, "namespaceCode"); 388 incomingParamCheck(roleName, "roleName"); 389 390 Role role = getRoleByNamespaceCodeAndName(namespaceCode, roleName); 391 if (role != null) { 392 return role.getId(); 393 } else { 394 return null; 395 } 396 } 397 398 @Override 399 public boolean isRoleActive(String roleId) throws RiceIllegalStateException { 400 incomingParamCheck(roleId, "roleId"); 401 Role role = getRole(roleId); 402 return role != null && role.isActive(); 403 } 404 405 @Override 406 public List<Map<String, String>> getRoleQualifersForPrincipalByRoleIds(String principalId, List<String> roleIds, 407 Map<String, String> qualification) throws RiceIllegalStateException { 408 incomingParamCheck(principalId, "principalId"); 409 incomingParamCheck(roleIds, "roleIds"); 410 411 List<Map<String, String>> results = new ArrayList<Map<String, String>>(); 412 413 List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersUsingExactMatchOnQualification(principalId, null, 414 roleIds, qualification); 415 416 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 417 for (RoleMemberBo roleMemberBo : roleMemberBoList) { 418 // gather up the qualifier sets and the service they go with 419 if (MemberType.PRINCIPAL.equals(roleMemberBo.getType())) { 420 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 421 if (roleTypeService != null) { 422 List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId()); 423 if (las == null) { 424 las = new ArrayList<RoleMembership>(); 425 roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las); 426 } 427 RoleMembership mi = RoleMembership.Builder.create( 428 roleMemberBo.getRoleId(), 429 roleMemberBo.getId(), 430 roleMemberBo.getMemberId(), 431 roleMemberBo.getType(), 432 roleMemberBo.getAttributes()).build(); 433 434 las.add(mi); 435 } else { 436 results.add(roleMemberBo.getAttributes()); 437 } 438 } 439 } 440 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 441 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 442 //it is possible that the the roleTypeService is coming from a remote application 443 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 444 try { 445 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue()); 446 for (RoleMembership rmi : matchingMembers) { 447 results.add(rmi.getQualifier()); 448 } 449 } catch (Exception ex) { 450 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 451 } 452 } 453 return Collections.unmodifiableList(results); 454 } 455 456 @Override 457 public List<Map<String, String>> getRoleQualifersForPrincipalByNamespaceAndRolename(String principalId, 458 String namespaceCode, String roleName, Map<String, String> qualification) 459 throws RiceIllegalStateException { 460 incomingParamCheck(principalId, "principalId"); 461 incomingParamCheck(namespaceCode, "namespaceCode"); 462 incomingParamCheck(roleName, "roleName"); 463 464 String roleId = getRoleIdByNamespaceCodeAndName(namespaceCode, roleName); 465 if (roleId == null) { 466 return Collections.emptyList(); 467 } 468 return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId), 469 qualification); 470 } 471 472 @Override 473 public List<Map<String, String>> getNestedRoleQualifersForPrincipalByNamespaceAndRolename(String principalId, 474 String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 475 incomingParamCheck(principalId, "principalId"); 476 incomingParamCheck(namespaceCode, "namespaceCode"); 477 incomingParamCheck(roleName, "roleName"); 478 479 String roleId = getRoleIdByNamespaceCodeAndName(namespaceCode, roleName); 480 if (roleId == null) { 481 return new ArrayList<Map<String, String>>(0); 482 } 483 return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId), 484 qualification); 485 } 486 487 @Override 488 public List<Map<String, String>> getNestedRoleQualifiersForPrincipalByRoleIds(String principalId, 489 List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 490 incomingParamCheck(principalId, "principalId"); 491 incomingParamCheck(roleIds, "roleIds"); 492 493 494 List<Map<String, String>> results = new ArrayList<Map<String, String>>(); 495 496 Map<String, RoleBoLite> roleBosById = getRoleBoLiteMap(roleIds); 497 498 // get the person's groups 499 List<String> groupIds = getGroupService().getGroupIdsByPrincipalId(principalId); 500 List<RoleMemberBo> roleMemberBos = getStoredRoleMembersUsingExactMatchOnQualification(principalId, groupIds, roleIds, qualification); 501 502 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 503 for (RoleMemberBo roleMemberBo : roleMemberBos) { 504 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 505 // gather up the qualifier sets and the service they go with 506 if (MemberType.PRINCIPAL.equals(roleMemberBo.getType()) 507 || MemberType.GROUP.equals(roleMemberBo.getType())) { 508 if (roleTypeService != null) { 509 List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId()); 510 if (las == null) { 511 las = new ArrayList<RoleMembership>(); 512 roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las); 513 } 514 RoleMembership mi = RoleMembership.Builder.create( 515 roleMemberBo.getRoleId(), 516 roleMemberBo.getId(), 517 roleMemberBo.getMemberId(), 518 roleMemberBo.getType(), 519 roleMemberBo.getAttributes()).build(); 520 521 las.add(mi); 522 } else { 523 results.add(roleMemberBo.getAttributes()); 524 } 525 } else if (MemberType.ROLE.equals(roleMemberBo.getType())) { 526 // find out if the user has the role 527 // need to convert qualification using this role's service 528 Map<String, String> nestedQualification = qualification; 529 if (roleTypeService != null) { 530 RoleBoLite roleBo = roleBosById.get(roleMemberBo.getRoleId()); 531 // pulling from here as the nested roleBo is not necessarily (and likely is not) 532 // in the roleBosById Map created earlier 533 RoleBoLite nestedRole = getRoleBoLite(roleMemberBo.getMemberId()); 534 //it is possible that the the roleTypeService is coming from a remote application 535 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 536 try { 537 nestedQualification = roleTypeService.convertQualificationForMemberRoles(roleBo.getNamespaceCode(), roleBo.getName(), nestedRole.getNamespaceCode(), nestedRole.getName(), qualification); 538 } catch (Exception ex) { 539 LOG.warn("Not able to retrieve RoleTypeService from remote system for roleBo Id: " + roleBo.getId(), ex); 540 } 541 } 542 List<String> nestedRoleId = new ArrayList<String>(1); 543 nestedRoleId.add(roleMemberBo.getMemberId()); 544 // if the user has the given role, add the qualifier the *nested role* has with the 545 // originally queries role 546 if (this.getProxiedRoleService().principalHasRole(principalId, nestedRoleId, nestedQualification, false)) { 547 results.add(roleMemberBo.getAttributes()); 548 } 549 } 550 } 551 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 552 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 553 //it is possible that the the roleTypeService is coming from a remote 554 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 555 try { 556 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, 557 entry.getValue()); 558 for (RoleMembership roleMembership : matchingMembers) { 559 results.add(roleMembership.getQualifier()); 560 } 561 } catch (Exception ex) { 562 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 563 } 564 } 565 return Collections.unmodifiableList(results); 566 } 567 568 @Override 569 public List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 570 incomingParamCheck(roleIds, "roleIds"); 571 572 Set<String> foundRoleTypeMembers = new HashSet<String>(); 573 List<RoleMembership> roleMembers = getRoleMembers(roleIds, qualification, true, foundRoleTypeMembers); 574 575 return Collections.unmodifiableList(roleMembers); 576 } 577 578 @Override 579 public Collection<String> getRoleMemberPrincipalIds(String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 580 incomingParamCheck(namespaceCode, "namespaceCode"); 581 incomingParamCheck(roleName, "roleName"); 582 583 Set<String> principalIds = new HashSet<String>(); 584 Set<String> foundRoleTypeMembers = new HashSet<String>(); 585 List<String> roleIds = Collections.singletonList(getRoleIdByNamespaceCodeAndName(namespaceCode, roleName)); 586 for (RoleMembership roleMembership : getRoleMembers(roleIds, qualification, false, foundRoleTypeMembers)) { 587 if (MemberType.GROUP.equals(roleMembership.getType())) { 588 principalIds.addAll(getGroupService().getMemberPrincipalIds(roleMembership.getMemberId())); 589 } else { 590 principalIds.add(roleMembership.getMemberId()); 591 } 592 } 593 594 return Collections.unmodifiableSet(principalIds); 595 } 596 597 @Override 598 public boolean principalHasRole(String principalId, List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 599 600 if ( LOG.isDebugEnabled() ) { 601 logPrincipalHasRoleCheck(principalId, roleIds, qualification); 602 } 603 604 boolean hasRole = this.getProxiedRoleService().principalHasRole(principalId, roleIds, qualification, true); 605 606 if ( LOG.isDebugEnabled() ) { 607 LOG.debug( "Result: " + hasRole ); 608 } 609 610 return hasRole; 611 } 612 613 @Override 614 public List<String> getPrincipalIdSubListWithRole(List<String> principalIds, 615 String roleNamespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 616 incomingParamCheck(principalIds, "principalIds"); 617 incomingParamCheck(roleNamespaceCode, "roleNamespaceCode"); 618 incomingParamCheck(roleName, "roleName"); 619 620 List<String> subList = new ArrayList<String>(); 621 RoleBoLite role = getRoleBoLiteByName(roleNamespaceCode, roleName); 622 for (String principalId : principalIds) { 623 if (this.getProxiedRoleService().principalHasRole(principalId, Collections.singletonList(role.getId()), qualification)) { 624 subList.add(principalId); 625 } 626 } 627 return Collections.unmodifiableList(subList); 628 } 629 630 @Override 631 public RoleQueryResults findRoles(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 632 incomingParamCheck(queryByCriteria, "queryByCriteria"); 633 634 GenericQueryResults<RoleBoLite> results = getCriteriaLookupService().lookup(RoleBoLite.class, queryByCriteria); 635 636 RoleQueryResults.Builder builder = RoleQueryResults.Builder.create(); 637 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 638 builder.setTotalRowCount(results.getTotalRowCount()); 639 640 final List<Role.Builder> ims = new ArrayList<Role.Builder>(); 641 for (RoleBoLite bo : results.getResults()) { 642 ims.add(Role.Builder.create(bo)); 643 } 644 645 builder.setResults(ims); 646 return builder.build(); 647 } 648 649 @Override 650 public List<RoleMembership> getFirstLevelRoleMembers(List<String> roleIds) throws RiceIllegalStateException { 651 incomingParamCheck(roleIds, "roleIds"); 652 if (roleIds.isEmpty()) { 653 return Collections.emptyList(); 654 } 655 656 List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersForRoleIds(roleIds, null, null); 657 List<RoleMembership> roleMemberships = new ArrayList<RoleMembership>(); 658 for (RoleMemberBo roleMemberBo : roleMemberBoList) { 659 RoleMembership roleMembeship = RoleMembership.Builder.create( 660 roleMemberBo.getRoleId(), 661 roleMemberBo.getId(), 662 roleMemberBo.getMemberId(), 663 roleMemberBo.getType(), 664 roleMemberBo.getAttributes()).build(); 665 roleMemberships.add(roleMembeship); 666 } 667 return Collections.unmodifiableList(roleMemberships); 668 } 669 670 @Override 671 public RoleMembershipQueryResults findRoleMemberships( QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 672 incomingParamCheck(queryByCriteria, "queryByCriteria"); 673 674 //KULRICE-8972 lookup customizer for attribute transform 675 LookupCustomizer.Builder<RoleMemberBo> lc = LookupCustomizer.Builder.create(); 676 lc.setPredicateTransform(AttributeTransform.getInstance()); 677 678 GenericQueryResults<RoleMemberBo> results = getCriteriaLookupService().lookup(RoleMemberBo.class, queryByCriteria, lc.build()); 679 680 RoleMembershipQueryResults.Builder builder = RoleMembershipQueryResults.Builder.create(); 681 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 682 builder.setTotalRowCount(results.getTotalRowCount()); 683 684 final List<RoleMembership.Builder> ims = new ArrayList<RoleMembership.Builder>(); 685 for (RoleMemberBo bo : results.getResults()) { 686 RoleMembership.Builder roleMembership = RoleMembership.Builder.create( 687 bo.getRoleId(), 688 bo.getId(), 689 bo.getMemberId(), 690 bo.getType(), 691 bo.getAttributes()); 692 ims.add(roleMembership); 693 } 694 695 builder.setResults(ims); 696 return builder.build(); 697 } 698 699 @Override 700 public List<DelegateMember> getDelegationMembersByDelegationId(String delegationId) throws RiceIllegalStateException { 701 incomingParamCheck(delegationId, "delegationId"); 702 703 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 704 if (delegateBo == null) {return Collections.emptyList();} 705 706 return getDelegateMembersForDelegation(delegateBo); 707 } 708 709 @Override 710 public DelegateMember getDelegationMemberByDelegationAndMemberId(String delegationId, String memberId) throws RiceIllegalStateException { 711 incomingParamCheck(delegationId, "delegationId"); 712 incomingParamCheck(memberId, "memberId"); 713 714 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 715 DelegateMemberBo delegationMember = getKimDelegationMemberImplByDelegationAndId(delegationId, memberId); 716 717 return getDelegateCompleteInfo(delegateBo, delegationMember); 718 } 719 720 @Override 721 public DelegateMember getDelegationMemberById(String delegationMemberId) throws RiceIllegalStateException { 722 incomingParamCheck(delegationMemberId, "delegationMemberId"); 723 724 DelegateMemberBo delegateMemberBo = getDelegateMemberBo(delegationMemberId); 725 if (delegateMemberBo == null) { 726 return null; 727 } 728 729 DelegateTypeBo delegateBo = getKimDelegationImpl(delegateMemberBo.getDelegationId()); 730 731 return getDelegateCompleteInfo(delegateBo, delegateMemberBo); 732 } 733 734 @Override 735 public List<RoleResponsibility> getRoleResponsibilities(String roleId) throws RiceIllegalStateException { 736 incomingParamCheck(roleId, "roleId"); 737 738 Map<String, String> criteria = new HashMap<String, String>(1); 739 criteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId); 740 List<RoleResponsibilityBo> roleResponsibilityBos = (List<RoleResponsibilityBo>) 741 getBusinessObjectService().findMatching(RoleResponsibilityBo.class, criteria); 742 List<RoleResponsibility> roleResponsibilities = new ArrayList<RoleResponsibility>(); 743 744 for (RoleResponsibilityBo roleResponsibilityImpl : roleResponsibilityBos) { 745 roleResponsibilities.add(RoleResponsibilityBo.to(roleResponsibilityImpl)); 746 } 747 return Collections.unmodifiableList(roleResponsibilities); 748 } 749 750 @Override 751 public DelegateType getDelegateTypeByRoleIdAndDelegateTypeCode(String roleId, DelegationType delegationType) throws RiceIllegalStateException { 752 incomingParamCheck(roleId, "roleId"); 753 incomingParamCheck(delegationType, "delegationType"); 754 755 DelegateTypeBo delegateBo = getDelegationOfType(roleId, delegationType); 756 return DelegateTypeBo.to(delegateBo); 757 } 758 759 @Override 760 public DelegateType getDelegateTypeByDelegationId(String delegationId) throws RiceIllegalStateException { 761 incomingParamCheck(delegationId, "delegationId"); 762 763 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 764 return DelegateTypeBo.to(delegateBo); 765 } 766 767 protected List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification, boolean followDelegations, Set<String> foundRoleTypeMembers) { 768 List<RoleMembership> results = new ArrayList<RoleMembership>(); 769 Set<String> allRoleIds = new HashSet<String>(); 770 for (String roleId : roleIds) { 771 if (this.getProxiedRoleService().isRoleActive(roleId)) { 772 allRoleIds.add(roleId); 773 } 774 } 775 // short-circuit if no roles match 776 if (allRoleIds.isEmpty()) { 777 return Collections.emptyList(); 778 } 779 Set<String> matchingRoleIds = new HashSet<String>(allRoleIds.size()); 780 // for efficiency, retrieve all roles and store in a map 781 Map<String, RoleBoLite> roles = getRoleBoLiteMap(allRoleIds); 782 783 List<String> copyRoleIds = new ArrayList<String>(allRoleIds); 784 List<RoleMemberBo> rms = new ArrayList<RoleMemberBo>(); 785 786 for (String roleId : allRoleIds) { 787 RoleTypeService roleTypeService = getRoleTypeService(roleId); 788 if (roleTypeService != null) { 789 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 790 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 791 copyRoleIds.remove(roleId); 792 rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), null, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 793 } 794 } 795 } 796 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 797 rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIds, null, null)); 798 } 799 800 // build a map of role ID to membership information 801 // this will be used for later qualification checks 802 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 803 for (RoleMemberBo roleMemberBo : rms) { 804 RoleMembership mi = RoleMembership.Builder.create( 805 roleMemberBo.getRoleId(), 806 roleMemberBo.getId(), 807 roleMemberBo.getMemberId(), 808 roleMemberBo.getType(), 809 roleMemberBo.getAttributes()).build(); 810 811 // if the qualification check does not need to be made, just add the result 812 if ((qualification == null || qualification.isEmpty())) { 813 if (MemberType.ROLE.equals(roleMemberBo.getType())) { 814 // if a role member type, do a non-recursive role member check 815 // to obtain the group and principal members of that role 816 // given the qualification 817 Map<String, String> nestedRoleQualification = qualification; 818 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 819 if (roleTypeService != null) { 820 // get the member role object 821 RoleBoLite memberRole = getRoleBoLite(mi.getMemberId()); 822 nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles( 823 roles.get(roleMemberBo.getRoleId()).getNamespaceCode(), 824 roles.get(roleMemberBo.getRoleId()).getName(), 825 memberRole.getNamespaceCode(), 826 memberRole.getName(), 827 qualification); 828 } 829 if (this.getProxiedRoleService().isRoleActive(roleMemberBo.getRoleId())) { 830 Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, mi, foundRoleTypeMembers); 831 if (!nestedRoleMembers.isEmpty()) { 832 results.addAll(nestedRoleMembers); 833 matchingRoleIds.add(roleMemberBo.getRoleId()); 834 } 835 } 836 } else { // not a role member type 837 results.add(mi); 838 matchingRoleIds.add(roleMemberBo.getRoleId()); 839 } 840 matchingRoleIds.add(roleMemberBo.getRoleId()); 841 } else { 842 List<RoleMembership> lrmi = roleIdToMembershipMap.get(mi.getRoleId()); 843 if (lrmi == null) { 844 lrmi = new ArrayList<RoleMembership>(); 845 roleIdToMembershipMap.put(mi.getRoleId(), lrmi); 846 } 847 lrmi.add(mi); 848 } 849 } 850 // if there is anything in the role to membership map, we need to check the role type services 851 // for those entries 852 if (!roleIdToMembershipMap.isEmpty()) { 853 // for each role, send in all the qualifiers for that role to the type service 854 // for evaluation, the service will return those which match 855 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 856 //it is possible that the the roleTypeService is coming from a remote application 857 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 858 try { 859 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 860 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, 861 entry.getValue()); 862 // loop over the matching entries, adding them to the results 863 for (RoleMembership roleMemberships : matchingMembers) { 864 if (MemberType.ROLE.equals(roleMemberships.getType())) { 865 // if a role member type, do a non-recursive role member check 866 // to obtain the group and principal members of that role 867 // given the qualification 868 // get the member role object 869 RoleBoLite memberRole = getRoleBoLite(roleMemberships.getMemberId()); 870 if (memberRole.isActive()) { 871 Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles( 872 roles.get(roleMemberships.getRoleId()).getNamespaceCode(), 873 roles.get(roleMemberships.getRoleId()).getName(), 874 memberRole.getNamespaceCode(), 875 memberRole.getName(), 876 qualification); 877 Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, roleMemberships, foundRoleTypeMembers); 878 if (!nestedRoleMembers.isEmpty()) { 879 results.addAll(nestedRoleMembers); 880 matchingRoleIds.add(roleMemberships.getRoleId()); 881 } 882 } 883 } else { // not a role member 884 results.add(roleMemberships); 885 matchingRoleIds.add(roleMemberships.getRoleId()); 886 } 887 } 888 } catch (Exception ex) { 889 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 890 } 891 } 892 } 893 894 // handle derived roles 895 for ( String roleId : allRoleIds ) { 896 RoleTypeService roleTypeService = getRoleTypeService( roleId ); 897 RoleBoLite role = roles.get( roleId ); 898 // check if a derived role 899 try { 900 if ( isDerivedRoleType(roleTypeService) ) { 901 // for each derived role, get the list of principals and groups which are in that role given the qualification (per the role type service) 902 List<RoleMembership> roleMembers = roleTypeService.getRoleMembersFromDerivedRole(role.getNamespaceCode(), role.getName(), qualification); 903 if ( !roleMembers.isEmpty() ) { 904 matchingRoleIds.add( roleId ); 905 } 906 for ( RoleMembership rm : roleMembers ) { 907 RoleMembership.Builder builder = RoleMembership.Builder.create(rm); 908 builder.setRoleId(roleId); 909 builder.setId("*"); 910 results.add(builder.build()); 911 } 912 } 913 } catch (Exception ex) { 914 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex); 915 } 916 } 917 918 if ( followDelegations && !matchingRoleIds.isEmpty() ) { 919 // we have a list of RoleMembershipInfo objects 920 // need to get delegations for distinct list of roles in that list 921 Map<String, DelegateTypeBo> delegationIdToDelegationMap = getStoredDelegationImplMapFromRoleIds(matchingRoleIds); 922 if (!delegationIdToDelegationMap.isEmpty()) { 923 List<RoleMembership.Builder> membershipsWithDelegations = 924 applyDelegationsToRoleMembers(results, delegationIdToDelegationMap.values(), qualification); 925 resolveDelegationMemberRoles(membershipsWithDelegations, qualification, foundRoleTypeMembers); 926 results = ModelObjectUtils.buildImmutableCopy(membershipsWithDelegations); 927 } 928 } 929 930 // sort the results if a single role type service can be identified for 931 // all the matching role members 932 if ( results.size() > 1 ) { 933 // if a single role: easy case 934 if ( matchingRoleIds.size() == 1 ) { 935 String roleId = matchingRoleIds.iterator().next(); 936 RoleTypeService roleTypeService = getRoleTypeService( roleId ); 937 //it is possible that the the roleTypeService is coming from a remote application 938 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 939 try { 940 if ( roleTypeService != null ) { 941 results = roleTypeService.sortRoleMembers( results ); 942 } 943 } catch (Exception ex) { 944 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex); 945 } 946 } else if ( matchingRoleIds.size() > 1 ) { 947 // if more than one, check if there is only a single role type service 948 String prevServiceName = null; 949 boolean multipleServices = false; 950 for ( String roleId : matchingRoleIds ) { 951 String serviceName = KimApiServiceLocator.getKimTypeInfoService().getKimType(getRole(roleId).getKimTypeId()).getServiceName(); 952 if ( prevServiceName != null && !StringUtils.equals( prevServiceName, serviceName ) ) { 953 multipleServices = true; 954 break; 955 } 956 prevServiceName = serviceName; 957 } 958 if ( !multipleServices ) { 959 String roleId = matchingRoleIds.iterator().next(); 960 //it is possible that the the roleTypeService is coming from a remote application 961 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 962 try { 963 RoleTypeService kimRoleTypeService = getRoleTypeService( roleId ); 964 if ( kimRoleTypeService != null ) { 965 results = kimRoleTypeService.sortRoleMembers( results ); 966 } 967 } catch (Exception ex) { 968 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex); 969 } 970 } else { 971 LOG.warn( "Did not sort role members - multiple role type services found. Role Ids: " + matchingRoleIds ); 972 } 973 } 974 } 975 return Collections.unmodifiableList(results); 976 } 977 978 /** 979 * Checks each of the result records to determine if there are potentially applicable delegation members for that 980 * role membership. If there are, applicable delegations and members will be linked to the RoleMemberships in the 981 * given list. An updated list will be returned from this method which includes the appropriate linked delegations. 982 */ 983 protected List<RoleMembership.Builder> applyDelegationsToRoleMembers(List<RoleMembership> roleMemberships, 984 Collection<DelegateTypeBo> delegations, Map<String, String> qualification) { 985 MultiValueMap<String, String> roleIdToRoleMembershipIds = new LinkedMultiValueMap<String, String>(); 986 Map<String, RoleMembership.Builder> roleMembershipIdToBuilder = new HashMap<String, RoleMembership.Builder>(); 987 List<RoleMembership.Builder> roleMembershipBuilders = new ArrayList<RoleMembership.Builder>(); 988 // to make our algorithm less painful, let's do some indexing and load the given list of RoleMemberships into 989 // builders 990 for (RoleMembership roleMembership : roleMemberships) { 991 roleIdToRoleMembershipIds.add(roleMembership.getRoleId(), roleMembership.getId()); 992 RoleMembership.Builder builder = RoleMembership.Builder.create(roleMembership); 993 roleMembershipBuilders.add(builder); 994 roleMembershipIdToBuilder.put(roleMembership.getId(), builder); 995 } 996 for (DelegateTypeBo delegation : delegations) { 997 // determine the candidate role memberships where this delegation can be mapped 998 List<String> candidateRoleMembershipIds = roleIdToRoleMembershipIds.get(delegation.getRoleId()); 999 if (CollectionUtils.isNotEmpty(candidateRoleMembershipIds)) { 1000 DelegationTypeService delegationTypeService = getDelegationTypeService(delegation.getDelegationId()); 1001 for (DelegateMemberBo delegationMember : delegation.getMembers()) { 1002 // Make sure that the delegation member is active 1003 if (delegationMember.isActive(DateTime.now()) && (delegationTypeService == null || 1004 delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegationMember.getQualifier()))) { 1005 DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegationMember); 1006 // if the member has no role member id, check qualifications and apply to all matching role memberships on the role 1007 if (StringUtils.isBlank(delegationMember.getRoleMemberId())) { 1008 RoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId()); 1009 for (String roleMembershipId : candidateRoleMembershipIds) { 1010 RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(roleMembershipId); 1011 if (roleTypeService == null || roleTypeService.doesRoleQualifierMatchQualification(roleMembershipBuilder.getQualifier(), delegationMember.getQualifier())) { 1012 linkDelegateToRoleMembership(delegation, delegateMemberBuilder, roleMembershipBuilder); 1013 } 1014 } 1015 } else if (candidateRoleMembershipIds.contains(delegationMember.getRoleMemberId())) { 1016 RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(delegationMember.getRoleMemberId()); 1017 linkDelegateToRoleMembership(delegation, delegateMemberBuilder, roleMembershipBuilder); 1018 } 1019 } 1020 } 1021 } 1022 } 1023 return roleMembershipBuilders; 1024 } 1025 1026 protected void linkDelegateToRoleMembership(DelegateTypeBo delegation, DelegateMember.Builder delegateMemberBuilder, 1027 RoleMembership.Builder roleMembershipBuilder) { 1028 DelegateType.Builder delegateBuilder = null; 1029 for(DelegateType.Builder existingDelegateBuilder : roleMembershipBuilder.getDelegates()) { 1030 if (existingDelegateBuilder.getDelegationId().equals(delegation.getDelegationId())) { 1031 delegateBuilder = existingDelegateBuilder; 1032 } 1033 } 1034 if (delegateBuilder == null) { 1035 delegateBuilder = DelegateType.Builder.create(delegation); 1036 delegateBuilder.setMembers(new ArrayList<DelegateMember.Builder>()); 1037 roleMembershipBuilder.getDelegates().add(delegateBuilder); 1038 } 1039 delegateBuilder.getMembers().add(delegateMemberBuilder); 1040 1041 } 1042 1043 /** 1044 * Once the delegations for a RoleMembershipInfo object have been determined, 1045 * any "role" member types need to be resolved into groups and principals so that 1046 * further KIM requests are not needed. 1047 */ 1048 protected void resolveDelegationMemberRoles(List<RoleMembership.Builder> membershipBuilders, 1049 Map<String, String> qualification, Set<String> foundRoleTypeMembers) { 1050 // check delegations assigned to this role 1051 for (RoleMembership.Builder roleMembership : membershipBuilders) { 1052 // the applicable delegation IDs will already be set in the RoleMembership.Builder 1053 // this code examines those delegations and obtains the member groups and principals 1054 for (DelegateType.Builder delegation : roleMembership.getDelegates()) { 1055 List<DelegateMember.Builder> newMembers = new ArrayList<DelegateMember.Builder>(); 1056 for (DelegateMember.Builder member : delegation.getMembers()) { 1057 if (MemberType.ROLE.equals(member.getType())) { 1058 // loop over delegation roles and extract the role IDs where the qualifications match 1059 Collection<RoleMembership> delegateMembers = getRoleMembers(Collections.singletonList( 1060 member.getMemberId()), qualification, false, foundRoleTypeMembers); 1061 // loop over the role members and create the needed DelegationMember builders 1062 for (RoleMembership rmi : delegateMembers) { 1063 DelegateMember.Builder delegateMember = DelegateMember.Builder.create(member); 1064 delegateMember.setMemberId(rmi.getMemberId()); 1065 delegateMember.setType(rmi.getType()); 1066 newMembers.add(delegateMember); 1067 } 1068 } else { 1069 newMembers.add(member); 1070 } 1071 } 1072 delegation.setMembers(newMembers); 1073 } 1074 } 1075 } 1076 1077 @Override 1078 public boolean principalHasRole(String principalId, List<String> roleIds, Map<String, String> qualification, boolean checkDelegations) { 1079 1080 incomingParamCheck(principalId, "principalId"); 1081 incomingParamCheck(roleIds, "roleIds"); 1082 return principalHasRole(new Context(principalId), principalId, roleIds, qualification, checkDelegations); 1083 } 1084 1085 /** 1086 * An internal helper class which is used to keep context for an invocation of principalHasRole. 1087 */ 1088 private final class Context { 1089 1090 private String principalId; 1091 private List<String> principalGroupIds; 1092 private Map<String, RoleTypeService> roleTypeServiceCache; 1093 private Map<String, Boolean> isDerivedRoleTypeCache; 1094 1095 Context(String principalId) { 1096 this.principalId = principalId; 1097 this.roleTypeServiceCache = new HashMap<String, RoleTypeService>(); 1098 this.isDerivedRoleTypeCache = new HashMap<String, Boolean>(); 1099 } 1100 1101 String getPrincipalId() { 1102 return principalId; 1103 } 1104 1105 List<String> getPrincipalGroupIds() { 1106 if (principalGroupIds == null) { 1107 principalGroupIds = getGroupService().getGroupIdsByPrincipalId(principalId); 1108 } 1109 return principalGroupIds; 1110 } 1111 1112 RoleTypeService getRoleTypeService(String kimTypeId) { 1113 if (roleTypeServiceCache.containsKey(kimTypeId)) { 1114 return roleTypeServiceCache.get(kimTypeId); 1115 } 1116 RoleTypeService roleTypeService = null; 1117 if (kimTypeId != null) { 1118 KimType roleType = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId); 1119 if (roleType != null && StringUtils.isNotBlank(roleType.getServiceName())) { 1120 roleTypeService = getRoleTypeServiceByName(roleType.getServiceName()); 1121 } 1122 } 1123 if (roleTypeService == null) { 1124 roleTypeService = KimImplServiceLocator.getDefaultRoleTypeService(); 1125 } 1126 roleTypeServiceCache.put(kimTypeId, roleTypeService); 1127 return roleTypeService; 1128 } 1129 1130 boolean isDerivedRoleType(String kimTypeId) { 1131 Boolean isDerived = isDerivedRoleTypeCache.get(kimTypeId); 1132 if (isDerived == null) { 1133 isDerived = Boolean.valueOf(RoleServiceImpl.this.isDerivedRoleType(getRoleTypeService(kimTypeId))); 1134 isDerivedRoleTypeCache.put(kimTypeId, isDerived); 1135 } 1136 return isDerived.booleanValue(); 1137 } 1138 1139 } 1140 1141 1142 protected boolean principalHasRole(Context context, String principalId, List<String> roleIds, Map<String, String> qualification, boolean checkDelegations) { 1143 1144 /** 1145 * This method uses a multi-phase approach to determining if the given principal of any of the roles given based 1146 * on the qualification map that is pased. 1147 * 1148 * Phase 1: Check the cache to find if it's already been determined that the principal is a member of any of 1149 * the roles with the given ids. 1150 * Phase 2: Perform exact database-level matching. This can be done for all roles if the given qualification map 1151 * is null or empty since that means qualification matching does not need to be performed. It can also 1152 * be done for roles who's RoleTypeService defines qualifiers for exact match. 1153 * Phase 3: Use RoleTypeService matching for roles which have not already been checked. Will need to determine 1154 * which role memberships match the given principal then delegate to the appropriate RoleTypeService 1155 * to execute matching logic. 1156 * Phase 4: Check nested roles. 1157 * Phase 5: For any cases where derived roles are used, determine if the principal is a member of those 1158 * derived roles. 1159 * Phase 6: If checkDelegations is true, check if any delegations match 1160 */ 1161 try { 1162 // Phase 1: first check if any of the role membership is cached, only proceed with checking the role ids that 1163 // aren't already cached 1164 1165 List<String> roleIdsToCheck = new ArrayList<String>(roleIds.size()); 1166 for (String roleId : roleIds) { 1167 Boolean hasRole = getPrincipalHasRoleFromCache(principalId, roleId, qualification, checkDelegations); 1168 if (hasRole != null) { 1169 if (hasRole.booleanValue()) { 1170 return true; 1171 } 1172 } else { 1173 roleIdsToCheck.add(roleId); 1174 } 1175 } 1176 1177 // load the roles, this will also filter out inactive roles! 1178 List<Role> roles = loadRoles(roleIdsToCheck); 1179 // short-circuit if no roles match 1180 if (roles.isEmpty()) { 1181 return false; 1182 } 1183 1184 // Phase 2: If they didn't pass any qualifications or they are using exact qualifier matching, we can go 1185 // straight to the database 1186 1187 Set<String> rolesCheckedForExactMatch = new HashSet<String>(); 1188 for (Role role : roles) { 1189 Map<String, String> qualificationForExactMatch = null; 1190 if (qualification == null || qualification.isEmpty()) { 1191 qualificationForExactMatch = new HashMap<String, String>(); 1192 } else { 1193 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1194 if (roleTypeService != null) { 1195 List<String> attributesForExactMatch = getQualifiersForExactMatch(role.getKimTypeId(), roleTypeService); 1196 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 1197 qualificationForExactMatch = populateQualifiersForExactMatch(qualification, attributesForExactMatch); 1198 if (qualificationForExactMatch.isEmpty()) { 1199 // None of the attributes passed into principalHasRole matched attribute qualifiers on 1200 // the roleTypeService. In this case we want to skip the remaining processing and 1201 // go onto the next role. 1202 continue; 1203 } 1204 } 1205 } 1206 } 1207 if (qualificationForExactMatch != null) { 1208 rolesCheckedForExactMatch.add(role.getId()); 1209 List<RoleMemberBo> matchingRoleMembers = getStoredRolePrincipalsForPrincipalIdAndRoleIds( 1210 Collections.singletonList(role.getId()), principalId, qualificationForExactMatch); 1211 // if a role member matched our principal, we're good to go 1212 if (CollectionUtils.isNotEmpty(matchingRoleMembers)) { 1213 return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1214 } 1215 // now check groups 1216 if (!context.getPrincipalGroupIds().isEmpty()) { 1217 List<RoleMemberBo> matchingRoleGroupMembers = 1218 getStoredRoleGroupsUsingExactMatchOnQualification(context.getPrincipalGroupIds(), role.getId(), qualification); 1219 if (CollectionUtils.isNotEmpty(matchingRoleGroupMembers)) { 1220 return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1221 } 1222 } 1223 // if we drop to this point, either we didn't match or the role has nested or derived role membership, 1224 // we'll check that later 1225 } 1226 } 1227 1228 // Phase 3: If we couldn't do an exact match, we need to work with the RoleTypeService in order to 1229 // perform matching 1230 1231 for (Role role : roles) { 1232 // if we didn't do an exact match, we need to do a manual match 1233 if (!rolesCheckedForExactMatch.contains(role.getId())) { 1234 List<RoleMemberBo> matchingPrincipalRoleMembers = getRoleMembersForPrincipalId(role.getId(), principalId); 1235 List<RoleMemberBo> matchingGroupRoleMembers = getRoleMembersForGroupIds(role.getId(), context.getPrincipalGroupIds()); 1236 List<RoleMembership> roleMemberships = convertToRoleMemberships(matchingPrincipalRoleMembers, matchingGroupRoleMembers); 1237 for (RoleMembership roleMembership : roleMemberships) { 1238 try { 1239 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1240 if (!roleTypeService.getMatchingRoleMemberships(qualification, roleMemberships).isEmpty()) { 1241 return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1242 } 1243 } catch (Exception ex) { 1244 LOG.warn("Unable to find role type service with id: " + role.getKimTypeId()); 1245 } 1246 } 1247 } 1248 } 1249 1250 // Phase 4: If we have nested roles, execute a recursive check on those 1251 1252 // first, check that the qualifiers on the role membership match 1253 // then, perform a principalHasRole on the embedded role 1254 Map<String, Role> roleIndex = new HashMap<String, Role>(); 1255 for (Role role :roles) { 1256 roleIndex.put(role.getId(), role); 1257 } 1258 List<RoleMemberBo> roleMemberBos = getStoredRoleMembersForRoleIds(new ArrayList<String>(roleIndex.keySet()), 1259 MemberType.ROLE.getCode(), null); 1260 for (RoleMemberBo roleMemberBo : roleMemberBos) { 1261 Role role = roleIndex.get(roleMemberBo.getRoleId()); 1262 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1263 if (roleTypeService != null) { 1264 //it is possible that the the roleTypeService is coming from a remote application 1265 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1266 try { 1267 if (roleTypeService.doesRoleQualifierMatchQualification(qualification, 1268 roleMemberBo.getAttributes())) { 1269 RoleBoLite memberRole = getRoleBoLite(roleMemberBo.getMemberId()); 1270 Map<String, String> nestedRoleQualification = 1271 roleTypeService.convertQualificationForMemberRoles(role.getNamespaceCode(), 1272 role.getName(), memberRole.getNamespaceCode(), memberRole.getName(), 1273 qualification); 1274 if (principalHasRole(context, principalId, 1275 Collections.singletonList(roleMemberBo.getMemberId()), nestedRoleQualification, true)) { 1276 return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1277 } 1278 } 1279 } catch (Exception ex) { 1280 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleMemberBo 1281 .getRoleId(), ex); 1282 } 1283 } else { 1284 // no qualifiers - role is always used - check membership 1285 // no role type service, so can't convert qualification - just pass as is 1286 if (principalHasRole(context, principalId, Collections.singletonList(roleMemberBo.getMemberId()), 1287 qualification, true)) { 1288 return putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1289 } 1290 } 1291 1292 } 1293 1294 // Phase 5: derived roles 1295 1296 // check for derived roles and extract principals and groups from that - then check them against the 1297 // role type service passing in the qualification and principal - the qualifier comes from the 1298 // external system (application) 1299 for (Role role : roles) { 1300 // check if an derived role 1301 //it is possible that the the roleTypeService is coming from a remote application 1302 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1303 try { 1304 boolean isDerivedRoleType = context.isDerivedRoleType(role.getKimTypeId()); 1305 if (isDerivedRoleType) { 1306 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1307 if (roleTypeService.hasDerivedRole(principalId, 1308 context.getPrincipalGroupIds(), role.getNamespaceCode(), role.getName(), qualification)) { 1309 if (!roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) { 1310 putPrincipalHasRoleInCache(true, principalId, role.getId(), qualification, checkDelegations); 1311 } 1312 return true; 1313 } 1314 } else { 1315 if(!checkDelegations) { 1316 putPrincipalHasRoleInCache(false, principalId, role.getId(), qualification, checkDelegations); 1317 } 1318 } 1319 } catch (Exception ex) { 1320 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + role.getId(), ex); 1321 } 1322 } 1323 1324 // Phase 6: delegations 1325 1326 if (checkDelegations) { 1327 if (matchesOnDelegation(roleIndex.keySet(), principalId, context.getPrincipalGroupIds(), qualification, context)) { 1328 return true; 1329 } 1330 } 1331 } catch (Exception e) { 1332 LOG.warn("Caught exception during a principalHasRole check", e); 1333 } 1334 return false; 1335 } 1336 1337 protected Boolean getPrincipalHasRoleFromCache(String principalId, String roleId, Map<String, String> qualification, boolean checkDelegations) { 1338 String key = buildPrincipalHasRoleCacheKey(principalId, roleId, qualification, checkDelegations); 1339 Cache.ValueWrapper value = cacheManager.getCache(Role.Cache.NAME).get(key); 1340 return value == null ? null : (Boolean)value.get(); 1341 } 1342 1343 protected boolean putPrincipalHasRoleInCache(boolean principalHasRole, String principalId, String roleId, 1344 Map<String, String> qualification, boolean checkDelegations) { 1345 String key = buildPrincipalHasRoleCacheKey(principalId, roleId, qualification, checkDelegations); 1346 cacheManager.getCache(Role.Cache.NAME).put(key, Boolean.valueOf(principalHasRole)); 1347 return principalHasRole; 1348 } 1349 1350 private String buildPrincipalHasRoleCacheKey(String principalId, String roleId, Map<String, String> qualification, boolean checkDelegations) { 1351 return new StringBuilder("{principalHasRole}") 1352 .append("principalId=").append(principalId).append("|") 1353 .append("roleId=").append(roleId).append("|") 1354 .append("qualification=").append(CacheKeyUtils.mapKey(qualification)).append("|") 1355 .append("checkDelegations=").append(checkDelegations).toString(); 1356 } 1357 1358 protected List<String> getQualifiersForExactMatch(String kimTypeId, RoleTypeService roleTypeService) { 1359 String cacheKey = "{getQualifiersForExactMatch}kimTypeId=" + kimTypeId; 1360 Cache cache = cacheManager.getCache(Role.Cache.NAME); 1361 Cache.ValueWrapper value = cache.get(cacheKey); 1362 List<String> qualifiers = new ArrayList<String>(); 1363 if (value == null) { 1364 try { 1365 qualifiers = roleTypeService.getQualifiersForExactMatch(); 1366 cache.put(cacheKey, qualifiers); 1367 } catch (Exception e) { 1368 LOG.warn("Caught exception when attempting to invoke a role type service", e); 1369 } 1370 } else { 1371 qualifiers = (List<String>)value.get(); 1372 } 1373 return qualifiers; 1374 } 1375 1376 public boolean isDerivedRoleType(RoleTypeService service) { 1377 return service != null && service.isDerivedRoleType(); 1378 } 1379 1380 private boolean dynamicRoleMembership(RoleTypeService service, Role role) { 1381 return service != null && service.dynamicRoleMembership(role.getNamespaceCode(), role.getName()); 1382 } 1383 1384 @Override 1385 public boolean isDerivedRole(String roleId) { 1386 incomingParamCheck(roleId, "roleId"); 1387 RoleTypeService service = getRoleTypeService(roleId); 1388 return isDerivedRoleType(service); 1389 } 1390 1391 @Override 1392 public boolean isDynamicRoleMembership(String roleId) { 1393 incomingParamCheck(roleId, "roleId"); 1394 RoleTypeService service = getRoleTypeService(roleId); 1395 try { 1396 return dynamicRoleMembership(service, getRole(roleId)); 1397 } catch (Exception e) { 1398 LOG.warn("Caught exception while invoking a role type service for role " + roleId, e); 1399 // Returning true so the role won't be cached 1400 return true; 1401 } 1402 } 1403 1404 /** 1405 * Support method for principalHasRole. Checks delegations on the passed in roles for the given principal and groups. (It's assumed that the principal 1406 * belongs to the given groups.) 1407 * <p/> 1408 * Delegation checks are mostly the same as role checks except that the delegateBo itself is qualified against the original role (like a RolePrincipal 1409 * or RoleGroup.) And then, the members of that delegateBo may have additional qualifiers which are not part of the original role qualifiers. 1410 * <p/> 1411 * For example: 1412 * <p/> 1413 * A role could be qualified by organization. So, there is a person in the organization with primary authority for that org. But, then they delegate authority 1414 * for that organization (not their authority - the delegateBo is attached to the org.) So, in this case the delegateBo has a qualifier of the organization 1415 * when it is attached to the role. 1416 * <p/> 1417 * The principals then attached to that delegateBo (which is specific to the organization), may have additional qualifiers. 1418 * For Example: dollar amount range, effective dates, document types. 1419 * As a subsequent step, those qualifiers are checked against the qualification passed in from the client. 1420 */ 1421 protected boolean matchesOnDelegation(Set<String> allRoleIds, String principalId, List<String> principalGroupIds, Map<String, String> qualification, Context context) { 1422 // get the list of delegations for the roles 1423 Map<String, DelegateTypeBo> delegations = getStoredDelegationImplMapFromRoleIds(allRoleIds); 1424 1425 // If there are no delegations then we should cache that the principal 1426 // doesn't have the given roles if those roles do not have dynamic 1427 // membership 1428 if(delegations.isEmpty()) { 1429 for(String roleId : allRoleIds) { 1430 Role role = loadRole(roleId); 1431 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1432 if(!context.isDerivedRoleType(role.getKimTypeId()) || roleTypeService == null || !roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) { 1433 putPrincipalHasRoleInCache(false, principalId, roleId, qualification, true); 1434 } 1435 } 1436 return false; 1437 } 1438 1439 // Build a map from a role ID to the delegations for that role ID 1440 Map<String, List<DelegateTypeBo>> roleToDelegations = new HashMap<String, List<DelegateTypeBo>>(); 1441 for(DelegateTypeBo delegation : delegations.values()) { 1442 List<DelegateTypeBo> roleDelegations = roleToDelegations.get(delegation.getRoleId()); 1443 if(roleDelegations == null) { 1444 roleDelegations = new ArrayList<DelegateTypeBo>(); 1445 roleToDelegations.put(delegation.getRoleId(), roleDelegations); 1446 } 1447 roleDelegations.add(delegation); 1448 } 1449 // Iterate through each role and check its delegations to determine if 1450 // the principal has one of the roles 1451 for(String roleId : roleToDelegations.keySet()) { 1452 boolean matchesOnRoleDelegation = false; 1453 Role role = getRole(roleId); 1454 RoleTypeService roleTypeService = context.getRoleTypeService(role.getKimTypeId()); 1455 // Iterate through each delegation for this role and determine if 1456 // the principal has the role through this delegation 1457 for(DelegateTypeBo delegation : roleToDelegations.get(roleId)) { 1458 // If the delegation isn't active skip it 1459 if (!delegation.isActive()) { 1460 continue; 1461 } 1462 // Now iterate through all of the members of the delegation to 1463 // determine if any of them apply to this principal 1464 for (DelegateMemberBo delegateMemberBo : delegation.getMembers()) { 1465 // If the membership isn't active skip the rest of the checks 1466 if (!delegateMemberBo.isActive(new Timestamp(new Date().getTime()))) { 1467 continue; 1468 } 1469 // If the membership is a principal type then check the 1470 // delegate's member ID against the principal ID 1471 if (MemberType.PRINCIPAL.equals(delegateMemberBo.getType()) 1472 && !delegateMemberBo.getMemberId().equals(principalId)) { 1473 continue; // no match on principal 1474 } 1475 // If the membership is a group type then check to see if 1476 // the group's ID is contained in the list of groups the 1477 // principal belongs to 1478 if (MemberType.GROUP.equals(delegateMemberBo.getType()) 1479 && !principalGroupIds.contains(delegateMemberBo.getMemberId())) { 1480 continue; // No match on group 1481 } 1482 // If the membership is a role type then we need to recurse 1483 // into the principalHasRole method to check if this 1484 // principal is a member of that role 1485 if (MemberType.ROLE.equals(delegateMemberBo.getType()) 1486 && !principalHasRole(principalId, Collections.singletonList(delegateMemberBo.getMemberId()), qualification, false)) { 1487 continue; // No match on role 1488 } 1489 1490 // OK, the member matches the current user, now check the qualifications 1491 1492 // NOTE: this compare is slightly different than the member enumeration 1493 // since the requested qualifier is always being used rather than 1494 // the role qualifier for the member (which is not available) 1495 1496 //it is possible that the the roleTypeService is coming from a remote application 1497 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1498 try { 1499 if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) { 1500 continue; // no match - skip to next record 1501 } 1502 } catch (Exception ex) { 1503 LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + delegateMemberBo.getQualifier(), ex); 1504 continue; 1505 } 1506 1507 // role service matches this qualifier 1508 // now try the delegateBo service 1509 DelegationTypeService delegationTypeService = getDelegationTypeService(delegateMemberBo.getDelegationId()); 1510 // QUESTION: does the qualifier map need to be merged with the main delegateBo qualification? 1511 if (delegationTypeService != null && !delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) { 1512 continue; // no match - skip to next record 1513 } 1514 // check if a role member ID is present on the delegateBo record 1515 // if so, check that the original role member would match the given qualifiers 1516 if (StringUtils.isNotBlank(delegateMemberBo.getRoleMemberId())) { 1517 RoleMemberBo rm = getRoleMemberBo(delegateMemberBo.getRoleMemberId()); 1518 if (rm != null) { 1519 // check that the original role member's is active and that their 1520 // qualifier would have matched this request's 1521 // qualifications (that the original person would have the permission/responsibility 1522 // for an action) 1523 // this prevents a role-membership based delegateBo from surviving the inactivation/ 1524 // changing of the main person's role membership 1525 if (!rm.isActive(new Timestamp(new Date().getTime()))) { 1526 continue; 1527 } 1528 Map<String, String> roleQualifier = rm.getAttributes(); 1529 //it is possible that the the roleTypeService is coming from a remote application 1530 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1531 try { 1532 if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, roleQualifier)) { 1533 continue; 1534 } 1535 } catch (Exception ex) { 1536 LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + roleQualifier, ex); 1537 continue; 1538 } 1539 } else { 1540 LOG.warn("Unknown role member ID cited in the delegateBo member table:"); 1541 LOG.warn(" assignedToId: " + delegateMemberBo.getDelegationMemberId() + " / roleMemberId: " + delegateMemberBo.getRoleMemberId()); 1542 } 1543 } 1544 // If we've made it here then all of the tests pass so the 1545 // principal must belong to this delegation so set the flag 1546 // to true and break out of this loop 1547 matchesOnRoleDelegation = true; 1548 break; 1549 } 1550 1551 // If we've found a match for one of the delegations break out 1552 // of this loop 1553 if(matchesOnRoleDelegation) { 1554 break; 1555 } 1556 } 1557 // If the role is not derived nor dynamic then cache the result of 1558 // this since the principal has the role through one of these 1559 // delegations 1560 if(!context.isDerivedRoleType(role.getKimTypeId()) || roleTypeService == null || !roleTypeService.dynamicRoleMembership(role.getNamespaceCode(), role.getName())) { 1561 putPrincipalHasRoleInCache(matchesOnRoleDelegation, principalId, roleId, qualification, true); 1562 } 1563 // If we've found a matching delegation skip processing the rest of 1564 // the roles 1565 if(matchesOnRoleDelegation) { 1566 return matchesOnRoleDelegation; 1567 } 1568 } 1569 // If we get here we didn't find a matching delegation so return false 1570 return false; 1571 } 1572 1573 protected List<RoleMembership> convertToRoleMemberships(List<RoleMemberBo>... roleMemberLists) { 1574 List<RoleMembership> roleMemberships = new ArrayList<RoleMembership>(); 1575 for (List<RoleMemberBo> roleMembers : roleMemberLists) { 1576 for (RoleMemberBo roleMember : roleMembers) { 1577 RoleMembership roleMembership = RoleMembership.Builder.create( 1578 roleMember.getRoleId(), 1579 roleMember.getId(), 1580 roleMember.getMemberId(), 1581 roleMember.getType(), 1582 roleMember.getAttributes()).build(); 1583 roleMemberships.add(roleMembership); 1584 } 1585 } 1586 return roleMemberships; 1587 } 1588 1589 /** 1590 * Helper method used by principalHasRole to build the role ID -> list of members map. 1591 * 1592 * @return <b>true</b> if no further checks are needed because no role service is defined 1593 */ 1594 protected boolean getRoleIdToMembershipMap(Map<String, List<RoleMembership>> roleIdToMembershipMap, List<RoleMemberBo> roleMembers) { 1595 for (RoleMemberBo roleMemberBo : roleMembers) { 1596 RoleMembership roleMembership = RoleMembership.Builder.create( 1597 roleMemberBo.getRoleId(), 1598 roleMemberBo.getId(), 1599 roleMemberBo.getMemberId(), 1600 roleMemberBo.getType(), 1601 roleMemberBo.getAttributes()).build(); 1602 1603 // if the role type service is null, assume that all qualifiers match 1604 if (getRoleTypeService(roleMemberBo.getRoleId()) == null) { 1605 return true; 1606 } 1607 List<RoleMembership> lrmi = roleIdToMembershipMap.get(roleMembership.getRoleId()); 1608 if (lrmi == null) { 1609 lrmi = new ArrayList<RoleMembership>(); 1610 roleIdToMembershipMap.put(roleMembership.getRoleId(), lrmi); 1611 } 1612 lrmi.add(roleMembership); 1613 } 1614 return false; 1615 } 1616 1617 /** 1618 * Retrieves a KimDelegationImpl object by its ID. If the delegateBo already exists in the cache, this method will return the cached 1619 * version; otherwise, it will retrieve the uncached version from the database and then cache it before returning it. 1620 */ 1621 protected DelegateTypeBo getKimDelegationImpl(String delegationId) { 1622 if (StringUtils.isBlank(delegationId)) { 1623 return null; 1624 } 1625 1626 return getBusinessObjectService().findByPrimaryKey(DelegateTypeBo.class, 1627 Collections.singletonMap(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId)); 1628 } 1629 1630 protected DelegationTypeService getDelegationTypeService(String delegationId) { 1631 DelegationTypeService service = null; 1632 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 1633 KimType delegationType = KimApiServiceLocator.getKimTypeInfoService().getKimType(delegateBo.getKimTypeId()); 1634 if (delegationType != null) { 1635 KimTypeService tempService = KimFrameworkServiceLocator.getKimTypeService(delegationType); 1636 if (tempService != null && tempService instanceof DelegationTypeService) { 1637 service = (DelegationTypeService) tempService; 1638 } else { 1639 LOG.error("Service returned for type " + delegationType + "(" + delegationType.getName() + ") was not a DelegationTypeService. Was a " + (tempService != null ? tempService.getClass() : "(null)")); 1640 } 1641 } else { // delegateBo has no type - default to role type if possible 1642 RoleTypeService roleTypeService = getRoleTypeService(delegateBo.getRoleId()); 1643 if (roleTypeService != null && roleTypeService instanceof DelegationTypeService) { 1644 service = (DelegationTypeService) roleTypeService; 1645 } 1646 } 1647 return service; 1648 } 1649 1650 protected Collection<RoleMembership> getNestedRoleMembers(Map<String, String> qualification, RoleMembership rm, Set<String> foundRoleTypeMembers) { 1651 // If this role has already been traversed, skip it 1652 if (foundRoleTypeMembers.contains(rm.getMemberId())) { 1653 return new ArrayList<RoleMembership>(); // return an empty list 1654 } 1655 foundRoleTypeMembers.add(rm.getMemberId()); 1656 1657 ArrayList<String> roleIdList = new ArrayList<String>(1); 1658 roleIdList.add(rm.getMemberId()); 1659 1660 // get the list of members from the nested role - ignore delegations on those sub-roles 1661 Collection<RoleMembership> currentNestedRoleMembers = getRoleMembers(roleIdList, qualification, false, foundRoleTypeMembers); 1662 1663 // add the roles whose members matched to the list for delegateBo checks later 1664 Collection<RoleMembership> returnRoleMembers = new ArrayList<RoleMembership>(); 1665 for (RoleMembership roleMembership : currentNestedRoleMembers) { 1666 RoleMembership.Builder rmBuilder = RoleMembership.Builder.create(roleMembership); 1667 1668 // use the member ID of the parent role (needed for responsibility joining) 1669 rmBuilder.setId(rm.getId()); 1670 // store the role ID, so we know where this member actually came from 1671 rmBuilder.setRoleId(rm.getRoleId()); 1672 rmBuilder.setEmbeddedRoleId(rm.getMemberId()); 1673 returnRoleMembers.add(rmBuilder.build()); 1674 } 1675 return returnRoleMembers; 1676 } 1677 1678 /** 1679 * Retrieves a KimDelegationMemberImpl object by its ID and the ID of the delegation it belongs to. If the delegation member exists in the cache, 1680 * this method will return the cached one; otherwise, it will retrieve the uncached version from the database and then cache it before returning it. 1681 */ 1682 protected DelegateMemberBo getKimDelegationMemberImplByDelegationAndId(String delegationId, String delegationMemberId) { 1683 if (StringUtils.isBlank(delegationId) || StringUtils.isBlank(delegationMemberId)) { 1684 return null; 1685 } 1686 1687 Map<String, String> searchCriteria = new HashMap<String, String>(); 1688 searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId); 1689 searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMemberId); 1690 List<DelegateMemberBo> memberList = 1691 (List<DelegateMemberBo>) getBusinessObjectService().findMatching(DelegateMemberBo.class, searchCriteria); 1692 if (memberList != null && !memberList.isEmpty()) { 1693 return memberList.get(0); 1694 } 1695 return null; 1696 } 1697 1698 private List<RoleMemberBo> getStoredRoleMembersUsingExactMatchOnQualification(String principalId, List<String> groupIds, List<String> roleIds, Map<String, String> qualification) { 1699 List<String> copyRoleIds = new ArrayList<String>(roleIds); 1700 List<RoleMemberBo> roleMemberBoList = new ArrayList<RoleMemberBo>(); 1701 1702 for (String roleId : roleIds) { 1703 RoleTypeService roleTypeService = getRoleTypeService(roleId); 1704 if (roleTypeService != null) { 1705 try { 1706 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 1707 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 1708 copyRoleIds.remove(roleId); 1709 roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(Collections.singletonList(roleId), principalId, groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 1710 } 1711 } catch (Exception e) { 1712 LOG.warn("Caught exception when attempting to invoke a role type service for role " + roleId, e); 1713 } 1714 } 1715 } 1716 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 1717 roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(copyRoleIds, principalId, groupIds, null)); 1718 } 1719 return roleMemberBoList; 1720 } 1721 1722 private List<RoleMemberBo> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, String roleId, Map<String, String> qualification) { 1723 Set<String> roleIds = new HashSet<String>(); 1724 if (roleId != null) { 1725 roleIds.add(roleId); 1726 } 1727 return getStoredRoleGroupsUsingExactMatchOnQualification(groupIds, roleIds, qualification); 1728 } 1729 1730 private List<RoleMemberBo> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, Set<String> roleIds, Map<String, String> qualification) { 1731 List<String> copyRoleIds = new ArrayList<String>(roleIds); 1732 List<RoleMemberBo> roleMemberBos = new ArrayList<RoleMemberBo>(); 1733 1734 for (String roleId : roleIds) { 1735 RoleTypeService roleTypeService = getRoleTypeService(roleId); 1736 if (roleTypeService != null) { 1737 try { 1738 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 1739 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 1740 copyRoleIds.remove(roleId); 1741 roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(roleId), groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 1742 } 1743 } catch (Exception e) { 1744 LOG.warn("Caught exception when attempting to invoke a role type service for role " + roleId, e); 1745 } 1746 } 1747 } 1748 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 1749 roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(copyRoleIds, groupIds, null)); 1750 } 1751 return roleMemberBos; 1752 } 1753 1754 private List<DelegateMember> getDelegateMembersForDelegation(DelegateTypeBo delegateBo) { 1755 if (delegateBo == null || delegateBo.getMembers() == null) {return null;} 1756 List<DelegateMember> delegateMembersReturnList = new ArrayList<DelegateMember>(); 1757 for (DelegateMemberBo delegateMemberBo : delegateBo.getMembers()) { 1758 //FIXME: What is up with this!?! 1759 DelegateMember delegateMember = getDelegateCompleteInfo(delegateBo, delegateMemberBo); 1760 1761 delegateMembersReturnList.add(DelegateMemberBo.to(delegateMemberBo)); 1762 } 1763 return Collections.unmodifiableList(delegateMembersReturnList); 1764 } 1765 1766 private DelegateMember getDelegateCompleteInfo(DelegateTypeBo delegateBo, DelegateMemberBo delegateMemberBo) { 1767 if (delegateBo == null || delegateMemberBo == null) {return null;} 1768 1769 DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegateMemberBo); 1770 delegateMemberBuilder.setType(delegateMemberBo.getType()); 1771 return delegateMemberBuilder.build(); 1772 } 1773 1774 @Override 1775 public RoleMember assignPrincipalToRole(String principalId, 1776 String namespaceCode, String roleName, Map<String, String> qualifier) 1777 throws RiceIllegalArgumentException { 1778 incomingParamCheck(principalId, "principalId"); 1779 incomingParamCheck(namespaceCode, "namespaceCode"); 1780 incomingParamCheck(roleName, "roleName"); 1781 incomingParamCheck(qualifier, "qualifier"); 1782 1783 // look up the role 1784 RoleBoLite role = getRoleBoLiteByName(namespaceCode, roleName); 1785 1786 // check that identical member does not already exist 1787 List<RoleMember> membersMatchByExactQualifiers = doAnyMemberRecordsMatchByExactQualifier(role, principalId, memberTypeToRoleDaoActionMap.get(MemberType.PRINCIPAL.getCode()), qualifier); 1788 if (CollectionUtils.isNotEmpty(membersMatchByExactQualifiers)) { 1789 return membersMatchByExactQualifiers.get(0); 1790 } 1791 List<String> roleIds = new ArrayList<String>(); 1792 roleIds.add(role.getId()); 1793 List<RoleMemberBo> roleMembers = getRoleDao().getRoleMembersForRoleIds(roleIds, MemberType.PRINCIPAL.getCode(), 1794 qualifier); 1795 RoleMember anyMemberMatch = doAnyMemberRecordsMatch( roleMembers, principalId, MemberType.PRINCIPAL.getCode(), qualifier ); 1796 if (null != anyMemberMatch) { 1797 return anyMemberMatch; 1798 } 1799 1800 // create the new role member object 1801 RoleMemberBo newRoleMember = new RoleMemberBo(); 1802 1803 newRoleMember.setRoleId(role.getId()); 1804 newRoleMember.setMemberId(principalId); 1805 newRoleMember.setType(MemberType.PRINCIPAL); 1806 1807 // build role member attribute objects from the given Map<String, String> 1808 addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId()); 1809 1810 // add row to member table 1811 // When members are added to roles, clients must be notified. 1812 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(newRoleMember)); 1813 } 1814 1815 @Override 1816 public RoleMember assignGroupToRole(String groupId, String namespaceCode, 1817 String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1818 incomingParamCheck(groupId, "groupId"); 1819 incomingParamCheck(namespaceCode, "namespaceCode"); 1820 incomingParamCheck(roleName, "roleName"); 1821 incomingParamCheck(qualifier, "qualifier"); 1822 1823 // look up the role 1824 RoleBo role = getRoleBoByName(namespaceCode, roleName); 1825 1826 // check that identical member does not already exist 1827 List<RoleMember> membersMatchByExactQualifiers = doAnyMemberRecordsMatchByExactQualifier(role, groupId, memberTypeToRoleDaoActionMap.get(MemberType.GROUP.getCode()), qualifier); 1828 if (CollectionUtils.isNotEmpty(membersMatchByExactQualifiers)) { 1829 return membersMatchByExactQualifiers.get(0); 1830 } 1831 RoleMember anyMemberMatch = doAnyMemberRecordsMatch( role.getMembers(), groupId, MemberType.GROUP.getCode(), qualifier ); 1832 if (null != anyMemberMatch) { 1833 return anyMemberMatch; 1834 } 1835 1836 // create the new role member object 1837 RoleMemberBo newRoleMember = new RoleMemberBo(); 1838 newRoleMember.setRoleId(role.getId()); 1839 newRoleMember.setMemberId(groupId); 1840 newRoleMember.setType(MemberType.GROUP); 1841 1842 // build role member attribute objects from the given Map<String, String> 1843 addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId()); 1844 1845 // When members are added to roles, clients must be notified. 1846 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(newRoleMember)); 1847 } 1848 1849 @Override 1850 public RoleMember assignRoleToRole(String roleId, 1851 String namespaceCode, String roleName, Map<String, String> qualifier) 1852 throws RiceIllegalStateException { 1853 incomingParamCheck(roleId, "roleId"); 1854 incomingParamCheck(namespaceCode, "namespaceCode"); 1855 incomingParamCheck(roleName, "roleName"); 1856 incomingParamCheck(qualifier, "qualifier"); 1857 1858 // look up the roleBo 1859 RoleBo roleBo = getRoleBoByName(namespaceCode, roleName); 1860 1861 // check that identical member does not already exist 1862 List<RoleMember> membersMatchByExactQualifiers = doAnyMemberRecordsMatchByExactQualifier(roleBo, roleId, memberTypeToRoleDaoActionMap.get(MemberType.ROLE.getCode()), qualifier); 1863 if (CollectionUtils.isNotEmpty(membersMatchByExactQualifiers)) { 1864 return membersMatchByExactQualifiers.get(0); 1865 } 1866 RoleMember anyMemberMatch = doAnyMemberRecordsMatch( roleBo.getMembers(), roleId, MemberType.ROLE.getCode(), qualifier); 1867 if (null != anyMemberMatch) { 1868 return anyMemberMatch; 1869 } 1870 1871 1872 // Check to make sure this doesn't create a circular membership 1873 if (!checkForCircularRoleMembership(roleId, roleBo)) { 1874 throw new IllegalArgumentException("Circular roleBo reference."); 1875 } 1876 // create the new roleBo member object 1877 RoleMemberBo newRoleMember = new RoleMemberBo(); 1878 newRoleMember.setRoleId(roleBo.getId()); 1879 newRoleMember.setMemberId(roleId); 1880 newRoleMember.setType(MemberType.ROLE); 1881 // build roleBo member attribute objects from the given Map<String, String> 1882 addMemberAttributeData(newRoleMember, qualifier, roleBo.getKimTypeId()); 1883 1884 // When members are added to roles, clients must be notified. 1885 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(newRoleMember)); 1886 } 1887 1888 @Override 1889 public RoleMember createRoleMember(RoleMember roleMember) throws RiceIllegalStateException { 1890 incomingParamCheck(roleMember, "roleMember"); 1891 1892 if (StringUtils.isNotBlank(roleMember.getId()) && getRoleMemberBo(roleMember.getId()) != null) { 1893 throw new RiceIllegalStateException("the roleMember to create already exists: " + roleMember); 1894 } 1895 1896 String kimTypeId = getRoleBoLite(roleMember.getRoleId()).getKimTypeId(); 1897 List<RoleMemberAttributeDataBo> attrBos = Collections.emptyList(); 1898 attrBos = KimAttributeDataBo.createFrom(RoleMemberAttributeDataBo.class, roleMember.getAttributes(), kimTypeId); 1899 1900 RoleMemberBo bo = RoleMemberBo.from(roleMember); 1901 bo.setAttributeDetails(attrBos); 1902 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(bo)); 1903 } 1904 1905 @Override 1906 public RoleMember updateRoleMember(@WebParam( 1907 name = "roleMember") RoleMember roleMember) throws RiceIllegalArgumentException, RiceIllegalStateException { 1908 incomingParamCheck(roleMember, "roleMember"); 1909 1910 RoleMemberBo originalRoleMemberBo = null; 1911 if (StringUtils.isNotBlank(roleMember.getId())) { 1912 originalRoleMemberBo = getRoleMemberBo(roleMember.getId()); 1913 } 1914 if (StringUtils.isBlank(roleMember.getId()) || originalRoleMemberBo == null) { 1915 throw new RiceIllegalStateException("the roleMember to update does not exists: " + roleMember); 1916 } 1917 1918 String kimTypeId = getRoleBoLite(roleMember.getRoleId()).getKimTypeId(); 1919 List<RoleMemberAttributeDataBo> attrBos = Collections.emptyList(); 1920 attrBos = KimAttributeDataBo.createFrom(RoleMemberAttributeDataBo.class, roleMember.getAttributes(), kimTypeId); 1921 1922 RoleMemberBo bo = RoleMemberBo.from(roleMember); 1923 List<RoleMemberAttributeDataBo> updateAttrBos = new ArrayList<RoleMemberAttributeDataBo>(); 1924 1925 boolean matched = false; 1926 for (RoleMemberAttributeDataBo newRoleMemberAttrDataBo : attrBos) { 1927 for (RoleMemberAttributeDataBo oldRoleMemberAttrDataBo : originalRoleMemberBo.getAttributeDetails()) { 1928 if (newRoleMemberAttrDataBo.getKimTypeId().equals(oldRoleMemberAttrDataBo.getKimTypeId()) && 1929 newRoleMemberAttrDataBo.getKimAttributeId().equals(oldRoleMemberAttrDataBo.getKimAttributeId())) { 1930 newRoleMemberAttrDataBo.setAssignedToId(oldRoleMemberAttrDataBo.getAssignedToId()); 1931 newRoleMemberAttrDataBo.setVersionNumber(oldRoleMemberAttrDataBo.getVersionNumber()); 1932 newRoleMemberAttrDataBo.setId(oldRoleMemberAttrDataBo.getId()); 1933 updateAttrBos.add(newRoleMemberAttrDataBo); 1934 matched = true; 1935 break; 1936 } 1937 } 1938 if (!matched) { 1939 updateAttrBos.add(newRoleMemberAttrDataBo); 1940 } else { 1941 matched = false; 1942 } 1943 } 1944 1945 bo.setAttributeDetails(updateAttrBos); 1946 1947 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(bo)); 1948 } 1949 1950 @Override 1951 public DelegateMember updateDelegateMember(@WebParam( 1952 name = "delegateMember") DelegateMember delegateMember) throws RiceIllegalArgumentException, RiceIllegalStateException { 1953 1954 //check delegateMember not empty 1955 incomingParamCheck(delegateMember, "delegateMember"); 1956 1957 //check delegate exists 1958 String delegationId = delegateMember.getDelegationId(); 1959 incomingParamCheck(delegationId,"delegationId"); 1960 DelegateTypeBo delegate = getKimDelegationImpl(delegationId); 1961 DelegateMemberBo originalDelegateMemberBo = null; 1962 String delegationMemberId = delegateMember.getDelegationMemberId(); 1963 if (StringUtils.isNotEmpty(delegationMemberId)) { 1964 originalDelegateMemberBo = getDelegateMemberBo(delegateMember.getDelegationMemberId()); 1965 } 1966 if(delegate==null) { 1967 throw new RiceIllegalStateException("the delegate does not exist: " + delegationId); 1968 } 1969 1970 //save the delegateMember (actually updates) 1971 String kimTypeId = getRoleBoLite(delegate.getRoleId()).getKimTypeId(); 1972 List<DelegateMemberAttributeDataBo> attrBos = Collections.emptyList(); 1973 attrBos = KimAttributeDataBo.createFrom(DelegateMemberAttributeDataBo.class, delegateMember.getAttributes(), kimTypeId); 1974 DelegateMemberBo bo = DelegateMemberBo.from(delegateMember); 1975 1976 List<DelegateMemberAttributeDataBo> updateAttrBos = new ArrayList<DelegateMemberAttributeDataBo>(); 1977 1978 boolean matched = false; 1979 if (originalDelegateMemberBo !=null ) { 1980 bo.setVersionNumber(originalDelegateMemberBo.getVersionNumber()); 1981 for (DelegateMemberAttributeDataBo newDelegateMemberAttrDataBo : attrBos) { 1982 for (DelegateMemberAttributeDataBo oldDelegateMemberAttrDataBo : originalDelegateMemberBo.getAttributeDetails()) { 1983 if (newDelegateMemberAttrDataBo.getKimTypeId().equals(oldDelegateMemberAttrDataBo.getKimTypeId()) && 1984 newDelegateMemberAttrDataBo.getKimAttributeId().equals(oldDelegateMemberAttrDataBo.getKimAttributeId())) { 1985 newDelegateMemberAttrDataBo.setAssignedToId(oldDelegateMemberAttrDataBo.getAssignedToId()); 1986 newDelegateMemberAttrDataBo.setVersionNumber(oldDelegateMemberAttrDataBo.getVersionNumber()); 1987 newDelegateMemberAttrDataBo.setId(oldDelegateMemberAttrDataBo.getId()); 1988 updateAttrBos.add(newDelegateMemberAttrDataBo); 1989 matched = true; 1990 break; 1991 } 1992 } 1993 if (!matched) { 1994 updateAttrBos.add(newDelegateMemberAttrDataBo); 1995 } else { 1996 matched = false; 1997 } 1998 } 1999 } 2000 2001 bo.setAttributeDetails(updateAttrBos); 2002 return DelegateMemberBo.to(getResponsibilityInternalService().saveDelegateMember(bo)); 2003 } 2004 2005 @Override 2006 public DelegateMember createDelegateMember(@WebParam( 2007 name = "delegateMember") DelegateMember delegateMember) throws RiceIllegalArgumentException, RiceIllegalStateException { 2008 //ensure object not empty 2009 incomingParamCheck(delegateMember, "delegateMember"); 2010 2011 //check key is null 2012 if(delegateMember.getDelegationMemberId()!=null ) { 2013 throw new RiceIllegalStateException("the delegate member already exists: " + delegateMember.getDelegationMemberId()); 2014 } 2015 2016 //check delegate exists 2017 String delegationId = delegateMember.getDelegationId(); 2018 incomingParamCheck(delegationId,"delegationId"); 2019 DelegateTypeBo delegate = getKimDelegationImpl(delegationId); 2020 if(delegate==null) { 2021 throw new RiceIllegalStateException("the delegate does not exist: " + delegationId); 2022 } 2023 2024 //check member exists 2025 String memberId = delegateMember.getMemberId(); 2026 incomingParamCheck(memberId,"memberId"); 2027 Principal kPrincipal = KimApiServiceLocator.getIdentityService().getPrincipal(memberId); 2028 if(kPrincipal==null){ 2029 throw new RiceIllegalStateException("the user does not exist: " + memberId); 2030 } 2031 2032 //create member delegate 2033 String kimTypeId = getRoleBoLite(delegate.getRoleId()).getKimTypeId(); 2034 List<DelegateMemberAttributeDataBo> attrBos = Collections.emptyList(); 2035 attrBos = KimAttributeDataBo.createFrom(DelegateMemberAttributeDataBo.class, delegateMember.getAttributes(), kimTypeId); 2036 DelegateMemberBo bo = DelegateMemberBo.from(delegateMember); 2037 bo.setAttributeDetails(attrBos); 2038 return DelegateMemberBo.to(getResponsibilityInternalService().saveDelegateMember(bo)); 2039 } 2040 2041 @Override 2042 public void removeDelegateMembers(@WebParam( 2043 name = "delegateMembers") List<DelegateMember> delegateMembers) throws RiceIllegalArgumentException, RiceIllegalStateException { 2044 incomingParamCheck(delegateMembers, "delegateMembers"); 2045 for (DelegateMember delegateMember : delegateMembers) { 2046 DelegateMember.Builder delegateMemberInfo = DelegateMember.Builder.create(); 2047 delegateMemberInfo.setDelegationMemberId(delegateMember.getDelegationMemberId()); 2048 delegateMemberInfo.setAttributes(delegateMember.getAttributes()); 2049 delegateMemberInfo.setDelegationId(delegateMember.getDelegationId()); 2050 delegateMemberInfo.setMemberId(delegateMember.getMemberId()); 2051 delegateMemberInfo.setRoleMemberId(delegateMember.getRoleMemberId()); 2052 delegateMemberInfo.setType(delegateMember.getType()); 2053 delegateMemberInfo.setActiveFromDate(delegateMember.getActiveFromDate()); 2054 delegateMemberInfo.setActiveToDate(DateTime.now()); 2055 updateDelegateMember(delegateMemberInfo.build()); 2056 } 2057 } 2058 2059 @Override 2060 public RoleResponsibilityAction createRoleResponsibilityAction(RoleResponsibilityAction roleResponsibilityAction) 2061 throws RiceIllegalArgumentException, RiceIllegalStateException { 2062 incomingParamCheck(roleResponsibilityAction, "roleResponsibilityAction"); 2063 2064 2065 if (StringUtils.isNotBlank(roleResponsibilityAction.getId()) 2066 && getRoleResponsibilityActionBo(roleResponsibilityAction.getId()) != null) { 2067 throw new RiceIllegalStateException("the roleResponsibilityAction to create already exists: " + roleResponsibilityAction); 2068 } 2069 2070 RoleResponsibilityActionBo bo = RoleResponsibilityActionBo.from(roleResponsibilityAction); 2071 return RoleResponsibilityActionBo.to(getBusinessObjectService().save(bo)); 2072 } 2073 2074 /** 2075 * Queues ActionRequest refresh/regeneration for RoleResponsbilityAction change 2076 * @param bo the changed or deleted RoleResponsibilityActionBo 2077 */ 2078 protected void updateActionRequestsForRoleResponsibilityActionChange(RoleResponsibilityActionBo bo) { 2079 RoleResponsibilityBo rr = bo.getRoleResponsibility(); 2080 if (rr != null) { 2081 getResponsibilityInternalService().updateActionRequestsForResponsibilityChange(Collections.singleton(rr.getResponsibilityId())); 2082 } 2083 } 2084 2085 @Override 2086 public RoleResponsibilityAction updateRoleResponsibilityAction(RoleResponsibilityAction roleResponsibilityAction) 2087 throws RiceIllegalArgumentException, RiceIllegalStateException { 2088 incomingParamCheck(roleResponsibilityAction, "roleResponsibilityAction"); 2089 2090 if (StringUtils.isBlank(roleResponsibilityAction.getId()) || getRoleResponsibilityActionBo(roleResponsibilityAction.getId()) == null) { 2091 throw new RiceIllegalStateException("the roleResponsibilityAction to create does not exist: " + roleResponsibilityAction); 2092 } 2093 2094 RoleResponsibilityActionBo bo = RoleResponsibilityActionBo.from(roleResponsibilityAction); 2095 roleResponsibilityAction = RoleResponsibilityActionBo.to(getBusinessObjectService().save(bo)); 2096 2097 // update action requests 2098 updateActionRequestsForRoleResponsibilityActionChange(bo); 2099 2100 return roleResponsibilityAction; 2101 } 2102 2103 @Override 2104 public void deleteRoleResponsibilityAction(String roleResponsibilityActionId) 2105 throws RiceIllegalArgumentException, RiceIllegalStateException { 2106 incomingParamCheck(roleResponsibilityActionId, "roleResponsibilityActionId"); 2107 2108 RoleResponsibilityActionBo bo = getRoleResponsibilityActionBo(roleResponsibilityActionId); 2109 if (StringUtils.isBlank(roleResponsibilityActionId) || bo == null) { 2110 throw new RiceIllegalStateException("the roleResponsibilityAction to delete does not exist: " + roleResponsibilityActionId); 2111 } 2112 2113 getBusinessObjectService().delete(bo); 2114 2115 // update action requests 2116 updateActionRequestsForRoleResponsibilityActionChange(bo); 2117 } 2118 2119 @Override 2120 public DelegateType createDelegateType(DelegateType delegateType) throws RiceIllegalArgumentException, RiceIllegalStateException { 2121 incomingParamCheck(delegateType, "delegateType"); 2122 2123 if (StringUtils.isNotBlank(delegateType.getDelegationId()) 2124 && getDelegateTypeByDelegationId(delegateType.getDelegationId()) != null) { 2125 throw new RiceIllegalStateException("the delegateType to create already exists: " + delegateType); 2126 } 2127 2128 DelegateTypeBo bo = DelegateTypeBo.from(delegateType); 2129 return DelegateTypeBo.to(getBusinessObjectService().save(bo)); 2130 // look up the role 2131 /*RoleBo role = getRoleBo(delegationType.getRoleId()); 2132 DelegateTypeBo delegation = getDelegationOfType(role.getId(), delegationType.getDelegationTypeCode()); 2133 // create the new role member object 2134 DelegateMemberBo newDelegationMember = new DelegateMemberBo(); 2135 2136 DelegateMemberBo origDelegationMember; 2137 if(StringUtils.isNotEmpty(delegationMemberId)){ 2138 origDelegationMember = getDelegateMemberBo(delegationMemberId); 2139 } else{ 2140 List<DelegateMemberBo> origDelegationMembers = 2141 this.getDelegationMemberBoListByMemberAndDelegationId(memberId, delegation.getDelegationId()); 2142 origDelegationMember = 2143 (origDelegationMembers!=null && !origDelegationMembers.isEmpty()) ? origDelegationMembers.get(0) : null; 2144 } 2145 if(origDelegationMember!=null){ 2146 newDelegationMember.setDelegationMemberId(origDelegationMember.getDelegationMemberId()); 2147 newDelegationMember.setVersionNumber(origDelegationMember.getVersionNumber()); 2148 } 2149 newDelegationMember.setMemberId(memberId); 2150 newDelegationMember.setDelegationId(delegation.getDelegationId()); 2151 newDelegationMember.setRoleMemberId(roleMemberId); 2152 newDelegationMember.setTypeCode(memberTypeCode); 2153 if (activeFromDate != null) { 2154 newDelegationMember.setActiveFromDateValue(new java.sql.Timestamp(activeFromDate.getMillis())); 2155 } 2156 if (activeToDate != null) { 2157 newDelegationMember.setActiveToDateValue(new java.sql.Timestamp(activeToDate.getMillis())); 2158 } 2159 2160 // build role member attribute objects from the given Map<String, String> 2161 addDelegationMemberAttributeData( newDelegationMember, qualifications, role.getKimTypeId() ); 2162 2163 List<DelegateMemberBo> delegationMembers = new ArrayList<DelegateMemberBo>(); 2164 delegationMembers.add(newDelegationMember); 2165 delegation.setMembers(delegationMembers); 2166 2167 getBusinessObjectService().save(delegation); 2168 for(DelegateMemberBo delegationMember: delegation.getMembers()){ 2169 deleteNullDelegationMemberAttributeData(delegationMember.getAttributes()); 2170 }*/ 2171 } 2172 2173 @Override 2174 public DelegateType updateDelegateType(DelegateType delegateType) throws RiceIllegalArgumentException, RiceIllegalStateException { 2175 incomingParamCheck(delegateType, "delegateType"); 2176 2177 if (StringUtils.isBlank(delegateType.getDelegationId()) 2178 || getDelegateTypeByDelegationId(delegateType.getDelegationId()) == null) { 2179 throw new RiceIllegalStateException("the delegateType to update does not exist: " + delegateType); 2180 } 2181 2182 DelegateTypeBo bo = DelegateTypeBo.from(delegateType); 2183 return DelegateTypeBo.to(getBusinessObjectService().save(bo)); 2184 } 2185 2186 2187 private void removeRoleMembers(List<RoleMemberBo> members) { 2188 if(CollectionUtils.isNotEmpty(members)) { 2189 for ( RoleMemberBo rm : members ) { 2190 getResponsibilityInternalService().removeRoleMember(rm); 2191 } 2192 } 2193 } 2194 2195 2196 private List<RoleMemberBo> getRoleMembersByDefaultStrategy(String roleId, String memberId, String memberTypeCode, Map<String, String> qualifier) { 2197 List<RoleMemberBo> rms = new ArrayList<RoleMemberBo>(); 2198 List<RoleMemberBo> roleMem= getRoleDao().getRoleMembershipsForMemberId(memberTypeCode,memberId,qualifier); 2199 for ( RoleMemberBo rm : roleMem ) { 2200 if ( rm.getRoleId().equals(roleId) ) { 2201 // if found, remove 2202 rms.add(rm); 2203 } 2204 } 2205 return rms; 2206 } 2207 2208 @Override 2209 public void removePrincipalFromRole(String principalId, 2210 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalArgumentException { 2211 if (StringUtils.isBlank(principalId)) { 2212 throw new RiceIllegalArgumentException("principalId is null"); 2213 } 2214 2215 if (StringUtils.isBlank(namespaceCode)) { 2216 throw new RiceIllegalArgumentException("namespaceCode is null"); 2217 } 2218 2219 if (StringUtils.isBlank(roleName)) { 2220 throw new RiceIllegalArgumentException("roleName is null"); 2221 } 2222 2223 if (qualifier == null) { 2224 throw new RiceIllegalArgumentException("qualifier is null"); 2225 } 2226 // look up the role 2227 RoleBoLite role = getRoleBoLiteByName(namespaceCode, roleName); 2228 // pull all the principal members 2229 // look for an exact qualifier match 2230 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(role, principalId, memberTypeToRoleDaoActionMap.get(MemberType.PRINCIPAL.getCode()), qualifier); 2231 if(CollectionUtils.isEmpty(rms)) { 2232 rms = getRoleMembersByDefaultStrategy(role.getId(), principalId, MemberType.PRINCIPAL.getCode(), qualifier); 2233 } 2234 removeRoleMembers(rms); 2235 } 2236 2237 @Override 2238 public void removeGroupFromRole(String groupId, 2239 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalArgumentException { 2240 if (StringUtils.isBlank(groupId)) { 2241 throw new RiceIllegalArgumentException("groupId is null"); 2242 } 2243 2244 if (StringUtils.isBlank(namespaceCode)) { 2245 throw new RiceIllegalArgumentException("namespaceCode is null"); 2246 } 2247 2248 if (StringUtils.isBlank(roleName)) { 2249 throw new RiceIllegalArgumentException("roleName is null"); 2250 } 2251 2252 if (qualifier == null) { 2253 throw new RiceIllegalArgumentException("qualifier is null"); 2254 } 2255 2256 // look up the roleBo 2257 RoleBoLite roleBo = getRoleBoLiteByName(namespaceCode, roleName); 2258 // pull all the group roleBo members 2259 // look for an exact qualifier match 2260 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(roleBo, groupId, memberTypeToRoleDaoActionMap.get(MemberType.GROUP.getCode()), qualifier); 2261 if(CollectionUtils.isEmpty(rms)) { 2262 rms = getRoleMembersByDefaultStrategy(roleBo.getId(), groupId, MemberType.GROUP.getCode(), qualifier); 2263 } 2264 removeRoleMembers(rms); 2265 } 2266 2267 @Override 2268 public void removeRoleFromRole(String roleId, 2269 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalArgumentException { 2270 incomingParamCheck(roleId, "roleId"); 2271 incomingParamCheck(namespaceCode, "namespaceCode"); 2272 incomingParamCheck(roleName, "roleName"); 2273 incomingParamCheck(qualifier, "qualifier"); 2274 2275 2276 // look up the role 2277 RoleBoLite role = getRoleBoLiteByName(namespaceCode, roleName); 2278 // pull all the group role members 2279 // look for an exact qualifier match 2280 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(role, roleId, memberTypeToRoleDaoActionMap.get(MemberType.ROLE.getCode()), qualifier); 2281 if(CollectionUtils.isEmpty(rms)) { 2282 rms = getRoleMembersByDefaultStrategy(role.getId(), roleId, MemberType.ROLE.getCode(), qualifier); 2283 } 2284 removeRoleMembers(rms); 2285 } 2286 2287 @Override 2288 public void assignPermissionToRole(String permissionId, String roleId) throws RiceIllegalArgumentException { 2289 incomingParamCheck(permissionId, "permissionId"); 2290 incomingParamCheck(roleId, "roleId"); 2291 2292 RolePermissionBo newRolePermission = new RolePermissionBo(); 2293 2294 Long nextSeq = KRADServiceLocator.getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S, RolePermissionBo.class); 2295 2296 if (nextSeq == null) { 2297 LOG.error("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S); 2298 throw new RuntimeException("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S); 2299 } 2300 2301 newRolePermission.setId(nextSeq.toString()); 2302 newRolePermission.setRoleId(roleId); 2303 newRolePermission.setPermissionId(permissionId); 2304 newRolePermission.setActive(true); 2305 2306 getBusinessObjectService().save(newRolePermission); 2307 } 2308 2309 @Override 2310 public void revokePermissionFromRole(String permissionId, String roleId) throws RiceIllegalArgumentException { 2311 incomingParamCheck(permissionId, "permissionId"); 2312 incomingParamCheck(roleId, "roleId"); 2313 2314 Map<String, Object> params = new HashMap<String, Object>(); 2315 params.put("roleId", roleId); 2316 params.put("permissionId", permissionId); 2317 params.put("active", Boolean.TRUE); 2318 Collection<RolePermissionBo> rolePermissionBos = getBusinessObjectService().findMatching(RolePermissionBo.class, params); 2319 List<RolePermissionBo> rolePermsToSave = new ArrayList<RolePermissionBo>(); 2320 for (RolePermissionBo rolePerm : rolePermissionBos) { 2321 rolePerm.setActive(false); 2322 rolePermsToSave.add(rolePerm); 2323 } 2324 2325 getBusinessObjectService().save(rolePermsToSave); 2326 } 2327 2328 protected void addMemberAttributeData(RoleMemberBo roleMember, Map<String, String> qualifier, String kimTypeId) { 2329 List<RoleMemberAttributeDataBo> attributes = new ArrayList<RoleMemberAttributeDataBo>(); 2330 for (Map.Entry<String, String> entry : qualifier.entrySet()) { 2331 RoleMemberAttributeDataBo roleMemberAttrBo = new RoleMemberAttributeDataBo(); 2332 roleMemberAttrBo.setAttributeValue(entry.getValue()); 2333 roleMemberAttrBo.setKimTypeId(kimTypeId); 2334 roleMemberAttrBo.setAssignedToId(roleMember.getId()); 2335 // look up the attribute ID 2336 roleMemberAttrBo.setKimAttributeId(getKimAttributeId(entry.getKey())); 2337 2338 Map<String, String> criteria = new HashMap<String, String>(); 2339 criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, roleMemberAttrBo.getKimAttributeId()); 2340 //criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMember.getId()); 2341 criteria.put("assignedToId", roleMember.getId()); 2342 List<RoleMemberAttributeDataBo> origRoleMemberAttributes = 2343 (List<RoleMemberAttributeDataBo>) getBusinessObjectService().findMatching(RoleMemberAttributeDataBo.class, criteria); 2344 RoleMemberAttributeDataBo origRoleMemberAttribute = 2345 (origRoleMemberAttributes != null && !origRoleMemberAttributes.isEmpty()) ? origRoleMemberAttributes.get(0) : null; 2346 if (origRoleMemberAttribute != null) { 2347 roleMemberAttrBo.setId(origRoleMemberAttribute.getId()); 2348 roleMemberAttrBo.setVersionNumber(origRoleMemberAttribute.getVersionNumber()); 2349 } 2350 attributes.add(roleMemberAttrBo); 2351 } 2352 roleMember.setAttributeDetails(attributes); 2353 } 2354 2355 protected void addDelegationMemberAttributeData( DelegateMemberBo delegationMember, Map<String, String> qualifier, String kimTypeId ) { 2356 List<DelegateMemberAttributeDataBo> attributes = new ArrayList<DelegateMemberAttributeDataBo>(); 2357 for ( Map.Entry<String, String> entry : qualifier.entrySet() ) { 2358 DelegateMemberAttributeDataBo delegateMemberAttrBo = new DelegateMemberAttributeDataBo(); 2359 delegateMemberAttrBo.setAttributeValue(entry.getValue()); 2360 delegateMemberAttrBo.setKimTypeId(kimTypeId); 2361 delegateMemberAttrBo.setAssignedToId(delegationMember.getDelegationMemberId()); 2362 // look up the attribute ID 2363 delegateMemberAttrBo.setKimAttributeId(getKimAttributeId(entry.getKey())); 2364 Map<String, String> criteria = new HashMap<String, String>(); 2365 criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, delegateMemberAttrBo.getKimAttributeId()); 2366 criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMember.getDelegationMemberId()); 2367 List<DelegateMemberAttributeDataBo> origDelegationMemberAttributes = 2368 (List<DelegateMemberAttributeDataBo>)getBusinessObjectService().findMatching(DelegateMemberAttributeDataBo.class, criteria); 2369 DelegateMemberAttributeDataBo origDelegationMemberAttribute = 2370 (origDelegationMemberAttributes!=null && !origDelegationMemberAttributes.isEmpty()) ? origDelegationMemberAttributes.get(0) : null; 2371 if(origDelegationMemberAttribute!=null){ 2372 delegateMemberAttrBo.setId(origDelegationMemberAttribute.getId()); 2373 delegateMemberAttrBo.setVersionNumber(origDelegationMemberAttribute.getVersionNumber()); 2374 } 2375 attributes.add( delegateMemberAttrBo ); 2376 } 2377 delegationMember.setAttributeDetails( attributes ); 2378 } 2379 2380 2381 2382 // -------------------- 2383 // Persistence Methods 2384 // -------------------- 2385 2386 private void deleteNullMemberAttributeData(List<RoleMemberAttributeDataBo> attributes) { 2387 List<RoleMemberAttributeDataBo> attributesToDelete = new ArrayList<RoleMemberAttributeDataBo>(); 2388 for(RoleMemberAttributeDataBo attribute: attributes){ 2389 if(attribute.getAttributeValue()==null){ 2390 attributesToDelete.add(attribute); 2391 } 2392 } 2393 getBusinessObjectService().delete(attributesToDelete); 2394 } 2395 2396 private void deleteNullDelegationMemberAttributeData(List<DelegateMemberAttributeDataBo> attributes) { 2397 List<DelegateMemberAttributeDataBo> attributesToDelete = new ArrayList<DelegateMemberAttributeDataBo>(); 2398 2399 for(DelegateMemberAttributeDataBo attribute: attributes){ 2400 if(attribute.getAttributeValue()==null){ 2401 attributesToDelete.add(attribute); 2402 } 2403 } 2404 getBusinessObjectService().delete(attributesToDelete); 2405 } 2406 2407 protected void logPrincipalHasRoleCheck(String principalId, List<String> roleIds, Map<String, String> roleQualifiers ) { 2408 StringBuilder sb = new StringBuilder(); 2409 sb.append( '\n' ); 2410 sb.append( "Has Role : " ).append( roleIds ).append( '\n' ); 2411 if ( roleIds != null ) { 2412 for ( String roleId : roleIds ) { 2413 Role role = getRole( roleId ); 2414 if ( role != null ) { 2415 sb.append( " Name : " ).append( role.getNamespaceCode() ).append( '/').append( role.getName() ); 2416 sb.append( " (" ).append( roleId ).append( ')' ); 2417 sb.append( '\n' ); 2418 } 2419 } 2420 } 2421 sb.append( " Principal : " ).append( principalId ); 2422 if ( principalId != null ) { 2423 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId); 2424 if ( principal != null ) { 2425 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' ); 2426 } 2427 } 2428 sb.append( '\n' ); 2429 sb.append( " Details :\n" ); 2430 if ( roleQualifiers != null ) { 2431 sb.append( roleQualifiers ); 2432 } else { 2433 sb.append( " [null]\n" ); 2434 } 2435 if (LOG.isTraceEnabled()) { 2436 LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable()))); 2437 } else { 2438 LOG.debug(sb.toString()); 2439 } 2440 } 2441 2442 private void incomingParamCheck(Object object, String name) { 2443 if (object == null) { 2444 throw new RiceIllegalArgumentException(name + " was null"); 2445 } else if (object instanceof String 2446 && StringUtils.isBlank((String) object)) { 2447 throw new RiceIllegalArgumentException(name + " was blank"); 2448 } 2449 } 2450 2451 /** 2452 * This gets the proxied version of the role service which will go through 2453 * Spring's caching mechanism for method calls rather than skipping it when 2454 * methods are called directly. 2455 * 2456 * @return The proxied role service 2457 */ 2458 protected RoleService getProxiedRoleService() { 2459 if(this.proxiedRoleService == null) { 2460 this.proxiedRoleService = KimApiServiceLocator.getRoleService(); 2461 } 2462 return this.proxiedRoleService; 2463 } 2464 2465 /** 2466 * Sets the cache manager which this service implementation can for internal caching. 2467 * Calling this setter is optional, though the value passed to it must not be null. 2468 * 2469 * @param cacheManager the cache manager to use for internal caching, must not be null 2470 * @throws IllegalArgumentException if a null cache manager is passed 2471 */ 2472 public void setCacheManager(CacheManager cacheManager) { 2473 if (cacheManager == null) { 2474 throw new IllegalArgumentException("cacheManager must not be null"); 2475 } 2476 this.cacheManager = cacheManager; 2477 } 2478}