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("template.active", "Y");
476 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
477 List<Permission> permissions =
478 toPermissions(businessObjectService.findMatching(PermissionBo.class, criteria));
479 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, permissions);
480 return permissions;
481 }
482
483 protected List<Permission> getPermissionsByName( String namespaceCode, String permissionName ) {
484 String cacheKey = new StringBuilder("{getPermissionsByName}")
485 .append("namespaceCode=").append(namespaceCode).append("|")
486 .append("permissionName=").append(permissionName).toString();
487 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
488 if (cachedValue != null && cachedValue.get() instanceof List) {
489 return ((List<Permission>)cachedValue.get());
490 }
491 HashMap<String,Object> criteria = new HashMap<String,Object>(3);
492 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
493 criteria.put(KimConstants.UniqueKeyConstants.PERMISSION_NAME, permissionName);
494 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
495 List<Permission> permissions =
496 toPermissions(businessObjectService.findMatching( PermissionBo.class, criteria ));
497 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, permissions);
498 return permissions;
499 }
500
501 @Override
502 public Template getPermissionTemplate(String permissionTemplateId) throws RiceIllegalArgumentException {
503 incomingParamCheck(permissionTemplateId, "permissionTemplateId");
504
505 PermissionTemplateBo impl = businessObjectService.findBySinglePrimaryKey( PermissionTemplateBo.class, permissionTemplateId );
506 if ( impl != null ) {
507 return PermissionTemplateBo.to(impl);
508 }
509 return null;
510 }
511
512 @Override
513 public Template findPermTemplateByNamespaceCodeAndName(String namespaceCode,
514 String permissionTemplateName) throws RiceIllegalArgumentException {
515 incomingParamCheck(namespaceCode, "namespaceCode");
516 incomingParamCheck(permissionTemplateName, "permissionTemplateName");
517
518 Map<String,String> criteria = new HashMap<String,String>(2);
519 criteria.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
520 criteria.put( KimConstants.UniqueKeyConstants.PERMISSION_TEMPLATE_NAME, permissionTemplateName );
521 PermissionTemplateBo impl = businessObjectService.findByPrimaryKey( PermissionTemplateBo.class, criteria );
522 if ( impl != null ) {
523 return PermissionTemplateBo.to(impl);
524 }
525 return null;
526 }
527
528 @Override
529 public List<Template> getAllTemplates() {
530 if ( allTemplates.isEmpty() ) {
531 Map<String,String> criteria = new HashMap<String,String>(1);
532 criteria.put( KRADPropertyConstants.ACTIVE, "Y" );
533 List<PermissionTemplateBo> impls = (List<PermissionTemplateBo>) businessObjectService.findMatching( PermissionTemplateBo.class, criteria );
534 List<Template> infos = new ArrayList<Template>( impls.size() );
535 for ( PermissionTemplateBo impl : impls ) {
536 infos.add( PermissionTemplateBo.to(impl) );
537 }
538 Collections.sort(infos, new Comparator<Template>() {
539 @Override public int compare(Template tmpl1,
540 Template tmpl2) {
541
542 int result = tmpl1.getNamespaceCode().compareTo(tmpl2.getNamespaceCode());
543 if ( result != 0 ) {
544 return result;
545 }
546 result = tmpl1.getName().compareTo(tmpl2.getName());
547 return result;
548 }
549 });
550 allTemplates.addAll(infos);
551 }
552 return Collections.unmodifiableList(allTemplates);
553 }
554
555
556 @Override
557 public Permission createPermission(Permission permission)
558 throws RiceIllegalArgumentException, RiceIllegalStateException {
559 incomingParamCheck(permission, "permission");
560
561 if (StringUtils.isNotBlank(permission.getId()) && getPermission(permission.getId()) != null) {
562 throw new RiceIllegalStateException("the permission to create already exists: " + permission);
563 }
564 List<PermissionAttributeBo> attrBos = Collections.emptyList();
565 if (permission.getTemplate() != null) {
566 attrBos = KimAttributeDataBo.createFrom(PermissionAttributeBo.class, permission.getAttributes(), permission.getTemplate().getKimTypeId());
567 }
568 PermissionBo bo = PermissionBo.from(permission);
569 if (bo.getTemplate() == null && bo.getTemplateId() != null) {
570 bo.setTemplate(PermissionTemplateBo.from(getPermissionTemplate(bo.getTemplateId())));
571 }
572 bo.setAttributeDetails(attrBos);
573 return PermissionBo.to(businessObjectService.save(bo));
574 }
575
576 @Override
577 public Permission updatePermission(Permission permission)
578 throws RiceIllegalArgumentException, RiceIllegalStateException {
579 incomingParamCheck(permission, "permission");
580
581 PermissionBo oldPermission = getPermissionImpl(permission.getId());
582 if (StringUtils.isBlank(permission.getId()) || oldPermission == null) {
583 throw new RiceIllegalStateException("the permission does not exist: " + permission);
584 }
585
586
587
588 List<PermissionAttributeBo> oldAttrBos = oldPermission.getAttributeDetails();
589
590 Map<String, PermissionAttributeBo> oldAttrMap = new HashMap<String, PermissionAttributeBo>();
591 for (PermissionAttributeBo oldAttr : oldAttrBos) {
592 oldAttrMap.put(oldAttr.getKimAttribute().getAttributeName(), oldAttr);
593 }
594 List<PermissionAttributeBo> newAttrBos = new ArrayList<PermissionAttributeBo>();
595 for (String key : permission.getAttributes().keySet()) {
596 if (oldAttrMap.containsKey(key)) {
597 PermissionAttributeBo updatedAttr = oldAttrMap.get(key);
598 updatedAttr.setAttributeValue(permission.getAttributes().get(key));
599 newAttrBos.add(updatedAttr);
600 } else {
601 newAttrBos.addAll(KimAttributeDataBo.createFrom(PermissionAttributeBo.class, Collections.singletonMap(key, permission.getAttributes().get(key)), permission.getTemplate().getKimTypeId()));
602 }
603 }
604 PermissionBo bo = PermissionBo.from(permission);
605 if (CollectionUtils.isNotEmpty(newAttrBos)) {
606 if(null!= bo.getAttributeDetails()) {
607 bo.getAttributeDetails().clear();
608 }
609 bo.setAttributeDetails(newAttrBos);
610 }
611 if (bo.getTemplate() == null && bo.getTemplateId() != null) {
612 bo.setTemplate(PermissionTemplateBo.from(getPermissionTemplate(bo.getTemplateId())));
613 }
614
615 return PermissionBo.to(businessObjectService.save(bo));
616 }
617
618 @Override
619 public Permission findPermByNamespaceCodeAndName(String namespaceCode, String permissionName)
620 throws RiceIllegalArgumentException {
621 incomingParamCheck(namespaceCode, "namespaceCode");
622 incomingParamCheck(permissionName, "permissionName");
623
624 PermissionBo permissionBo = getPermissionBoByName(namespaceCode, permissionName);
625 if (permissionBo != null) {
626 return PermissionBo.to(permissionBo);
627 }
628 return null;
629 }
630
631 protected PermissionBo getPermissionBoByName(String namespaceCode, String permissionName) {
632 if (StringUtils.isBlank(namespaceCode)
633 || StringUtils.isBlank(permissionName)) {
634 return null;
635 }
636 Map<String, String> criteria = new HashMap<String, String>();
637 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
638 criteria.put(KimConstants.UniqueKeyConstants.NAME, permissionName);
639 criteria.put(KRADPropertyConstants.ACTIVE, "Y");
640
641 return businessObjectService.findByPrimaryKey(PermissionBo.class, criteria);
642 }
643
644 @Override
645 public PermissionQueryResults findPermissions(final QueryByCriteria queryByCriteria)
646 throws RiceIllegalArgumentException {
647 incomingParamCheck(queryByCriteria, "queryByCriteria");
648
649 LookupCustomizer.Builder<PermissionBo> lc = LookupCustomizer.Builder.create();
650 lc.setPredicateTransform(AttributeTransform.getInstance());
651
652 GenericQueryResults<PermissionBo> results = criteriaLookupService.lookup(PermissionBo.class, queryByCriteria, lc.build());
653
654 PermissionQueryResults.Builder builder = PermissionQueryResults.Builder.create();
655 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
656 builder.setTotalRowCount(results.getTotalRowCount());
657
658 final List<Permission.Builder> ims = new ArrayList<Permission.Builder>();
659 for (PermissionBo bo : results.getResults()) {
660 ims.add(Permission.Builder.create(bo));
661 }
662
663 builder.setResults(ims);
664 return builder.build();
665 }
666
667 @Override
668 public TemplateQueryResults findPermissionTemplates(final QueryByCriteria queryByCriteria)
669 throws RiceIllegalArgumentException {
670 incomingParamCheck(queryByCriteria, "queryByCriteria");
671
672 GenericQueryResults<PermissionTemplateBo> results = criteriaLookupService.lookup(PermissionTemplateBo.class, queryByCriteria);
673
674 TemplateQueryResults.Builder builder = TemplateQueryResults.Builder.create();
675 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
676 builder.setTotalRowCount(results.getTotalRowCount());
677
678 final List<Template.Builder> ims = new ArrayList<Template.Builder>();
679 for (PermissionTemplateBo bo : results.getResults()) {
680 ims.add(Template.Builder.create(bo));
681 }
682
683 builder.setResults(ims);
684 return builder.build();
685 }
686
687 private List<String> getRoleIdsForPermissions( Collection<Permission> permissions ) {
688 if (CollectionUtils.isEmpty(permissions)) {
689 return Collections.emptyList();
690 }
691 List<String> ids = new ArrayList<String>();
692 for (Permission p : permissions) {
693 ids.add(p.getId());
694 }
695
696 return getRoleIdsForPermissionIds(ids);
697 }
698
699 private List<String> getRoleIdsForPermissionIds(Collection<String> permissionIds) {
700 if (CollectionUtils.isEmpty(permissionIds)) {
701 return Collections.emptyList();
702 }
703 String cacheKey = new StringBuilder("{getRoleIdsForPermissionIds}")
704 .append("permissionIds=").append(CacheKeyUtils.key(permissionIds)).toString();
705 Cache.ValueWrapper cachedValue = cacheManager.getCache(Permission.Cache.NAME).get(cacheKey);
706 if (cachedValue != null && cachedValue.get() instanceof List) {
707 return ((List<String>)cachedValue.get());
708 }
709 QueryByCriteria query = QueryByCriteria.Builder.fromPredicates(equal("active", "true"), in("permissionId", permissionIds.toArray(new String[]{})));
710 GenericQueryResults<RolePermissionBo> results = criteriaLookupService.lookup(RolePermissionBo.class, query);
711 List<String> roleIds = new ArrayList<String>();
712 for (RolePermissionBo bo : results.getResults()) {
713 roleIds.add(bo.getRoleId());
714 }
715 roleIds = Collections.unmodifiableList(roleIds);
716 cacheManager.getCache(Permission.Cache.NAME).put(cacheKey, roleIds);
717 return roleIds;
718 }
719
720
721
722
723
724
725 public void setKimTypeInfoService(KimTypeInfoService kimTypeInfoService) {
726 this.kimTypeInfoService = kimTypeInfoService;
727 }
728
729
730
731
732
733
734 public void setDefaultPermissionTypeService(PermissionTypeService defaultPermissionTypeService) {
735 this.defaultPermissionTypeService = defaultPermissionTypeService;
736 }
737
738
739
740
741
742
743 public void setRoleService(RoleService roleService) {
744 this.roleService = roleService;
745 }
746
747
748
749
750
751
752 public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
753 this.businessObjectService = businessObjectService;
754 }
755
756
757
758
759
760
761 public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
762 this.criteriaLookupService = criteriaLookupService;
763 }
764
765
766
767
768
769
770
771
772 public void setCacheManager(final CacheManager cacheManager) {
773 if (cacheManager == null) {
774 throw new IllegalArgumentException("cacheManager must not be null");
775 }
776 this.cacheManager = cacheManager;
777 }
778
779 private List<Permission> toPermissions(Collection<PermissionBo> permissionBos) {
780 if (CollectionUtils.isEmpty(permissionBos)) {
781 return new ArrayList<Permission>();
782 }
783 List<Permission> permissions = new ArrayList<Permission>(permissionBos.size());
784 for (PermissionBo permissionBo : permissionBos) {
785 permissions.add(PermissionBo.to(permissionBo));
786 }
787 return permissions;
788 }
789
790 protected void logAuthorizationCheck(String checkType, String principalId, String namespaceCode, String permissionName, Map<String, String> qualification ) {
791 StringBuilder sb = new StringBuilder();
792 sb.append( '\n' );
793 sb.append( "Is AuthZ for " ).append( checkType ).append( ": " ).append( namespaceCode ).append( "/" ).append( permissionName ).append( '\n' );
794 sb.append( " Principal: " ).append( principalId );
795 if ( principalId != null ) {
796 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
797 if ( principal != null ) {
798 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' );
799 }
800 }
801 sb.append( '\n' );
802 sb.append( " Qualifiers:\n" );
803 if ( qualification != null && !qualification.isEmpty() ) {
804 sb.append( qualification );
805 } else {
806 sb.append( " [null]\n" );
807 }
808 if (LOG.isTraceEnabled()) {
809 LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
810 } else {
811 LOG.debug(sb.toString());
812 }
813 }
814
815 protected void logAuthorizationCheckByTemplate(String checkType, String principalId, String namespaceCode, String permissionName,
816 Map<String, String> permissionDetails, Map<String, String> qualification ) {
817 StringBuilder sb = new StringBuilder();
818 sb.append( '\n' );
819 sb.append( "Is AuthZ for " ).append( checkType ).append( ": " ).append( namespaceCode ).append( "/" ).append( permissionName ).append( '\n' );
820 sb.append( " Principal: " ).append( principalId );
821 if ( principalId != null ) {
822 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
823 if ( principal != null ) {
824 sb.append( " (" ).append( principal.getPrincipalName() ).append( ')' );
825 }
826 }
827 sb.append( '\n' );
828 sb.append( " Details:\n" );
829 if ( permissionDetails != null ) {
830 sb.append( permissionDetails );
831 } else {
832 sb.append( " [null]\n" );
833 }
834 sb.append( " Qualifiers:\n" );
835 if ( qualification != null && !qualification.isEmpty() ) {
836 sb.append( qualification );
837 } else {
838 sb.append( " [null]\n" );
839 }
840 if (LOG.isTraceEnabled()) {
841 LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
842 } else {
843 LOG.debug(sb.toString());
844 }
845 }
846
847 private void incomingParamCheck(Object object, String name) {
848 if (object == null) {
849 throw new RiceIllegalArgumentException(name + " was null");
850 } else if (object instanceof String
851 && StringUtils.isBlank((String) object)) {
852 throw new RiceIllegalArgumentException(name + " was blank");
853 }
854 }
855
856
857 }