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 021package org.granite.tide.spring.security; 022 023import java.util.ArrayList; 024import java.util.HashSet; 025import java.util.List; 026import java.util.Set; 027import java.util.StringTokenizer; 028 029import org.granite.tide.annotations.TideEnabled; 030import org.springframework.security.Authentication; 031import org.springframework.security.acls.Acl; 032import org.springframework.security.acls.AclService; 033import org.springframework.security.acls.NotFoundException; 034import org.springframework.security.acls.Permission; 035import org.springframework.security.acls.domain.DefaultPermissionFactory; 036import org.springframework.security.acls.domain.PermissionFactory; 037import org.springframework.security.acls.objectidentity.ObjectIdentity; 038import org.springframework.security.acls.objectidentity.ObjectIdentityRetrievalStrategy; 039import org.springframework.security.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl; 040import org.springframework.security.acls.sid.Sid; 041import org.springframework.security.acls.sid.SidRetrievalStrategy; 042import org.springframework.security.acls.sid.SidRetrievalStrategyImpl; 043import org.springframework.security.context.SecurityContextHolder; 044 045 046/** 047 * @author William DRAI 048 * 049 * Adapted from the Spring security JSP taglib 050 */ 051@TideEnabled 052public 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}