diff --git a/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java b/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java index 7fda017ae1..878df1e101 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/SimpleAclEntry.java @@ -18,7 +18,6 @@ package org.acegisecurity.acl.basic; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - /** * Stores some privileges typical of a domain object. * @@ -49,6 +48,9 @@ public class SimpleAclEntry extends AbstractBasicAclEntry { NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE, READ_WRITE, READ_WRITE_DELETE }; + private static final String[] VALID_PERMISSIONS_AS_STRING = { + "NOTHING", "ADMINISTRATION", "READ", "WRITE", "CREATE", "DELETE", "READ_WRITE_CREATE_DELETE", "READ_WRITE_CREATE", + "READ_WRITE", "READ_WRITE_DELETE" }; //~ Constructors =================================================================================================== @@ -110,4 +112,34 @@ public class SimpleAclEntry extends AbstractBasicAclEntry { return sb.toString(); } + + /** + * Parse a permission {@link String} literal and return associated value. + * + * @param permission one of the field names that represent a permission: ADMINISTRATION, + * READ, WRITE,... + * @return the value associated to that permission + * @throws IllegalArgumentException if argument is not a valid permission + */ + public static int parsePermission(String permission) { + for (int i = 0; i < VALID_PERMISSIONS_AS_STRING.length; i++) { + if (VALID_PERMISSIONS_AS_STRING[i].equalsIgnoreCase(permission)) + return validPermissions[i]; + } + throw new IllegalArgumentException("Permission provided does not exist: " + permission); + } + + /** + * Parse a list of permission {@link String} literals and return associated values. + * + * @param permissions array with permissions as {@link String} + * @see #parsePermission(String) for valid values + */ + public static int[] parsePermissions(String[] permissions) { + int[] requirepermissionAsIntArray = new int[permissions.length]; + for (int i = 0; i < requirepermissionAsIntArray.length; i++) { + requirepermissionAsIntArray[i] = parsePermission(permissions[i]); + } + return requirepermissionAsIntArray; + } } diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java index 3a67393b3f..e2b96d410e 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProvider.java @@ -211,6 +211,16 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements this.requirePermission = requirePermission; } + /** + * Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])} + * + * @param requirePermission permission literals + * @see SimpleAclEntry#parsePermissions(String[]) for valid values + */ + public void setRequirePermissionFromString(String[] requirePermission) { + setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission)); + } + public boolean supports(ConfigAttribute attribute) { if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) { return true; diff --git a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java index fb856c3055..390bd2f9a7 100644 --- a/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java +++ b/core/src/main/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProvider.java @@ -39,7 +39,6 @@ import org.springframework.util.Assert; import java.util.Iterator; - /** *

Given a domain object instance returned from a secure object invocation, ensures the principal has * appropriate permission as defined by the {@link AclManager}.

@@ -187,6 +186,16 @@ public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProv this.requirePermission = requirePermission; } + /** + * Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])} + * + * @param requirePermission Permission literals + * @see SimpleAclEntry#parsePermissions(String[]) for valid values + */ + public void setRequirePermissionFromString(String[] requirePermission) { + setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission)); + } + public boolean supports(ConfigAttribute attribute) { if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) { return true; diff --git a/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java b/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java index 867b530a71..bb74894b07 100644 --- a/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/BasicAclEntryVoter.java @@ -23,6 +23,7 @@ import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.BasicAclEntry; +import org.acegisecurity.acl.basic.SimpleAclEntry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -143,6 +144,16 @@ public class BasicAclEntryVoter extends AbstractAclVoter implements Initializing this.requirePermission = requirePermission; } + /** + * Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])} + * + * @param requirePermission Permission literals + * @see SimpleAclEntry#parsePermissions(String[]) for valid values + */ + public void setRequirePermissionFromString(String[] requirePermission) { + setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission)); + } + public boolean supports(ConfigAttribute attribute) { if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getProcessConfigAttribute())) { return true; diff --git a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java index b447e945c1..b60085f167 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java @@ -17,7 +17,6 @@ package org.acegisecurity.acl.basic; import junit.framework.TestCase; - /** * Tests {@link SimpleAclEntry}. * @@ -171,4 +170,27 @@ public class SimpleAclEntryTests extends TestCase { acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE}); assertTrue(acl.toString().endsWith("marissa=-RWC- ............................111. (14)]")); } + + public void testParsePermission() { + assertPermission("NOTHING", 0); + assertPermission("ADMINISTRATION", 1); + assertPermission("READ", 2); + assertPermission("WRITE", 4); + assertPermission("CREATE", 8); + assertPermission("DELETE", 16); + assertPermission("READ_WRITE_DELETE", 22); + } + + public void testParsePermissionWrongValues() { + try { + SimpleAclEntry.parsePermission("X"); + fail(IllegalArgumentException.class.getName() + " must have been thrown."); + } catch (IllegalArgumentException e) { + // expected + } + } + + private void assertPermission(String permission, int value) { + assertEquals(value, SimpleAclEntry.parsePermission(permission)); + } } diff --git a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java index 54b6a76601..f68efad70d 100644 --- a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java +++ b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java @@ -21,23 +21,17 @@ import org.acegisecurity.AuthorizationServiceException; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockAclManager; import org.acegisecurity.SecurityConfig; - import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.MockAclObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; - import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; - import org.acegisecurity.util.SimpleMethodInvocation; - import org.aopalliance.intercept.MethodInvocation; - import org.aspectj.lang.JoinPoint; import java.lang.reflect.Method; - /** * Tests {@link BasicAclEntryVoter}. * @@ -451,6 +445,40 @@ public class BasicAclEntryVoterTests extends TestCase { } } + public void testSetRequirePermissionFromString() { + assertPermission("NOTHING", 0); + assertPermission("ADMINISTRATION", 1); + assertPermission("READ", 2); + assertPermission("WRITE", 4); + assertPermission("CREATE", 8); + assertPermission("DELETE", 16); + assertPermission(new String[] { "WRITE", "CREATE" }, new int[] { 4, 8 }); + } + + public void testSetRequirePermissionFromStringWrongValues() { + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + try { + voter.setRequirePermissionFromString(new String[] { "X" }); + fail(IllegalArgumentException.class.getName() + " must have been thrown."); + } catch (IllegalArgumentException e) { + // expected + } + } + + private void assertPermission(String text, int value) { + assertPermission(new String[] { text }, new int[] { value }); + } + + private void assertPermission(String[] text, int[] value) { + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setRequirePermissionFromString(text); + assertEquals("Test incorreclty coded", value.length, text.length); + assertEquals(value.length, voter.getRequirePermission().length); + for (int i = 0; i < value.length; i++) { + assertEquals(value[i], voter.getRequirePermission()[i]); + } + } + //~ Inner Classes ================================================================================================== private class MockAclEntry implements AclEntry {