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