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