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.List; 025import java.util.StringTokenizer; 026 027import org.granite.tide.annotations.TideEnabled; 028import org.springframework.security.acls.domain.DefaultPermissionFactory; 029import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl; 030import org.springframework.security.acls.domain.PermissionFactory; 031import org.springframework.security.acls.domain.SidRetrievalStrategyImpl; 032import org.springframework.security.acls.model.Acl; 033import org.springframework.security.acls.model.AclService; 034import org.springframework.security.acls.model.NotFoundException; 035import org.springframework.security.acls.model.ObjectIdentity; 036import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy; 037import org.springframework.security.acls.model.Permission; 038import org.springframework.security.acls.model.Sid; 039import org.springframework.security.acls.model.SidRetrievalStrategy; 040import org.springframework.security.core.Authentication; 041import 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 050public 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}