From ae6af5d73ce77f93926379f96371e84b1e9401f1 Mon Sep 17 00:00:00 2001
From: Rob Winch
- * Given a domain object instance passed as a method argument, ensures the principal has appropriate permission
- * as indicated by the {@link AclService}.
+ * Given a domain object instance passed as a method argument, ensures the principal has
+ * appropriate permission as indicated by the {@link AclService}.
*
- * The AclService is used to retrieve the access control list (ACL) permissions associated with a
- * domain object instance for the current Authentication object.
+ * The AclService is used to retrieve the access control list (ACL) permissions
+ * associated with a domain object instance for the current Authentication
+ * object.
*
- * The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link #processConfigAttribute}.
- * The provider will then locate the first method argument of type {@link #processDomainObjectClass}. Assuming that
- * method argument is non-null, the provider will then lookup the ACLs from the
- * If the method argument is null, the voter will abstain from voting. If the method argument
- * could not be found, an {@link AuthorizationServiceException} will be thrown.
+ * If the method argument is null, the voter will abstain from voting. If the
+ * method argument could not be found, an {@link AuthorizationServiceException} will be
+ * thrown.
*
- * In practical terms users will typically setup a number of AclEntryVoters. Each will have a
- * different {@link #setProcessDomainObjectClass processDomainObjectClass}, {@link #processConfigAttribute} and
- * {@link #requirePermission} combination. For example, a small application might employ the following instances of
+ * In practical terms users will typically setup a number of AclEntryVoters. Each
+ * will have a different {@link #setProcessDomainObjectClass processDomainObjectClass},
+ * {@link #processConfigAttribute} and {@link #requirePermission} combination. For
+ * example, a small application might employ the following instances of
* AclEntryVoter:
- * AclManager
and ensure the
- * principal is {@link Acl#isGranted(List,
- * List, boolean)} when presenting the {@link #requirePermission} array to that
- * method.
+ * The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the
+ * {@link #processConfigAttribute}. The provider will then locate the first method
+ * argument of type {@link #processDomainObjectClass}. Assuming that method argument is
+ * non-null, the provider will then lookup the ACLs from the AclManager
and
+ * ensure the principal is {@link Acl#isGranted(List, List, boolean)} when presenting the
+ * {@link #requirePermission} array to that method.
*
- *
- * Alternatively, you could have used a common superclass or interface for the {@link #processDomainObjectClass}
- * if both BankAccount
, configuration attribute
- * VOTE_ACL_BANK_ACCONT_READ
, require permission BasePermission.READ
BankAccount
, configuration attribute
- * VOTE_ACL_BANK_ACCOUNT_WRITE
, require permission list BasePermission.WRITE
and
- * BasePermission.CREATE
(allowing the principal to have either of these two permissions)Customer
, configuration attribute
- * VOTE_ACL_CUSTOMER_READ
, require permission BasePermission.READ
Customer
, configuration attribute
- * VOTE_ACL_CUSTOMER_WRITE
, require permission list BasePermission.WRITE
and
- * BasePermission.CREATE
BankAccount
and Customer
had common parents.
If the principal does not have sufficient permissions, the voter will vote to deny access.
- *All comparisons and prefixes are case sensitive.
+ *BankAccount
, configuration attribute
+ * VOTE_ACL_BANK_ACCONT_READ
, require permission
+ * BasePermission.READ
BankAccount
, configuration attribute
+ * VOTE_ACL_BANK_ACCOUNT_WRITE
, require permission list
+ * BasePermission.WRITE
and BasePermission.CREATE
(allowing the
+ * principal to have either of these two permissions)Customer
, configuration attribute
+ * VOTE_ACL_CUSTOMER_READ
, require permission
+ * BasePermission.READ
Customer
, configuration attribute
+ * VOTE_ACL_CUSTOMER_WRITE
, require permission list
+ * BasePermission.WRITE
and BasePermission.CREATE
BankAccount
and
+ * Customer
had common parents.
+ *
+ * + * If the principal does not have sufficient permissions, the voter will vote to deny + * access. + *
+ *+ * All comparisons and prefixes are case sensitive. + *
* * @author Ben Alex */ public class AclEntryVoter extends AbstractAclVoter { - //~ Static fields/initializers ===================================================================================== + // ~ Static fields/initializers + // ===================================================================================== - private static final Log logger = LogFactory.getLog(AclEntryVoter.class); + private static final Log logger = LogFactory.getLog(AclEntryVoter.class); - //~ Instance fields ================================================================================================ + // ~ Instance fields + // ================================================================================================ - private AclService aclService; - private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl(); - private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl(); - private String internalMethod; - private String processConfigAttribute; - private Listnull
to use the domain object, or the name of a method (that requires no arguments) that
- * should be invoked to obtain an Object
which will be the domain object used for ACL
- * evaluation
- */
- protected String getInternalMethod() {
- return internalMethod;
- }
+ /**
+ * Optionally specifies a method of the domain object that will be used to obtain a
+ * contained domain object. That contained domain object will be used for the ACL
+ * evaluation. This is useful if a domain object contains a parent that an ACL
+ * evaluation should be targeted for, instead of the child domain object (which
+ * perhaps is being created and as such does not yet have any ACL permissions)
+ *
+ * @return null
to use the domain object, or the name of a method (that
+ * requires no arguments) that should be invoked to obtain an Object
+ * which will be the domain object used for ACL evaluation
+ */
+ protected String getInternalMethod() {
+ return internalMethod;
+ }
- public void setInternalMethod(String internalMethod) {
- this.internalMethod = internalMethod;
- }
+ public void setInternalMethod(String internalMethod) {
+ this.internalMethod = internalMethod;
+ }
- protected String getProcessConfigAttribute() {
- return processConfigAttribute;
- }
+ protected String getProcessConfigAttribute() {
+ return processConfigAttribute;
+ }
- public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
- Assert.notNull(objectIdentityRetrievalStrategy, "ObjectIdentityRetrievalStrategy required");
- this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
- }
+ public void setObjectIdentityRetrievalStrategy(
+ ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
+ Assert.notNull(objectIdentityRetrievalStrategy,
+ "ObjectIdentityRetrievalStrategy required");
+ this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
+ }
- public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
- Assert.notNull(sidRetrievalStrategy, "SidRetrievalStrategy required");
- this.sidRetrievalStrategy = sidRetrievalStrategy;
- }
+ public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
+ Assert.notNull(sidRetrievalStrategy, "SidRetrievalStrategy required");
+ this.sidRetrievalStrategy = sidRetrievalStrategy;
+ }
- public boolean supports(ConfigAttribute attribute) {
- return (attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute());
- }
+ public boolean supports(ConfigAttribute attribute) {
+ return (attribute.getAttribute() != null)
+ && attribute.getAttribute().equals(getProcessConfigAttribute());
+ }
- public int vote(Authentication authentication, MethodInvocation object, Collectiontrue
- */
- public boolean supports(Class> clazz) {
- return true;
- }
+ /**
+ * This implementation supports any type of class, because it does not query the
+ * presented secure object.
+ *
+ * @param clazz the secure object
+ *
+ * @return always true
+ */
+ public boolean supports(Class> clazz) {
+ return true;
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
index 2ddcf12230..673c753910 100644
--- a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
+++ b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
@@ -26,96 +26,113 @@ import org.springframework.security.acls.model.AclService;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.core.Authentication;
-
/**
*
- * Given a Collection
of domain object instances returned from a secure object invocation, remove
- * any Collection
elements the principal does not have appropriate permission to access as defined by the
- * {@link AclService}.
+ * Given a Collection
of domain object instances returned from a secure
+ * object invocation, remove any Collection
elements the principal does not
+ * have appropriate permission to access as defined by the {@link AclService}.
*
- * The AclService
is used to retrieve the access control list (ACL) permissions associated with
- * each Collection
domain object instance element for the current Authentication
object.
+ * The AclService
is used to retrieve the access control list (ACL)
+ * permissions associated with each Collection
domain object instance element
+ * for the current Authentication
object.
*
- * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
- * #processConfigAttribute}. The provider will then lookup the ACLs from the AclService
and ensure the
- * principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean) Acl.isGranted()}
- * when presenting the {@link #requirePermission} array to that method.
+ * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()}
+ * matches the {@link #processConfigAttribute}. The provider will then lookup the ACLs
+ * from the AclService
and ensure the principal is
+ * {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean)
+ * Acl.isGranted()} when presenting the {@link #requirePermission} array to that method.
*
- * If the principal does not have permission, that element will not be included in the returned
- * Collection
.
+ * If the principal does not have permission, that element will not be included in the
+ * returned Collection
.
*
- * Often users will setup a BasicAclEntryAfterInvocationProvider
with a {@link
- * #processConfigAttribute} of AFTER_ACL_COLLECTION_READ
and a {@link #requirePermission} of
- * BasePermission.READ
. These are also the defaults.
+ * Often users will setup a BasicAclEntryAfterInvocationProvider
with a
+ * {@link #processConfigAttribute} of AFTER_ACL_COLLECTION_READ
and a
+ * {@link #requirePermission} of BasePermission.READ
. These are also the
+ * defaults.
*
- * If the provided returnObject
is null
, a null
Collection
- * will be returned. If the provided returnObject
is not a Collection
, an {@link
- * AuthorizationServiceException} will be thrown.
+ * If the provided returnObject
is null
, a null
+ * Collection
will be returned. If the provided returnObject
is
+ * not a Collection
, an {@link AuthorizationServiceException} will be thrown.
*
* All comparisons and prefixes are case sensitive.
*
* @author Ben Alex
* @author Paulo Neves
*/
-public class AclEntryAfterInvocationCollectionFilteringProvider extends AbstractAclProvider {
- //~ Static fields/initializers =====================================================================================
+public class AclEntryAfterInvocationCollectionFilteringProvider extends
+ AbstractAclProvider {
+ // ~ Static fields/initializers
+ // =====================================================================================
- protected static final Log logger = LogFactory.getLog(AclEntryAfterInvocationCollectionFilteringProvider.class);
+ protected static final Log logger = LogFactory
+ .getLog(AclEntryAfterInvocationCollectionFilteringProvider.class);
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public AclEntryAfterInvocationCollectionFilteringProvider(AclService aclService, List
- * The
- * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
- * #processConfigAttribute}. The provider will then lookup the ACLs from the AclService and ensure the
- * principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean)
- * Acl.isGranted(List, List, boolean)} when presenting the {@link #requirePermission} array to that method.
+ * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()}
+ * matches the {@link #processConfigAttribute}. The provider will then lookup the ACLs
+ * from the AclService and ensure the principal is
+ * {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean)
+ * Acl.isGranted(List, List, boolean)} when presenting the {@link #requirePermission}
+ * array to that method.
*
- * Often users will set up an
- * If the principal does not have sufficient permissions, an
- * If the provided returnedObject is
* All comparisons and prefixes are case sensitive.
*/
-public class AclEntryAfterInvocationProvider extends AbstractAclProvider implements MessageSourceAware {
- //~ Static fields/initializers =====================================================================================
+public class AclEntryAfterInvocationProvider extends AbstractAclProvider implements
+ MessageSourceAware {
+ // ~ Static fields/initializers
+ // =====================================================================================
- protected static final Log logger = LogFactory.getLog(AclEntryAfterInvocationProvider.class);
+ protected static final Log logger = LogFactory
+ .getLog(AclEntryAfterInvocationProvider.class);
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
+ protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public AclEntryAfterInvocationProvider(AclService aclService, List
- * Permission will be granted if at least one of the following conditions is true for the current
- * principal.
+ * Permission will be granted if at least one of the following conditions is true for the
+ * current principal.
*
- * Alternatively, a single value can be supplied for all three permissions.
- */
- public AclAuthorizationStrategyImpl(GrantedAuthority... auths) {
- Assert.isTrue(auths != null && (auths.length == 3 || auths.length == 1),
- "One or three GrantedAuthority instances required");
- if (auths.length == 3) {
- gaTakeOwnership = auths[0];
- gaModifyAuditing = auths[1];
- gaGeneralChanges = auths[2];
- } else {
- gaTakeOwnership = gaModifyAuditing = gaGeneralChanges = auths[0];
- }
- }
+ /**
+ * Constructor. The only mandatory parameter relates to the system-wide
+ * {@link GrantedAuthority} instances that can be held to always permit ACL changes.
+ *
+ * @param auths the
+ * Alternatively, a single value can be supplied for all three permissions.
+ */
+ public AclAuthorizationStrategyImpl(GrantedAuthority... auths) {
+ Assert.isTrue(auths != null && (auths.length == 3 || auths.length == 1),
+ "One or three GrantedAuthority instances required");
+ if (auths.length == 3) {
+ gaTakeOwnership = auths[0];
+ gaModifyAuditing = auths[1];
+ gaGeneralChanges = auths[2];
+ }
+ else {
+ gaTakeOwnership = gaModifyAuditing = gaGeneralChanges = auths[0];
+ }
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public void securityCheck(Acl acl, int changeType) {
- if ((SecurityContextHolder.getContext() == null)
- || (SecurityContextHolder.getContext().getAuthentication() == null)
- || !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
- throw new AccessDeniedException("Authenticated principal required to operate with ACLs");
- }
+ public void securityCheck(Acl acl, int changeType) {
+ if ((SecurityContextHolder.getContext() == null)
+ || (SecurityContextHolder.getContext().getAuthentication() == null)
+ || !SecurityContextHolder.getContext().getAuthentication()
+ .isAuthenticated()) {
+ throw new AccessDeniedException(
+ "Authenticated principal required to operate with ACLs");
+ }
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ Authentication authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
- // Check if authorized by virtue of ACL ownership
- Sid currentUser = createCurrentUser(authentication);
+ // Check if authorized by virtue of ACL ownership
+ Sid currentUser = createCurrentUser(authentication);
- if (currentUser.equals(acl.getOwner())
- && ((changeType == CHANGE_GENERAL) || (changeType == CHANGE_OWNERSHIP))) {
- return;
- }
+ if (currentUser.equals(acl.getOwner())
+ && ((changeType == CHANGE_GENERAL) || (changeType == CHANGE_OWNERSHIP))) {
+ return;
+ }
- // Not authorized by ACL ownership; try via adminstrative permissions
- GrantedAuthority requiredAuthority;
+ // Not authorized by ACL ownership; try via adminstrative permissions
+ GrantedAuthority requiredAuthority;
- if (changeType == CHANGE_AUDITING) {
- requiredAuthority = this.gaModifyAuditing;
- } else if (changeType == CHANGE_GENERAL) {
- requiredAuthority = this.gaGeneralChanges;
- } else if (changeType == CHANGE_OWNERSHIP) {
- requiredAuthority = this.gaTakeOwnership;
- } else {
- throw new IllegalArgumentException("Unknown change type");
- }
+ if (changeType == CHANGE_AUDITING) {
+ requiredAuthority = this.gaModifyAuditing;
+ }
+ else if (changeType == CHANGE_GENERAL) {
+ requiredAuthority = this.gaGeneralChanges;
+ }
+ else if (changeType == CHANGE_OWNERSHIP) {
+ requiredAuthority = this.gaTakeOwnership;
+ }
+ else {
+ throw new IllegalArgumentException("Unknown change type");
+ }
- // Iterate this principal's authorities to determine right
- if (authentication.getAuthorities().contains(requiredAuthority)) {
- return;
- }
+ // Iterate this principal's authorities to determine right
+ if (authentication.getAuthorities().contains(requiredAuthority)) {
+ return;
+ }
- // Try to get permission via ACEs within the ACL
- List
- * Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.
- *
- * @param i the integer bit mask to print the active bits for
- *
- * @return a 32-character representation of the bit mask
- */
- public static String printBinary(int i) {
- return printBinary(i, '*', Permission.RESERVED_OFF);
- }
+ /**
+ * Returns a representation of the active bits in the presented mask, with each active
+ * bit being denoted by character '*'.
+ *
+ * Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.
+ *
+ * @param i the integer bit mask to print the active bits for
+ *
+ * @return a 32-character representation of the bit mask
+ */
+ public static String printBinary(int i) {
+ return printBinary(i, '*', Permission.RESERVED_OFF);
+ }
- /**
- * Returns a representation of the active bits in the presented mask, with each active bit being denoted by
- * the passed character.
- *
- * Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.
- *
- * @param mask the integer bit mask to print the active bits for
- * @param code the character to print when an active bit is detected
- *
- * @return a 32-character representation of the bit mask
- */
- public static String printBinary(int mask, char code) {
- Assert.doesNotContain(Character.toString(code), Character.toString(Permission.RESERVED_ON),
- Permission.RESERVED_ON + " is a reserved character code");
- Assert.doesNotContain(Character.toString(code), Character.toString(Permission.RESERVED_OFF),
- Permission.RESERVED_OFF + " is a reserved character code");
+ /**
+ * Returns a representation of the active bits in the presented mask, with each active
+ * bit being denoted by the passed character.
+ *
+ * Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.
+ *
+ * @param mask the integer bit mask to print the active bits for
+ * @param code the character to print when an active bit is detected
+ *
+ * @return a 32-character representation of the bit mask
+ */
+ public static String printBinary(int mask, char code) {
+ Assert.doesNotContain(Character.toString(code),
+ Character.toString(Permission.RESERVED_ON), Permission.RESERVED_ON
+ + " is a reserved character code");
+ Assert.doesNotContain(Character.toString(code),
+ Character.toString(Permission.RESERVED_OFF), Permission.RESERVED_OFF
+ + " is a reserved character code");
- return printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF).replace(Permission.RESERVED_ON, code);
- }
+ return printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF)
+ .replace(Permission.RESERVED_ON, code);
+ }
- private static String printBinary(int i, char on, char off) {
- String s = Integer.toBinaryString(i);
- String pattern = Permission.THIRTY_TWO_RESERVED_OFF;
- String temp2 = pattern.substring(0, pattern.length() - s.length()) + s;
+ private static String printBinary(int i, char on, char off) {
+ String s = Integer.toBinaryString(i);
+ String pattern = Permission.THIRTY_TWO_RESERVED_OFF;
+ String temp2 = pattern.substring(0, pattern.length() - s.length()) + s;
- return temp2.replace('0', off).replace('1', on);
- }
+ return temp2.replace('0', off).replace('1', on);
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/AclImpl.java b/acl/src/main/java/org/springframework/security/acls/domain/AclImpl.java
index b6f915c0ab..9f6b94623d 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/AclImpl.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/AclImpl.java
@@ -31,297 +31,333 @@ import org.springframework.security.acls.model.Sid;
import org.springframework.security.acls.model.UnloadedSidException;
import org.springframework.util.Assert;
-
/**
* Base implementation of Methods return
+ * Methods return
- * Used as a strategy by classes which wish to map integer masks and permission names to Permission
- * instances for use with the ACL implementation.
+ * Used as a strategy by classes which wish to map integer masks and permission names to
+ * Permission instances for use with the ACL implementation.
*
* Maintains a registry of permission names and masks to Permission instances.
*
@@ -23,125 +23,131 @@ import org.springframework.util.Assert;
* @since 2.0.3
*/
public class DefaultPermissionFactory implements PermissionFactory {
- private final Map
- * These permissions will be registered under the name of the field. See {@link BasePermission}
- * for an example.
- *
- * @param clazz a {@link Permission} class with public static fields to register
- */
- protected void registerPublicPermissions(Class extends Permission> clazz) {
- Assert.notNull(clazz, "Class required");
+ /**
+ * Registers the public static fields of type {@link Permission} for a give class.
+ *
+ * These permissions will be registered under the name of the field. See
+ * {@link BasePermission} for an example.
+ *
+ * @param clazz a {@link Permission} class with public static fields to register
+ */
+ protected void registerPublicPermissions(Class extends Permission> clazz) {
+ Assert.notNull(clazz, "Class required");
- Field[] fields = clazz.getFields();
+ Field[] fields = clazz.getFields();
- for (Field field : fields) {
- try {
- Object fieldValue = field.get(null);
+ for (Field field : fields) {
+ try {
+ Object fieldValue = field.get(null);
- if (Permission.class.isAssignableFrom(fieldValue.getClass())) {
- // Found a Permission static field
- Permission perm = (Permission) fieldValue;
- String permissionName = field.getName();
+ if (Permission.class.isAssignableFrom(fieldValue.getClass())) {
+ // Found a Permission static field
+ Permission perm = (Permission) fieldValue;
+ String permissionName = field.getName();
- registerPermission(perm, permissionName);
- }
- } catch (Exception ignore) {
- }
- }
- }
+ registerPermission(perm, permissionName);
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+ }
- protected void registerPermission(Permission perm, String permissionName) {
- Assert.notNull(perm, "Permission required");
- Assert.hasText(permissionName, "Permission name required");
+ protected void registerPermission(Permission perm, String permissionName) {
+ Assert.notNull(perm, "Permission required");
+ Assert.hasText(permissionName, "Permission name required");
- Integer mask = Integer.valueOf(perm.getMask());
+ Integer mask = Integer.valueOf(perm.getMask());
- // Ensure no existing Permission uses this integer or code
- Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask), "An existing Permission already provides mask " + mask);
- Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName), "An existing Permission already provides name '" + permissionName + "'");
+ // Ensure no existing Permission uses this integer or code
+ Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask),
+ "An existing Permission already provides mask " + mask);
+ Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName),
+ "An existing Permission already provides name '" + permissionName + "'");
- // Register the new Permission
- registeredPermissionsByInteger.put(mask, perm);
- registeredPermissionsByName.put(permissionName, perm);
- }
+ // Register the new Permission
+ registeredPermissionsByInteger.put(mask, perm);
+ registeredPermissionsByName.put(permissionName, perm);
+ }
- public Permission buildFromMask(int mask) {
- if (registeredPermissionsByInteger.containsKey(Integer.valueOf(mask))) {
- // The requested mask has an exact match against a statically-defined Permission, so return it
- return registeredPermissionsByInteger.get(Integer.valueOf(mask));
- }
+ public Permission buildFromMask(int mask) {
+ if (registeredPermissionsByInteger.containsKey(Integer.valueOf(mask))) {
+ // The requested mask has an exact match against a statically-defined
+ // Permission, so return it
+ return registeredPermissionsByInteger.get(Integer.valueOf(mask));
+ }
- // To get this far, we have to use a CumulativePermission
- CumulativePermission permission = new CumulativePermission();
+ // To get this far, we have to use a CumulativePermission
+ CumulativePermission permission = new CumulativePermission();
- for (int i = 0; i < 32; i++) {
- int permissionToCheck = 1 << i;
+ for (int i = 0; i < 32; i++) {
+ int permissionToCheck = 1 << i;
- if ((mask & permissionToCheck) == permissionToCheck) {
- Permission p = registeredPermissionsByInteger.get(Integer.valueOf(permissionToCheck));
+ if ((mask & permissionToCheck) == permissionToCheck) {
+ Permission p = registeredPermissionsByInteger.get(Integer
+ .valueOf(permissionToCheck));
- if (p == null) {
- throw new IllegalStateException("Mask '" + permissionToCheck + "' does not have a corresponding static Permission");
- }
- permission.set(p);
- }
- }
+ if (p == null) {
+ throw new IllegalStateException("Mask '" + permissionToCheck
+ + "' does not have a corresponding static Permission");
+ }
+ permission.set(p);
+ }
+ }
- return permission;
- }
+ return permission;
+ }
- public Permission buildFromName(String name) {
- Permission p = registeredPermissionsByName.get(name);
+ public Permission buildFromName(String name) {
+ Permission p = registeredPermissionsByName.get(name);
- if (p == null) {
- throw new IllegalArgumentException("Unknown permission '" + name + "'");
- }
+ if (p == null) {
+ throw new IllegalArgumentException("Unknown permission '" + name + "'");
+ }
- return p;
- }
+ return p;
+ }
- public List
- * Designed to handle the transient fields in {@link AclImpl}. Note that this implementation assumes all
- * {@link AclImpl} instances share the same {@link PermissionGrantingStrategy} and {@link AclAuthorizationStrategy}
- * instances.
+ * Designed to handle the transient fields in {@link AclImpl}. Note that this
+ * implementation assumes all {@link AclImpl} instances share the same
+ * {@link PermissionGrantingStrategy} and {@link AclAuthorizationStrategy} instances.
*
* @author Ben Alex
*/
public class EhCacheBasedAclCache implements AclCache {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private final Ehcache cache;
- private PermissionGrantingStrategy permissionGrantingStrategy;
- private AclAuthorizationStrategy aclAuthorizationStrategy;
+ private final Ehcache cache;
+ private PermissionGrantingStrategy permissionGrantingStrategy;
+ private AclAuthorizationStrategy aclAuthorizationStrategy;
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public EhCacheBasedAclCache(Ehcache cache, PermissionGrantingStrategy permissionGrantingStrategy,
- AclAuthorizationStrategy aclAuthorizationStrategy) {
- Assert.notNull(cache, "Cache required");
- Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
- Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
- this.cache = cache;
- this.permissionGrantingStrategy = permissionGrantingStrategy;
- this.aclAuthorizationStrategy = aclAuthorizationStrategy;
- }
+ public EhCacheBasedAclCache(Ehcache cache,
+ PermissionGrantingStrategy permissionGrantingStrategy,
+ AclAuthorizationStrategy aclAuthorizationStrategy) {
+ Assert.notNull(cache, "Cache required");
+ Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
+ Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
+ this.cache = cache;
+ this.permissionGrantingStrategy = permissionGrantingStrategy;
+ this.aclAuthorizationStrategy = aclAuthorizationStrategy;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public void evictFromCache(Serializable pk) {
- Assert.notNull(pk, "Primary key (identifier) required");
+ public void evictFromCache(Serializable pk) {
+ Assert.notNull(pk, "Primary key (identifier) required");
- MutableAcl acl = getFromCache(pk);
+ MutableAcl acl = getFromCache(pk);
- if (acl != null) {
- cache.remove(acl.getId());
- cache.remove(acl.getObjectIdentity());
- }
- }
+ if (acl != null) {
+ cache.remove(acl.getId());
+ cache.remove(acl.getObjectIdentity());
+ }
+ }
- public void evictFromCache(ObjectIdentity objectIdentity) {
- Assert.notNull(objectIdentity, "ObjectIdentity required");
+ public void evictFromCache(ObjectIdentity objectIdentity) {
+ Assert.notNull(objectIdentity, "ObjectIdentity required");
- MutableAcl acl = getFromCache(objectIdentity);
+ MutableAcl acl = getFromCache(objectIdentity);
- if (acl != null) {
- cache.remove(acl.getId());
- cache.remove(acl.getObjectIdentity());
- }
- }
+ if (acl != null) {
+ cache.remove(acl.getId());
+ cache.remove(acl.getObjectIdentity());
+ }
+ }
- public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
- Assert.notNull(objectIdentity, "ObjectIdentity required");
+ public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
+ Assert.notNull(objectIdentity, "ObjectIdentity required");
- Element element = null;
+ Element element = null;
- try {
- element = cache.get(objectIdentity);
- } catch (CacheException ignored) {}
+ try {
+ element = cache.get(objectIdentity);
+ }
+ catch (CacheException ignored) {
+ }
- if (element == null) {
- return null;
- }
+ if (element == null) {
+ return null;
+ }
- return initializeTransientFields((MutableAcl)element.getValue());
- }
+ return initializeTransientFields((MutableAcl) element.getValue());
+ }
- public MutableAcl getFromCache(Serializable pk) {
- Assert.notNull(pk, "Primary key (identifier) required");
+ public MutableAcl getFromCache(Serializable pk) {
+ Assert.notNull(pk, "Primary key (identifier) required");
- Element element = null;
+ Element element = null;
- try {
- element = cache.get(pk);
- } catch (CacheException ignored) {}
+ try {
+ element = cache.get(pk);
+ }
+ catch (CacheException ignored) {
+ }
- if (element == null) {
- return null;
- }
+ if (element == null) {
+ return null;
+ }
- return initializeTransientFields((MutableAcl) element.getValue());
- }
+ return initializeTransientFields((MutableAcl) element.getValue());
+ }
- public void putInCache(MutableAcl acl) {
- Assert.notNull(acl, "Acl required");
- Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required");
- Assert.notNull(acl.getId(), "ID required");
+ public void putInCache(MutableAcl acl) {
+ Assert.notNull(acl, "Acl required");
+ Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required");
+ Assert.notNull(acl.getId(), "ID required");
- if (this.aclAuthorizationStrategy == null) {
- if (acl instanceof AclImpl) {
- this.aclAuthorizationStrategy = (AclAuthorizationStrategy) FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", acl);
- this.permissionGrantingStrategy = (PermissionGrantingStrategy) FieldUtils.getProtectedFieldValue("permissionGrantingStrategy", acl);
- }
- }
+ if (this.aclAuthorizationStrategy == null) {
+ if (acl instanceof AclImpl) {
+ this.aclAuthorizationStrategy = (AclAuthorizationStrategy) FieldUtils
+ .getProtectedFieldValue("aclAuthorizationStrategy", acl);
+ this.permissionGrantingStrategy = (PermissionGrantingStrategy) FieldUtils
+ .getProtectedFieldValue("permissionGrantingStrategy", acl);
+ }
+ }
- if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
- putInCache((MutableAcl) acl.getParentAcl());
- }
+ if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
+ putInCache((MutableAcl) acl.getParentAcl());
+ }
- cache.put(new Element(acl.getObjectIdentity(), acl));
- cache.put(new Element(acl.getId(), acl));
- }
+ cache.put(new Element(acl.getObjectIdentity(), acl));
+ cache.put(new Element(acl.getId(), acl));
+ }
- private MutableAcl initializeTransientFields(MutableAcl value) {
- if (value instanceof AclImpl) {
- FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
- FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
- }
+ private MutableAcl initializeTransientFields(MutableAcl value) {
+ if (value instanceof AclImpl) {
+ FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value,
+ this.aclAuthorizationStrategy);
+ FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value,
+ this.permissionGrantingStrategy);
+ }
- if (value.getParentAcl() != null) {
- initializeTransientFields((MutableAcl) value.getParentAcl());
- }
- return value;
- }
+ if (value.getParentAcl() != null) {
+ initializeTransientFields((MutableAcl) value.getParentAcl());
+ }
+ return value;
+ }
- public void clearCache() {
- cache.removeAll();
- }
+ public void clearCache() {
+ cache.removeAll();
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/GrantedAuthoritySid.java b/acl/src/main/java/org/springframework/security/acls/domain/GrantedAuthoritySid.java
index e31f265c93..ecaaf68133 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/GrantedAuthoritySid.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/GrantedAuthoritySid.java
@@ -19,53 +19,61 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;
-
/**
- * Represents a This is a basic implementation that simply
- * uses the
+ * This is a basic implementation that simply uses the
- * Uses
- * The class name of the object passed will be considered the {@link #type}, so if more control is required,
- * a different constructor should be used.
- *
- * @param object the domain object instance to create an identity for.
- *
- * @throws IdentityUnavailableException if identity could not be extracted
- */
- public ObjectIdentityImpl(Object object) throws IdentityUnavailableException {
- Assert.notNull(object, "object cannot be null");
+ /**
+ * Creates the
+ * The class name of the object passed will be considered the {@link #type}, so if
+ * more control is required, a different constructor should be used.
+ *
+ * @param object the domain object instance to create an identity for.
+ *
+ * @throws IdentityUnavailableException if identity could not be extracted
+ */
+ public ObjectIdentityImpl(Object object) throws IdentityUnavailableException {
+ Assert.notNull(object, "object cannot be null");
- Class> typeClass = ClassUtils.getUserClass(object.getClass());
- type = typeClass.getName();
+ Class> typeClass = ClassUtils.getUserClass(object.getClass());
+ type = typeClass.getName();
- Object result;
+ Object result;
- try {
- Method method = typeClass.getMethod("getId", new Class[] {});
- result = method.invoke(object);
- } catch (Exception e) {
- throw new IdentityUnavailableException("Could not extract identity from object " + object, e);
- }
+ try {
+ Method method = typeClass.getMethod("getId", new Class[] {});
+ result = method.invoke(object);
+ }
+ catch (Exception e) {
+ throw new IdentityUnavailableException(
+ "Could not extract identity from object " + object, e);
+ }
- Assert.notNull(result, "getId() is required to return a non-null value");
- Assert.isInstanceOf(Serializable.class, result, "Getter must provide a return value of type Serializable");
- this.identifier = (Serializable) result;
- }
+ Assert.notNull(result, "getId() is required to return a non-null value");
+ Assert.isInstanceOf(Serializable.class, result,
+ "Getter must provide a return value of type Serializable");
+ this.identifier = (Serializable) result;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- /**
- * Important so caching operates properly.
- *
- * Considers an object of the same class equal if it has the same
- * Numeric identities (Integer and Long values) are considered equal if they are numerically equal. Other
- * serializable types are evaluated using a simple equality.
- *
- * @param arg0 object to compare
- *
- * @return
+ * Considers an object of the same class equal if it has the same
+ *
+ * Numeric identities (Integer and Long values) are considered equal if they are
+ * numerically equal. Other serializable types are evaluated using a simple equality.
+ *
+ * @param arg0 object to compare
+ *
+ * @return This is a basic implementation
- * that simply uses the
+ * This is a basic implementation that simply uses the
- * The returned array will always contain the {@link PrincipalSid} before any {@link GrantedAuthoritySid} elements.
+ * The returned array will always contain the {@link PrincipalSid} before any
+ * {@link GrantedAuthoritySid} elements.
*
* @author Ben Alex
*/
public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
- private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
+ private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
- public SidRetrievalStrategyImpl() {
- }
+ public SidRetrievalStrategyImpl() {
+ }
- public SidRetrievalStrategyImpl(RoleHierarchy roleHierarchy) {
- Assert.notNull(roleHierarchy, "RoleHierarchy must not be null");
- this.roleHierarchy = roleHierarchy;
- }
+ public SidRetrievalStrategyImpl(RoleHierarchy roleHierarchy) {
+ Assert.notNull(roleHierarchy, "RoleHierarchy must not be null");
+ this.roleHierarchy = roleHierarchy;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public List
- * Designed to handle the transient fields in {@link org.springframework.security.acls.domain.AclImpl}. Note that this implementation assumes all
- * {@link org.springframework.security.acls.domain.AclImpl} instances share the same {@link org.springframework.security.acls.model.PermissionGrantingStrategy} and {@link org.springframework.security.acls.domain.AclAuthorizationStrategy}
- * instances.
+ * Designed to handle the transient fields in
+ * {@link org.springframework.security.acls.domain.AclImpl}. Note that this implementation
+ * assumes all {@link org.springframework.security.acls.domain.AclImpl} instances share
+ * the same {@link org.springframework.security.acls.model.PermissionGrantingStrategy} and
+ * {@link org.springframework.security.acls.domain.AclAuthorizationStrategy} instances.
*
* @author Marten Deinum
* @since 3.2
*/
public class SpringCacheBasedAclCache implements AclCache {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private final Cache cache;
- private PermissionGrantingStrategy permissionGrantingStrategy;
- private AclAuthorizationStrategy aclAuthorizationStrategy;
+ private final Cache cache;
+ private PermissionGrantingStrategy permissionGrantingStrategy;
+ private AclAuthorizationStrategy aclAuthorizationStrategy;
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public SpringCacheBasedAclCache(Cache cache, PermissionGrantingStrategy permissionGrantingStrategy,
- AclAuthorizationStrategy aclAuthorizationStrategy) {
- Assert.notNull(cache, "Cache required");
- Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
- Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
- this.cache = cache;
- this.permissionGrantingStrategy = permissionGrantingStrategy;
- this.aclAuthorizationStrategy = aclAuthorizationStrategy;
- }
+ public SpringCacheBasedAclCache(Cache cache,
+ PermissionGrantingStrategy permissionGrantingStrategy,
+ AclAuthorizationStrategy aclAuthorizationStrategy) {
+ Assert.notNull(cache, "Cache required");
+ Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
+ Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
+ this.cache = cache;
+ this.permissionGrantingStrategy = permissionGrantingStrategy;
+ this.aclAuthorizationStrategy = aclAuthorizationStrategy;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public void evictFromCache(Serializable pk) {
- Assert.notNull(pk, "Primary key (identifier) required");
+ public void evictFromCache(Serializable pk) {
+ Assert.notNull(pk, "Primary key (identifier) required");
- MutableAcl acl = getFromCache(pk);
+ MutableAcl acl = getFromCache(pk);
- if (acl != null) {
- cache.evict(acl.getId());
- cache.evict(acl.getObjectIdentity());
- }
- }
+ if (acl != null) {
+ cache.evict(acl.getId());
+ cache.evict(acl.getObjectIdentity());
+ }
+ }
- public void evictFromCache(ObjectIdentity objectIdentity) {
- Assert.notNull(objectIdentity, "ObjectIdentity required");
+ public void evictFromCache(ObjectIdentity objectIdentity) {
+ Assert.notNull(objectIdentity, "ObjectIdentity required");
- MutableAcl acl = getFromCache(objectIdentity);
+ MutableAcl acl = getFromCache(objectIdentity);
- if (acl != null) {
- cache.evict(acl.getId());
- cache.evict(acl.getObjectIdentity());
- }
- }
+ if (acl != null) {
+ cache.evict(acl.getId());
+ cache.evict(acl.getObjectIdentity());
+ }
+ }
- public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
- Assert.notNull(objectIdentity, "ObjectIdentity required");
- return getFromCache((Object)objectIdentity);
- }
+ public MutableAcl getFromCache(ObjectIdentity objectIdentity) {
+ Assert.notNull(objectIdentity, "ObjectIdentity required");
+ return getFromCache((Object) objectIdentity);
+ }
- public MutableAcl getFromCache(Serializable pk) {
- Assert.notNull(pk, "Primary key (identifier) required");
- return getFromCache((Object)pk);
- }
+ public MutableAcl getFromCache(Serializable pk) {
+ Assert.notNull(pk, "Primary key (identifier) required");
+ return getFromCache((Object) pk);
+ }
- public void putInCache(MutableAcl acl) {
- Assert.notNull(acl, "Acl required");
- Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required");
- Assert.notNull(acl.getId(), "ID required");
+ public void putInCache(MutableAcl acl) {
+ Assert.notNull(acl, "Acl required");
+ Assert.notNull(acl.getObjectIdentity(), "ObjectIdentity required");
+ Assert.notNull(acl.getId(), "ID required");
- if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
- putInCache((MutableAcl) acl.getParentAcl());
- }
+ if ((acl.getParentAcl() != null) && (acl.getParentAcl() instanceof MutableAcl)) {
+ putInCache((MutableAcl) acl.getParentAcl());
+ }
- cache.put(acl.getObjectIdentity(), acl);
- cache.put(acl.getId(), acl);
- }
+ cache.put(acl.getObjectIdentity(), acl);
+ cache.put(acl.getId(), acl);
+ }
- private MutableAcl getFromCache(Object key) {
- Cache.ValueWrapper element = cache.get(key);
+ private MutableAcl getFromCache(Object key) {
+ Cache.ValueWrapper element = cache.get(key);
- if (element == null) {
- return null;
- }
+ if (element == null) {
+ return null;
+ }
- return initializeTransientFields((MutableAcl) element.get());
- }
+ return initializeTransientFields((MutableAcl) element.get());
+ }
- private MutableAcl initializeTransientFields(MutableAcl value) {
- if (value instanceof AclImpl) {
- FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
- FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
- }
+ private MutableAcl initializeTransientFields(MutableAcl value) {
+ if (value instanceof AclImpl) {
+ FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value,
+ this.aclAuthorizationStrategy);
+ FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value,
+ this.permissionGrantingStrategy);
+ }
- if (value.getParentAcl() != null) {
- initializeTransientFields((MutableAcl) value.getParentAcl());
- }
- return value;
- }
+ if (value.getParentAcl() != null) {
+ initializeTransientFields((MutableAcl) value.getParentAcl());
+ }
+ return value;
+ }
- public void clearCache() {
- cache.clear();
- }
+ public void clearCache() {
+ cache.clear();
+ }
}
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 aaf742cb41..ce8178f6e6 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
@@ -55,600 +55,650 @@ import org.springframework.security.acls.model.UnloadedSidException;
import org.springframework.security.util.FieldUtils;
import org.springframework.util.Assert;
-
/**
* Performs lookups in a manner that is compatible with ANSI SQL.
*
- * NB: This implementation does attempt to provide reasonably optimised lookups - within the constraints of a normalised
- * database and standard ANSI SQL features. If you are willing to sacrifice either of these constraints
- * (e.g. use a particular database feature such as hierarchical queries or materalized views, or reduce normalisation)
- * you are likely to achieve better performance. In such situations you will need to provide your own custom
- *
- * There are two SQL queries executed, one in the lookupPrimaryKeys method and one in
- * lookupObjectIdentities. These are built from the same select and "order by" clause, using a different
- * where clause in each case. In order to use custom schema or column names, each of these SQL clauses can be
- * customized, but they must be consistent with each other and with the expected result set
- * generated by the the default values.
+ * There are two SQL queries executed, one in the lookupPrimaryKeys method and
+ * one in lookupObjectIdentities. These are built from the same select and
+ * "order by" clause, using a different where clause in each case. In order to use custom
+ * schema or column names, each of these SQL clauses can be customized, but they must be
+ * consistent with each other and with the expected result set generated by the the
+ * default values.
*
* @author Ben Alex
*/
public class BasicLookupStrategy implements LookupStrategy {
- public final static String DEFAULT_SELECT_CLAUSE = "select acl_object_identity.object_id_identity, "
- + "acl_entry.ace_order, "
- + "acl_object_identity.id as acl_id, "
- + "acl_object_identity.parent_object, "
- + "acl_object_identity.entries_inheriting, "
- + "acl_entry.id as ace_id, "
- + "acl_entry.mask, "
- + "acl_entry.granting, "
- + "acl_entry.audit_success, "
- + "acl_entry.audit_failure, "
- + "acl_sid.principal as ace_principal, "
- + "acl_sid.sid as ace_sid, "
- + "acli_sid.principal as acl_principal, "
- + "acli_sid.sid as acl_sid, "
- + "acl_class.class "
- + "from acl_object_identity "
- + "left join acl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid "
- + "left join acl_class on acl_class.id = acl_object_identity.object_id_class "
- + "left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity "
- + "left join acl_sid on acl_entry.sid = acl_sid.id "
- + "where ( ";
-
- private final static String DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE = "(acl_object_identity.id = ?)";
-
- private final static String DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE = "(acl_object_identity.object_id_identity = ? and acl_class.class = ?)";
-
- public final static String DEFAULT_ORDER_BY_CLAUSE = ") order by acl_object_identity.object_id_identity"
- + " asc, acl_entry.ace_order asc";
-
- //~ Instance fields ================================================================================================
-
- private final AclAuthorizationStrategy aclAuthorizationStrategy;
- private PermissionFactory permissionFactory = new DefaultPermissionFactory();
- private final AclCache aclCache;
- private final PermissionGrantingStrategy grantingStrategy;
- private final JdbcTemplate jdbcTemplate;
- private int batchSize = 50;
-
- private final Field fieldAces = FieldUtils.getField(AclImpl.class, "aces");
- private final Field fieldAcl = FieldUtils.getField(AccessControlEntryImpl.class, "acl");
-
- // SQL Customization fields
- private String selectClause = DEFAULT_SELECT_CLAUSE;
- private String lookupPrimaryKeysWhereClause = DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE;
- private String lookupObjectIdentitiesWhereClause = DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE;
- private String orderByClause = DEFAULT_ORDER_BY_CLAUSE;
-
- //~ Constructors ===================================================================================================
-
- /**
- * Constructor accepting mandatory arguments
- *
- * @param dataSource to access the database
- * @param aclCache the cache where fully-loaded elements can be stored
- * @param aclAuthorizationStrategy authorization strategy (required)
- */
- public BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
- AclAuthorizationStrategy aclAuthorizationStrategy, AuditLogger auditLogger) {
- this(dataSource, aclCache, aclAuthorizationStrategy, new DefaultPermissionGrantingStrategy(auditLogger));
- }
-
- /**
- * Creates a new instance
- *
- * @param dataSource to access the database
- * @param aclCache the cache where fully-loaded elements can be stored
- * @param aclAuthorizationStrategy authorization strategy (required)
- * @param grantingStrategy the PermissionGrantingStrategy
- */
- public BasicLookupStrategy(DataSource dataSource, AclCache aclCache,
- AclAuthorizationStrategy aclAuthorizationStrategy, PermissionGrantingStrategy grantingStrategy) {
- Assert.notNull(dataSource, "DataSource required");
- Assert.notNull(aclCache, "AclCache required");
- Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
- Assert.notNull(grantingStrategy, "grantingStrategy required");
- jdbcTemplate = new JdbcTemplate(dataSource);
- this.aclCache = aclCache;
- this.aclAuthorizationStrategy = aclAuthorizationStrategy;
- this.grantingStrategy = grantingStrategy;
- fieldAces.setAccessible(true);
- fieldAcl.setAccessible(true);
-
- }
-
- //~ Methods ========================================================================================================
-
- private String computeRepeatingSql(String repeatingSql, int requiredRepetitions) {
- assert requiredRepetitions > 0 : "requiredRepetitions must be > 0";
-
- final String startSql = selectClause;
-
- final String endSql = orderByClause;
-
- StringBuilder sqlStringBldr =
- new StringBuilder(startSql.length() + endSql.length() + requiredRepetitions * (repeatingSql.length() + 4));
- sqlStringBldr.append(startSql);
-
- for (int i = 1; i <= requiredRepetitions; i++) {
- sqlStringBldr.append(repeatingSql);
-
- if (i != requiredRepetitions) {
- sqlStringBldr.append(" or ");
- }
- }
-
- sqlStringBldr.append(endSql);
-
- return sqlStringBldr.toString();
- }
-
- @SuppressWarnings("unchecked")
- private List
- * WARNING: This implementation completely disregards the "sids" argument! Every item in the cache is expected to
- * contain all SIDs. If you have serious performance needs (e.g. a very large number of
- * SIDs per object identity), you'll probably want to develop a custom {@link LookupStrategy} implementation
- * instead.
- *
- * The implementation works in batch sizes specified by {@link #batchSize}.
- *
- * @param objects the identities to lookup (required)
- * @param sids the SIDs for which identities are required (ignored by this implementation)
- *
- * @return a Map where keys represent the {@link ObjectIdentity} of the located {@link Acl} and values
- * are the located {@link Acl} (never null although some entries may be missing; this method
- * should not throw {@link NotFoundException}, as a chain of {@link LookupStrategy}s may be used
- * to automatically create entries if required)
- */
- public final Map
- * The caller is responsible for optimization issues, such as selecting the identities to lookup, ensuring the
- * cache doesn't contain them already, and adding the returned elements to the cache etc.
- *
- * This subclass is required to return fully valid
+ * WARNING: This implementation completely disregards the "sids" argument! Every item
+ * in the cache is expected to contain all SIDs. If you have serious performance needs
+ * (e.g. a very large number of SIDs per object identity), you'll probably want to
+ * develop a custom {@link LookupStrategy} implementation instead.
+ *
+ * The implementation works in batch sizes specified by {@link #batchSize}.
+ *
+ * @param objects the identities to lookup (required)
+ * @param sids the SIDs for which identities are required (ignored by this
+ * implementation)
+ *
+ * @return a Map where keys represent the {@link ObjectIdentity} of the
+ * located {@link Acl} and values are the located {@link Acl} (never null
+ * although some entries may be missing; this method should not throw
+ * {@link NotFoundException}, as a chain of {@link LookupStrategy}s may be used to
+ * automatically create entries if required)
+ */
+ public final Map
+ * The caller is responsible for optimization issues, such as selecting the identities
+ * to lookup, ensuring the cache doesn't contain them already, and adding the returned
+ * elements to the cache etc.
+ *
+ * This subclass is required to return fully valid
- * Requires the "dirty" flags in {@link org.springframework.security.acls.domain.AclImpl} and
- * {@link org.springframework.security.acls.domain.AccessControlEntryImpl} to be set, so that the implementation can
- * detect changed parameters easily.
+ * Requires the "dirty" flags in {@link org.springframework.security.acls.domain.AclImpl}
+ * and {@link org.springframework.security.acls.domain.AccessControlEntryImpl} to be set,
+ * so that the implementation can detect changed parameters easily.
*
* @author Ben Alex
*/
public class JdbcAclService implements AclService {
- //~ Static fields/initializers =====================================================================================
+ // ~ Static fields/initializers
+ // =====================================================================================
- protected static final Log log = LogFactory.getLog(JdbcAclService.class);
- private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, class.class as class "
- + "from acl_object_identity obj, acl_object_identity parent, acl_class class "
- + "where obj.parent_object = parent.id and obj.object_id_class = class.id "
- + "and parent.object_id_identity = ? and parent.object_id_class = ("
- + "select id FROM acl_class where acl_class.class = ?)";
+ protected static final Log log = LogFactory.getLog(JdbcAclService.class);
+ private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, class.class as class "
+ + "from acl_object_identity obj, acl_object_identity parent, acl_class class "
+ + "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+ + "and parent.object_id_identity = ? and parent.object_id_class = ("
+ + "select id FROM acl_class where acl_class.class = ?)";
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- protected final JdbcTemplate jdbcTemplate;
- private final LookupStrategy lookupStrategy;
- private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
+ protected final JdbcTemplate jdbcTemplate;
+ private final LookupStrategy lookupStrategy;
+ private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
- Assert.notNull(dataSource, "DataSource required");
- Assert.notNull(lookupStrategy, "LookupStrategy required");
- this.jdbcTemplate = new JdbcTemplate(dataSource);
- this.lookupStrategy = lookupStrategy;
- }
+ public JdbcAclService(DataSource dataSource, LookupStrategy lookupStrategy) {
+ Assert.notNull(dataSource, "DataSource required");
+ Assert.notNull(lookupStrategy, "LookupStrategy required");
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ this.lookupStrategy = lookupStrategy;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public List
- * The default settings are for HSQLDB. If you are using a different database you
- * will probably need to set the {@link #setSidIdentityQuery(String) sidIdentityQuery} and
- * {@link #setClassIdentityQuery(String) classIdentityQuery} properties appropriately. The other queries,
- * SQL inserts and updates can also be customized to accomodate schema variations, but must produce results
- * consistent with those expected by the defaults.
+ * The default settings are for HSQLDB. If you are using a different database you will
+ * probably need to set the {@link #setSidIdentityQuery(String) sidIdentityQuery} and
+ * {@link #setClassIdentityQuery(String) classIdentityQuery} properties appropriately. The
+ * other queries, SQL inserts and updates can also be customized to accomodate schema
+ * variations, but must produce results consistent with those expected by the defaults.
*
- * See the appendix of the Spring Security reference manual for more information on the expected schema
- * and how it is used. Information on using PostgreSQL is also included.
+ * See the appendix of the Spring Security reference manual for more information on the
+ * expected schema and how it is used. Information on using PostgreSQL is also included.
*
* @author Ben Alex
* @author Johannes Zlattinger
*/
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private boolean foreignKeysInDatabase = true;
- private final AclCache aclCache;
- private String deleteEntryByObjectIdentityForeignKey = "delete from acl_entry where acl_object_identity=?";
- private String deleteObjectIdentityByPrimaryKey = "delete from acl_object_identity where id=?";
- private String classIdentityQuery = "call identity()";
- private String sidIdentityQuery = "call identity()";
- private String insertClass = "insert into acl_class (class) values (?)";
- private String insertEntry = "insert into acl_entry "
- + "(acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
- + "values (?, ?, ?, ?, ?, ?, ?)";
- private String insertObjectIdentity = "insert into acl_object_identity "
- + "(object_id_class, object_id_identity, owner_sid, entries_inheriting) " + "values (?, ?, ?, ?)";
- private String insertSid = "insert into acl_sid (principal, sid) values (?, ?)";
- private String selectClassPrimaryKey = "select id from acl_class where class=?";
- private String selectObjectIdentityPrimaryKey = "select acl_object_identity.id from acl_object_identity, acl_class "
- + "where acl_object_identity.object_id_class = acl_class.id and acl_class.class=? "
- + "and acl_object_identity.object_id_identity = ?";
- private String selectSidPrimaryKey = "select id from acl_sid where principal=? and sid=?";
- private String updateObjectIdentity = "update acl_object_identity set "
- + "parent_object = ?, owner_sid = ?, entries_inheriting = ?" + " where id = ?";
+ private boolean foreignKeysInDatabase = true;
+ private final AclCache aclCache;
+ private String deleteEntryByObjectIdentityForeignKey = "delete from acl_entry where acl_object_identity=?";
+ private String deleteObjectIdentityByPrimaryKey = "delete from acl_object_identity where id=?";
+ private String classIdentityQuery = "call identity()";
+ private String sidIdentityQuery = "call identity()";
+ private String insertClass = "insert into acl_class (class) values (?)";
+ private String insertEntry = "insert into acl_entry "
+ + "(acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
+ + "values (?, ?, ?, ?, ?, ?, ?)";
+ private String insertObjectIdentity = "insert into acl_object_identity "
+ + "(object_id_class, object_id_identity, owner_sid, entries_inheriting) "
+ + "values (?, ?, ?, ?)";
+ private String insertSid = "insert into acl_sid (principal, sid) values (?, ?)";
+ private String selectClassPrimaryKey = "select id from acl_class where class=?";
+ private String selectObjectIdentityPrimaryKey = "select acl_object_identity.id from acl_object_identity, acl_class "
+ + "where acl_object_identity.object_id_class = acl_class.id and acl_class.class=? "
+ + "and acl_object_identity.object_id_identity = ?";
+ private String selectSidPrimaryKey = "select id from acl_sid where principal=? and sid=?";
+ private String updateObjectIdentity = "update acl_object_identity set "
+ + "parent_object = ?, owner_sid = ?, entries_inheriting = ?"
+ + " where id = ?";
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {
- super(dataSource, lookupStrategy);
- Assert.notNull(aclCache, "AclCache required");
- this.aclCache = aclCache;
- }
+ public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy,
+ AclCache aclCache) {
+ super(dataSource, lookupStrategy);
+ Assert.notNull(aclCache, "AclCache required");
+ this.aclCache = aclCache;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException {
- Assert.notNull(objectIdentity, "Object Identity required");
+ public MutableAcl createAcl(ObjectIdentity objectIdentity)
+ throws AlreadyExistsException {
+ Assert.notNull(objectIdentity, "Object Identity required");
- // Check this object identity hasn't already been persisted
- if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {
- throw new AlreadyExistsException("Object identity '" + objectIdentity + "' already exists");
- }
+ // Check this object identity hasn't already been persisted
+ if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {
+ throw new AlreadyExistsException("Object identity '" + objectIdentity
+ + "' already exists");
+ }
- // Need to retrieve the current principal, in order to know who "owns" this ACL (can be changed later on)
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- PrincipalSid sid = new PrincipalSid(auth);
+ // Need to retrieve the current principal, in order to know who "owns" this ACL
+ // (can be changed later on)
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ PrincipalSid sid = new PrincipalSid(auth);
- // Create the acl_object_identity row
- createObjectIdentity(objectIdentity, sid);
+ // Create the acl_object_identity row
+ createObjectIdentity(objectIdentity, sid);
- // Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
- Acl acl = readAclById(objectIdentity);
- Assert.isInstanceOf(MutableAcl.class, acl, "MutableAcl should be been returned");
+ // Retrieve the ACL via superclass (ensures cache registration, proper retrieval
+ // etc)
+ Acl acl = readAclById(objectIdentity);
+ Assert.isInstanceOf(MutableAcl.class, acl, "MutableAcl should be been returned");
- return (MutableAcl) acl;
- }
+ return (MutableAcl) acl;
+ }
- /**
- * Creates a new row in acl_entry for every ACE defined in the passed MutableAcl object.
- *
- * @param acl containing the ACEs to insert
- */
- protected void createEntries(final MutableAcl acl) {
- if(acl.getEntries().isEmpty()) {
- return;
- }
- jdbcTemplate.batchUpdate(insertEntry,
- new BatchPreparedStatementSetter() {
- public int getBatchSize() {
- return acl.getEntries().size();
- }
+ /**
+ * Creates a new row in acl_entry for every ACE defined in the passed MutableAcl
+ * object.
+ *
+ * @param acl containing the ACEs to insert
+ */
+ protected void createEntries(final MutableAcl acl) {
+ if (acl.getEntries().isEmpty()) {
+ return;
+ }
+ jdbcTemplate.batchUpdate(insertEntry, new BatchPreparedStatementSetter() {
+ public int getBatchSize() {
+ return acl.getEntries().size();
+ }
- public void setValues(PreparedStatement stmt, int i) throws SQLException {
- AccessControlEntry entry_ = acl.getEntries().get(i);
- Assert.isTrue(entry_ instanceof AccessControlEntryImpl, "Unknown ACE class");
- AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
+ public void setValues(PreparedStatement stmt, int i) throws SQLException {
+ AccessControlEntry entry_ = acl.getEntries().get(i);
+ Assert.isTrue(entry_ instanceof AccessControlEntryImpl,
+ "Unknown ACE class");
+ AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
- stmt.setLong(1, ((Long) acl.getId()).longValue());
- stmt.setInt(2, i);
- stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true).longValue());
- stmt.setInt(4, entry.getPermission().getMask());
- stmt.setBoolean(5, entry.isGranting());
- stmt.setBoolean(6, entry.isAuditSuccess());
- stmt.setBoolean(7, entry.isAuditFailure());
- }
- });
- }
+ stmt.setLong(1, ((Long) acl.getId()).longValue());
+ stmt.setInt(2, i);
+ stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true)
+ .longValue());
+ stmt.setInt(4, entry.getPermission().getMask());
+ stmt.setBoolean(5, entry.isGranting());
+ stmt.setBoolean(6, entry.isAuditSuccess());
+ stmt.setBoolean(7, entry.isAuditFailure());
+ }
+ });
+ }
- /**
- * Creates an entry in the acl_object_identity table for the passed ObjectIdentity. The Sid is also
- * necessary, as acl_object_identity has defined the sid column as non-null.
- *
- * @param object to represent an acl_object_identity for
- * @param owner for the SID column (will be created if there is no acl_sid entry for this particular Sid already)
- */
- protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
- Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
- Long classId = createOrRetrieveClassPrimaryKey(object.getType(), true);
- jdbcTemplate.update(insertObjectIdentity, classId, object.getIdentifier(), sidId, Boolean.TRUE);
- }
+ /**
+ * Creates an entry in the acl_object_identity table for the passed ObjectIdentity.
+ * The Sid is also necessary, as acl_object_identity has defined the sid column as
+ * non-null.
+ *
+ * @param object to represent an acl_object_identity for
+ * @param owner for the SID column (will be created if there is no acl_sid entry for
+ * this particular Sid already)
+ */
+ protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
+ Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
+ Long classId = createOrRetrieveClassPrimaryKey(object.getType(), true);
+ jdbcTemplate.update(insertObjectIdentity, classId, object.getIdentifier(), sidId,
+ Boolean.TRUE);
+ }
- /**
- * Retrieves the primary key from {@code acl_class}, creating a new row if needed and the
- * {@code allowCreate} property is {@code true}.
- *
- * @param type to find or create an entry for (often the fully-qualified class name)
- * @param allowCreate true if creation is permitted if not found
- *
- * @return the primary key or null if not found
- */
- protected Long createOrRetrieveClassPrimaryKey(String type, boolean allowCreate) {
- List
- * We do not delete any entries from acl_class, even if no classes are using that class any longer. This is a
- * deadlock avoidance approach.
- *
- * @param oidPrimaryKey to delete the acl_object_identity
- */
- protected void deleteObjectIdentity(Long oidPrimaryKey) {
- // Delete the acl_object_identity row
- jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, oidPrimaryKey);
- }
+ /**
+ * Deletes a single row from acl_object_identity that is associated with the presented
+ * ObjectIdentity primary key.
+ *
+ * We do not delete any entries from acl_class, even if no classes are using that
+ * class any longer. This is a deadlock avoidance approach.
+ *
+ * @param oidPrimaryKey to delete the acl_object_identity
+ */
+ protected void deleteObjectIdentity(Long oidPrimaryKey) {
+ // Delete the acl_object_identity row
+ jdbcTemplate.update(deleteObjectIdentityByPrimaryKey, oidPrimaryKey);
+ }
- /**
- * Retrieves the primary key from the acl_object_identity table for the passed ObjectIdentity. Unlike some
- * other methods in this implementation, this method will NOT create a row (use {@link
- * #createObjectIdentity(ObjectIdentity, Sid)} instead).
- *
- * @param oid to find
- *
- * @return the object identity or null if not found
- */
- protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
- try {
- return new Long(jdbcTemplate.queryForLong(selectObjectIdentityPrimaryKey, oid.getType(), oid.getIdentifier()));
- } catch (DataAccessException notFound) {
- return null;
- }
- }
+ /**
+ * Retrieves the primary key from the acl_object_identity table for the passed
+ * ObjectIdentity. Unlike some other methods in this implementation, this method will
+ * NOT create a row (use {@link #createObjectIdentity(ObjectIdentity, Sid)} instead).
+ *
+ * @param oid to find
+ *
+ * @return the object identity or null if not found
+ */
+ protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
+ try {
+ return new Long(jdbcTemplate.queryForLong(selectObjectIdentityPrimaryKey,
+ oid.getType(), oid.getIdentifier()));
+ }
+ catch (DataAccessException notFound) {
+ return null;
+ }
+ }
- /**
- * This implementation will simply delete all ACEs in the database and recreate them on each invocation of
- * this method. A more comprehensive implementation might use dirty state checking, or more likely use ORM
- * capabilities for create, update and delete operations of {@link MutableAcl}.
- */
- public MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {
- Assert.notNull(acl.getId(), "Object Identity doesn't provide an identifier");
+ /**
+ * This implementation will simply delete all ACEs in the database and recreate them
+ * on each invocation of this method. A more comprehensive implementation might use
+ * dirty state checking, or more likely use ORM capabilities for create, update and
+ * delete operations of {@link MutableAcl}.
+ */
+ public MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {
+ Assert.notNull(acl.getId(), "Object Identity doesn't provide an identifier");
- // Delete this ACL's ACEs in the acl_entry table
- deleteEntries(retrieveObjectIdentityPrimaryKey(acl.getObjectIdentity()));
+ // Delete this ACL's ACEs in the acl_entry table
+ deleteEntries(retrieveObjectIdentityPrimaryKey(acl.getObjectIdentity()));
- // Create this ACL's ACEs in the acl_entry table
- createEntries(acl);
+ // Create this ACL's ACEs in the acl_entry table
+ createEntries(acl);
- // Change the mutable columns in acl_object_identity
- updateObjectIdentity(acl);
+ // Change the mutable columns in acl_object_identity
+ updateObjectIdentity(acl);
- // Clear the cache, including children
- clearCacheIncludingChildren(acl.getObjectIdentity());
+ // Clear the cache, including children
+ clearCacheIncludingChildren(acl.getObjectIdentity());
- // Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
- return (MutableAcl) super.readAclById(acl.getObjectIdentity());
- }
+ // Retrieve the ACL via superclass (ensures cache registration, proper retrieval
+ // etc)
+ return (MutableAcl) super.readAclById(acl.getObjectIdentity());
+ }
- private void clearCacheIncludingChildren(ObjectIdentity objectIdentity) {
- Assert.notNull(objectIdentity, "ObjectIdentity required");
- List
- * Instances MUST be immutable, as they are returned by AclService
is used to retrieve the access control list (ACL) permissions associated with a
- * domain object instance for the current Authentication
object.
+ * The AclService
is used to retrieve the access control list (ACL)
+ * permissions associated with a domain object instance for the current
+ * Authentication
object.
* AclEntryAfterInvocationProvider
with a {@link
- * #processConfigAttribute} of AFTER_ACL_READ
and a {@link #requirePermission} of
- * BasePermission.READ
. These are also the defaults.
+ * Often users will set up an AclEntryAfterInvocationProvider
with a
+ * {@link #processConfigAttribute} of AFTER_ACL_READ
and a
+ * {@link #requirePermission} of BasePermission.READ
. These are also the
+ * defaults.
* AccessDeniedException
will be thrown.
+ * If the principal does not have sufficient permissions, an
+ * AccessDeniedException
will be thrown.
* null
, permission will always be granted and
- * null
will be returned.
+ * If the provided returnedObject is null
, permission will always be
+ * granted and null
will be returned.
* AccessControlEntry
.
*
* @author Ben Alex
*/
-public class AccessControlEntryImpl implements AccessControlEntry, AuditableAccessControlEntry {
- //~ Instance fields ================================================================================================
+public class AccessControlEntryImpl implements AccessControlEntry,
+ AuditableAccessControlEntry {
+ // ~ Instance fields
+ // ================================================================================================
- private final Acl acl;
- private Permission permission;
- private final Serializable id;
- private final Sid sid;
- private boolean auditFailure = false;
- private boolean auditSuccess = false;
- private final boolean granting;
+ private final Acl acl;
+ private Permission permission;
+ private final Serializable id;
+ private final Sid sid;
+ private boolean auditFailure = false;
+ private boolean auditSuccess = false;
+ private final boolean granting;
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public AccessControlEntryImpl(Serializable id, Acl acl, Sid sid, Permission permission, boolean granting,
- boolean auditSuccess, boolean auditFailure) {
- Assert.notNull(acl, "Acl required");
- Assert.notNull(sid, "Sid required");
- Assert.notNull(permission, "Permission required");
- this.id = id;
- this.acl = acl; // can be null
- this.sid = sid;
- this.permission = permission;
- this.granting = granting;
- this.auditSuccess = auditSuccess;
- this.auditFailure = auditFailure;
- }
+ public AccessControlEntryImpl(Serializable id, Acl acl, Sid sid,
+ Permission permission, boolean granting, boolean auditSuccess,
+ boolean auditFailure) {
+ Assert.notNull(acl, "Acl required");
+ Assert.notNull(sid, "Sid required");
+ Assert.notNull(permission, "Permission required");
+ this.id = id;
+ this.acl = acl; // can be null
+ this.sid = sid;
+ this.permission = permission;
+ this.granting = granting;
+ this.auditSuccess = auditSuccess;
+ this.auditFailure = auditFailure;
+ }
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public boolean equals(Object arg0) {
- if (!(arg0 instanceof AccessControlEntryImpl)) {
- return false;
- }
+ public boolean equals(Object arg0) {
+ if (!(arg0 instanceof AccessControlEntryImpl)) {
+ return false;
+ }
- AccessControlEntryImpl rhs = (AccessControlEntryImpl) arg0;
+ AccessControlEntryImpl rhs = (AccessControlEntryImpl) arg0;
- if (this.acl == null) {
- if (rhs.getAcl() != null) {
- return false;
- }
- // Both this.acl and rhs.acl are null and thus equal
- } else {
- // this.acl is non-null
- if (rhs.getAcl() == null) {
- return false;
- }
+ if (this.acl == null) {
+ if (rhs.getAcl() != null) {
+ return false;
+ }
+ // Both this.acl and rhs.acl are null and thus equal
+ }
+ else {
+ // this.acl is non-null
+ if (rhs.getAcl() == null) {
+ return false;
+ }
- // Both this.acl and rhs.acl are non-null, so do a comparison
- if (this.acl.getObjectIdentity() == null) {
- if (rhs.acl.getObjectIdentity() != null) {
- return false;
- }
- // Both this.acl and rhs.acl are null and thus equal
- } else {
- // Both this.acl.objectIdentity and rhs.acl.objectIdentity are non-null
- if (!this.acl.getObjectIdentity().equals(rhs.getAcl().getObjectIdentity())) {
- return false;
- }
- }
- }
+ // Both this.acl and rhs.acl are non-null, so do a comparison
+ if (this.acl.getObjectIdentity() == null) {
+ if (rhs.acl.getObjectIdentity() != null) {
+ return false;
+ }
+ // Both this.acl and rhs.acl are null and thus equal
+ }
+ else {
+ // Both this.acl.objectIdentity and rhs.acl.objectIdentity are non-null
+ if (!this.acl.getObjectIdentity()
+ .equals(rhs.getAcl().getObjectIdentity())) {
+ return false;
+ }
+ }
+ }
- if (this.id == null) {
- if (rhs.id != null) {
- return false;
- }
- // Both this.id and rhs.id are null and thus equal
- } else {
- // this.id is non-null
- if (rhs.id == null) {
- return false;
- }
+ if (this.id == null) {
+ if (rhs.id != null) {
+ return false;
+ }
+ // Both this.id and rhs.id are null and thus equal
+ }
+ else {
+ // this.id is non-null
+ if (rhs.id == null) {
+ return false;
+ }
- // Both this.id and rhs.id are non-null
- if (!this.id.equals(rhs.id)) {
- return false;
- }
- }
+ // Both this.id and rhs.id are non-null
+ if (!this.id.equals(rhs.id)) {
+ return false;
+ }
+ }
- if ((this.auditFailure != rhs.isAuditFailure()) || (this.auditSuccess != rhs.isAuditSuccess())
- || (this.granting != rhs.isGranting())
- || !this.permission.equals(rhs.getPermission()) || !this.sid.equals(rhs.getSid())) {
- return false;
- }
+ if ((this.auditFailure != rhs.isAuditFailure())
+ || (this.auditSuccess != rhs.isAuditSuccess())
+ || (this.granting != rhs.isGranting())
+ || !this.permission.equals(rhs.getPermission())
+ || !this.sid.equals(rhs.getSid())) {
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- public Acl getAcl() {
- return acl;
- }
+ public Acl getAcl() {
+ return acl;
+ }
- public Serializable getId() {
- return id;
- }
+ public Serializable getId() {
+ return id;
+ }
- public Permission getPermission() {
- return permission;
- }
+ public Permission getPermission() {
+ return permission;
+ }
- public Sid getSid() {
- return sid;
- }
+ public Sid getSid() {
+ return sid;
+ }
- public boolean isAuditFailure() {
- return auditFailure;
- }
+ public boolean isAuditFailure() {
+ return auditFailure;
+ }
- public boolean isAuditSuccess() {
- return auditSuccess;
- }
+ public boolean isAuditSuccess() {
+ return auditSuccess;
+ }
- public boolean isGranting() {
- return granting;
- }
+ public boolean isGranting() {
+ return granting;
+ }
- void setAuditFailure(boolean auditFailure) {
- this.auditFailure = auditFailure;
- }
+ void setAuditFailure(boolean auditFailure) {
+ this.auditFailure = auditFailure;
+ }
- void setAuditSuccess(boolean auditSuccess) {
- this.auditSuccess = auditSuccess;
- }
+ void setAuditSuccess(boolean auditSuccess) {
+ this.auditSuccess = auditSuccess;
+ }
- void setPermission(Permission permission) {
- Assert.notNull(permission, "Permission required");
- this.permission = permission;
- }
+ void setPermission(Permission permission) {
+ Assert.notNull(permission, "Permission required");
+ this.permission = permission;
+ }
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("AccessControlEntryImpl[");
- sb.append("id: ").append(this.id).append("; ");
- sb.append("granting: ").append(this.granting).append("; ");
- sb.append("sid: ").append(this.sid).append("; ");
- sb.append("permission: ").append(this.permission).append("; ");
- sb.append("auditSuccess: ").append(this.auditSuccess).append("; ");
- sb.append("auditFailure: ").append(this.auditFailure);
- sb.append("]");
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("AccessControlEntryImpl[");
+ sb.append("id: ").append(this.id).append("; ");
+ sb.append("granting: ").append(this.granting).append("; ");
+ sb.append("sid: ").append(this.sid).append("; ");
+ sb.append("permission: ").append(this.permission).append("; ");
+ sb.append("auditSuccess: ").append(this.auditSuccess).append("; ");
+ sb.append("auditFailure: ").append(this.auditFailure);
+ sb.append("]");
- return sb.toString();
- }
+ return sb.toString();
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategy.java b/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategy.java
index a5cfcbd253..0541c16252 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategy.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategy.java
@@ -17,7 +17,6 @@ package org.springframework.security.acls.domain;
import org.springframework.security.acls.model.Acl;
-
/**
* Strategy used by {@link AclImpl} to determine whether a principal is permitted to call
* adminstrative methods on the AclImpl
.
@@ -25,13 +24,15 @@ import org.springframework.security.acls.model.Acl;
* @author Ben Alex
*/
public interface AclAuthorizationStrategy {
- //~ Static fields/initializers =====================================================================================
+ // ~ Static fields/initializers
+ // =====================================================================================
- int CHANGE_OWNERSHIP = 0;
- int CHANGE_AUDITING = 1;
- int CHANGE_GENERAL = 2;
+ int CHANGE_OWNERSHIP = 0;
+ int CHANGE_AUDITING = 1;
+ int CHANGE_GENERAL = 2;
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- void securityCheck(Acl acl, int changeType);
+ void securityCheck(Acl acl, int changeType);
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java b/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java
index 46e5601b0b..6514cd655e 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java
@@ -27,115 +27,124 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
-
/**
* Default implementation of {@link AclAuthorizationStrategy}.
*
- *
*
* @author Ben Alex
*/
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private final GrantedAuthority gaGeneralChanges;
- private final GrantedAuthority gaModifyAuditing;
- private final GrantedAuthority gaTakeOwnership;
- private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
+ private final GrantedAuthority gaGeneralChanges;
+ private final GrantedAuthority gaModifyAuditing;
+ private final GrantedAuthority gaTakeOwnership;
+ private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- /**
- * Constructor. The only mandatory parameter relates to the system-wide {@link GrantedAuthority} instances that
- * can be held to always permit ACL changes.
- *
- * @param auths the GrantedAuthority
s that have
- * special permissions (index 0 is the authority needed to change
- * ownership, index 1 is the authority needed to modify auditing details,
- * index 2 is the authority needed to change other ACL and ACE details) (required)
- * GrantedAuthority
s that have special permissions
+ * (index 0 is the authority needed to change ownership, index 1 is the authority
+ * needed to modify auditing details, index 2 is the authority needed to change other
+ * ACL and ACE details) (required)
+ * Acl
.
*
* @author Ben Alex
*/
public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private Acl parentAcl;
- private transient AclAuthorizationStrategy aclAuthorizationStrategy;
- private transient PermissionGrantingStrategy permissionGrantingStrategy;
- private final ListAclImpl
to log audit events.
*
@@ -24,7 +23,8 @@ import org.springframework.security.acls.model.AccessControlEntry;
*
*/
public interface AuditLogger {
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- void logIfNeeded(boolean granted, AccessControlEntry ace);
+ void logIfNeeded(boolean granted, AccessControlEntry ace);
}
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 a1fe8f0fb1..6953027f8e 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
@@ -16,7 +16,6 @@ package org.springframework.security.acls.domain;
import org.springframework.security.acls.model.Permission;
-
/**
* A set of standard permissions.
*
@@ -28,17 +27,17 @@ import org.springframework.security.acls.model.Permission;
* @author Ben Alex
*/
public class BasePermission extends AbstractPermission {
- public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
- public static final Permission WRITE = new BasePermission(1 << 1, 'W'); // 2
- public static final Permission CREATE = new BasePermission(1 << 2, 'C'); // 4
- public static final Permission DELETE = new BasePermission(1 << 3, 'D'); // 8
- public static final Permission ADMINISTRATION = new BasePermission(1 << 4, 'A'); // 16
+ public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
+ public static final Permission WRITE = new BasePermission(1 << 1, 'W'); // 2
+ public static final Permission CREATE = new BasePermission(1 << 2, 'C'); // 4
+ public static final Permission DELETE = new BasePermission(1 << 3, 'D'); // 8
+ public static final Permission ADMINISTRATION = new BasePermission(1 << 4, 'A'); // 16
- protected BasePermission(int mask) {
- super(mask);
- }
+ protected BasePermission(int mask) {
+ super(mask);
+ }
- protected BasePermission(int mask, char code) {
- super(mask, code);
- }
+ protected BasePermission(int mask, char code) {
+ super(mask, code);
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/ConsoleAuditLogger.java b/acl/src/main/java/org/springframework/security/acls/domain/ConsoleAuditLogger.java
index 5c0b059b02..482f49f71e 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/ConsoleAuditLogger.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/ConsoleAuditLogger.java
@@ -19,26 +19,27 @@ import org.springframework.security.acls.model.AuditableAccessControlEntry;
import org.springframework.util.Assert;
-
/**
* A basic implementation of {@link AuditLogger}.
*
* @author Ben Alex
*/
public class ConsoleAuditLogger implements AuditLogger {
- //~ Methods ========================================================================================================
+ // ~ Methods
+ // ========================================================================================================
- public void logIfNeeded(boolean granted, AccessControlEntry ace) {
- Assert.notNull(ace, "AccessControlEntry required");
+ public void logIfNeeded(boolean granted, AccessControlEntry ace) {
+ Assert.notNull(ace, "AccessControlEntry required");
- if (ace instanceof AuditableAccessControlEntry) {
- AuditableAccessControlEntry auditableAce = (AuditableAccessControlEntry) ace;
+ if (ace instanceof AuditableAccessControlEntry) {
+ AuditableAccessControlEntry auditableAce = (AuditableAccessControlEntry) ace;
- if (granted && auditableAce.isAuditSuccess()) {
- System.out.println("GRANTED due to ACE: " + ace);
- } else if (!granted && auditableAce.isAuditFailure()) {
- System.out.println("DENIED due to ACE: " + ace);
- }
- }
- }
+ if (granted && auditableAce.isAuditSuccess()) {
+ System.out.println("GRANTED due to ACE: " + ace);
+ }
+ else if (!granted && auditableAce.isAuditFailure()) {
+ System.out.println("DENIED due to ACE: " + ace);
+ }
+ }
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/CumulativePermission.java b/acl/src/main/java/org/springframework/security/acls/domain/CumulativePermission.java
index 554989dabf..158fd4150f 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/CumulativePermission.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/CumulativePermission.java
@@ -16,45 +16,49 @@ package org.springframework.security.acls.domain;
import org.springframework.security.acls.model.Permission;
-
/**
- * Represents a Permission
that is constructed at runtime from other permissions.
+ * Represents a Permission
that is constructed at runtime from other
+ * permissions.
*
- * this
, in order to facilitate method chaining.this
, in order to facilitate method chaining.
+ * permission
and sid
arguments is
- * extremely important! The method will iterate through each of the permission
s in the order
- * specified. For each iteration, all of the sid
s will be considered, again in the order they are
- * presented. A search will then be performed for the first {@link AccessControlEntry} object that directly
- * matches that permission:sid
combination. When the first full match is found (ie an ACE
- * that has the SID currently being searched for and the exact permission bit mask being search for), the grant or
- * deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return
- * true
. If the ACE specifies to deny access, the loop will stop and the next permission
- * iteration will be performed. If each permission indicates to deny access, the first deny ACE found will be
- * considered the reason for the failure (as it was the first match found, and is therefore the one most logically
- * requiring changes - although not always). If absolutely no matching ACE was found at all for any permission,
- * the parent ACL will be tried (provided that there is a parent and {@link Acl#isEntriesInheriting()} is
- * true
. The parent ACL will also scan its parent and so on. If ultimately no matching ACE is found,
- * a NotFoundException
will be thrown and the caller will need to decide how to handle the permission
- * check. Similarly, if any of the SID arguments presented to the method were not loaded by the ACL,
- * UnloadedSidException
will be thrown.
- *
- * @param permission the exact permissions to scan for (order is important)
- * @param sids the exact SIDs to scan for (order is important)
- * @param administrativeMode if true
denotes the query is for administrative purposes and no auditing
- * will be undertaken
- *
- * @return true
if one of the permissions has been granted, false
if one of the
- * permissions has been specifically revoked
- *
- * @throws NotFoundException if an exact ACE for one of the permission bit masks and SID combination could not be
- * found
- */
- public boolean isGranted(Acl acl, Listpermission
and
+ * sid
arguments is extremely important! The method will iterate
+ * through each of the permission
s in the order specified. For each
+ * iteration, all of the sid
s will be considered, again in the order they
+ * are presented. A search will then be performed for the first
+ * {@link AccessControlEntry} object that directly matches that
+ * permission:sid
combination. When the first full match is
+ * found (ie an ACE that has the SID currently being searched for and the exact
+ * permission bit mask being search for), the grant or deny flag for that ACE will
+ * prevail. If the ACE specifies to grant access, the method will return
+ * true
. If the ACE specifies to deny access, the loop will stop and the
+ * next permission
iteration will be performed. If each permission
+ * indicates to deny access, the first deny ACE found will be considered the reason
+ * for the failure (as it was the first match found, and is therefore the one most
+ * logically requiring changes - although not always). If absolutely no matching ACE
+ * was found at all for any permission, the parent ACL will be tried (provided that
+ * there is a parent and {@link Acl#isEntriesInheriting()} is true
. The
+ * parent ACL will also scan its parent and so on. If ultimately no matching ACE is
+ * found, a NotFoundException
will be thrown and the caller will need to
+ * decide how to handle the permission check. Similarly, if any of the SID arguments
+ * presented to the method were not loaded by the ACL,
+ * UnloadedSidException
will be thrown.
+ *
+ * @param permission the exact permissions to scan for (order is important)
+ * @param sids the exact SIDs to scan for (order is important)
+ * @param administrativeMode if true
denotes the query is for
+ * administrative purposes and no auditing will be undertaken
+ *
+ * @return true
if one of the permissions has been granted,
+ * false
if one of the permissions has been specifically revoked
+ *
+ * @throws NotFoundException if an exact ACE for one of the permission bit masks and
+ * SID combination could not be found
+ */
+ public boolean isGranted(Acl acl, ListGrantedAuthority
as a Sid
.String
-based principal for Sid
comparison. More complex principal objects may
- * wish to provide an alternative Sid
implementation that uses some other identifier.GrantedAuthority
as a Sid
.
+ * String
-based principal
+ * for Sid
comparison. More complex principal objects may wish to provide an
+ * alternative Sid
implementation that uses some other identifier.
+ * IdentityUnavailableException
with the specified message.
- *
- * @param msg the detail message
- */
- public IdentityUnavailableException(String msg) {
- super(msg);
- }
+ /**
+ * Constructs an IdentityUnavailableException
with the specified message.
+ *
+ * @param msg the detail message
+ */
+ public IdentityUnavailableException(String msg) {
+ super(msg);
+ }
- /**
- * Constructs an IdentityUnavailableException
with the specified message
- * and root cause.
- *
- * @param msg the detail message
- * @param t root cause
- */
- public IdentityUnavailableException(String msg, Throwable t) {
- super(msg, t);
- }
+ /**
+ * Constructs an IdentityUnavailableException
with the specified message
+ * and root cause.
+ *
+ * @param msg the detail message
+ * @param t root cause
+ */
+ public IdentityUnavailableException(String msg, Throwable t) {
+ super(msg, t);
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityImpl.java b/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityImpl.java
index 9026696325..2e485a670e 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityImpl.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityImpl.java
@@ -21,137 +21,145 @@ import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
-
/**
* Simple implementation of {@link ObjectIdentity}.
* String
s to store the identity of the domain object instance. Also offers a constructor that uses
- * reflection to build the identity information.
+ * Uses String
s to store the identity of the domain object instance. Also
+ * offers a constructor that uses reflection to build the identity information.
*
* @author Ben Alex
*/
public class ObjectIdentityImpl implements ObjectIdentity {
- //~ Instance fields ================================================================================================
+ // ~ Instance fields
+ // ================================================================================================
- private final String type;
- private Serializable identifier;
+ private final String type;
+ private Serializable identifier;
- //~ Constructors ===================================================================================================
+ // ~ Constructors
+ // ===================================================================================================
- public ObjectIdentityImpl(String type, Serializable identifier) {
- Assert.hasText(type, "Type required");
- Assert.notNull(identifier, "identifier required");
+ public ObjectIdentityImpl(String type, Serializable identifier) {
+ Assert.hasText(type, "Type required");
+ Assert.notNull(identifier, "identifier required");
- this.identifier = identifier;
- this.type = type;
- }
+ this.identifier = identifier;
+ this.type = type;
+ }
- /**
- * Constructor which uses the name of the supplied class as the type property.
- */
- public ObjectIdentityImpl(Class> javaType, Serializable identifier) {
- Assert.notNull(javaType, "Java Type required");
- Assert.notNull(identifier, "identifier required");
- this.type = javaType.getName();
- this.identifier = identifier;
- }
+ /**
+ * Constructor which uses the name of the supplied class as the type
+ * property.
+ */
+ public ObjectIdentityImpl(Class> javaType, Serializable identifier) {
+ Assert.notNull(javaType, "Java Type required");
+ Assert.notNull(identifier, "identifier required");
+ this.type = javaType.getName();
+ this.identifier = identifier;
+ }
- /**
- * Creates the ObjectIdentityImpl
based on the passed
- * object instance. The passed object must provide a getId()
- * method, otherwise an exception will be thrown.
- * ObjectIdentityImpl
based on the passed object instance.
+ * The passed object must provide a getId()
method, otherwise an
+ * exception will be thrown.
+ * classname
and
- * id
properties.
- * true
if the presented object matches this object
- */
- public boolean equals(Object arg0) {
- if (arg0 == null || !(arg0 instanceof ObjectIdentityImpl)) {
- return false;
- }
+ /**
+ * Important so caching operates properly.
+ * classname
and id
properties.
+ * true
if the presented object matches this object
+ */
+ public boolean equals(Object arg0) {
+ if (arg0 == null || !(arg0 instanceof ObjectIdentityImpl)) {
+ return false;
+ }
- ObjectIdentityImpl other = (ObjectIdentityImpl) arg0;
+ ObjectIdentityImpl other = (ObjectIdentityImpl) arg0;
- if (identifier instanceof Number && other.identifier instanceof Number) {
- // Integers and Longs with same value should be considered equal
- if (((Number)identifier).longValue() != ((Number)other.identifier).longValue()) {
- return false;
- }
- } else {
- // Use plain equality for other serializable types
- if (!identifier.equals(other.identifier)) {
- return false;
- }
- }
+ if (identifier instanceof Number && other.identifier instanceof Number) {
+ // Integers and Longs with same value should be considered equal
+ if (((Number) identifier).longValue() != ((Number) other.identifier)
+ .longValue()) {
+ return false;
+ }
+ }
+ else {
+ // Use plain equality for other serializable types
+ if (!identifier.equals(other.identifier)) {
+ return false;
+ }
+ }
- return type.equals(other.type);
- }
+ return type.equals(other.type);
+ }
- public Serializable getIdentifier() {
- return identifier;
- }
+ public Serializable getIdentifier() {
+ return identifier;
+ }
- public String getType() {
- return type;
- }
+ public String getType() {
+ return type;
+ }
- /**
- * Important so caching operates properly.
- *
- * @return the hash
- */
- public int hashCode() {
- int code = 31;
- code ^= this.type.hashCode();
- code ^= this.identifier.hashCode();
+ /**
+ * Important so caching operates properly.
+ *
+ * @return the hash
+ */
+ public int hashCode() {
+ int code = 31;
+ code ^= this.type.hashCode();
+ code ^= this.identifier.hashCode();
- return code;
- }
+ return code;
+ }
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(this.getClass().getName()).append("[");
- sb.append("Type: ").append(this.type);
- sb.append("; Identifier: ").append(this.identifier).append("]");
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(this.getClass().getName()).append("[");
+ sb.append("Type: ").append(this.type);
+ sb.append("; Identifier: ").append(this.identifier).append("]");
- return sb.toString();
- }
+ return sb.toString();
+ }
}
diff --git a/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityRetrievalStrategyImpl.java b/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityRetrievalStrategyImpl.java
index 8854f2c65c..e4345547c6 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityRetrievalStrategyImpl.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/ObjectIdentityRetrievalStrategyImpl.java
@@ -22,19 +22,22 @@ import org.springframework.security.acls.model.ObjectIdentityGenerator;
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
/**
- * Basic implementation of {@link ObjectIdentityRetrievalStrategy} and ObjectIdentityGenerator
- * that uses the constructors of {@link ObjectIdentityImpl} to create the {@link ObjectIdentity}.
+ * Basic implementation of {@link ObjectIdentityRetrievalStrategy} and
+ * ObjectIdentityGenerator that uses the constructors of
+ * {@link ObjectIdentityImpl} to create the {@link ObjectIdentity}.
*
* @author Ben Alex
*/
-public class ObjectIdentityRetrievalStrategyImpl implements ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
- //~ Methods ========================================================================================================
+public class ObjectIdentityRetrievalStrategyImpl implements
+ ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
+ // ~ Methods
+ // ========================================================================================================
- public ObjectIdentity getObjectIdentity(Object domainObject) {
- return new ObjectIdentityImpl(domainObject);
- }
+ public ObjectIdentity getObjectIdentity(Object domainObject) {
+ return new ObjectIdentityImpl(domainObject);
+ }
- public ObjectIdentity createObjectIdentity(Serializable id, String type) {
- return new ObjectIdentityImpl(type, id);
- }
+ public ObjectIdentity createObjectIdentity(Serializable id, String type) {
+ return new ObjectIdentityImpl(type, id);
+ }
}
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 92797f66f5..2d98a85f34 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
@@ -5,7 +5,8 @@ import java.util.List;
import org.springframework.security.acls.model.Permission;
/**
- * Provides a simple mechanism to retrieve {@link Permission} instances from integer masks.
+ * Provides a simple mechanism to retrieve {@link Permission} instances from integer
+ * masks.
*
* @author Ben Alex
* @since 2.0.3
@@ -13,19 +14,17 @@ import org.springframework.security.acls.model.Permission;
*/
public interface PermissionFactory {
- /**
- * Dynamically creates a CumulativePermission
or BasePermission
representing the
- * active bits in the passed mask.
- *
- * @param mask to build
- *
- * @return a Permission representing the requested object
- */
- Permission buildFromMask(int mask);
+ /**
+ * Dynamically creates a CumulativePermission
or
+ * BasePermission
representing the active bits in the passed mask.
+ *
+ * @param mask to build
+ *
+ * @return a Permission representing the requested object
+ */
+ Permission buildFromMask(int mask);
+ Permission buildFromName(String name);
- Permission buildFromName(String name);
-
-
- ListAuthentication.getPrincipal()
as a Sid
.String
-based principal for Sid
comparison. More complex principal
- * objects may wish to provide an alternative Sid
implementation that uses some other identifier.Authentication.getPrincipal()
as a Sid
.
+ * String
-based principal
+ * for Sid
comparison. More complex principal objects may wish to provide an
+ * alternative Sid
implementation that uses some other identifier.
+ * LookupStrategy
. This class does not support subclassing, as it is likely to change in future releases
- * and therefore subclassing is unsupported.
+ * NB: This implementation does attempt to provide reasonably optimised lookups - within
+ * the constraints of a normalised database and standard ANSI SQL features. If you are
+ * willing to sacrifice either of these constraints (e.g. use a particular database
+ * feature such as hierarchical queries or materalized views, or reduce normalisation) you
+ * are likely to achieve better performance. In such situations you will need to provide
+ * your own custom LookupStrategy
. This class does not support subclassing,
+ * as it is likely to change in future releases and therefore subclassing is unsupported.
* ObjectIdentity
s directly from the database.
- * Acl
s, including properly-configured
- * parent ACLs.
- *
- */
- private MapMap
of AclImpl
instances which contain
- * StubAclParent
s into proper, valid AclImpl
s with correct ACL parents.
- *
- * @param inputMap the unconverted AclImpl
s
- * @param currentIdentity the currentAcl
that we wish to convert (this may be
- *
- */
- private AclImpl convert(MapResultSet
row, and converts it into an AclImpl
that
- * contains a StubAclParent
- *
- * @param acls the Map we should add the converted Acl to
- * @param rs the ResultSet focused on a current row
- *
- * @throws SQLException if something goes wrong converting values
- */
- private void convertCurrentResultIntoObject(MapObjectIdentity
s directly from the database.
+ * Acl
s, including
+ * properly-configured parent ACLs.
+ *
+ */
+ private MapMap
of AclImpl
+ * instances which contain StubAclParent
s into proper, valid
+ * AclImpl
s with correct ACL parents.
+ *
+ * @param inputMap the unconverted AclImpl
s
+ * @param currentIdentity the currentAcl
that we wish to convert (this
+ * may be
+ *
+ */
+ private AclImpl convert(MapResultSet
row, and converts it into an
+ * AclImpl
that contains a StubAclParent
+ *
+ * @param acls the Map we should add the converted Acl to
+ * @param rs the ResultSet focused on a current row
+ *
+ * @throws SQLException if something goes wrong converting values
+ */
+ private void convertCurrentResultIntoObject(MapAclService
.
*