001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019 */
020
021 package org.granite.tide.spring.security;
022
023 import java.util.ArrayList;
024 import java.util.HashSet;
025 import java.util.List;
026 import java.util.Set;
027 import java.util.StringTokenizer;
028
029 import org.granite.tide.annotations.TideEnabled;
030 import org.springframework.security.Authentication;
031 import org.springframework.security.acls.Acl;
032 import org.springframework.security.acls.AclService;
033 import org.springframework.security.acls.NotFoundException;
034 import org.springframework.security.acls.Permission;
035 import org.springframework.security.acls.domain.DefaultPermissionFactory;
036 import org.springframework.security.acls.domain.PermissionFactory;
037 import org.springframework.security.acls.objectidentity.ObjectIdentity;
038 import org.springframework.security.acls.objectidentity.ObjectIdentityRetrievalStrategy;
039 import org.springframework.security.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl;
040 import org.springframework.security.acls.sid.Sid;
041 import org.springframework.security.acls.sid.SidRetrievalStrategy;
042 import org.springframework.security.acls.sid.SidRetrievalStrategyImpl;
043 import org.springframework.security.context.SecurityContextHolder;
044
045
046 /**
047 * @author William DRAI
048 *
049 * Adapted from the Spring security JSP taglib
050 */
051 @TideEnabled
052 public class AclIdentity extends Identity {
053
054 private SidRetrievalStrategy sidRetrievalStrategy = null;
055 private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = null;
056 private AclService aclService = null;
057
058
059 public AclIdentity() {
060 sidRetrievalStrategy = new SidRetrievalStrategyImpl();
061 objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
062 }
063
064 public void setSidRetrievalStrategy(SidRetrievalStrategy strategy) {
065 sidRetrievalStrategy = strategy;
066 }
067
068 public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy strategy) {
069 objectIdentityRetrievalStrategy = strategy;
070 }
071
072 public void setAclService(AclService aclService) {
073 this.aclService = aclService;
074 }
075
076
077 public boolean hasPermission(Object entity, String permissions) {
078 if (entity == null)
079 return true;
080
081 List<Permission> requiredPermissions = null;
082 try {
083 requiredPermissions = parsePermissionsString(permissions);
084 }
085 catch (NumberFormatException nfe) {
086 throw new RuntimeException(nfe);
087 }
088
089 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
090 if (authentication == null)
091 return false;
092
093 Sid[] sids = sidRetrievalStrategy.getSids(authentication);
094 ObjectIdentity oid = objectIdentityRetrievalStrategy.getObjectIdentity(entity);
095
096 // Obtain aclEntrys applying to the current Authentication object
097 try {
098 Acl acl = aclService.readAclById(oid, sids);
099
100 return acl.isGranted(requiredPermissions.toArray(new Permission[requiredPermissions.size()]), sids, false);
101 }
102 catch (NotFoundException nfe) {
103 return false;
104 }
105 }
106
107 private List<Permission> parsePermissionsString(String integersString) throws NumberFormatException {
108 final Set<Permission> permissions = new HashSet<Permission>();
109 final StringTokenizer tokenizer;
110 tokenizer = new StringTokenizer(integersString, ",", false);
111
112 PermissionFactory pf = new DefaultPermissionFactory();
113 while (tokenizer.hasMoreTokens()) {
114 String integer = tokenizer.nextToken();
115 permissions.add(pf.buildFromMask(new Integer(integer).intValue()));
116 }
117
118 return new ArrayList<Permission>(permissions);
119 }
120 }