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.List;
025    import java.util.StringTokenizer;
026    
027    import org.granite.tide.annotations.TideEnabled;
028    import org.springframework.security.acls.domain.DefaultPermissionFactory;
029    import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
030    import org.springframework.security.acls.domain.PermissionFactory;
031    import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
032    import org.springframework.security.acls.model.Acl;
033    import org.springframework.security.acls.model.AclService;
034    import org.springframework.security.acls.model.NotFoundException;
035    import org.springframework.security.acls.model.ObjectIdentity;
036    import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
037    import org.springframework.security.acls.model.Permission;
038    import org.springframework.security.acls.model.Sid;
039    import org.springframework.security.acls.model.SidRetrievalStrategy;
040    import org.springframework.security.core.Authentication;
041    import org.springframework.security.core.context.SecurityContextHolder;
042    
043    
044    /**
045     *      @author William DRAI
046     * 
047     *      Adapted from the Spring security JSP taglib
048     */
049    @TideEnabled
050    public class AclIdentity3 extends Identity3 {
051        
052        private SidRetrievalStrategy sidRetrievalStrategy = null;
053        private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = null;
054        private AclService aclService = null;
055        
056        
057        public AclIdentity3() {
058            sidRetrievalStrategy = new SidRetrievalStrategyImpl();
059            objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
060        }
061        
062        public void setSidRetrievalStrategy(SidRetrievalStrategy strategy) {
063            sidRetrievalStrategy = strategy;
064        }
065        
066        public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy strategy) {
067            objectIdentityRetrievalStrategy = strategy;
068        }
069        
070        public void setAclService(AclService aclService) {
071            this.aclService = aclService;
072        }
073        
074        
075        public boolean hasPermission(Object entity, String permissions) {
076            if (entity == null)
077                    return true;
078            
079            List<Permission> requiredPermissions = null;
080            try {
081                requiredPermissions = parsePermissionsString(permissions);
082            } 
083            catch (NumberFormatException nfe) {
084                throw new RuntimeException(nfe);
085            }
086    
087            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
088            if (authentication == null)
089                    return false;
090    
091            List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
092            ObjectIdentity oid = objectIdentityRetrievalStrategy.getObjectIdentity(entity);
093    
094            // Obtain aclEntrys applying to the current Authentication object
095            try {
096                Acl acl = aclService.readAclById(oid, sids);
097    
098                return acl.isGranted(requiredPermissions, sids, false);
099            } 
100            catch (NotFoundException nfe) {
101                return false;
102            }
103        }
104        
105        @SuppressWarnings({ "unchecked", "rawtypes" })
106            private List<Permission> parsePermissionsString(String integersString) throws NumberFormatException {
107            final List permissions = new ArrayList();   // Voluntarily not typed to avoid compilation problem with both Spring 2 and Spring 3
108            final StringTokenizer tokenizer;
109            tokenizer = new StringTokenizer(integersString, ",", false);
110            
111            PermissionFactory pf = new DefaultPermissionFactory();
112            while (tokenizer.hasMoreTokens()) {
113                    String integer = tokenizer.nextToken();
114                    permissions.add(pf.buildFromMask(new Integer(integer).intValue()));
115            }
116            
117            return permissions;
118        }
119    }