diff --git a/acl/src/main/java/org/springframework/security/acls/AclPermissionEvaluator.java b/acl/src/main/java/org/springframework/security/acls/AclPermissionEvaluator.java index 98ab85f271..76e5da5867 100644 --- a/acl/src/main/java/org/springframework/security/acls/AclPermissionEvaluator.java +++ b/acl/src/main/java/org/springframework/security/acls/AclPermissionEvaluator.java @@ -7,8 +7,9 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.access.PermissionEvaluator; -import org.springframework.security.acls.domain.BasePermission; +import org.springframework.security.acls.domain.DefaultPermissionFactory; import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl; +import org.springframework.security.acls.domain.PermissionFactory; import org.springframework.security.acls.domain.SidRetrievalStrategyImpl; import org.springframework.security.acls.model.Acl; import org.springframework.security.acls.model.AclService; @@ -38,6 +39,7 @@ public class AclPermissionEvaluator implements PermissionEvaluator { private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl(); private ObjectIdentityGenerator objectIdentityGenerator = new ObjectIdentityRetrievalStrategyImpl(); private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl(); + private PermissionFactory permissionFactory = new DefaultPermissionFactory(); public AclPermissionEvaluator(AclService aclService) { this.aclService = aclService; @@ -95,10 +97,9 @@ public class AclPermissionEvaluator implements PermissionEvaluator { } - // TODO: Add permission resolver/PermissionFactory rewrite List resolvePermission(Object permission) { if (permission instanceof Integer) { - return Arrays.asList(BasePermission.buildFromMask(((Integer)permission).intValue())); + return Arrays.asList(permissionFactory.buildFromMask(((Integer)permission).intValue())); } if (permission instanceof Permission) { @@ -114,9 +115,9 @@ public class AclPermissionEvaluator implements PermissionEvaluator { Permission p = null; try { - p = BasePermission.buildFromName(permString); + p = permissionFactory.buildFromName(permString); } catch(IllegalArgumentException notfound) { - p = BasePermission.buildFromName(permString.toUpperCase()); + p = permissionFactory.buildFromName(permString.toUpperCase()); } if (p != null) { diff --git a/acl/src/main/java/org/springframework/security/acls/domain/BasePermission.java b/acl/src/main/java/org/springframework/security/acls/domain/BasePermission.java index 582ab07e09..713f1d0bad 100644 --- a/acl/src/main/java/org/springframework/security/acls/domain/BasePermission.java +++ b/acl/src/main/java/org/springframework/security/acls/domain/BasePermission.java @@ -37,14 +37,6 @@ public class BasePermission extends AbstractPermission { protected static DefaultPermissionFactory defaultPermissionFactory = new DefaultPermissionFactory(); - /** - * Registers the public static permissions defined on this class. This is mandatory so - * that the static methods will operate correctly. - */ - static { - registerPermissionsFor(BasePermission.class); - } - protected BasePermission(int mask) { super(mask); } @@ -53,24 +45,20 @@ public class BasePermission extends AbstractPermission { super(mask, code); } - protected final static void registerPermissionsFor(Class subClass) { - defaultPermissionFactory.registerPublicPermissions(subClass); - } - - public final static Permission buildFromMask(int mask) { - return defaultPermissionFactory.buildFromMask(mask); - } - - public final static Permission[] buildFromMask(int[] masks) { - return defaultPermissionFactory.buildFromMask(masks); - } - - public final static Permission buildFromName(String name) { - return defaultPermissionFactory.buildFromName(name); - } - - public final static Permission[] buildFromName(String[] names) { - return defaultPermissionFactory.buildFromName(names); - } +// public final static Permission buildFromMask(int mask) { +// return defaultPermissionFactory.buildFromMask(mask); +// } +// +// public final static Permission[] buildFromMask(int[] masks) { +// return defaultPermissionFactory.buildFromMask(masks); +// } +// +// public final static Permission buildFromName(String name) { +// return defaultPermissionFactory.buildFromName(name); +// } +// +// public final static Permission[] buildFromName(String[] names) { +// return defaultPermissionFactory.buildFromName(names); +// } } diff --git a/acl/src/main/java/org/springframework/security/acls/domain/DefaultPermissionFactory.java b/acl/src/main/java/org/springframework/security/acls/domain/DefaultPermissionFactory.java index a9e1747b43..b193d0e6bb 100644 --- a/acl/src/main/java/org/springframework/security/acls/domain/DefaultPermissionFactory.java +++ b/acl/src/main/java/org/springframework/security/acls/domain/DefaultPermissionFactory.java @@ -1,7 +1,10 @@ package org.springframework.security.acls.domain; import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.springframework.security.acls.jdbc.LookupStrategy; @@ -23,6 +26,10 @@ public class DefaultPermissionFactory implements PermissionFactory { private final Map registeredPermissionsByInteger = new HashMap(); private final Map registeredPermissionsByName = new HashMap(); + public DefaultPermissionFactory() { + registerPublicPermissions(BasePermission.class); + } + /** * Permit registration of a {@link DefaultPermissionFactory} class. The class must provide * public static fields of type {@link Permission} to represent the possible permissions. @@ -106,15 +113,15 @@ public class DefaultPermissionFactory implements PermissionFactory { return (Permission) registeredPermissionsByName.get(name); } - public Permission[] buildFromName(String[] names) { - if ((names == null) || (names.length == 0)) { - return new Permission[0]; + public List buildFromNames(List names) { + if ((names == null) || (names.size() == 0)) { + return Collections.emptyList(); } - Permission[] permissions = new Permission[names.length]; + List permissions = new ArrayList(names.size()); - for (int i = 0; i < names.length; i++) { - permissions[i] = buildFromName(names[i]); + for (String name : names) { + permissions.add(buildFromName(name)); } return permissions; diff --git a/acl/src/main/java/org/springframework/security/acls/domain/PermissionFactory.java b/acl/src/main/java/org/springframework/security/acls/domain/PermissionFactory.java index 43b5c42212..92797f66f5 100644 --- a/acl/src/main/java/org/springframework/security/acls/domain/PermissionFactory.java +++ b/acl/src/main/java/org/springframework/security/acls/domain/PermissionFactory.java @@ -1,13 +1,15 @@ package org.springframework.security.acls.domain; +import java.util.List; + import org.springframework.security.acls.model.Permission; /** * Provides a simple mechanism to retrieve {@link Permission} instances from integer masks. - * + * * @author Ben Alex * @since 2.0.3 - * + * */ public interface PermissionFactory { @@ -19,6 +21,11 @@ public interface PermissionFactory { * * @return a Permission representing the requested object */ - public abstract Permission buildFromMask(int mask); + Permission buildFromMask(int mask); + + + Permission buildFromName(String name); + -} \ No newline at end of file + List buildFromNames(List names); +} diff --git a/acl/src/main/java/org/springframework/security/acls/jdbc/BasicLookupStrategy.java b/acl/src/main/java/org/springframework/security/acls/jdbc/BasicLookupStrategy.java index 188eb21843..44ff55ce80 100644 --- a/acl/src/main/java/org/springframework/security/acls/jdbc/BasicLookupStrategy.java +++ b/acl/src/main/java/org/springframework/security/acls/jdbc/BasicLookupStrategy.java @@ -37,9 +37,10 @@ import org.springframework.security.acls.domain.AccessControlEntryImpl; import org.springframework.security.acls.domain.AclAuthorizationStrategy; import org.springframework.security.acls.domain.AclImpl; import org.springframework.security.acls.domain.AuditLogger; -import org.springframework.security.acls.domain.BasePermission; +import org.springframework.security.acls.domain.DefaultPermissionFactory; import org.springframework.security.acls.domain.GrantedAuthoritySid; import org.springframework.security.acls.domain.ObjectIdentityImpl; +import org.springframework.security.acls.domain.PermissionFactory; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.AccessControlEntry; import org.springframework.security.acls.model.Acl; @@ -71,6 +72,7 @@ public final class BasicLookupStrategy implements LookupStrategy { //~ Instance fields ================================================================================================ private AclAuthorizationStrategy aclAuthorizationStrategy; + private PermissionFactory permissionFactory = new DefaultPermissionFactory(); private AclCache aclCache; private AuditLogger auditLogger; private JdbcTemplate jdbcTemplate; @@ -225,11 +227,6 @@ public final class BasicLookupStrategy implements LookupStrategy { } } - - protected Permission convertMaskIntoPermission(int mask) { - return BasePermission.buildFromMask(mask); - } - /** * Locates the primary key IDs specified in "findNow", adding AclImpl instances with StubAclParents to the * "acls" Map. @@ -519,7 +516,7 @@ public final class BasicLookupStrategy implements LookupStrategy { } int mask = rs.getInt("mask"); - Permission permission = convertMaskIntoPermission(mask); + Permission permission = permissionFactory.buildFromMask(mask); boolean granting = rs.getBoolean("granting"); boolean auditSuccess = rs.getBoolean("audit_success"); boolean auditFailure = rs.getBoolean("audit_failure"); diff --git a/acl/src/test/java/org/springframework/security/acls/domain/PermissionTests.java b/acl/src/test/java/org/springframework/security/acls/domain/PermissionTests.java index 5eb0edbfb6..ddf837c970 100644 --- a/acl/src/test/java/org/springframework/security/acls/domain/PermissionTests.java +++ b/acl/src/test/java/org/springframework/security/acls/domain/PermissionTests.java @@ -16,6 +16,7 @@ package org.springframework.security.acls.domain; import static org.junit.Assert.*; +import org.junit.Before; import org.junit.Test; import org.springframework.security.acls.model.Permission; @@ -24,13 +25,20 @@ import org.springframework.security.acls.model.Permission; * Tests classes associated with Permission. * * @author Ben Alex - * @version $Id${date} + * @version $Id$ */ public class PermissionTests { + private DefaultPermissionFactory permissionFactory; + + @Before + public void createPermissionfactory() { + permissionFactory = new DefaultPermissionFactory(); + } + @Test public void basePermissionTest() { - Permission p = BasePermission.buildFromName("WRITE"); + Permission p = permissionFactory.buildFromName("WRITE"); assertNotNull(p); } @@ -47,14 +55,16 @@ public class PermissionTests { @Test public void fromInteger() { - Permission permission = BasePermission.buildFromMask(7); + Permission permission = permissionFactory.buildFromMask(7); System.out.println("7 = " + permission.toString()); - permission = BasePermission.buildFromMask(4); + permission = permissionFactory.buildFromMask(4); System.out.println("4 = " + permission.toString()); } @Test public void stringConversion() { + permissionFactory.registerPublicPermissions(SpecialPermission.class); + System.out.println("R = " + BasePermission.READ.toString()); assertEquals("BasePermission[...............................R=1]", BasePermission.READ.toString()); diff --git a/acl/src/test/java/org/springframework/security/acls/domain/SpecialPermission.java b/acl/src/test/java/org/springframework/security/acls/domain/SpecialPermission.java index 55a89b3b5c..451a8b8b8c 100644 --- a/acl/src/test/java/org/springframework/security/acls/domain/SpecialPermission.java +++ b/acl/src/test/java/org/springframework/security/acls/domain/SpecialPermission.java @@ -19,20 +19,12 @@ import org.springframework.security.acls.model.Permission; /** * A test permission. - * + * * @author Ben Alex * @version $Id$ */ public class SpecialPermission extends BasePermission { public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32 - - /** - * Registers the public static permissions defined on this class. This is mandatory so - * that the static methods will operate correctly. - */ - static { - registerPermissionsFor(SpecialPermission.class); - } protected SpecialPermission(int mask, char code) { super(mask, code); diff --git a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java index 85bc7ebeb8..928b4b29f5 100644 --- a/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java +++ b/samples/contacts/src/main/java/sample/contact/AdminPermissionController.java @@ -10,7 +10,9 @@ import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; import org.springframework.dao.DataAccessException; import org.springframework.security.acls.domain.BasePermission; +import org.springframework.security.acls.domain.DefaultPermissionFactory; import org.springframework.security.acls.domain.ObjectIdentityImpl; +import org.springframework.security.acls.domain.PermissionFactory; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.Acl; import org.springframework.security.acls.model.AclService; @@ -45,6 +47,7 @@ public final class AdminPermissionController implements MessageSourceAware{ private ContactManager contactManager; private MessageSourceAccessor messages; private Validator addPermissionValidator = new AddPermissionValidator(); + private PermissionFactory permissionFactory = new DefaultPermissionFactory(); /** * Displays the permission admin page for a particular contact. @@ -99,7 +102,7 @@ public final class AdminPermissionController implements MessageSourceAware{ } PrincipalSid sid = new PrincipalSid(addPermission.getRecipient()); - Permission permission = BasePermission.buildFromMask(addPermission.getPermission().intValue()); + Permission permission = permissionFactory.buildFromMask(addPermission.getPermission()); try { contactManager.addPermission(addPermission.getContact(), sid, permission); @@ -127,7 +130,7 @@ public final class AdminPermissionController implements MessageSourceAware{ Contact contact = contactManager.getById(new Long(contactId)); Sid sidObject = new PrincipalSid(sid); - Permission permission = BasePermission.buildFromMask(mask); + Permission permission = permissionFactory.buildFromMask(mask); contactManager.deletePermission(contact, sidObject, permission); diff --git a/taglibs/src/main/java/org/springframework/security/taglibs/authz/AccessControlListTag.java b/taglibs/src/main/java/org/springframework/security/taglibs/authz/AccessControlListTag.java index fcd13f15e7..2365ece81c 100644 --- a/taglibs/src/main/java/org/springframework/security/taglibs/authz/AccessControlListTag.java +++ b/taglibs/src/main/java/org/springframework/security/taglibs/authz/AccessControlListTag.java @@ -14,8 +14,25 @@ */ package org.springframework.security.taglibs.authz; -import org.springframework.security.acls.domain.BasePermission; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.servlet.ServletContext; +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.Tag; +import javax.servlet.jsp.tagext.TagSupport; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.security.acls.domain.DefaultPermissionFactory; import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl; +import org.springframework.security.acls.domain.PermissionFactory; import org.springframework.security.acls.domain.SidRetrievalStrategyImpl; import org.springframework.security.acls.model.Acl; import org.springframework.security.acls.model.AclService; @@ -25,31 +42,10 @@ import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy; import org.springframework.security.acls.model.Permission; import org.springframework.security.acls.model.Sid; import org.springframework.security.acls.model.SidRetrievalStrategy; - import org.springframework.security.core.context.SecurityContextHolder; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.context.ApplicationContext; - import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.util.ExpressionEvaluationUtils; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.HashMap; - -import javax.servlet.ServletContext; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; - /** * An implementation of {@link Tag} that allows its body through if some authorizations are granted to the request's @@ -81,17 +77,18 @@ public class AccessControlListTag extends TagSupport { private Object domainObject; private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy; private SidRetrievalStrategy sidRetrievalStrategy; + private PermissionFactory permissionFactory; private String hasPermission = ""; //~ Methods ======================================================================================================== public int doStartTag() throws JspException { - initializeIfRequired(); - if ((null == hasPermission) || "".equals(hasPermission)) { return Tag.SKIP_BODY; } + initializeIfRequired(); + final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission, pageContext); @@ -169,7 +166,6 @@ public class AccessControlListTag extends TagSupport { return hasPermission; } - @SuppressWarnings("unchecked") private void initializeIfRequired() throws JspException { if (applicationContext != null) { return; @@ -177,42 +173,43 @@ public class AccessControlListTag extends TagSupport { this.applicationContext = getContext(pageContext); - Map map = new HashMap(); - ApplicationContext context = applicationContext; + aclService = getBeanOfType(AclService.class); - while (context != null) { - map.putAll(context.getBeansOfType(AclService.class)); - context = context.getParent(); - } + sidRetrievalStrategy = getBeanOfType(SidRetrievalStrategy.class); - if (map.size() != 1) { - throw new JspException( - "Found incorrect number of AclService instances in application context - you must have only have one!"); + if (sidRetrievalStrategy == null) { + sidRetrievalStrategy = new SidRetrievalStrategyImpl(); } - aclService = (AclService) map.values().iterator().next(); + objectIdentityRetrievalStrategy = getBeanOfType(ObjectIdentityRetrievalStrategy.class); + + if (objectIdentityRetrievalStrategy == null) { + objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl(); + } - map = applicationContext.getBeansOfType(SidRetrievalStrategy.class); + permissionFactory = getBeanOfType(PermissionFactory.class); - if (map.size() == 0) { - sidRetrievalStrategy = new SidRetrievalStrategyImpl(); - } else if (map.size() == 1) { - sidRetrievalStrategy = (SidRetrievalStrategy) map.values().iterator().next(); - } else { - throw new JspException("Found incorrect number of SidRetrievalStrategy instances in application " - + "context - you must have only have one!"); + if (permissionFactory == null) { + permissionFactory = new DefaultPermissionFactory(); } + } - map = applicationContext.getBeansOfType(ObjectIdentityRetrievalStrategy.class); + private T getBeanOfType(Class type) throws JspException { + Map map = applicationContext.getBeansOfType(type); + + for (ApplicationContext context = applicationContext.getParent(); + context != null; context = context.getParent()) { + map.putAll(context.getBeansOfType(type)); + } if (map.size() == 0) { - objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl(); + return null; } else if (map.size() == 1) { - objectIdentityRetrievalStrategy = (ObjectIdentityRetrievalStrategy) map.values().iterator().next(); - } else { - throw new JspException("Found incorrect number of ObjectIdentityRetrievalStrategy instances in " - + "application context - you must have only have one!"); + return map.values().iterator().next(); } + + throw new JspException("Found incorrect number of " + type.getSimpleName() +" instances in " + + "application context - you must have only have one!"); } private List parsePermissionsString(String integersString) @@ -223,7 +220,7 @@ public class AccessControlListTag extends TagSupport { while (tokenizer.hasMoreTokens()) { String integer = tokenizer.nextToken(); - permissions.add(BasePermission.buildFromMask(new Integer(integer).intValue())); + permissions.add(permissionFactory.buildFromMask(new Integer(integer))); } return new ArrayList(permissions);