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