1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.impl.permission;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.exception.ExceptionUtils;
21 import org.apache.log4j.Logger;
22 import org.kuali.rice.core.api.cache.CacheKeyUtils;
23 import org.kuali.rice.core.api.criteria.CriteriaLookupService;
24 import org.kuali.rice.core.api.criteria.GenericQueryResults;
25 import org.kuali.rice.core.api.criteria.LookupCustomizer;
26 import org.kuali.rice.core.api.criteria.QueryByCriteria;
27 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
28 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
29 import org.kuali.rice.core.api.membership.MemberType;
30 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
31 import org.kuali.rice.kim.api.KimConstants;
32 import org.kuali.rice.kim.api.common.assignee.Assignee;
33 import org.kuali.rice.kim.api.common.delegate.DelegateType;
34 import org.kuali.rice.kim.api.common.template.Template;
35 import org.kuali.rice.kim.api.common.template.TemplateQueryResults;
36 import org.kuali.rice.kim.api.identity.principal.Principal;
37 import org.kuali.rice.kim.api.permission.Permission;
38 import org.kuali.rice.kim.api.permission.PermissionQueryResults;
39 import org.kuali.rice.kim.api.permission.PermissionService;
40 import org.kuali.rice.kim.api.role.RoleMembership;
41 import org.kuali.rice.kim.api.role.RoleService;
42 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
43 import org.kuali.rice.kim.api.type.KimType;
44 import org.kuali.rice.kim.api.type.KimTypeInfoService;
45 import org.kuali.rice.kim.framework.permission.PermissionTypeService;
46 import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
47 import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
48 import org.kuali.rice.kim.impl.role.RolePermissionBo;
49 import org.kuali.rice.krad.service.BusinessObjectService;
50 import org.kuali.rice.krad.util.KRADPropertyConstants;
51 import org.springframework.cache.Cache;
52 import org.springframework.cache.CacheManager;
53 import org.springframework.cache.support.NoOpCacheManager;
54
55 import javax.xml.namespace.QName;
56 import java.util.ArrayList;
57 import java.util.Collection;
58 import java.util.Collections;
59 import java.util.Comparator;
60 import java.util.HashMap;
61 import java.util.List;
62 import java.util.Map;
63 import java.util.concurrent.CopyOnWriteArrayList;
64
65 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
66 import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
67
68 public class PermissionServiceImpl implements PermissionService {
69 private static final Logger LOG = Logger.getLogger( PermissionServiceImpl.class );
70
71 private RoleService roleService;
72 private PermissionTypeService defaultPermissionTypeService;
73 private KimTypeInfoService kimTypeInfoService;
74 private BusinessObjectService businessObjectService;
75 private CriteriaLookupService criteriaLookupService;
76 private CacheManager cacheManager;
77
78 private final CopyOnWriteArrayList<Template> allTemplates = new CopyOnWriteArrayList<Template>();
79
80
81
82
83
84 public PermissionServiceImpl() {
85 this.cacheManager = new NoOpCacheManager();
86 }
87
88 protected PermissionTypeService getPermissionTypeService(Template permissionTemplate) {
89 if ( permissionTemplate == null ) {
90 throw new IllegalArgumentException( "permissionTemplate may not be null" );
91 }
92 KimType kimType = kimTypeInfoService.getKimType( permissionTemplate.getKimTypeId() );
93 String serviceName = kimType.getServiceName();
94
95 if ( StringUtils.isBlank( serviceName ) ) {
96 return defaultPermissionTypeService;
97 }
98 try {
99 Object service = GlobalResourceLoader.getService(QName.valueOf(serviceName));
100
101 if ( service == null ) {
102 throw new RuntimeException("null returned for permission type service for service name: " + serviceName);
103 }
104
105 if ( !(service instanceof PermissionTypeService) ) {
106 throw new RuntimeException( "Service " + serviceName + " was not a PermissionTypeService. Was: " + service.getClass().getName() );
107 }
108 return (PermissionTypeService)service;
109 } catch( Exception ex ) {
110
111 throw new RuntimeException( "Error retrieving service: " + serviceName + " from the KimImplServiceLocator.", ex );
112 }
113 }
114
115 @Override
116 public boolean hasPermission(String principalId, String namespaceCode,
117 String permissionName) throws RiceIllegalArgumentException {
118 incomingParamCheck(principalId, "principalId");
119 incomingParamCheck(namespaceCode, "namespaceCode");
120 incomingParamCheck(permissionName, "permissionName");
121
122 return isAuthorized( principalId, namespaceCode, permissionName, Collections.<String, String>emptyMap() );
123 }
124
125 @Override
126 public boolean isAuthorized(String principalId, String namespaceCode,
127 String permissionName, Map<String, String> qualification ) throws RiceIllegalArgumentException {
128 incomingParamCheck(principalId, "principalId");
129 incomingParamCheck(namespaceCode, "namespaceCode");
130 incomingParamCheck(permissionName, "permissionName");
131 incomingParamCheck(qualification, "qualification");
132
133 if ( LOG.isDebugEnabled() ) {
134 logAuthorizationCheck("Permission", principalId, namespaceCode, permissionName, qualification);
135 }
136
137 List<String> roleIds = getRoleIdsForPermission(namespaceCode, permissionName);
138 if ( roleIds.isEmpty() ) {
139 if ( LOG.isDebugEnabled() ) {
140 LOG.debug( "Result: false");
141 }
142 return false;
143 }
144
145 boolean isAuthorized = roleService.principalHasRole(principalId, roleIds, qualification);
146
147 if ( LOG.isDebugEnabled() ) {
148 LOG.debug( "Result: " + isAuthorized );
149 }
150 return isAuthorized;
151
152 }
153 @Override
154 public boolean hasPermissionByTemplate(String principalId, String namespaceCode, String permissionTemplateName,
155 Map<String, String> permissionDetails) throws RiceIllegalArgumentException {
156 incomingParamCheck(principalId, "principalId");
157 incomingParamCheck(namespaceCode, "namespaceCode");
158 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
159
160 return isAuthorizedByTemplate(principalId, namespaceCode, permissionTemplateName, permissionDetails,
161 Collections.<String, String>emptyMap());
162 }
163 @Override
164 public boolean isAuthorizedByTemplate(String principalId, String namespaceCode, String permissionTemplateName,
165 Map<String, String> permissionDetails, Map<String, String> qualification) throws RiceIllegalArgumentException {
166 incomingParamCheck(principalId, "principalId");
167 incomingParamCheck(namespaceCode, "namespaceCode");
168 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
169 incomingParamCheck(qualification, "qualification");
170
171 if ( LOG.isDebugEnabled() ) {
172 logAuthorizationCheckByTemplate("Perm Templ", principalId, namespaceCode, permissionTemplateName, permissionDetails, qualification);
173 }
174
175 List<String> roleIds = getRoleIdsForPermissionTemplate(namespaceCode, permissionTemplateName, permissionDetails);
176 if (roleIds.isEmpty()) {
177 if (LOG.isDebugEnabled()) {
178 LOG.debug("Result: false");
179 }
180 return false;
181 }
182 boolean isAuthorized = roleService.principalHasRole(principalId, roleIds, qualification);
183 if (LOG.isDebugEnabled()) {
184 LOG.debug( "Result: " + isAuthorized );
185 }
186 return isAuthorized;
187
188 }
189 @Override
190 public List<Permission> getAuthorizedPermissions( String principalId,
191 String namespaceCode, String permissionName,
192 Map<String, String> qualification ) throws RiceIllegalArgumentException {
193 incomingParamCheck(principalId, "principalId");
194 incomingParamCheck(namespaceCode, "namespaceCode");
195 incomingParamCheck(permissionName, "permissionName");
196 incomingParamCheck(qualification, "qualification");
197
198
199 List<Permission> permissions = getPermissionsByName(namespaceCode, permissionName);
200
201 List<Permission> applicablePermissions = getMatchingPermissions( permissions, null );
202 List<Permission> permissionsForUser = getPermissionsForUser(principalId, applicablePermissions, qualification);
203 return permissionsForUser;
204 }
205 @Override
206 public List<Permission> getAuthorizedPermissionsByTemplate(String principalId, String namespaceCode,
207 String permissionTemplateName, Map<String, String> permissionDetails, Map<String, String> qualification) throws RiceIllegalArgumentException {
208 incomingParamCheck(principalId, "principalId");
209 incomingParamCheck(namespaceCode, "namespaceCode");
210 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
211 incomingParamCheck(qualification, "qualification");
212
213
214 List<Permission> permissions = getPermissionsByTemplateName(namespaceCode, permissionTemplateName);
215
216 List<Permission> applicablePermissions = getMatchingPermissions( permissions, permissionDetails );
217
218 return getPermissionsForUser(principalId, applicablePermissions, qualification);
219 }
220
221
222
223
224 protected List<Permission> getPermissionsForUser( String principalId, List<Permission> permissions,
225 Map<String, String> qualification ) {
226 List<Permission> results = new ArrayList<Permission>();
227 for ( Permission perm : permissions ) {
228 List<String> roleIds = getRoleIdsForPermissions( Collections.singletonList(perm) );
229 if ( roleIds != null && !roleIds.isEmpty() ) {
230 if ( roleService.principalHasRole( principalId, roleIds, qualification) ) {
231 results.add( perm );
232 }
233 }
234 }
235 return Collections.unmodifiableList(results);
236 }
237
238 protected Map<String,PermissionTypeService> getPermissionTypeServicesByTemplateId( Collection<Permission> permissions ) {
239 Map<String,PermissionTypeService> permissionTypeServices = new HashMap<String, PermissionTypeService>( permissions.size() );
240 for (Permission perm : permissions) {
241 if(!permissionTypeServices.containsKey(perm.getTemplate().getId())) {
242 permissionTypeServices.put(perm.getTemplate().getId(), getPermissionTypeService(perm.getTemplate()));
243 }
244 }
245 return permissionTypeServices;
246 }
247
248 protected Map<String,List<Permission>> groupPermissionsByTemplate(Collection<Permission> permissions) {
249 Map<String,List<Permission>> results = new HashMap<String,List<Permission>>();
250 for (Permission perm : permissions) {
251 List<Permission> perms = results.get(perm.getTemplate().getId());
252 if (perms == null) {
253 perms = new ArrayList<Permission>();
254 results.put(perm.getTemplate().getId(), perms);
255 }
256 perms.add(perm);
257 }
258 return results;
259 }
260
261
262
263
264
265 protected List<Permission> getMatchingPermissions( List<Permission> permissions, Map<String, String> permissionDetails ) {
266 List<String> permissionIds = new ArrayList<String>(permissions.size());
267 for (Permission permission : permissions) {
268 permissionIds.add(permission.getId());
269 }
270 String cacheKey = new StringBuilder("{getMatchingPermissions}")
271 .append("permissionIds=").append(CacheKeyUtils.key(permissionIds)).append("|")
272 .append("permissionDetails=").append(CacheKeyUtils.mapKey(permissionDetails)).toString();
273 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
274 if (cachedValue != null && cachedValue.get() instanceof List) {
275 return ((List<Permission>)cachedValue.get());
276 }
277
278 List<Permission> applicablePermissions = new ArrayList<Permission>();
279 if ( permissionDetails == null || permissionDetails.isEmpty() ) {
280
281 for ( Permission perm : permissions ) {
282 applicablePermissions.add(perm);
283 }
284 } else {
285
286
287 Map<String,PermissionTypeService> permissionTypeServices = getPermissionTypeServicesByTemplateId(permissions);
288
289 Map<String, List<Permission>> permissionMap = groupPermissionsByTemplate(permissions);
290
291
292 for ( Map.Entry<String,List<Permission>> entry : permissionMap.entrySet() ) {
293 PermissionTypeService permissionTypeService = permissionTypeServices.get( entry.getKey() );
294 List<Permission> permissionList = entry.getValue();
295 applicablePermissions.addAll( permissionTypeService.getMatchingPermissions( permissionDetails, permissionList ) );
296 }
297 }
298 applicablePermissions = Collections.unmodifiableList(applicablePermissions);
299 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, applicablePermissions);
300 return applicablePermissions;
301 }
302
303
304 @Override
305 public List<Assignee> getPermissionAssignees( String namespaceCode, String permissionName,
306 Map<String, String> qualification ) throws RiceIllegalArgumentException {
307 incomingParamCheck(namespaceCode, "namespaceCode");
308 incomingParamCheck(permissionName, "permissionName");
309 incomingParamCheck(qualification, "qualification");
310
311 List<String> roleIds = getRoleIdsForPermission( namespaceCode, permissionName);
312 if ( roleIds.isEmpty() ) {
313 return Collections.emptyList();
314 }
315 Collection<RoleMembership> roleMembers = roleService.getRoleMembers( roleIds,qualification );
316 List<Assignee> results = new ArrayList<Assignee>();
317 for ( RoleMembership rm : roleMembers ) {
318 List<DelegateType.Builder> delegateBuilderList = new ArrayList<DelegateType.Builder>();
319 if (!rm.getDelegates().isEmpty()) {
320 for (DelegateType delegate : rm.getDelegates()){
321 delegateBuilderList.add(DelegateType.Builder.create(delegate));
322 }
323 }
324 if ( MemberType.PRINCIPAL.equals(rm.getType()) ) {
325 results.add (Assignee.Builder.create(rm.getMemberId(), null, delegateBuilderList).build());
326 } else if ( MemberType.GROUP.equals(rm.getType()) ) {
327 results.add (Assignee.Builder.create(null, rm.getMemberId(), delegateBuilderList).build());
328 }
329 }
330
331 return Collections.unmodifiableList(results);
332 }
333
334 @Override
335 public List<Assignee> getPermissionAssigneesByTemplate(String namespaceCode, String permissionTemplateName,
336 Map<String, String> permissionDetails, Map<String, String> qualification) throws RiceIllegalArgumentException {
337 incomingParamCheck(namespaceCode, "namespaceCode");
338 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
339 incomingParamCheck(qualification, "qualification");
340
341 List<String> roleIds = getRoleIdsForPermissionTemplate( namespaceCode, permissionTemplateName, permissionDetails);
342 if ( roleIds.isEmpty() ) {
343 return Collections.emptyList();
344 }
345 Collection<RoleMembership> roleMembers = roleService.getRoleMembers( roleIds,qualification);
346 List<Assignee> results = new ArrayList<Assignee>();
347 for ( RoleMembership rm : roleMembers ) {
348 List<DelegateType.Builder> delegateBuilderList = new ArrayList<DelegateType.Builder>();
349 if (!rm.getDelegates().isEmpty()) {
350 for (DelegateType delegate : rm.getDelegates()){
351 delegateBuilderList.add(DelegateType.Builder.create(delegate));
352 }
353 }
354 if ( MemberType.PRINCIPAL.equals(rm.getType()) ) {
355 results.add (Assignee.Builder.create(rm.getMemberId(), null, delegateBuilderList).build());
356 } else {
357 results.add (Assignee.Builder.create(null, rm.getMemberId(), delegateBuilderList).build());
358 }
359 }
360 return Collections.unmodifiableList(results);
361 }
362
363 @Override
364 public boolean isPermissionDefined( String namespaceCode, String permissionName ) throws RiceIllegalArgumentException {
365 incomingParamCheck(namespaceCode, "namespaceCode");
366 incomingParamCheck(permissionName, "permissionName");
367
368
369 List<Permission> permissions = getPermissionsByName(namespaceCode, permissionName);
370
371 return !getMatchingPermissions(permissions, null).isEmpty();
372 }
373
374 @Override
375 public boolean isPermissionDefinedByTemplate(String namespaceCode, String permissionTemplateName,
376 Map<String, String> permissionDetails) throws RiceIllegalArgumentException {
377
378 incomingParamCheck(namespaceCode, "namespaceCode");
379 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
380
381
382 List<Permission> permissions = getPermissionsByTemplateName(namespaceCode, permissionTemplateName);
383
384 return !getMatchingPermissions(permissions, permissionDetails).isEmpty();
385 }
386
387 @Override
388 public List<String> getRoleIdsForPermission(String namespaceCode, String permissionName) throws RiceIllegalArgumentException {
389 incomingParamCheck(namespaceCode, "namespaceCode");
390 incomingParamCheck(permissionName, "permissionName");
391
392
393 String cacheKey = new StringBuilder("{RoleIds}")
394 .append("namespaceCode=").append(namespaceCode).append("|")
395 .append("name=").append(permissionName).toString();
396 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
397 if (cachedValue != null && cachedValue.get() instanceof List) {
398 return ((List<String>)cachedValue.get());
399 }
400
401 List<Permission> permissions = getPermissionsByName(namespaceCode, permissionName);
402
403 List<Permission> applicablePermissions = getMatchingPermissions(permissions, null);
404 List<String> roleIds = getRoleIdsForPermissions(applicablePermissions);
405 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, roleIds);
406 return roleIds;
407 }
408
409 protected List<String> getRoleIdsForPermissionTemplate(String namespaceCode,
410 String permissionTemplateName,
411 Map<String, String> permissionDetails) {
412 String cacheKey = new StringBuilder("{getRoleIdsForPermissionTemplate}")
413 .append("namespaceCode=").append(namespaceCode).append("|")
414 .append("permissionTemplateName=").append(permissionTemplateName).append("|")
415 .append("permissionDetails=").append(CacheKeyUtils.mapKey(permissionDetails)).toString();
416 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
417 if (cachedValue != null && cachedValue.get() instanceof List) {
418 return ((List<String>)cachedValue.get());
419 }
420
421 List<Permission> permissions = getPermissionsByTemplateName(namespaceCode, permissionTemplateName);
422
423 List<Permission> applicablePermissions = getMatchingPermissions(permissions, permissionDetails);
424 List<String> roleIds = getRoleIdsForPermissions(applicablePermissions);
425 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, roleIds);
426 return roleIds;
427 }
428
429
430
431
432
433 @Override
434 public Permission getPermission(String permissionId) throws RiceIllegalArgumentException {
435 incomingParamCheck(permissionId, "permissionId");
436 PermissionBo impl = getPermissionImpl(permissionId);
437 if (impl != null) {
438 return PermissionBo.to(impl);
439 }
440 return null;
441 }
442
443 @Override
444 public List<Permission> findPermissionsByTemplate(String namespaceCode, String permissionTemplateName) throws RiceIllegalArgumentException {
445 incomingParamCheck(namespaceCode, "namespaceCode");
446 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
447
448 List<Permission> perms = getPermissionsByTemplateName(namespaceCode, permissionTemplateName);
449 List<Permission> results = new ArrayList<Permission>(perms.size());
450 for (Permission perm : perms) {
451 results.add(perm);
452 }
453 return Collections.unmodifiableList(results);
454 }
455
456 protected PermissionBo getPermissionImpl(String permissionId) throws RiceIllegalArgumentException {
457 incomingParamCheck(permissionId, "permissionId");
458
459 HashMap<String,Object> pk = new HashMap<String,Object>( 1 );
460 pk.put( KimConstants.PrimaryKeyConstants.PERMISSION_ID, permissionId );
461 return businessObjectService.findByPrimaryKey( PermissionBo.class, pk );
462 }
463
464 protected List<Permission> getPermissionsByTemplateName( String namespaceCode, String permissionTemplateName ){
465 String cacheKey = new StringBuilder("{getPermissionsByTemplateName}")
466 .append("namespaceCode=").append(namespaceCode).append("|")
467 .append("permissionTemplateName=").append(permissionTemplateName).toString();
468 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
469 if (cachedValue != null && cachedValue.get() instanceof List) {
470 return ((List<Permission>)cachedValue.get());
471 }
472 HashMap<String,Object> criteria = new HashMap<String,Object>(3);
473 criteria.put("template.namespaceCode", namespaceCode);
474 criteria.put("template.name", permissionTemplateName);
475 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
476 List<Permission> permissions =
477 toPermissions(businessObjectService.findMatching(PermissionBo.class, criteria));
478 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, permissions);
479 return permissions;
480 }
481
482 protected List<Permission> getPermissionsByName( String namespaceCode, String permissionName ) {
483 String cacheKey = new StringBuilder("{getPermissionsByName}")
484 .append("namespaceCode=").append(namespaceCode).append("|")
485 .append("permissionName=").append(permissionName).toString();
486 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
487 if (cachedValue != null && cachedValue.get() instanceof List) {
488 return ((List<Permission>)cachedValue.get());
489 }
490 HashMap<String,Object> criteria = new HashMap<String,Object>(3);
491 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
492 criteria.put(KimConstants.UniqueKeyConstants.PERMISSION_NAME, permissionName);
493 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
494 List<Permission> permissions =
495 toPermissions(businessObjectService.findMatching( PermissionBo.class, criteria ));
496 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, permissions);
497 return permissions;
498 }
499
500 @Override
501 public Template getPermissionTemplate(String permissionTemplateId) throws RiceIllegalArgumentException {
502 incomingParamCheck(permissionTemplateId, "permissionTemplateId");
503
504 PermissionTemplateBo impl = businessObjectService.findBySinglePrimaryKey( PermissionTemplateBo.class, permissionTemplateId );
505 if ( impl != null ) {
506 return PermissionTemplateBo.to(impl);
507 }
508 return null;
509 }
510
511 @Override
512 public Template findPermTemplateByNamespaceCodeAndName(String namespaceCode,
513 String permissionTemplateName) throws RiceIllegalArgumentException {
514 incomingParamCheck(namespaceCode, "namespaceCode");
515 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
516
517 Map<String,String> criteria = new HashMap<String,String>(2);
518 criteria.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
519 criteria.put( KimConstants.UniqueKeyConstants.PERMISSION_TEMPLATE_NAME, permissionTemplateName );
520 PermissionTemplateBo impl = businessObjectService.findByPrimaryKey( PermissionTemplateBo.class, criteria );
521 if ( impl != null ) {
522 return PermissionTemplateBo.to(impl);
523 }
524 return null;
525 }
526
527 @Override
528 public List<Template> getAllTemplates() {
529 if ( allTemplates.isEmpty() ) {
530 Map<String,String> criteria = new HashMap<String,String>(1);
531 criteria.put( KRADPropertyConstants.ACTIVE, "Y" );
532 List<PermissionTemplateBo> impls = (List<PermissionTemplateBo>) businessObjectService.findMatching( PermissionTemplateBo.class, criteria );
533 List<Template> infos = new ArrayList<Template>( impls.size() );
534 for ( PermissionTemplateBo impl : impls ) {
535 infos.add( PermissionTemplateBo.to(impl) );
536 }
537 Collections.sort(infos, new Comparator<Template>() {
538 @Override public int compare(Template tmpl1,
539 Template tmpl2) {
540
541 int result = tmpl1.getNamespaceCode().compareTo(tmpl2.getNamespaceCode());
542 if ( result != 0 ) {
543 return result;
544 }
545 result = tmpl1.getName().compareTo(tmpl2.getName());
546 return result;
547 }
548 });
549 allTemplates.addAll(infos);
550 }
551 return Collections.unmodifiableList(allTemplates);
552 }
553
554
555 @Override
556 public Permission createPermission(Permission permission)
557 throws RiceIllegalArgumentException, RiceIllegalStateException {
558 incomingParamCheck(permission, "permission");
559
560 if (StringUtils.isNotBlank(permission.getId()) && getPermission(permission.getId()) != null) {
561 throw new RiceIllegalStateException("the permission to create already exists: " + permission);
562 }
563 List<PermissionAttributeBo> attrBos = Collections.emptyList();
564 if (permission.getTemplate() != null) {
565 attrBos = KimAttributeDataBo.createFrom(PermissionAttributeBo.class, permission.getAttributes(), permission.getTemplate().getKimTypeId());
566 }
567 PermissionBo bo = PermissionBo.from(permission);
568 if (bo.getTemplate() == null && bo.getTemplateId() != null) {
569 bo.setTemplate(PermissionTemplateBo.from(getPermissionTemplate(bo.getTemplateId())));
570 }
571 bo.setAttributeDetails(attrBos);
572 return PermissionBo.to(businessObjectService.save(bo));
573 }
574
575 @Override
576 public Permission updatePermission(Permission permission)
577 throws RiceIllegalArgumentException, RiceIllegalStateException {
578 incomingParamCheck(permission, "permission");
579
580 PermissionBo oldPermission = getPermissionImpl(permission.getId());
581 if (StringUtils.isBlank(permission.getId()) || oldPermission == null) {
582 throw new RiceIllegalStateException("the permission does not exist: " + permission);
583 }
584
585
586
587 List<PermissionAttributeBo> oldAttrBos = oldPermission.getAttributeDetails();
588
589 Map<String, PermissionAttributeBo> oldAttrMap = new HashMap<String, PermissionAttributeBo>();
590 for (PermissionAttributeBo oldAttr : oldAttrBos) {
591 oldAttrMap.put(oldAttr.getKimAttribute().getAttributeName(), oldAttr);
592 }
593 List<PermissionAttributeBo> newAttrBos = new ArrayList<PermissionAttributeBo>();
594 for (String key : permission.getAttributes().keySet()) {
595 if (oldAttrMap.containsKey(key)) {
596 PermissionAttributeBo updatedAttr = oldAttrMap.get(key);
597 updatedAttr.setAttributeValue(permission.getAttributes().get(key));
598 newAttrBos.add(updatedAttr);
599 } else {
600 newAttrBos.addAll(KimAttributeDataBo.createFrom(PermissionAttributeBo.class, Collections.singletonMap(key, permission.getAttributes().get(key)), permission.getTemplate().getKimTypeId()));
601 }
602 }
603 PermissionBo bo = PermissionBo.from(permission);
604 if (CollectionUtils.isNotEmpty(newAttrBos)) {
605 if(null!= bo.getAttributeDetails()) {
606 bo.getAttributeDetails().clear();
607 }
608 bo.setAttributeDetails(newAttrBos);
609 }
610 if (bo.getTemplate() == null && bo.getTemplateId() != null) {
611 bo.setTemplate(PermissionTemplateBo.from(getPermissionTemplate(bo.getTemplateId())));
612 }
613
614 return PermissionBo.to(businessObjectService.save(bo));
615 }
616
617 @Override
618 public Permission findPermByNamespaceCodeAndName(String namespaceCode, String permissionName)
619 throws RiceIllegalArgumentException {
620 incomingParamCheck(namespaceCode, "namespaceCode");
621 incomingParamCheck(permissionName, "permissionName");
622
623 PermissionBo permissionBo = getPermissionBoByName(namespaceCode, permissionName);
624 if (permissionBo != null) {
625 return PermissionBo.to(permissionBo);
626 }
627 return null;
628 }
629
630 protected PermissionBo getPermissionBoByName(String namespaceCode, String permissionName) {
631 if (StringUtils.isBlank(namespaceCode)
632 || StringUtils.isBlank(permissionName)) {
633 return null;
634 }
635 Map<String, String> criteria = new HashMap<String, String>();
636 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
637 criteria.put(KimConstants.UniqueKeyConstants.NAME, permissionName);
638 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
639
640 return businessObjectService.findByPrimaryKey(PermissionBo.class, criteria);
641 }
642
643 @Override
644 public PermissionQueryResults findPermissions(final QueryByCriteria queryByCriteria)
645 throws RiceIllegalArgumentException {
646 incomingParamCheck(queryByCriteria, "queryByCriteria");
647
648 LookupCustomizer.Builder<PermissionBo> lc = LookupCustomizer.Builder.create();
649 lc.setPredicateTransform(AttributeTransform.getInstance());
650
651 GenericQueryResults<PermissionBo> results = criteriaLookupService.lookup(PermissionBo.class, queryByCriteria, lc.build());
652
653 PermissionQueryResults.Builder builder = PermissionQueryResults.Builder.create();
654 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
655 builder.setTotalRowCount(results.getTotalRowCount());
656
657 final List<Permission.Builder> ims = new ArrayList<Permission.Builder>();
658 for (PermissionBo bo : results.getResults()) {
659 ims.add(Permission.Builder.create(bo));
660 }
661
662 builder.setResults(ims);
663 return builder.build();
664 }
665
666 @Override
667 public TemplateQueryResults findPermissionTemplates(final QueryByCriteria queryByCriteria)
668 throws RiceIllegalArgumentException {
669 incomingParamCheck(queryByCriteria, "queryByCriteria");
670
671 GenericQueryResults<PermissionTemplateBo> results = criteriaLookupService.lookup(PermissionTemplateBo.class, queryByCriteria);
672
673 TemplateQueryResults.Builder builder = TemplateQueryResults.Builder.create();
674 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
675 builder.setTotalRowCount(results.getTotalRowCount());
676
677 final List<Template.Builder> ims = new ArrayList<Template.Builder>();
678 for (PermissionTemplateBo bo : results.getResults()) {
679 ims.add(Template.Builder.create(bo));
680 }
681
682 builder.setResults(ims);
683 return builder.build();
684 }
685
686 private List<String> getRoleIdsForPermissions( Collection<Permission> permissions ) {
687 if (CollectionUtils.isEmpty(permissions)) {
688 return Collections.emptyList();
689 }
690 List<String> ids = new ArrayList<String>();
691 for (Permission p : permissions) {
692 ids.add(p.getId());
693 }
694
695 return getRoleIdsForPermissionIds(ids);
696 }
697
698 private List<String> getRoleIdsForPermissionIds(Collection<String> permissionIds) {
699 if (CollectionUtils.isEmpty(permissionIds)) {
700 return Collections.emptyList();
701 }
702 String cacheKey = new StringBuilder("{getRoleIdsForPermissionIds}")
703 .append("permissionIds=").append(CacheKeyUtils.key(permissionIds)).toString();
704 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
705 if (cachedValue != null && cachedValue.get() instanceof List) {
706 return ((List<String>)cachedValue.get());
707 }
708 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(equal("active", "true"), in("permissionId", permissionIds.toArray(new String[]{})));
709 GenericQueryResults<RolePermissionBo> results = criteriaLookupService.lookup(RolePermissionBo.class, query);
710 List<String> roleIds = new ArrayList<String>();
711 for (RolePermissionBo bo : results.getResults()) {
712 roleIds.add(bo.getRoleId());
713 }
714 roleIds = Collections.unmodifiableList(roleIds);
715 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, roleIds);
716 return roleIds;
717 }
718
719
720
721
722
723
724 public void setKimTypeInfoService(KimTypeInfoService kimTypeInfoService) {
725 this.kimTypeInfoService = kimTypeInfoService;
726 }
727
728
729
730
731
732
733 public void setDefaultPermissionTypeService(PermissionTypeService defaultPermissionTypeService) {
734 this.defaultPermissionTypeService = defaultPermissionTypeService;
735 }
736
737
738
739
740
741
742 public void setRoleService(RoleService roleService) {
743 this.roleService = roleService;
744 }
745
746
747
748
749
750
751 public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
752 this.businessObjectService = businessObjectService;
753 }
754
755
756
757
758
759
760 public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
761 this.criteriaLookupService = criteriaLookupService;
762 }
763
764
765
766
767
768
769
770
771 public void setCacheManager(final CacheManager cacheManager) {
772 if (cacheManager == null) {
773 throw new IllegalArgumentException("cacheManager must not be null");
774 }
775 this.cacheManager = cacheManager;
776 }
777
778 private List<Permission> toPermissions(Collection<PermissionBo> permissionBos) {
779 if (CollectionUtils.isEmpty(permissionBos)) {
780 return new ArrayList<Permission>();
781 }
782 List<Permission> permissions = new ArrayList<Permission>(permissionBos.size());
783 for (PermissionBo permissionBo : permissionBos) {
784 permissions.add(PermissionBo.to(permissionBo));
785 }
786 return permissions;
787 }
788
789 protected void logAuthorizationCheck(String checkType, String principalId, String namespaceCode, String permissionName, Map<String, String> qualification ) {
790 StringBuilder sb = new StringBuilder();
791 sb.append( '\n' );
792 sb.append( "Is AuthZ for " ).append( checkType ).append( ": " ).append( namespaceCode ).append( "/" ).append( permissionName ).append( '\n' );
793 sb.append( " Principal: " ).append( principalId );
794 if ( principalId != null ) {
795 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
796 if ( principal != null ) {
797 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' );
798 }
799 }
800 sb.append( '\n' );
801 sb.append( " Qualifiers:\n" );
802 if ( qualification != null && !qualification.isEmpty() ) {
803 sb.append( qualification );
804 } else {
805 sb.append( " [null]\n" );
806 }
807 if (LOG.isTraceEnabled()) {
808 LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
809 } else {
810 LOG.debug(sb.toString());
811 }
812 }
813
814 protected void logAuthorizationCheckByTemplate(String checkType, String principalId, String namespaceCode, String permissionName,
815 Map<String, String> permissionDetails, Map<String, String> qualification ) {
816 StringBuilder sb = new StringBuilder();
817 sb.append( '\n' );
818 sb.append( "Is AuthZ for " ).append( checkType ).append( ": " ).append( namespaceCode ).append( "/" ).append( permissionName ).append( '\n' );
819 sb.append( " Principal: " ).append( principalId );
820 if ( principalId != null ) {
821 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
822 if ( principal != null ) {
823 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' );
824 }
825 }
826 sb.append( '\n' );
827 sb.append( " Details:\n" );
828 if ( permissionDetails != null ) {
829 sb.append( permissionDetails );
830 } else {
831 sb.append( " [null]\n" );
832 }
833 sb.append( " Qualifiers:\n" );
834 if ( qualification != null && !qualification.isEmpty() ) {
835 sb.append( qualification );
836 } else {
837 sb.append( " [null]\n" );
838 }
839 if (LOG.isTraceEnabled()) {
840 LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
841 } else {
842 LOG.debug(sb.toString());
843 }
844 }
845
846 private void incomingParamCheck(Object object, String name) {
847 if (object == null) {
848 throw new RiceIllegalArgumentException(name + " was null");
849 } else if (object instanceof String
850 && StringUtils.isBlank((String) object)) {
851 throw new RiceIllegalArgumentException(name + " was blank");
852 }
853 }
854
855
856 }