001 /** 002 * Copyright 2005-2011 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 */ 016 package org.kuali.rice.kim.impl.role; 017 018 import org.apache.commons.collections.CollectionUtils; 019 import org.apache.commons.lang.StringUtils; 020 import org.apache.log4j.Logger; 021 import org.joda.time.DateTime; 022 import org.kuali.rice.core.api.criteria.GenericQueryResults; 023 import org.kuali.rice.core.api.criteria.QueryByCriteria; 024 import org.kuali.rice.core.api.delegation.DelegationType; 025 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 026 import org.kuali.rice.core.api.exception.RiceIllegalStateException; 027 import org.kuali.rice.core.api.membership.MemberType; 028 import org.kuali.rice.core.api.mo.ModelObjectUtils; 029 import org.kuali.rice.kim.api.KimConstants; 030 import org.kuali.rice.kim.api.common.delegate.DelegateMember; 031 import org.kuali.rice.kim.api.common.delegate.DelegateType; 032 import org.kuali.rice.kim.api.role.DelegateMemberQueryResults; 033 import org.kuali.rice.kim.api.role.Role; 034 import org.kuali.rice.kim.api.role.RoleMember; 035 import org.kuali.rice.kim.api.role.RoleMemberQueryResults; 036 import org.kuali.rice.kim.api.role.RoleMembership; 037 import org.kuali.rice.kim.api.role.RoleMembershipQueryResults; 038 import org.kuali.rice.kim.api.role.RoleQueryResults; 039 import org.kuali.rice.kim.api.role.RoleResponsibility; 040 import org.kuali.rice.kim.api.role.RoleResponsibilityAction; 041 import org.kuali.rice.kim.api.role.RoleService; 042 import org.kuali.rice.kim.api.services.KimApiServiceLocator; 043 import org.kuali.rice.kim.api.type.KimType; 044 import org.kuali.rice.kim.framework.common.delegate.DelegationTypeService; 045 import org.kuali.rice.kim.framework.role.RoleTypeService; 046 import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator; 047 import org.kuali.rice.kim.framework.type.KimTypeService; 048 import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo; 049 import org.kuali.rice.kim.impl.common.delegate.DelegateMemberAttributeDataBo; 050 import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo; 051 import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo; 052 import org.kuali.rice.kim.impl.services.KimImplServiceLocator; 053 import org.kuali.rice.krad.service.KRADServiceLocator; 054 import org.springframework.util.LinkedMultiValueMap; 055 import org.springframework.util.MultiValueMap; 056 057 import javax.jws.WebParam; 058 import java.sql.Timestamp; 059 import java.util.ArrayList; 060 import java.util.Collection; 061 import java.util.Collections; 062 import java.util.Date; 063 import java.util.HashMap; 064 import java.util.HashSet; 065 import java.util.List; 066 import java.util.Map; 067 import java.util.Set; 068 069 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 070 071 public class RoleServiceImpl extends RoleServiceBase implements RoleService { 072 private static final Logger LOG = Logger.getLogger(RoleServiceImpl.class); 073 074 private static final Map<String, RoleDaoAction> memberTypeToRoleDaoActionMap = populateMemberTypeToRoleDaoActionMap(); 075 076 private static Map<String, RoleDaoAction> populateMemberTypeToRoleDaoActionMap() { 077 Map<String, RoleDaoAction> map = new HashMap<String, RoleDaoAction>(); 078 map.put(MemberType.GROUP.getCode(), RoleDaoAction.ROLE_GROUPS_FOR_GROUP_IDS_AND_ROLE_IDS); 079 map.put(MemberType.PRINCIPAL.getCode(), RoleDaoAction.ROLE_PRINCIPALS_FOR_PRINCIPAL_ID_AND_ROLE_IDS); 080 map.put(MemberType.ROLE.getCode(), RoleDaoAction.ROLE_MEMBERSHIPS_FOR_ROLE_IDS_AS_MEMBERS); 081 return Collections.unmodifiableMap(map); 082 } 083 084 085 @Override 086 public Role createRole(final Role role) throws RiceIllegalArgumentException, RiceIllegalStateException { 087 incomingParamCheck(role, "role"); 088 089 if (StringUtils.isNotBlank(role.getId()) && getRole(role.getId()) != null) { 090 throw new RiceIllegalStateException("the role to create already exists: " + role); 091 } 092 RoleBo bo = RoleBo.from(role); 093 return RoleBo.to(getBusinessObjectService().save(bo)); 094 } 095 096 @Override 097 public Role updateRole(final Role role) throws RiceIllegalArgumentException, RiceIllegalStateException { 098 incomingParamCheck(role, "role"); 099 100 RoleBo originalRole = getRoleBo(role.getId()); 101 if (StringUtils.isBlank(role.getId()) || originalRole == null) { 102 throw new RiceIllegalStateException("the role does not exist: " + role); 103 } 104 105 RoleBo bo = RoleBo.from(role); 106 107 RoleBo updatedRole = getBusinessObjectService().save(bo); 108 if (originalRole.isActive() 109 && !updatedRole.isActive()) { 110 KimImplServiceLocator.getRoleInternalService().roleInactivated(updatedRole.getId()); 111 } 112 return RoleBo.to(updatedRole); 113 } 114 115 /** 116 * This method tests to see if assigning a roleBo to another roleBo will create a circular reference. 117 * The Role is checked to see if it is a member (direct or nested) of the roleBo to be assigned as a member. 118 * 119 * @param newMemberId 120 * @param roleBo 121 * @return true - assignment is allowed, no circular reference will be created. 122 * false - illegal assignment, it will create a circular membership 123 */ 124 protected boolean checkForCircularRoleMembership(String newMemberId, RoleBo roleBo) { 125 // get all nested roleBo members that are of type roleBo 126 Set<String> newRoleMemberIds = getRoleTypeRoleMemberIds(newMemberId); 127 return !newRoleMemberIds.contains(roleBo.getId()); 128 } 129 130 protected RoleMember findRoleMember(String roleMemberId) { 131 final List<RoleMember> roleMembers = findRoleMembers(QueryByCriteria.Builder.fromPredicates(equal(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId))).getResults(); 132 if (roleMembers != null && !roleMembers.isEmpty()) { 133 return roleMembers.get(0); 134 } 135 return null; 136 } 137 138 @Override 139 public RoleMemberQueryResults findRoleMembers(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 140 incomingParamCheck(queryByCriteria, "queryByCriteria"); 141 142 GenericQueryResults<RoleMemberBo> results = getCriteriaLookupService().lookup(RoleMemberBo.class, queryByCriteria); 143 144 RoleMemberQueryResults.Builder builder = RoleMemberQueryResults.Builder.create(); 145 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 146 builder.setTotalRowCount(results.getTotalRowCount()); 147 148 final List<RoleMember.Builder> ims = new ArrayList<RoleMember.Builder>(); 149 for (RoleMemberBo bo : results.getResults()) { 150 ims.add(RoleMember.Builder.create(bo)); 151 } 152 153 builder.setResults(ims); 154 return builder.build(); 155 } 156 157 @Override 158 public Set<String> getRoleTypeRoleMemberIds(String roleId) throws RiceIllegalStateException { 159 incomingParamCheck(roleId, "roleId"); 160 161 Set<String> results = new HashSet<String>(); 162 getNestedRoleTypeMemberIds(roleId, results); 163 return Collections.unmodifiableSet(results); 164 } 165 166 @Override 167 public List<String> getMemberParentRoleIds(String memberType, String memberId) throws RiceIllegalStateException { 168 incomingParamCheck(memberType, "memberType"); 169 incomingParamCheck(memberId, "memberId"); 170 171 List<RoleMemberBo> parentRoleMembers = getRoleDao().getRoleMembershipsForMemberId(memberType, memberId, 172 Collections.<String, String>emptyMap()); 173 174 List<String> parentRoleIds = new ArrayList<String>(parentRoleMembers.size()); 175 for (RoleMemberBo parentRoleMember : parentRoleMembers) { 176 parentRoleIds.add(parentRoleMember.getRoleId()); 177 } 178 179 return parentRoleIds; 180 } 181 182 @Override 183 public List<RoleResponsibilityAction> getRoleMemberResponsibilityActions(String roleMemberId) throws RiceIllegalStateException { 184 incomingParamCheck(roleMemberId, "roleMemberId"); 185 186 Map<String, String> criteria = new HashMap<String, String>(1); 187 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMemberId); 188 189 List<RoleResponsibilityActionBo> responsibilityActionBoList = (List<RoleResponsibilityActionBo>) 190 getBusinessObjectService().findMatching(RoleResponsibilityActionBo.class, criteria); 191 192 List<RoleResponsibilityAction> roleResponsibilityActionsList = new ArrayList<RoleResponsibilityAction>(); 193 for (RoleResponsibilityActionBo roleResponsibilityActionBo : responsibilityActionBoList) { 194 RoleResponsibilityAction roleResponsibility = RoleResponsibilityActionBo.to(roleResponsibilityActionBo); 195 roleResponsibilityActionsList.add(roleResponsibility); 196 } 197 return roleResponsibilityActionsList; 198 } 199 200 @Override 201 public DelegateMemberQueryResults findDelegateMembers(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 202 incomingParamCheck(queryByCriteria, "queryByCriteria"); 203 204 GenericQueryResults<DelegateMemberBo> results = getCriteriaLookupService().lookup(DelegateMemberBo.class, queryByCriteria); 205 206 DelegateMemberQueryResults.Builder builder = DelegateMemberQueryResults.Builder.create(); 207 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 208 builder.setTotalRowCount(results.getTotalRowCount()); 209 210 final List<DelegateMember.Builder> ims = new ArrayList<DelegateMember.Builder>(); 211 for (DelegateMemberBo bo : results.getResults()) { 212 ims.add(DelegateMember.Builder.create(bo)); 213 } 214 215 builder.setResults(ims); 216 return builder.build(); 217 } 218 219 @Override 220 public Role getRole(String roleId) throws RiceIllegalStateException { 221 incomingParamCheck(roleId, "rpleId"); 222 223 RoleBo roleBo = getRoleBo(roleId); 224 if (roleBo == null) { 225 return null; 226 } 227 return RoleBo.to(roleBo); 228 } 229 230 protected Map<String, RoleBo> getRoleBoMap(Collection<String> roleIds) { 231 Map<String, RoleBo> result; 232 // check for a non-null result in the cache, return it if found 233 if (roleIds.size() == 1) { 234 String roleId = roleIds.iterator().next(); 235 RoleBo bo = getRoleBo(roleId); 236 result = bo.isActive() ? Collections.singletonMap(roleId, bo) : Collections.<String, RoleBo>emptyMap(); 237 } else { 238 result = new HashMap<String, RoleBo>(roleIds.size()); 239 for (String roleId : roleIds) { 240 RoleBo bo = getRoleBo(roleId); 241 if (bo.isActive()) { 242 result.put(roleId, bo); 243 } 244 } 245 } 246 return result; 247 } 248 249 @Override 250 public List<Role> getRoles(List<String> roleIds) throws RiceIllegalStateException { 251 if (CollectionUtils.isEmpty(roleIds)) { 252 throw new RiceIllegalArgumentException("roleIds is null or empty"); 253 } 254 255 Collection<RoleBo> roleBos = getRoleBoMap(roleIds).values(); 256 List<Role> roles = new ArrayList<Role>(roleBos.size()); 257 for (RoleBo bo : roleBos) { 258 roles.add(RoleBo.to(bo)); 259 } 260 return Collections.unmodifiableList(roles); 261 } 262 263 @Override 264 public Role getRoleByNameAndNamespaceCode(String namespaceCode, String roleName) throws RiceIllegalStateException { 265 incomingParamCheck(namespaceCode, "namespaceCode"); 266 incomingParamCheck(roleName, "roleName"); 267 268 RoleBo roleBo = getRoleBoByName(namespaceCode, roleName); 269 if (roleBo != null) { 270 return RoleBo.to(roleBo); 271 } 272 return null; 273 } 274 275 @Override 276 public String getRoleIdByNameAndNamespaceCode(String namespaceCode, String roleName) throws RiceIllegalStateException { 277 incomingParamCheck(namespaceCode, "namespaceCode"); 278 incomingParamCheck(roleName, "roleName"); 279 280 Role role = getRoleByNameAndNamespaceCode(namespaceCode, roleName); 281 if (role != null) { 282 return role.getId(); 283 } else { 284 return null; 285 } 286 } 287 288 @Override 289 public boolean isRoleActive(String roleId) throws RiceIllegalStateException { 290 incomingParamCheck(roleId, "roleId"); 291 292 RoleBo roleBo = getRoleBo(roleId); 293 return roleBo != null && roleBo.isActive(); 294 } 295 296 @Override 297 public List<Map<String, String>> getRoleQualifersForPrincipalByRoleIds(String principalId, List<String> roleIds, 298 Map<String, String> qualification) throws RiceIllegalStateException { 299 incomingParamCheck(principalId, "principalId"); 300 incomingParamCheck(roleIds, "roleIds"); 301 incomingParamCheck(qualification, "qualification"); 302 303 List<Map<String, String>> results = new ArrayList<Map<String, String>>(); 304 305 List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersUsingExactMatchOnQualification(principalId, null, 306 roleIds, qualification); 307 308 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 309 for (RoleMemberBo roleMemberBo : roleMemberBoList) { 310 // gather up the qualifier sets and the service they go with 311 if (MemberType.PRINCIPAL.equals(roleMemberBo.getMemberType())) { 312 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 313 if (roleTypeService != null) { 314 List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId()); 315 if (las == null) { 316 las = new ArrayList<RoleMembership>(); 317 roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las); 318 } 319 RoleMembership mi = RoleMembership.Builder.create( 320 roleMemberBo.getRoleId(), 321 roleMemberBo.getRoleMemberId(), 322 roleMemberBo.getMemberId(), 323 roleMemberBo.getMemberType(), 324 roleMemberBo.getAttributes()).build(); 325 326 las.add(mi); 327 } else { 328 results.add(roleMemberBo.getAttributes()); 329 } 330 } 331 } 332 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 333 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 334 //it is possible that the the roleTypeService is coming from a remote application 335 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 336 try { 337 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue()); 338 for (RoleMembership rmi : matchingMembers) { 339 results.add(rmi.getQualifier()); 340 } 341 } catch (Exception ex) { 342 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 343 } 344 } 345 return Collections.unmodifiableList(results); 346 } 347 348 @Override 349 public List<Map<String, String>> getRoleQualifersForPrincipalByNamespaceAndRolename(String principalId, 350 String namespaceCode, String roleName, Map<String, String> qualification) 351 throws RiceIllegalStateException { 352 incomingParamCheck(principalId, "principalId"); 353 incomingParamCheck(namespaceCode, "namespaceCode"); 354 incomingParamCheck(roleName, "roleName"); 355 incomingParamCheck(qualification, "qualification"); 356 357 String roleId = getRoleIdByNameAndNamespaceCode(namespaceCode, roleName); 358 if (roleId == null) { 359 return Collections.emptyList(); 360 } 361 return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId), 362 qualification); 363 } 364 365 @Override 366 public List<Map<String, String>> getNestedRoleQualifersForPrincipalByNamespaceAndRolename(String principalId, 367 String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 368 incomingParamCheck(principalId, "principalId"); 369 incomingParamCheck(namespaceCode, "namespaceCode"); 370 incomingParamCheck(roleName, "roleName"); 371 incomingParamCheck(qualification, "qualification"); 372 373 String roleId = getRoleIdByNameAndNamespaceCode(namespaceCode, roleName); 374 if (roleId == null) { 375 return new ArrayList<Map<String, String>>(0); 376 } 377 return getNestedRoleQualifiersForPrincipalByRoleIds(principalId, Collections.singletonList(roleId), 378 qualification); 379 } 380 381 @Override 382 public List<Map<String, String>> getNestedRoleQualifiersForPrincipalByRoleIds(String principalId, 383 List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 384 incomingParamCheck(principalId, "principalId"); 385 incomingParamCheck(roleIds, "roleIds"); 386 incomingParamCheck(qualification, "qualification"); 387 388 389 List<Map<String, String>> results = new ArrayList<Map<String, String>>(); 390 391 Map<String, RoleBo> roleBosById = getRoleBoMap(roleIds); 392 393 // get the person's groups 394 List<String> groupIds = getGroupService().getGroupIdsByPrincipalId(principalId); 395 List<RoleMemberBo> roleMemberBos = getStoredRoleMembersUsingExactMatchOnQualification(principalId, groupIds, roleIds, qualification); 396 397 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 398 for (RoleMemberBo roleMemberBo : roleMemberBos) { 399 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 400 // gather up the qualifier sets and the service they go with 401 if (MemberType.PRINCIPAL.equals(roleMemberBo.getMemberType()) 402 || MemberType.GROUP.equals(roleMemberBo.getMemberType())) { 403 if (roleTypeService != null) { 404 List<RoleMembership> las = roleIdToMembershipMap.get(roleMemberBo.getRoleId()); 405 if (las == null) { 406 las = new ArrayList<RoleMembership>(); 407 roleIdToMembershipMap.put(roleMemberBo.getRoleId(), las); 408 } 409 RoleMembership mi = RoleMembership.Builder.create( 410 roleMemberBo.getRoleId(), 411 roleMemberBo.getRoleMemberId(), 412 roleMemberBo.getMemberId(), 413 roleMemberBo.getMemberType(), 414 roleMemberBo.getAttributes()).build(); 415 416 las.add(mi); 417 } else { 418 results.add(roleMemberBo.getAttributes()); 419 } 420 } else if (MemberType.ROLE.equals(roleMemberBo.getMemberType())) { 421 // find out if the user has the role 422 // need to convert qualification using this role's service 423 Map<String, String> nestedQualification = qualification; 424 if (roleTypeService != null) { 425 RoleBo roleBo = roleBosById.get(roleMemberBo.getRoleId()); 426 // pulling from here as the nested roleBo is not necessarily (and likely is not) 427 // in the roleBosById Map created earlier 428 RoleBo nestedRole = getRoleBo(roleMemberBo.getMemberId()); 429 //it is possible that the the roleTypeService is coming from a remote application 430 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 431 try { 432 nestedQualification = roleTypeService.convertQualificationForMemberRoles(roleBo.getNamespaceCode(), roleBo.getName(), nestedRole.getNamespaceCode(), nestedRole.getName(), qualification); 433 } catch (Exception ex) { 434 LOG.warn("Not able to retrieve RoleTypeService from remote system for roleBo Id: " + roleBo.getId(), ex); 435 } 436 } 437 List<String> nestedRoleId = new ArrayList<String>(1); 438 nestedRoleId.add(roleMemberBo.getMemberId()); 439 // if the user has the given role, add the qualifier the *nested role* has with the 440 // originally queries role 441 if (principalHasRole(principalId, nestedRoleId, nestedQualification, false)) { 442 results.add(roleMemberBo.getAttributes()); 443 } 444 } 445 } 446 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 447 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 448 //it is possible that the the roleTypeService is coming from a remote application 449 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 450 try { 451 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, 452 entry.getValue()); 453 for (RoleMembership roleMembership : matchingMembers) { 454 results.add(roleMembership.getQualifier()); 455 } 456 } catch (Exception ex) { 457 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 458 } 459 } 460 return Collections.unmodifiableList(results); 461 } 462 463 @Override 464 public List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 465 incomingParamCheck(roleIds, "roleIds"); 466 incomingParamCheck(qualification, "qualification"); 467 468 Set<String> foundRoleTypeMembers = new HashSet<String>(); 469 return getRoleMembers(roleIds, qualification, true, foundRoleTypeMembers); 470 } 471 472 @Override 473 public Collection<String> getRoleMemberPrincipalIds(String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 474 incomingParamCheck(namespaceCode, "namespaceCode"); 475 incomingParamCheck(roleName, "roleName"); 476 incomingParamCheck(qualification, "qualification"); 477 478 Set<String> principalIds = new HashSet<String>(); 479 Set<String> foundRoleTypeMembers = new HashSet<String>(); 480 List<String> roleIds = Collections.singletonList(getRoleIdByNameAndNamespaceCode(namespaceCode, roleName)); 481 for (RoleMembership roleMembership : getRoleMembers(roleIds, qualification, false, foundRoleTypeMembers)) { 482 if (MemberType.GROUP.equals(roleMembership.getMemberType())) { 483 principalIds.addAll(getGroupService().getMemberPrincipalIds(roleMembership.getMemberId())); 484 } else { 485 principalIds.add(roleMembership.getMemberId()); 486 } 487 } 488 return Collections.unmodifiableSet(principalIds); 489 } 490 491 @Override 492 public boolean principalHasRole(String principalId, List<String> roleIds, Map<String, String> qualification) throws RiceIllegalStateException { 493 incomingParamCheck(principalId, "principalId"); 494 incomingParamCheck(roleIds, "roleIds"); 495 incomingParamCheck(qualification, "qualification"); 496 497 return principalHasRole(principalId, roleIds, qualification, true); 498 } 499 500 @Override 501 public List<String> getPrincipalIdSubListWithRole(List<String> principalIds, 502 String roleNamespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalStateException { 503 incomingParamCheck(principalIds, "principalIds"); 504 incomingParamCheck(roleNamespaceCode, "roleNamespaceCode"); 505 incomingParamCheck(roleName, "roleName"); 506 incomingParamCheck(qualification, "qualification"); 507 508 List<String> subList = new ArrayList<String>(); 509 RoleBo role = getRoleBoByName(roleNamespaceCode, roleName); 510 for (String principalId : principalIds) { 511 if (principalHasRole(principalId, Collections.singletonList(role.getId()), qualification)) { 512 subList.add(principalId); 513 } 514 } 515 return Collections.unmodifiableList(subList); 516 } 517 518 @Override 519 public RoleQueryResults findRoles(QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 520 incomingParamCheck(queryByCriteria, "queryByCriteria"); 521 522 GenericQueryResults<RoleBo> results = getCriteriaLookupService().lookup(RoleBo.class, queryByCriteria); 523 524 RoleQueryResults.Builder builder = RoleQueryResults.Builder.create(); 525 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 526 builder.setTotalRowCount(results.getTotalRowCount()); 527 528 final List<Role.Builder> ims = new ArrayList<Role.Builder>(); 529 for (RoleBo bo : results.getResults()) { 530 ims.add(Role.Builder.create(bo)); 531 } 532 533 builder.setResults(ims); 534 return builder.build(); 535 } 536 537 @Override 538 public List<RoleMembership> getFirstLevelRoleMembers(List<String> roleIds) throws RiceIllegalStateException { 539 incomingParamCheck(roleIds, "roleIds"); 540 if (roleIds.isEmpty()) { 541 return Collections.emptyList(); 542 } 543 544 List<RoleMemberBo> roleMemberBoList = getStoredRoleMembersForRoleIds(roleIds, null, null); 545 List<RoleMembership> roleMemberships = new ArrayList<RoleMembership>(); 546 for (RoleMemberBo roleMemberBo : roleMemberBoList) { 547 RoleMembership roleMembeship = RoleMembership.Builder.create( 548 roleMemberBo.getRoleId(), 549 roleMemberBo.getRoleMemberId(), 550 roleMemberBo.getMemberId(), 551 roleMemberBo.getMemberType(), 552 roleMemberBo.getAttributes()).build(); 553 roleMemberships.add(roleMembeship); 554 } 555 return Collections.unmodifiableList(roleMemberships); 556 } 557 558 @Override 559 public RoleMembershipQueryResults findRoleMemberships( QueryByCriteria queryByCriteria) throws RiceIllegalStateException { 560 incomingParamCheck(queryByCriteria, "queryByCriteria"); 561 562 GenericQueryResults<RoleMemberBo> results = getCriteriaLookupService().lookup(RoleMemberBo.class, queryByCriteria); 563 564 RoleMembershipQueryResults.Builder builder = RoleMembershipQueryResults.Builder.create(); 565 builder.setMoreResultsAvailable(results.isMoreResultsAvailable()); 566 builder.setTotalRowCount(results.getTotalRowCount()); 567 568 final List<RoleMembership.Builder> ims = new ArrayList<RoleMembership.Builder>(); 569 for (RoleMemberBo bo : results.getResults()) { 570 RoleMembership.Builder roleMembership = RoleMembership.Builder.create( 571 bo.getRoleId(), 572 bo.getRoleMemberId(), 573 bo.getMemberId(), 574 bo.getMemberType(), 575 bo.getAttributes()); 576 ims.add(roleMembership); 577 } 578 579 builder.setResults(ims); 580 return builder.build(); 581 } 582 583 @Override 584 public List<DelegateMember> getDelegationMembersByDelegationId(String delegationId) throws RiceIllegalStateException { 585 incomingParamCheck(delegationId, "delegationId"); 586 587 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 588 if (delegateBo == null) {return Collections.emptyList();} 589 590 return getDelegateMembersForDelegation(delegateBo); 591 } 592 593 @Override 594 public DelegateMember getDelegationMemberByDelegationAndMemberId(String delegationId, String memberId) throws RiceIllegalStateException { 595 incomingParamCheck(delegationId, "delegationId"); 596 incomingParamCheck(memberId, "memberId"); 597 598 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 599 DelegateMemberBo delegationMember = getKimDelegationMemberImplByDelegationAndId(delegationId, memberId); 600 601 return getDelegateCompleteInfo(delegateBo, delegationMember); 602 } 603 604 @Override 605 public DelegateMember getDelegationMemberById(String delegationMemberId) throws RiceIllegalStateException { 606 incomingParamCheck(delegationMemberId, "delegationMemberId"); 607 608 DelegateMemberBo delegateMemberBo = getDelegateMemberBo(delegationMemberId); 609 if (delegateMemberBo == null) { 610 return null; 611 } 612 613 DelegateTypeBo delegateBo = getKimDelegationImpl(delegateMemberBo.getDelegationId()); 614 615 return getDelegateCompleteInfo(delegateBo, delegateMemberBo); 616 } 617 618 @Override 619 public List<RoleResponsibility> getRoleResponsibilities(String roleId) throws RiceIllegalStateException { 620 incomingParamCheck(roleId, "roleId"); 621 622 Map<String, String> criteria = new HashMap<String, String>(1); 623 criteria.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId); 624 List<RoleResponsibilityBo> roleResponsibilityBos = (List<RoleResponsibilityBo>) 625 getBusinessObjectService().findMatching(RoleResponsibilityBo.class, criteria); 626 List<RoleResponsibility> roleResponsibilities = new ArrayList<RoleResponsibility>(); 627 628 for (RoleResponsibilityBo roleResponsibilityImpl : roleResponsibilityBos) { 629 roleResponsibilities.add(RoleResponsibilityBo.to(roleResponsibilityImpl)); 630 } 631 return Collections.unmodifiableList(roleResponsibilities); 632 } 633 634 @Override 635 public DelegateType getDelegateTypeByRoleIdAndDelegateTypeCode(String roleId, DelegationType delegationType) throws RiceIllegalStateException { 636 incomingParamCheck(roleId, "roleId"); 637 incomingParamCheck(delegationType, "delegationType"); 638 639 DelegateTypeBo delegateBo = getDelegationOfType(roleId, delegationType); 640 return DelegateTypeBo.to(delegateBo); 641 } 642 643 @Override 644 public DelegateType getDelegateTypeByDelegationId(String delegationId) throws RiceIllegalStateException { 645 incomingParamCheck(delegationId, "delegationId"); 646 647 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 648 return DelegateTypeBo.to(delegateBo); 649 } 650 651 protected List<RoleMembership> getRoleMembers(List<String> roleIds, Map<String, String> qualification, boolean followDelegations, Set<String> foundRoleTypeMembers) { 652 List<RoleMembership> results = new ArrayList<RoleMembership>(); 653 Set<String> allRoleIds = new HashSet<String>(); 654 for (String roleId : roleIds) { 655 if (isRoleActive(roleId)) { 656 allRoleIds.add(roleId); 657 } 658 } 659 // short-circuit if no roles match 660 if (allRoleIds.isEmpty()) { 661 return Collections.emptyList(); 662 } 663 Set<String> matchingRoleIds = new HashSet<String>(allRoleIds.size()); 664 // for efficiency, retrieve all roles and store in a map 665 Map<String, RoleBo> roles = getRoleBoMap(allRoleIds); 666 667 List<String> copyRoleIds = new ArrayList<String>(allRoleIds); 668 List<RoleMemberBo> rms = new ArrayList<RoleMemberBo>(); 669 670 for (String roleId : allRoleIds) { 671 RoleTypeService roleTypeService = getRoleTypeService(roleId); 672 if (roleTypeService != null) { 673 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 674 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 675 copyRoleIds.remove(roleId); 676 rms.addAll(getStoredRoleMembersForRoleIds(Collections.singletonList(roleId), null, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 677 } 678 } 679 } 680 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 681 rms.addAll(getStoredRoleMembersForRoleIds(copyRoleIds, null, null)); 682 } 683 684 // build a map of role ID to membership information 685 // this will be used for later qualification checks 686 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 687 for (RoleMemberBo roleMemberBo : rms) { 688 RoleMembership mi = RoleMembership.Builder.create( 689 roleMemberBo.getRoleId(), 690 roleMemberBo.getRoleMemberId(), 691 roleMemberBo.getMemberId(), 692 roleMemberBo.getMemberType(), 693 roleMemberBo.getAttributes()).build(); 694 695 // if the qualification check does not need to be made, just add the result 696 if ((qualification == null || qualification.isEmpty()) || getRoleTypeService(roleMemberBo.getRoleId()) == null) { 697 if (MemberType.ROLE.equals(roleMemberBo.getMemberType())) { 698 // if a role member type, do a non-recursive role member check 699 // to obtain the group and principal members of that role 700 // given the qualification 701 Map<String, String> nestedRoleQualification = qualification; 702 if (getRoleTypeService(roleMemberBo.getRoleId()) != null) { 703 // get the member role object 704 RoleBo memberRole = getRoleBo(mi.getMemberId()); 705 nestedRoleQualification = getRoleTypeService(roleMemberBo.getRoleId()) 706 .convertQualificationForMemberRoles( 707 roles.get(roleMemberBo.getRoleId()).getNamespaceCode(), 708 roles.get(roleMemberBo.getRoleId()).getName(), 709 memberRole.getNamespaceCode(), 710 memberRole.getName(), 711 qualification); 712 } 713 if (isRoleActive(roleMemberBo.getRoleId())) { 714 Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, mi, foundRoleTypeMembers); 715 if (!nestedRoleMembers.isEmpty()) { 716 results.addAll(nestedRoleMembers); 717 matchingRoleIds.add(roleMemberBo.getRoleId()); 718 } 719 } 720 } else { // not a role member type 721 results.add(mi); 722 matchingRoleIds.add(roleMemberBo.getRoleId()); 723 } 724 matchingRoleIds.add(roleMemberBo.getRoleId()); 725 } else { 726 List<RoleMembership> lrmi = roleIdToMembershipMap.get(mi.getRoleId()); 727 if (lrmi == null) { 728 lrmi = new ArrayList<RoleMembership>(); 729 roleIdToMembershipMap.put(mi.getRoleId(), lrmi); 730 } 731 lrmi.add(mi); 732 } 733 } 734 // if there is anything in the role to membership map, we need to check the role type services 735 // for those entries 736 if (!roleIdToMembershipMap.isEmpty()) { 737 // for each role, send in all the qualifiers for that role to the type service 738 // for evaluation, the service will return those which match 739 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 740 //it is possible that the the roleTypeService is coming from a remote application 741 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 742 try { 743 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 744 List<RoleMembership> matchingMembers = roleTypeService.getMatchingRoleMemberships(qualification, 745 entry.getValue()); 746 // loop over the matching entries, adding them to the results 747 for (RoleMembership roleMemberships : matchingMembers) { 748 if (MemberType.ROLE.equals(roleMemberships.getMemberType())) { 749 // if a role member type, do a non-recursive role member check 750 // to obtain the group and principal members of that role 751 // given the qualification 752 // get the member role object 753 RoleBo memberRole = getRoleBo(roleMemberships.getMemberId()); 754 if (memberRole.isActive()) { 755 Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles( 756 roles.get(roleMemberships.getRoleId()).getNamespaceCode(), 757 roles.get(roleMemberships.getRoleId()).getName(), 758 memberRole.getNamespaceCode(), 759 memberRole.getName(), 760 qualification); 761 Collection<RoleMembership> nestedRoleMembers = getNestedRoleMembers(nestedRoleQualification, roleMemberships, foundRoleTypeMembers); 762 if (!nestedRoleMembers.isEmpty()) { 763 results.addAll(nestedRoleMembers); 764 matchingRoleIds.add(roleMemberships.getRoleId()); 765 } 766 } 767 } else { // not a role member 768 results.add(roleMemberships); 769 matchingRoleIds.add(roleMemberships.getRoleId()); 770 } 771 } 772 } catch (Exception ex) { 773 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + entry.getKey(), ex); 774 } 775 } 776 } 777 778 // handle application roles 779 for ( String roleId : allRoleIds ) { 780 RoleTypeService roleTypeService = getRoleTypeService( roleId ); 781 RoleBo role = roles.get( roleId ); 782 // check if an application role 783 try { 784 if ( isApplicationRoleType(role.getKimTypeId(), roleTypeService) ) { 785 // for each application role, get the list of principals and groups which are in that role given the qualification (per the role type service) 786 List<RoleMembership> roleMembers = roleTypeService.getRoleMembersFromApplicationRole(role.getNamespaceCode(), role.getName(), qualification); 787 if ( !roleMembers.isEmpty() ) { 788 matchingRoleIds.add( roleId ); 789 } 790 for ( RoleMembership rm : roleMembers ) { 791 RoleMembership.Builder builder = RoleMembership.Builder.create(rm); 792 builder.setRoleId(roleId); 793 builder.setRoleMemberId("*"); 794 results.add(builder.build()); 795 } 796 } 797 } catch (Exception ex) { 798 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex); 799 } 800 } 801 802 if ( followDelegations && !matchingRoleIds.isEmpty() ) { 803 // we have a list of RoleMembershipInfo objects 804 // need to get delegations for distinct list of roles in that list 805 Map<String, DelegateTypeBo> delegationIdToDelegationMap = getStoredDelegationImplMapFromRoleIds(matchingRoleIds); 806 if (!delegationIdToDelegationMap.isEmpty()) { 807 List<RoleMembership.Builder> membershipsWithDelegations = 808 applyDelegationsToRoleMembers(results, delegationIdToDelegationMap.values(), qualification); 809 resolveDelegationMemberRoles(membershipsWithDelegations, qualification, foundRoleTypeMembers); 810 results = ModelObjectUtils.buildImmutableCopy(membershipsWithDelegations); 811 } 812 } 813 814 return Collections.unmodifiableList(results); 815 } 816 817 /** 818 * Checks each of the result records to determine if there are potentially applicable delegation members for that 819 * role membership. If there are, applicable delegations and members will be linked to the RoleMemberships in the 820 * given list. An updated list will be returned from this method which includes the appropriate linked delegations. 821 */ 822 protected List<RoleMembership.Builder> applyDelegationsToRoleMembers(List<RoleMembership> roleMemberships, 823 Collection<DelegateTypeBo> delegations, Map<String, String> qualification) { 824 MultiValueMap<String, String> roleIdToRoleMembershipIds = new LinkedMultiValueMap<String, String>(); 825 Map<String, RoleMembership.Builder> roleMembershipIdToBuilder = new HashMap<String, RoleMembership.Builder>(); 826 List<RoleMembership.Builder> roleMembershipBuilders = new ArrayList<RoleMembership.Builder>(); 827 // to make our algorithm less painful, let's do some indexing and load the given list of RoleMemberships into 828 // builders 829 for (RoleMembership roleMembership : roleMemberships) { 830 roleIdToRoleMembershipIds.add(roleMembership.getRoleId(), roleMembership.getRoleMemberId()); 831 RoleMembership.Builder builder = RoleMembership.Builder.create(roleMembership); 832 roleMembershipBuilders.add(builder); 833 roleMembershipIdToBuilder.put(roleMembership.getRoleMemberId(), builder); 834 } 835 for (DelegateTypeBo delegation : delegations) { 836 // determine the candidate role memberships where this delegation can be mapped 837 List<String> candidateRoleMembershipIds = roleIdToRoleMembershipIds.get(delegation.getRoleId()); 838 if (CollectionUtils.isNotEmpty(candidateRoleMembershipIds)) { 839 DelegationTypeService delegationTypeService = getDelegationTypeService(delegation.getDelegationId()); 840 for (DelegateMemberBo delegationMember : delegation.getMembers()) { 841 // Make sure that the delegation member is active 842 if (delegationMember.isActive(DateTime.now()) && (delegationTypeService == null || 843 delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegationMember.getQualifier()))) { 844 DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegationMember); 845 // if the member has no role member id, check qualifications and apply to all matching role memberships on the role 846 if (StringUtils.isBlank(delegationMember.getRoleMemberId())) { 847 RoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId()); 848 for (String roleMembershipId : candidateRoleMembershipIds) { 849 RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(roleMembershipId); 850 if (roleTypeService == null || roleTypeService.doesRoleQualifierMatchQualification(roleMembershipBuilder.getQualifier(), delegationMember.getQualifier())) { 851 linkDelegateToRoleMembership(delegation, delegateMemberBuilder, roleMembershipBuilder); 852 } 853 } 854 } else if (candidateRoleMembershipIds.contains(delegationMember.getRoleMemberId())) { 855 RoleMembership.Builder roleMembershipBuilder = roleMembershipIdToBuilder.get(delegationMember.getRoleMemberId()); 856 linkDelegateToRoleMembership(delegation, delegateMemberBuilder, roleMembershipBuilder); 857 } 858 } 859 } 860 } 861 } 862 return roleMembershipBuilders; 863 } 864 865 protected void linkDelegateToRoleMembership(DelegateTypeBo delegation, DelegateMember.Builder delegateMemberBuilder, 866 RoleMembership.Builder roleMembershipBuilder) { 867 DelegateType.Builder delegateBuilder = null; 868 for(DelegateType.Builder existingDelegateBuilder : roleMembershipBuilder.getDelegates()) { 869 if (existingDelegateBuilder.getDelegationId().equals(delegation.getDelegationId())) { 870 delegateBuilder = existingDelegateBuilder; 871 } 872 } 873 if (delegateBuilder == null) { 874 delegateBuilder = DelegateType.Builder.create(delegation); 875 delegateBuilder.setMembers(new ArrayList<DelegateMember.Builder>()); 876 roleMembershipBuilder.getDelegates().add(delegateBuilder); 877 } 878 delegateBuilder.getMembers().add(delegateMemberBuilder); 879 880 } 881 882 /** 883 * Once the delegations for a RoleMembershipInfo object have been determined, 884 * any "role" member types need to be resolved into groups and principals so that 885 * further KIM requests are not needed. 886 */ 887 protected void resolveDelegationMemberRoles(List<RoleMembership.Builder> membershipBuilders, 888 Map<String, String> qualification, Set<String> foundRoleTypeMembers) { 889 // check delegations assigned to this role 890 for (RoleMembership.Builder roleMembership : membershipBuilders) { 891 // the applicable delegation IDs will already be set in the RoleMembership.Builder 892 // this code examines those delegations and obtains the member groups and principals 893 for (DelegateType.Builder delegation : roleMembership.getDelegates()) { 894 List<DelegateMember.Builder> newMembers = new ArrayList<DelegateMember.Builder>(); 895 for (DelegateMember.Builder member : delegation.getMembers()) { 896 if (MemberType.ROLE.equals(member.getType())) { 897 // loop over delegation roles and extract the role IDs where the qualifications match 898 Collection<RoleMembership> delegateMembers = getRoleMembers(Collections.singletonList( 899 member.getMemberId()), qualification, false, foundRoleTypeMembers); 900 // loop over the role members and create the needed DelegationMember builders 901 for (RoleMembership rmi : delegateMembers) { 902 DelegateMember.Builder delegateMember = DelegateMember.Builder.create(member); 903 delegateMember.setMemberId(rmi.getMemberId()); 904 delegateMember.setType(rmi.getMemberType()); 905 newMembers.add(delegateMember); 906 } 907 } else { 908 newMembers.add(member); 909 } 910 } 911 delegation.setMembers(newMembers); 912 } 913 } 914 } 915 916 protected boolean principalHasRole(String principalId, List<String> roleIds, Map<String, String> qualification, boolean checkDelegations) { 917 if (StringUtils.isBlank(principalId)) { 918 return false; 919 } 920 Set<String> allRoleIds = new HashSet<String>(); 921 // remove inactive roles 922 for (String roleId : roleIds) { 923 if (isRoleActive(roleId)) { 924 allRoleIds.add(roleId); 925 } 926 } 927 // short-circuit if no roles match 928 if (allRoleIds.isEmpty()) { 929 return false; 930 } 931 // for efficiency, retrieve all roles and store in a map 932 Map<String, RoleBo> roles = getRoleBoMap(allRoleIds); 933 // get all roles to which the principal is assigned 934 List<String> copyRoleIds = new ArrayList<String>(allRoleIds); 935 List<RoleMemberBo> rps = new ArrayList<RoleMemberBo>(); 936 937 for (String roleId : allRoleIds) { 938 RoleTypeService roleTypeService = getRoleTypeService(roleId); 939 if (roleTypeService != null) { 940 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 941 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 942 copyRoleIds.remove(roleId); 943 rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(Collections.singletonList(roleId), principalId, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 944 } 945 } 946 } 947 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 948 rps.addAll(getStoredRolePrincipalsForPrincipalIdAndRoleIds(copyRoleIds, principalId, null)); 949 } 950 951 // if the qualification is null and the role list is not, then any role in the list will match 952 // so since the role ID list is not blank, we can return true at this point 953 if ((qualification == null || qualification.isEmpty()) && !rps.isEmpty()) { 954 return true; 955 } 956 957 // check each membership to see if the principal matches 958 959 // build a map of role ID to membership information 960 // this will be used for later qualification checks 961 Map<String, List<RoleMembership>> roleIdToMembershipMap = new HashMap<String, List<RoleMembership>>(); 962 if (getRoleIdToMembershipMap(roleIdToMembershipMap, rps)) { 963 return true; 964 } 965 966 // perform the checks against the role type services 967 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 968 try { 969 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 970 if (!roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue()).isEmpty()) { 971 return true; 972 } 973 } catch (Exception ex) { 974 LOG.warn("Unable to find role type service with id: " + entry.getKey()); 975 } 976 } 977 978 // find the groups that the principal belongs to 979 List<String> principalGroupIds = getGroupService().getGroupIdsByPrincipalId(principalId); 980 // find the role/group associations 981 if (!principalGroupIds.isEmpty()) { 982 List<RoleMemberBo> rgs = getStoredRoleGroupsUsingExactMatchOnQualification(principalGroupIds, allRoleIds, qualification); 983 roleIdToMembershipMap.clear(); // clear the role/member map for further use 984 if (getRoleIdToMembershipMap(roleIdToMembershipMap, rgs)) { 985 return true; 986 } 987 988 // perform the checks against the role type services 989 for (Map.Entry<String, List<RoleMembership>> entry : roleIdToMembershipMap.entrySet()) { 990 try { 991 RoleTypeService roleTypeService = getRoleTypeService(entry.getKey()); 992 if (!roleTypeService.getMatchingRoleMemberships(qualification, entry.getValue()).isEmpty()) { 993 return true; 994 } 995 } catch (Exception ex) { 996 LOG.warn("Unable to find role type service with id: " + entry.getKey(), ex); 997 } 998 } 999 } 1000 1001 // check member roles 1002 // first, check that the qualifiers on the role membership match 1003 // then, perform a principalHasRole on the embedded role 1004 List<RoleMemberBo> roleMemberBos = getStoredRoleMembersForRoleIds(roleIds, MemberType.ROLE.getCode(), null); 1005 for (RoleMemberBo roleMemberBo : roleMemberBos) { 1006 RoleTypeService roleTypeService = getRoleTypeService(roleMemberBo.getRoleId()); 1007 if (roleTypeService != null) { 1008 //it is possible that the the roleTypeService is coming from a remote application 1009 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1010 try { 1011 if (roleTypeService.doesRoleQualifierMatchQualification(qualification, roleMemberBo.getAttributes())) { 1012 RoleBo memberRole = getRoleBo(roleMemberBo.getMemberId()); 1013 Map<String, String> nestedRoleQualification = roleTypeService.convertQualificationForMemberRoles( 1014 roles.get(roleMemberBo.getRoleId()).getNamespaceCode(), 1015 roles.get(roleMemberBo.getRoleId()).getName(), 1016 memberRole.getNamespaceCode(), 1017 memberRole.getName(), 1018 qualification); 1019 ArrayList<String> roleIdTempList = new ArrayList<String>(1); 1020 roleIdTempList.add(roleMemberBo.getMemberId()); 1021 if (principalHasRole(principalId, roleIdTempList, nestedRoleQualification, true)) { 1022 return true; 1023 } 1024 } 1025 } catch (Exception ex) { 1026 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleMemberBo.getRoleId(), ex); 1027 //return false; 1028 } 1029 } else { 1030 // no qualifiers - role is always used - check membership 1031 ArrayList<String> roleIdTempList = new ArrayList<String>(1); 1032 roleIdTempList.add(roleMemberBo.getMemberId()); 1033 // no role type service, so can't convert qualification - just pass as is 1034 if (principalHasRole(principalId, roleIdTempList, qualification, true)) { 1035 return true; 1036 } 1037 } 1038 1039 } 1040 1041 1042 // check for application roles and extract principals and groups from that - then check them against the 1043 // role type service passing in the qualification and principal - the qualifier comes from the 1044 // external system (application) 1045 1046 // loop over the allRoleIds list 1047 for (String roleId : allRoleIds) { 1048 RoleBo role = roles.get(roleId); 1049 RoleTypeService roleTypeService = getRoleTypeService(roleId); 1050 // check if an application role 1051 //it is possible that the the roleTypeService is coming from a remote application 1052 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1053 try { 1054 if (isApplicationRoleType(role.getKimTypeId(), roleTypeService)) { 1055 if (roleTypeService.hasApplicationRole(principalId, principalGroupIds, role.getNamespaceCode(), role.getName(), qualification)) { 1056 return true; 1057 } 1058 } 1059 } catch (Exception ex) { 1060 LOG.warn("Not able to retrieve RoleTypeService from remote system for role Id: " + roleId, ex); 1061 //return false; 1062 } 1063 } 1064 1065 // delegations 1066 if (checkDelegations) { 1067 if (matchesOnDelegation(allRoleIds, principalId, principalGroupIds, qualification)) { 1068 return true; 1069 } 1070 } 1071 1072 // NOTE: this logic is a little different from the getRoleMembers method 1073 // If there is no primary (matching non-delegate), this method will still return true 1074 return false; 1075 } 1076 1077 1078 protected boolean isApplicationRoleType(String roleTypeId, RoleTypeService service) { 1079 return service != null && service.isApplicationRoleType(); 1080 } 1081 1082 /** 1083 * Support method for principalHasRole. Checks delegations on the passed in roles for the given principal and groups. (It's assumed that the principal 1084 * belongs to the given groups.) 1085 * <p/> 1086 * Delegation checks are mostly the same as role checks except that the delegateBo itself is qualified against the original role (like a RolePrincipal 1087 * or RoleGroup.) And then, the members of that delegateBo may have additional qualifiers which are not part of the original role qualifiers. 1088 * <p/> 1089 * For example: 1090 * <p/> 1091 * 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 1092 * 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 1093 * when it is attached to the role. 1094 * <p/> 1095 * The principals then attached to that delegateBo (which is specific to the organization), may have additional qualifiers. 1096 * For Example: dollar amount range, effective dates, document types. 1097 * As a subsequent step, those qualifiers are checked against the qualification passed in from the client. 1098 */ 1099 protected boolean matchesOnDelegation(Set<String> allRoleIds, String principalId, List<String> principalGroupIds, Map<String, String> qualification) { 1100 // get the list of delegations for the roles 1101 Map<String, DelegateTypeBo> delegations = getStoredDelegationImplMapFromRoleIds(allRoleIds); 1102 // loop over the delegations - determine those which need to be inspected more directly 1103 for (DelegateTypeBo delegation : delegations.values()) { 1104 // check if each one matches via the original role type service 1105 if (!delegation.isActive()) { 1106 continue; 1107 } 1108 RoleTypeService roleTypeService = getRoleTypeService(delegation.getRoleId()); 1109 for (DelegateMemberBo delegateMemberBo : delegation.getMembers()) { 1110 if (!delegateMemberBo.isActive(new Timestamp(new Date().getTime()))) { 1111 continue; 1112 } 1113 // check if this delegateBo record applies to the given person 1114 if (MemberType.PRINCIPAL.equals(delegateMemberBo.getType()) 1115 && !delegateMemberBo.getMemberId().equals(principalId)) { 1116 continue; // no match on principal 1117 } 1118 // or if a group 1119 if (MemberType.GROUP.equals(delegateMemberBo.getType()) 1120 && !principalGroupIds.contains(delegateMemberBo.getMemberId())) { 1121 continue; // no match on group 1122 } 1123 // or if a role 1124 if (MemberType.ROLE.equals(delegateMemberBo.getType()) 1125 && !principalHasRole(principalId, Collections.singletonList(delegateMemberBo.getMemberId()), qualification, false)) { 1126 continue; // no match on role 1127 } 1128 // OK, the member matches the current user, now check the qualifications 1129 1130 // NOTE: this compare is slightly different than the member enumeration 1131 // since the requested qualifier is always being used rather than 1132 // the role qualifier for the member (which is not available) 1133 1134 //it is possible that the the roleTypeService is coming from a remote application 1135 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1136 try { 1137 //TODO: remove reference to Attributes here and use Attributes instead. 1138 if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) { 1139 continue; // no match - skip to next record 1140 } 1141 } catch (Exception ex) { 1142 LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + delegateMemberBo.getQualifier(), ex); 1143 continue; 1144 } 1145 1146 // role service matches this qualifier 1147 // now try the delegateBo service 1148 DelegationTypeService delegationTypeService = getDelegationTypeService(delegateMemberBo.getDelegationId()); 1149 // QUESTION: does the qualifier map need to be merged with the main delegateBo qualification? 1150 if (delegationTypeService != null && !delegationTypeService.doesDelegationQualifierMatchQualification(qualification, delegateMemberBo.getQualifier())) { 1151 continue; // no match - skip to next record 1152 } 1153 // check if a role member ID is present on the delegateBo record 1154 // if so, check that the original role member would match the given qualifiers 1155 if (StringUtils.isNotBlank(delegateMemberBo.getRoleMemberId())) { 1156 RoleMemberBo rm = getRoleMemberBo(delegateMemberBo.getRoleMemberId()); 1157 if (rm != null) { 1158 // check that the original role member's is active and that their 1159 // qualifier would have matched this request's 1160 // qualifications (that the original person would have the permission/responsibility 1161 // for an action) 1162 // this prevents a role-membership based delegateBo from surviving the inactivation/ 1163 // changing of the main person's role membership 1164 if (!rm.isActive(new Timestamp(new Date().getTime()))) { 1165 continue; 1166 } 1167 Map<String, String> roleQualifier = rm.getAttributes(); 1168 //it is possible that the the roleTypeService is coming from a remote application 1169 // and therefore it can't be guaranteed that it is up and working, so using a try/catch to catch this possibility. 1170 try { 1171 if (roleTypeService != null && !roleTypeService.doesRoleQualifierMatchQualification(qualification, roleQualifier)) { 1172 continue; 1173 } 1174 } catch (Exception ex) { 1175 LOG.warn("Unable to call doesRoleQualifierMatchQualification on role type service for role Id: " + delegation.getRoleId() + " / " + qualification + " / " + roleQualifier, ex); 1176 continue; 1177 } 1178 } else { 1179 LOG.warn("Unknown role member ID cited in the delegateBo member table:"); 1180 LOG.warn(" assignedToId: " + delegateMemberBo.getDelegationMemberId() + " / roleMemberId: " + delegateMemberBo.getRoleMemberId()); 1181 } 1182 } 1183 // all tests passed, return true 1184 return true; 1185 } 1186 } 1187 return false; 1188 } 1189 1190 /** 1191 * Helper method used by principalHasRole to build the role ID -> list of members map. 1192 * 1193 * @return <b>true</b> if no further checks are needed because no role service is defined 1194 */ 1195 protected boolean getRoleIdToMembershipMap(Map<String, List<RoleMembership>> roleIdToMembershipMap, List<RoleMemberBo> roleMembers) { 1196 for (RoleMemberBo roleMemberBo : roleMembers) { 1197 RoleMembership roleMembership = RoleMembership.Builder.create( 1198 roleMemberBo.getRoleId(), 1199 roleMemberBo.getRoleMemberId(), 1200 roleMemberBo.getMemberId(), 1201 roleMemberBo.getMemberType(), 1202 roleMemberBo.getAttributes()).build(); 1203 1204 // if the role type service is null, assume that all qualifiers match 1205 if (getRoleTypeService(roleMemberBo.getRoleId()) == null) { 1206 return true; 1207 } 1208 List<RoleMembership> lrmi = roleIdToMembershipMap.get(roleMembership.getRoleId()); 1209 if (lrmi == null) { 1210 lrmi = new ArrayList<RoleMembership>(); 1211 roleIdToMembershipMap.put(roleMembership.getRoleId(), lrmi); 1212 } 1213 lrmi.add(roleMembership); 1214 } 1215 return false; 1216 } 1217 1218 /** 1219 * Retrieves a KimDelegationImpl object by its ID. If the delegateBo already exists in the cache, this method will return the cached 1220 * version; otherwise, it will retrieve the uncached version from the database and then cache it before returning it. 1221 */ 1222 protected DelegateTypeBo getKimDelegationImpl(String delegationId) { 1223 if (StringUtils.isBlank(delegationId)) { 1224 return null; 1225 } 1226 1227 return getBusinessObjectService().findByPrimaryKey(DelegateTypeBo.class, 1228 Collections.singletonMap(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId)); 1229 } 1230 1231 protected DelegationTypeService getDelegationTypeService(String delegationId) { 1232 DelegationTypeService service = null; 1233 DelegateTypeBo delegateBo = getKimDelegationImpl(delegationId); 1234 KimType delegationType = KimApiServiceLocator.getKimTypeInfoService().getKimType(delegateBo.getKimTypeId()); 1235 if (delegationType != null) { 1236 KimTypeService tempService = KimFrameworkServiceLocator.getKimTypeService(delegationType); 1237 if (tempService != null && tempService instanceof DelegationTypeService) { 1238 service = (DelegationTypeService) tempService; 1239 } else { 1240 LOG.error("Service returned for type " + delegationType + "(" + delegationType.getName() + ") was not a DelegationTypeService. Was a " + (tempService != null ? tempService.getClass() : "(null)")); 1241 } 1242 } else { // delegateBo has no type - default to role type if possible 1243 RoleTypeService roleTypeService = getRoleTypeService(delegateBo.getRoleId()); 1244 if (roleTypeService != null && roleTypeService instanceof DelegationTypeService) { 1245 service = (DelegationTypeService) roleTypeService; 1246 } 1247 } 1248 return service; 1249 } 1250 1251 protected Collection<RoleMembership> getNestedRoleMembers(Map<String, String> qualification, RoleMembership rm, Set<String> foundRoleTypeMembers) { 1252 // If this role has already been traversed, skip it 1253 if (foundRoleTypeMembers.contains(rm.getMemberId())) { 1254 return new ArrayList<RoleMembership>(); // return an empty list 1255 } 1256 foundRoleTypeMembers.add(rm.getMemberId()); 1257 1258 ArrayList<String> roleIdList = new ArrayList<String>(1); 1259 roleIdList.add(rm.getMemberId()); 1260 1261 // get the list of members from the nested role - ignore delegations on those sub-roles 1262 Collection<RoleMembership> currentNestedRoleMembers = getRoleMembers(roleIdList, qualification, false, foundRoleTypeMembers); 1263 1264 // add the roles whose members matched to the list for delegateBo checks later 1265 Collection<RoleMembership> returnRoleMembers = new ArrayList<RoleMembership>(); 1266 for (RoleMembership roleMembership : currentNestedRoleMembers) { 1267 RoleMembership.Builder rmBuilder = RoleMembership.Builder.create(roleMembership); 1268 1269 // use the member ID of the parent role (needed for responsibility joining) 1270 rmBuilder.setRoleMemberId(rm.getRoleMemberId()); 1271 // store the role ID, so we know where this member actually came from 1272 rmBuilder.setRoleId(rm.getRoleId()); 1273 rmBuilder.setEmbeddedRoleId(rm.getMemberId()); 1274 returnRoleMembers.add(rmBuilder.build()); 1275 } 1276 return returnRoleMembers; 1277 } 1278 1279 /** 1280 * Retrieves a KimDelegationMemberImpl object by its ID and the ID of the delegation it belongs to. If the delegation member exists in the cache, 1281 * this method will return the cached one; otherwise, it will retrieve the uncached version from the database and then cache it before returning it. 1282 */ 1283 protected DelegateMemberBo getKimDelegationMemberImplByDelegationAndId(String delegationId, String delegationMemberId) { 1284 if (StringUtils.isBlank(delegationId) || StringUtils.isBlank(delegationMemberId)) { 1285 return null; 1286 } 1287 1288 Map<String, String> searchCriteria = new HashMap<String, String>(); 1289 searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationId); 1290 searchCriteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMemberId); 1291 List<DelegateMemberBo> memberList = 1292 (List<DelegateMemberBo>) getBusinessObjectService().findMatching(DelegateMemberBo.class, searchCriteria); 1293 if (memberList != null && !memberList.isEmpty()) { 1294 return memberList.get(0); 1295 } 1296 return null; 1297 } 1298 1299 private List<RoleMemberBo> getStoredRoleMembersUsingExactMatchOnQualification(String principalId, List<String> groupIds, List<String> roleIds, Map<String, String> qualification) { 1300 List<String> copyRoleIds = new ArrayList<String>(roleIds); 1301 List<RoleMemberBo> roleMemberBoList = new ArrayList<RoleMemberBo>(); 1302 1303 for (String roleId : roleIds) { 1304 RoleTypeService roleTypeService = getRoleTypeService(roleId); 1305 if (roleTypeService != null) { 1306 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 1307 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 1308 copyRoleIds.remove(roleId); 1309 roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(Collections.singletonList(roleId), principalId, groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 1310 } 1311 } 1312 } 1313 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 1314 roleMemberBoList.addAll(getStoredRoleMembersForRoleIdsWithFilters(copyRoleIds, principalId, groupIds, null)); 1315 } 1316 return roleMemberBoList; 1317 } 1318 1319 private List<RoleMemberBo> getStoredRoleGroupsUsingExactMatchOnQualification(List<String> groupIds, Set<String> roleIds, Map<String, String> qualification) { 1320 List<String> copyRoleIds = new ArrayList<String>(roleIds); 1321 List<RoleMemberBo> roleMemberBos = new ArrayList<RoleMemberBo>(); 1322 1323 for (String roleId : roleIds) { 1324 RoleTypeService roleTypeService = getRoleTypeService(roleId); 1325 if (roleTypeService != null) { 1326 List<String> attributesForExactMatch = roleTypeService.getQualifiersForExactMatch(); 1327 if (CollectionUtils.isNotEmpty(attributesForExactMatch)) { 1328 copyRoleIds.remove(roleId); 1329 roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(Collections.singletonList(roleId), groupIds, populateQualifiersForExactMatch(qualification, attributesForExactMatch))); 1330 } 1331 } 1332 } 1333 if (CollectionUtils.isNotEmpty(copyRoleIds)) { 1334 roleMemberBos.addAll(getStoredRoleGroupsForGroupIdsAndRoleIds(copyRoleIds, groupIds, null)); 1335 } 1336 return roleMemberBos; 1337 } 1338 1339 private List<DelegateMember> getDelegateMembersForDelegation(DelegateTypeBo delegateBo) { 1340 if (delegateBo == null || delegateBo.getMembers() == null) {return null;} 1341 List<DelegateMember> delegateMembersReturnList = new ArrayList<DelegateMember>(); 1342 for (DelegateMemberBo delegateMemberBo : delegateBo.getMembers()) { 1343 //FIXME: What is up with this!?! 1344 DelegateMember delegateMember = getDelegateCompleteInfo(delegateBo, delegateMemberBo); 1345 1346 delegateMembersReturnList.add(DelegateMemberBo.to(delegateMemberBo)); 1347 } 1348 return Collections.unmodifiableList(delegateMembersReturnList); 1349 } 1350 1351 private DelegateMember getDelegateCompleteInfo(DelegateTypeBo delegateBo, DelegateMemberBo delegateMemberBo) { 1352 if (delegateBo == null || delegateMemberBo == null) {return null;} 1353 1354 DelegateMember.Builder delegateMemberBuilder = DelegateMember.Builder.create(delegateMemberBo); 1355 delegateMemberBuilder.setType(delegateMemberBo.getType()); 1356 return delegateMemberBuilder.build(); 1357 } 1358 1359 @Override 1360 public void assignPrincipalToRole(String principalId, 1361 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1362 incomingParamCheck(principalId, "principalId"); 1363 incomingParamCheck(namespaceCode, "namespaceCode"); 1364 incomingParamCheck(roleName, "roleName"); 1365 incomingParamCheck(qualifier, "qualifier"); 1366 1367 // look up the role 1368 RoleBo role = getRoleBoByName(namespaceCode, roleName); 1369 role.refreshReferenceObject("members"); 1370 1371 // check that identical member does not already exist 1372 if ( doAnyMemberRecordsMatchByExactQualifier(role, principalId, memberTypeToRoleDaoActionMap.get(MemberType.PRINCIPAL.getCode()), qualifier) || 1373 doAnyMemberRecordsMatch( role.getMembers(), principalId, MemberType.PRINCIPAL.getCode(), qualifier ) ) { 1374 return; 1375 } 1376 // create the new role member object 1377 RoleMemberBo newRoleMember = new RoleMemberBo(); 1378 1379 newRoleMember.setRoleId(role.getId()); 1380 newRoleMember.setMemberId(principalId); 1381 newRoleMember.setMemberType(MemberType.PRINCIPAL); 1382 1383 // build role member attribute objects from the given Map<String, String> 1384 addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId()); 1385 1386 // add row to member table 1387 // When members are added to roles, clients must be notified. 1388 getResponsibilityInternalService().saveRoleMember(newRoleMember); 1389 } 1390 1391 @Override 1392 public void assignGroupToRole(String groupId, String namespaceCode, 1393 String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1394 incomingParamCheck(groupId, "groupId"); 1395 incomingParamCheck(namespaceCode, "namespaceCode"); 1396 incomingParamCheck(roleName, "roleName"); 1397 incomingParamCheck(qualifier, "qualifier"); 1398 1399 // look up the role 1400 RoleBo role = getRoleBoByName(namespaceCode, roleName); 1401 // check that identical member does not already exist 1402 if ( doAnyMemberRecordsMatchByExactQualifier(role, groupId, memberTypeToRoleDaoActionMap.get(MemberType.GROUP.getCode()), qualifier) || 1403 doAnyMemberRecordsMatch( role.getMembers(), groupId, MemberType.GROUP.getCode(), qualifier ) ) { 1404 return; 1405 } 1406 // create the new role member object 1407 RoleMemberBo newRoleMember = new RoleMemberBo(); 1408 newRoleMember.setRoleId(role.getId()); 1409 newRoleMember.setMemberId(groupId); 1410 newRoleMember.setMemberType(MemberType.GROUP); 1411 1412 // build role member attribute objects from the given Map<String, String> 1413 addMemberAttributeData(newRoleMember, qualifier, role.getKimTypeId()); 1414 1415 // When members are added to roles, clients must be notified. 1416 getResponsibilityInternalService().saveRoleMember(newRoleMember); 1417 } 1418 1419 @Override 1420 public void assignRoleToRole(String roleId, 1421 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1422 incomingParamCheck(roleId, "roleId"); 1423 incomingParamCheck(namespaceCode, "namespaceCode"); 1424 incomingParamCheck(roleName, "roleName"); 1425 incomingParamCheck(qualifier, "qualifier"); 1426 1427 // look up the roleBo 1428 RoleBo roleBo = getRoleBoByName(namespaceCode, roleName); 1429 // check that identical member does not already exist 1430 if ( doAnyMemberRecordsMatchByExactQualifier(roleBo, roleId, memberTypeToRoleDaoActionMap.get(MemberType.ROLE.getCode()), qualifier) || 1431 doAnyMemberRecordsMatch( roleBo.getMembers(), roleId, MemberType.ROLE.getCode(), qualifier ) ) { 1432 return; 1433 } 1434 // Check to make sure this doesn't create a circular membership 1435 if (!checkForCircularRoleMembership(roleId, roleBo)) { 1436 throw new IllegalArgumentException("Circular roleBo reference."); 1437 } 1438 // create the new roleBo member object 1439 RoleMemberBo newRoleMember = new RoleMemberBo(); 1440 newRoleMember.setRoleId(roleBo.getId()); 1441 newRoleMember.setMemberId(roleId); 1442 newRoleMember.setMemberType(MemberType.ROLE); 1443 // build roleBo member attribute objects from the given Map<String, String> 1444 addMemberAttributeData(newRoleMember, qualifier, roleBo.getKimTypeId()); 1445 1446 // When members are added to roles, clients must be notified. 1447 getResponsibilityInternalService().saveRoleMember(newRoleMember); 1448 } 1449 1450 @Override 1451 public RoleMember createRoleMember(RoleMember roleMember) throws RiceIllegalStateException { 1452 incomingParamCheck(roleMember, "roleMember"); 1453 1454 if (StringUtils.isNotBlank(roleMember.getRoleMemberId()) && getRoleMemberBo(roleMember.getRoleMemberId()) != null) { 1455 throw new RiceIllegalStateException("the roleMember to create already exists: " + roleMember); 1456 } 1457 1458 String kimTypeId = getRoleBo(roleMember.getRoleId()).getKimTypeId(); 1459 List<RoleMemberAttributeDataBo> attrBos = Collections.emptyList(); 1460 attrBos = KimAttributeDataBo.createFrom(RoleMemberAttributeDataBo.class, roleMember.getAttributes(), kimTypeId); 1461 1462 RoleMemberBo bo = RoleMemberBo.from(roleMember); 1463 bo.setAttributeDetails(attrBos); 1464 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(bo)); 1465 } 1466 1467 @Override 1468 public RoleMember updateRoleMember(@WebParam( 1469 name = "roleMember") RoleMember roleMember) throws RiceIllegalArgumentException, RiceIllegalStateException { 1470 incomingParamCheck(roleMember, "roleMember"); 1471 1472 if (StringUtils.isBlank(roleMember.getRoleMemberId()) || getRoleMemberBo(roleMember.getRoleMemberId()) == null) { 1473 throw new RiceIllegalStateException("the roleMember to update does not exists: " + roleMember); 1474 } 1475 1476 String kimTypeId = getRoleBo(roleMember.getRoleId()).getKimTypeId(); 1477 List<RoleMemberAttributeDataBo> attrBos = Collections.emptyList(); 1478 attrBos = KimAttributeDataBo.createFrom(RoleMemberAttributeDataBo.class, roleMember.getAttributes(), kimTypeId); 1479 1480 RoleMemberBo bo = RoleMemberBo.from(roleMember); 1481 bo.setAttributeDetails(attrBos); 1482 return RoleMemberBo.to(getResponsibilityInternalService().saveRoleMember(bo)); 1483 } 1484 1485 @Override 1486 public RoleResponsibilityAction createRoleResponsibilityAction(RoleResponsibilityAction roleResponsibilityAction) 1487 throws RiceIllegalArgumentException, RiceIllegalStateException { 1488 incomingParamCheck(roleResponsibilityAction, "roleResponsibilityAction"); 1489 1490 1491 if (StringUtils.isNotBlank(roleResponsibilityAction.getId()) 1492 && getBusinessObjectService().findByPrimaryKey 1493 (RoleResponsibilityActionBo.class, Collections.singletonMap("id", roleResponsibilityAction.getId())) != null) { 1494 throw new RiceIllegalStateException("the roleResponsibilityAction to create already exists: " + roleResponsibilityAction); 1495 } 1496 1497 RoleResponsibilityActionBo bo = RoleResponsibilityActionBo.from(roleResponsibilityAction); 1498 return RoleResponsibilityActionBo.to(getBusinessObjectService().save(bo)); 1499 } 1500 1501 @Override 1502 public DelegateType createDelegateType(DelegateType delegateType) throws RiceIllegalStateException { 1503 incomingParamCheck(delegateType, "delegateType"); 1504 1505 if (StringUtils.isNotBlank(delegateType.getDelegationId()) 1506 && getDelegateTypeByDelegationId(delegateType.getDelegationId()) != null) { 1507 throw new RiceIllegalStateException("the delegateType to create already exists: " + delegateType); 1508 } 1509 1510 DelegateTypeBo bo = DelegateTypeBo.from(delegateType); 1511 return DelegateTypeBo.to(getBusinessObjectService().save(bo)); 1512 // look up the role 1513 /*RoleBo role = getRoleBo(delegationType.getRoleId()); 1514 DelegateTypeBo delegation = getDelegationOfType(role.getId(), delegationType.getDelegationTypeCode()); 1515 // create the new role member object 1516 DelegateMemberBo newDelegationMember = new DelegateMemberBo(); 1517 1518 DelegateMemberBo origDelegationMember; 1519 if(StringUtils.isNotEmpty(delegationMemberId)){ 1520 origDelegationMember = getDelegateMemberBo(delegationMemberId); 1521 } else{ 1522 List<DelegateMemberBo> origDelegationMembers = 1523 this.getDelegationMemberBoListByMemberAndDelegationId(memberId, delegation.getDelegationId()); 1524 origDelegationMember = 1525 (origDelegationMembers!=null && !origDelegationMembers.isEmpty()) ? origDelegationMembers.get(0) : null; 1526 } 1527 if(origDelegationMember!=null){ 1528 newDelegationMember.setDelegationMemberId(origDelegationMember.getDelegationMemberId()); 1529 newDelegationMember.setVersionNumber(origDelegationMember.getVersionNumber()); 1530 } 1531 newDelegationMember.setMemberId(memberId); 1532 newDelegationMember.setDelegationId(delegation.getDelegationId()); 1533 newDelegationMember.setRoleMemberId(roleMemberId); 1534 newDelegationMember.setTypeCode(memberTypeCode); 1535 if (activeFromDate != null) { 1536 newDelegationMember.setActiveFromDateValue(new java.sql.Timestamp(activeFromDate.getMillis())); 1537 } 1538 if (activeToDate != null) { 1539 newDelegationMember.setActiveToDateValue(new java.sql.Timestamp(activeToDate.getMillis())); 1540 } 1541 1542 // build role member attribute objects from the given Map<String, String> 1543 addDelegationMemberAttributeData( newDelegationMember, qualifications, role.getKimTypeId() ); 1544 1545 List<DelegateMemberBo> delegationMembers = new ArrayList<DelegateMemberBo>(); 1546 delegationMembers.add(newDelegationMember); 1547 delegation.setMembers(delegationMembers); 1548 1549 getBusinessObjectService().save(delegation); 1550 for(DelegateMemberBo delegationMember: delegation.getMembers()){ 1551 deleteNullDelegationMemberAttributeData(delegationMember.getAttributes()); 1552 }*/ 1553 } 1554 1555 @Override 1556 public DelegateType updateDelegateType(DelegateType delegateType) throws RiceIllegalStateException { 1557 incomingParamCheck(delegateType, "delegateType"); 1558 1559 if (StringUtils.isBlank(delegateType.getDelegationId()) 1560 || getDelegateTypeByDelegationId(delegateType.getDelegationId()) == null) { 1561 throw new RiceIllegalStateException("the delegateType to update does not exist: " + delegateType); 1562 } 1563 1564 DelegateTypeBo bo = DelegateTypeBo.from(delegateType); 1565 return DelegateTypeBo.to(getBusinessObjectService().save(bo)); 1566 } 1567 1568 1569 private void removeRoleMembers(List<RoleMemberBo> members) { 1570 if(CollectionUtils.isNotEmpty(members)) { 1571 for ( RoleMemberBo rm : members ) { 1572 getResponsibilityInternalService().removeRoleMember(rm); 1573 } 1574 } 1575 } 1576 1577 private List<RoleMemberBo> getRoleMembersByDefaultStrategy(RoleBo role, String memberId, String memberTypeCode, Map<String, String> qualifier) { 1578 List<RoleMemberBo> rms = new ArrayList<RoleMemberBo>(); 1579 role.refreshReferenceObject("members"); 1580 for ( RoleMemberBo rm : role.getMembers() ) { 1581 if ( doesMemberMatch( rm, memberId, memberTypeCode, qualifier ) ) { 1582 // if found, remove 1583 rms.add(rm); 1584 } 1585 } 1586 return rms; 1587 } 1588 1589 @Override 1590 public void removePrincipalFromRole(String principalId, 1591 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1592 if (StringUtils.isBlank(principalId)) { 1593 throw new RiceIllegalArgumentException("principalId is null"); 1594 } 1595 1596 if (StringUtils.isBlank(namespaceCode)) { 1597 throw new RiceIllegalArgumentException("namespaceCode is null"); 1598 } 1599 1600 if (StringUtils.isBlank(roleName)) { 1601 throw new RiceIllegalArgumentException("roleName is null"); 1602 } 1603 1604 if (qualifier == null) { 1605 throw new RiceIllegalArgumentException("qualifier is null"); 1606 } 1607 1608 // look up the role 1609 RoleBo role = getRoleBoByName(namespaceCode, roleName); 1610 // pull all the principal members 1611 // look for an exact qualifier match 1612 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(role, principalId, memberTypeToRoleDaoActionMap.get(MemberType.PRINCIPAL.getCode()), qualifier); 1613 if(CollectionUtils.isEmpty(rms)) { 1614 rms = getRoleMembersByDefaultStrategy(role, principalId, MemberType.PRINCIPAL.getCode(), qualifier); 1615 } 1616 removeRoleMembers(rms); 1617 } 1618 1619 @Override 1620 public void removeGroupFromRole(String groupId, 1621 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1622 if (StringUtils.isBlank(groupId)) { 1623 throw new RiceIllegalArgumentException("groupId is null"); 1624 } 1625 1626 if (StringUtils.isBlank(namespaceCode)) { 1627 throw new RiceIllegalArgumentException("namespaceCode is null"); 1628 } 1629 1630 if (StringUtils.isBlank(roleName)) { 1631 throw new RiceIllegalArgumentException("roleName is null"); 1632 } 1633 1634 if (qualifier == null) { 1635 throw new RiceIllegalArgumentException("qualifier is null"); 1636 } 1637 1638 // look up the roleBo 1639 RoleBo roleBo = getRoleBoByName(namespaceCode, roleName); 1640 // pull all the group roleBo members 1641 // look for an exact qualifier match 1642 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(roleBo, groupId, memberTypeToRoleDaoActionMap.get(MemberType.GROUP.getCode()), qualifier); 1643 if(CollectionUtils.isEmpty(rms)) { 1644 rms = getRoleMembersByDefaultStrategy(roleBo, groupId, MemberType.GROUP.getCode(), qualifier); 1645 } 1646 removeRoleMembers(rms); 1647 } 1648 1649 @Override 1650 public void removeRoleFromRole(String roleId, 1651 String namespaceCode, String roleName, Map<String, String> qualifier) throws RiceIllegalStateException { 1652 incomingParamCheck(roleId, "roleId"); 1653 incomingParamCheck(namespaceCode, "namespaceCode"); 1654 incomingParamCheck(roleName, "roleName"); 1655 incomingParamCheck(qualifier, "qualifier"); 1656 1657 1658 // look up the role 1659 RoleBo role = getRoleBoByName(namespaceCode, roleName); 1660 // pull all the group role members 1661 // look for an exact qualifier match 1662 List<RoleMemberBo> rms = getRoleMembersByExactQualifierMatch(role, roleId, memberTypeToRoleDaoActionMap.get(MemberType.ROLE.getCode()), qualifier); 1663 if(CollectionUtils.isEmpty(rms)) { 1664 rms = getRoleMembersByDefaultStrategy(role, roleId, MemberType.ROLE.getCode(), qualifier); 1665 } 1666 removeRoleMembers(rms); 1667 } 1668 1669 @Override 1670 public void assignPermissionToRole(String permissionId, String roleId) throws RiceIllegalStateException { 1671 incomingParamCheck(permissionId, "permissionId"); 1672 incomingParamCheck(roleId, "roleId"); 1673 1674 RolePermissionBo newRolePermission = new RolePermissionBo(); 1675 1676 Long nextSeq = KRADServiceLocator.getSequenceAccessorService().getNextAvailableSequenceNumber(KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S, RolePermissionBo.class); 1677 1678 if (nextSeq == null) { 1679 LOG.error("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S); 1680 throw new RuntimeException("Unable to get new role permission id from sequence " + KimConstants.SequenceNames.KRIM_ROLE_PERM_ID_S); 1681 } 1682 1683 newRolePermission.setId(nextSeq.toString()); 1684 newRolePermission.setRoleId(roleId); 1685 newRolePermission.setPermissionId(permissionId); 1686 newRolePermission.setActive(true); 1687 1688 getBusinessObjectService().save(newRolePermission); 1689 } 1690 1691 protected void addMemberAttributeData(RoleMemberBo roleMember, Map<String, String> qualifier, String kimTypeId) { 1692 List<RoleMemberAttributeDataBo> attributes = new ArrayList<RoleMemberAttributeDataBo>(); 1693 for (Map.Entry<String, String> entry : qualifier.entrySet()) { 1694 RoleMemberAttributeDataBo roleMemberAttrBo = new RoleMemberAttributeDataBo(); 1695 roleMemberAttrBo.setAttributeValue(entry.getValue()); 1696 roleMemberAttrBo.setKimTypeId(kimTypeId); 1697 roleMemberAttrBo.setAssignedToId(roleMember.getRoleMemberId()); 1698 // look up the attribute ID 1699 roleMemberAttrBo.setKimAttributeId(getKimAttributeId(entry.getKey())); 1700 1701 Map<String, String> criteria = new HashMap<String, String>(); 1702 criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, roleMemberAttrBo.getKimAttributeId()); 1703 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID, roleMember.getRoleMemberId()); 1704 List<RoleMemberAttributeDataBo> origRoleMemberAttributes = 1705 (List<RoleMemberAttributeDataBo>) getBusinessObjectService().findMatching(RoleMemberAttributeDataBo.class, criteria); 1706 RoleMemberAttributeDataBo origRoleMemberAttribute = 1707 (origRoleMemberAttributes != null && !origRoleMemberAttributes.isEmpty()) ? origRoleMemberAttributes.get(0) : null; 1708 if (origRoleMemberAttribute != null) { 1709 roleMemberAttrBo.setId(origRoleMemberAttribute.getId()); 1710 roleMemberAttrBo.setVersionNumber(origRoleMemberAttribute.getVersionNumber()); 1711 } 1712 attributes.add(roleMemberAttrBo); 1713 } 1714 roleMember.setAttributeDetails(attributes); 1715 } 1716 1717 protected void addDelegationMemberAttributeData( DelegateMemberBo delegationMember, Map<String, String> qualifier, String kimTypeId ) { 1718 List<DelegateMemberAttributeDataBo> attributes = new ArrayList<DelegateMemberAttributeDataBo>(); 1719 for ( Map.Entry<String, String> entry : qualifier.entrySet() ) { 1720 DelegateMemberAttributeDataBo delegateMemberAttrBo = new DelegateMemberAttributeDataBo(); 1721 delegateMemberAttrBo.setAttributeValue(entry.getValue()); 1722 delegateMemberAttrBo.setKimTypeId(kimTypeId); 1723 delegateMemberAttrBo.setAssignedToId(delegationMember.getDelegationMemberId()); 1724 // look up the attribute ID 1725 delegateMemberAttrBo.setKimAttributeId(getKimAttributeId(entry.getKey())); 1726 Map<String, String> criteria = new HashMap<String, String>(); 1727 criteria.put(KimConstants.PrimaryKeyConstants.KIM_ATTRIBUTE_ID, delegateMemberAttrBo.getKimAttributeId()); 1728 criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID, delegationMember.getDelegationMemberId()); 1729 List<DelegateMemberAttributeDataBo> origDelegationMemberAttributes = 1730 (List<DelegateMemberAttributeDataBo>)getBusinessObjectService().findMatching(DelegateMemberAttributeDataBo.class, criteria); 1731 DelegateMemberAttributeDataBo origDelegationMemberAttribute = 1732 (origDelegationMemberAttributes!=null && !origDelegationMemberAttributes.isEmpty()) ? origDelegationMemberAttributes.get(0) : null; 1733 if(origDelegationMemberAttribute!=null){ 1734 delegateMemberAttrBo.setId(origDelegationMemberAttribute.getId()); 1735 delegateMemberAttrBo.setVersionNumber(origDelegationMemberAttribute.getVersionNumber()); 1736 } 1737 attributes.add( delegateMemberAttrBo ); 1738 } 1739 delegationMember.setAttributes( attributes ); 1740 } 1741 1742 1743 1744 // -------------------- 1745 // Persistence Methods 1746 // -------------------- 1747 1748 private void deleteNullMemberAttributeData(List<RoleMemberAttributeDataBo> attributes) { 1749 List<RoleMemberAttributeDataBo> attributesToDelete = new ArrayList<RoleMemberAttributeDataBo>(); 1750 for(RoleMemberAttributeDataBo attribute: attributes){ 1751 if(attribute.getAttributeValue()==null){ 1752 attributesToDelete.add(attribute); 1753 } 1754 } 1755 getBusinessObjectService().delete(attributesToDelete); 1756 } 1757 1758 private void deleteNullDelegationMemberAttributeData(List<DelegateMemberAttributeDataBo> attributes) { 1759 List<DelegateMemberAttributeDataBo> attributesToDelete = new ArrayList<DelegateMemberAttributeDataBo>(); 1760 1761 for(DelegateMemberAttributeDataBo attribute: attributes){ 1762 if(attribute.getAttributeValue()==null){ 1763 attributesToDelete.add(attribute); 1764 } 1765 } 1766 getBusinessObjectService().delete(attributesToDelete); 1767 } 1768 1769 private void incomingParamCheck(Object object, String name) { 1770 if (object == null) { 1771 throw new RiceIllegalArgumentException(name + " was null"); 1772 } else if (object instanceof String 1773 && StringUtils.isBlank((String) object)) { 1774 throw new RiceIllegalArgumentException(name + " was blank"); 1775 } 1776 } 1777 }