Reformat code using spring-javaformat
Run `./gradlew format` to reformat all java files. Issue gh-8945
This commit is contained in:
parent
81d9c6cac5
commit
b7fc18262d
|
@ -92,10 +92,10 @@ import org.springframework.util.StringUtils;
|
|||
* <p>
|
||||
* All comparisons and prefixes are case sensitive.
|
||||
*
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class AclEntryVoter extends AbstractAclVoter {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -105,23 +105,26 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
// ================================================================================================
|
||||
|
||||
private AclService aclService;
|
||||
|
||||
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
private String internalMethod;
|
||||
|
||||
private String processConfigAttribute;
|
||||
|
||||
private List<Permission> requirePermission;
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public AclEntryVoter(AclService aclService, String processConfigAttribute,
|
||||
Permission[] requirePermission) {
|
||||
public AclEntryVoter(AclService aclService, String processConfigAttribute, Permission[] requirePermission) {
|
||||
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
|
||||
Assert.notNull(aclService, "An AclService is mandatory");
|
||||
|
||||
if ((requirePermission == null) || (requirePermission.length == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"One or more requirePermission entries is mandatory");
|
||||
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
|
||||
}
|
||||
|
||||
this.aclService = aclService;
|
||||
|
@ -138,7 +141,6 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
* 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 <code>null</code> to use the domain object, or the name of a method (that
|
||||
* requires no arguments) that should be invoked to obtain an <code>Object</code>
|
||||
* which will be the domain object used for ACL evaluation
|
||||
|
@ -155,10 +157,8 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
return processConfigAttribute;
|
||||
}
|
||||
|
||||
public void setObjectIdentityRetrievalStrategy(
|
||||
ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
Assert.notNull(objectIdentityRetrievalStrategy,
|
||||
"ObjectIdentityRetrievalStrategy required");
|
||||
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
Assert.notNull(objectIdentityRetrievalStrategy, "ObjectIdentityRetrievalStrategy required");
|
||||
this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,10 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
return (attribute.getAttribute() != null)
|
||||
&& attribute.getAttribute().equals(getProcessConfigAttribute());
|
||||
return (attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute());
|
||||
}
|
||||
|
||||
public int vote(Authentication authentication, MethodInvocation object,
|
||||
Collection<ConfigAttribute> attributes) {
|
||||
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
|
||||
|
||||
for (ConfigAttribute attr : attributes) {
|
||||
|
||||
|
@ -201,30 +199,25 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
domainObject = method.invoke(domainObject);
|
||||
}
|
||||
catch (NoSuchMethodException nsme) {
|
||||
throw new AuthorizationServiceException("Object of class '"
|
||||
+ domainObject.getClass()
|
||||
+ "' does not provide the requested internalMethod: "
|
||||
+ internalMethod);
|
||||
throw new AuthorizationServiceException("Object of class '" + domainObject.getClass()
|
||||
+ "' does not provide the requested internalMethod: " + internalMethod);
|
||||
}
|
||||
catch (IllegalAccessException iae) {
|
||||
logger.debug("IllegalAccessException", iae);
|
||||
|
||||
throw new AuthorizationServiceException(
|
||||
"Problem invoking internalMethod: " + internalMethod
|
||||
+ " for object: " + domainObject);
|
||||
"Problem invoking internalMethod: " + internalMethod + " for object: " + domainObject);
|
||||
}
|
||||
catch (InvocationTargetException ite) {
|
||||
logger.debug("InvocationTargetException", ite);
|
||||
|
||||
throw new AuthorizationServiceException(
|
||||
"Problem invoking internalMethod: " + internalMethod
|
||||
+ " for object: " + domainObject);
|
||||
"Problem invoking internalMethod: " + internalMethod + " for object: " + domainObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain the OID applicable to the domain object
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy
|
||||
.getObjectIdentity(domainObject);
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy.getObjectIdentity(domainObject);
|
||||
|
||||
// Obtain the SIDs applicable to the principal
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
|
@ -253,7 +246,8 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Voting to deny access - ACLs returned, but insufficient permissions for this principal");
|
||||
logger.debug(
|
||||
"Voting to deny access - ACLs returned, but insufficient permissions for this principal");
|
||||
}
|
||||
|
||||
return ACCESS_DENIED;
|
||||
|
@ -271,4 +265,5 @@ public class AclEntryVoter extends AbstractAclVoter {
|
|||
// No configuration attribute matched, so abstain
|
||||
return ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,9 +38,13 @@ import org.springframework.security.core.Authentication;
|
|||
* @since 3.1
|
||||
*/
|
||||
public class AclPermissionCacheOptimizer implements PermissionCacheOptimizer {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final AclService aclService;
|
||||
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
private ObjectIdentityRetrievalStrategy oidRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
public AclPermissionCacheOptimizer(AclService aclService) {
|
||||
|
@ -71,12 +75,12 @@ public class AclPermissionCacheOptimizer implements PermissionCacheOptimizer {
|
|||
aclService.readAclsById(oidsToCache, sids);
|
||||
}
|
||||
|
||||
public void setObjectIdentityRetrievalStrategy(
|
||||
ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
this.oidRetrievalStrategy = objectIdentityRetrievalStrategy;
|
||||
}
|
||||
|
||||
public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
|
||||
this.sidRetrievalStrategy = sidRetrievalStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,9 +51,13 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
|||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final AclService aclService;
|
||||
|
||||
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
private ObjectIdentityGenerator objectIdentityGenerator = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
private PermissionFactory permissionFactory = new DefaultPermissionFactory();
|
||||
|
||||
public AclPermissionEvaluator(AclService aclService) {
|
||||
|
@ -65,28 +69,24 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
|||
* the ACL configuration. If the domain object is null, returns false (this can always
|
||||
* be overridden using a null check in the expression itself).
|
||||
*/
|
||||
public boolean hasPermission(Authentication authentication, Object domainObject,
|
||||
Object permission) {
|
||||
public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
|
||||
if (domainObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy
|
||||
.getObjectIdentity(domainObject);
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy.getObjectIdentity(domainObject);
|
||||
|
||||
return checkPermission(authentication, objectIdentity, permission);
|
||||
}
|
||||
|
||||
public boolean hasPermission(Authentication authentication, Serializable targetId,
|
||||
String targetType, Object permission) {
|
||||
ObjectIdentity objectIdentity = objectIdentityGenerator.createObjectIdentity(
|
||||
targetId, targetType);
|
||||
|
||||
return checkPermission(authentication, objectIdentity, permission);
|
||||
}
|
||||
|
||||
private boolean checkPermission(Authentication authentication, ObjectIdentity oid,
|
||||
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
|
||||
Object permission) {
|
||||
ObjectIdentity objectIdentity = objectIdentityGenerator.createObjectIdentity(targetId, targetType);
|
||||
|
||||
return checkPermission(authentication, objectIdentity, permission);
|
||||
}
|
||||
|
||||
private boolean checkPermission(Authentication authentication, ObjectIdentity oid, Object permission) {
|
||||
// Obtain the SIDs applicable to the principal
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
List<Permission> requiredPermission = resolvePermission(permission);
|
||||
|
@ -94,8 +94,7 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
|||
final boolean debug = logger.isDebugEnabled();
|
||||
|
||||
if (debug) {
|
||||
logger.debug("Checking permission '" + permission + "' for object '" + oid
|
||||
+ "'");
|
||||
logger.debug("Checking permission '" + permission + "' for object '" + oid + "'");
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -157,8 +156,7 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
|||
throw new IllegalArgumentException("Unsupported permission: " + permission);
|
||||
}
|
||||
|
||||
public void setObjectIdentityRetrievalStrategy(
|
||||
ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
|
||||
}
|
||||
|
||||
|
@ -173,4 +171,5 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
|
|||
public void setPermissionFactory(PermissionFactory permissionFactory) {
|
||||
this.permissionFactory = permissionFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,14 +40,20 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
protected final AclService aclService;
|
||||
|
||||
protected Class<?> processDomainObjectClass = Object.class;
|
||||
|
||||
protected ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
|
||||
protected SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
protected String processConfigAttribute;
|
||||
|
||||
protected final List<Permission> requirePermission;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -59,8 +65,7 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
|||
Assert.notNull(aclService, "An AclService is mandatory");
|
||||
|
||||
if (requirePermission == null || requirePermission.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"One or more requirePermission entries is mandatory");
|
||||
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
|
||||
}
|
||||
|
||||
this.aclService = aclService;
|
||||
|
@ -77,8 +82,7 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
|||
|
||||
protected boolean hasPermission(Authentication authentication, Object domainObject) {
|
||||
// Obtain the OID applicable to the domain object
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy
|
||||
.getObjectIdentity(domainObject);
|
||||
ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy.getObjectIdentity(domainObject);
|
||||
|
||||
// Obtain the SIDs applicable to the principal
|
||||
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
|
||||
|
@ -94,10 +98,8 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public void setObjectIdentityRetrievalStrategy(
|
||||
ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
Assert.notNull(objectIdentityRetrievalStrategy,
|
||||
"ObjectIdentityRetrievalStrategy required");
|
||||
public void setObjectIdentityRetrievalStrategy(ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy) {
|
||||
Assert.notNull(objectIdentityRetrievalStrategy, "ObjectIdentityRetrievalStrategy required");
|
||||
this.objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy;
|
||||
}
|
||||
|
||||
|
@ -107,8 +109,7 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
|||
}
|
||||
|
||||
public void setProcessDomainObjectClass(Class<?> processDomainObjectClass) {
|
||||
Assert.notNull(processDomainObjectClass,
|
||||
"processDomainObjectClass cannot be set to null");
|
||||
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
|
||||
this.processDomainObjectClass = processDomainObjectClass;
|
||||
}
|
||||
|
||||
|
@ -124,12 +125,11 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
|||
/**
|
||||
* This implementation supports any type of class, because it does not query the
|
||||
* presented secure object.
|
||||
*
|
||||
* @param clazz the secure object
|
||||
*
|
||||
* @return always <code>true</code>
|
||||
*/
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,13 +60,12 @@ import org.springframework.security.core.Authentication;
|
|||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
*/
|
||||
public class AclEntryAfterInvocationCollectionFilteringProvider extends
|
||||
AbstractAclProvider {
|
||||
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
|
||||
// ===================================================================================================
|
||||
|
@ -80,9 +79,8 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends
|
|||
// ========================================================================================================
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
Collection<ConfigAttribute> config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
public Object decide(Authentication authentication, Object object, Collection<ConfigAttribute> config,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
|
||||
if (returnedObject == null) {
|
||||
logger.debug("Return object is null, skipping");
|
||||
|
@ -105,19 +103,15 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends
|
|||
filterer = new ArrayFilterer((Object[]) returnedObject);
|
||||
}
|
||||
else {
|
||||
throw new AuthorizationServiceException(
|
||||
"A Collection or an array (or null) was required as the "
|
||||
+ "returnedObject, but the returnedObject was: "
|
||||
+ returnedObject);
|
||||
throw new AuthorizationServiceException("A Collection or an array (or null) was required as the "
|
||||
+ "returnedObject, but the returnedObject was: " + returnedObject);
|
||||
}
|
||||
|
||||
// Locate unauthorised Collection elements
|
||||
for (Object domainObject : filterer) {
|
||||
// Ignore nulls or entries which aren't instances of the configured domain
|
||||
// object class
|
||||
if (domainObject == null
|
||||
|| !getProcessDomainObjectClass().isAssignableFrom(
|
||||
domainObject.getClass())) {
|
||||
if (domainObject == null || !getProcessDomainObjectClass().isAssignableFrom(domainObject.getClass())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -125,8 +119,7 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends
|
|||
filterer.remove(domainObject);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Principal is NOT authorised for element: "
|
||||
+ domainObject);
|
||||
logger.debug("Principal is NOT authorised for element: " + domainObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,4 +129,5 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends
|
|||
|
||||
return returnedObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,13 +58,12 @@ import org.springframework.security.core.SpringSecurityMessageSource;
|
|||
* <p>
|
||||
* All comparisons and prefixes are case sensitive.
|
||||
*/
|
||||
public class AclEntryAfterInvocationProvider extends AbstractAclProvider implements
|
||||
MessageSourceAware {
|
||||
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
|
||||
// ================================================================================================
|
||||
|
@ -74,22 +73,20 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
|||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public AclEntryAfterInvocationProvider(AclService aclService,
|
||||
List<Permission> requirePermission) {
|
||||
public AclEntryAfterInvocationProvider(AclService aclService, List<Permission> requirePermission) {
|
||||
this(aclService, "AFTER_ACL_READ", requirePermission);
|
||||
}
|
||||
|
||||
public AclEntryAfterInvocationProvider(AclService aclService,
|
||||
String processConfigAttribute, List<Permission> requirePermission) {
|
||||
public AclEntryAfterInvocationProvider(AclService aclService, String processConfigAttribute,
|
||||
List<Permission> requirePermission) {
|
||||
super(aclService, processConfigAttribute, requirePermission);
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public Object decide(Authentication authentication, Object object,
|
||||
Collection<ConfigAttribute> config, Object returnedObject)
|
||||
throws AccessDeniedException {
|
||||
public Object decide(Authentication authentication, Object object, Collection<ConfigAttribute> config,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
|
||||
if (returnedObject == null) {
|
||||
// AclManager interface contract prohibits nulls
|
||||
|
@ -117,9 +114,8 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
|||
|
||||
logger.debug("Denying access");
|
||||
|
||||
throw new AccessDeniedException(messages.getMessage(
|
||||
"AclEntryAfterInvocationProvider.noPermission", new Object[] {
|
||||
authentication.getName(), returnedObject },
|
||||
throw new AccessDeniedException(messages.getMessage("AclEntryAfterInvocationProvider.noPermission",
|
||||
new Object[] { authentication.getName(), returnedObject },
|
||||
"Authentication {0} has NO permissions to the domain object {1}"));
|
||||
}
|
||||
|
||||
|
@ -129,4 +125,5 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
|||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
* @author Paulo Neves
|
||||
*/
|
||||
class ArrayFilterer<T> implements Filterer<T> {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -41,6 +42,7 @@ class ArrayFilterer<T> implements Filterer<T> {
|
|||
// ================================================================================================
|
||||
|
||||
private final Set<T> removeList;
|
||||
|
||||
private final T[] list;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -67,8 +69,7 @@ class ArrayFilterer<T> implements Filterer<T> {
|
|||
// Recreate an array of same type and filter the removed objects.
|
||||
int originalSize = list.length;
|
||||
int sizeOfResultingList = originalSize - removeList.size();
|
||||
T[] filtered = (T[]) Array.newInstance(list.getClass().getComponentType(),
|
||||
sizeOfResultingList);
|
||||
T[] filtered = (T[]) Array.newInstance(list.getClass().getComponentType(), sizeOfResultingList);
|
||||
|
||||
for (int i = 0, j = 0; i < list.length; i++) {
|
||||
T object = list[i];
|
||||
|
@ -80,8 +81,8 @@ class ArrayFilterer<T> implements Filterer<T> {
|
|||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Original array contained " + originalSize
|
||||
+ " elements; now contains " + sizeOfResultingList + " elements");
|
||||
logger.debug("Original array contained " + originalSize + " elements; now contains " + sizeOfResultingList
|
||||
+ " elements");
|
||||
}
|
||||
|
||||
return filtered;
|
||||
|
@ -119,4 +120,5 @@ class ArrayFilterer<T> implements Filterer<T> {
|
|||
public void remove(T object) {
|
||||
removeList.add(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
|||
* @author Paulo Neves
|
||||
*/
|
||||
class CollectionFilterer<T> implements Filterer<T> {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -77,8 +78,8 @@ class CollectionFilterer<T> implements Filterer<T> {
|
|||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Original collection contained " + originalSize
|
||||
+ " elements; now contains " + collection.size() + " elements");
|
||||
logger.debug("Original collection contained " + originalSize + " elements; now contains "
|
||||
+ collection.size() + " elements");
|
||||
}
|
||||
|
||||
return collection;
|
||||
|
@ -99,4 +100,5 @@ class CollectionFilterer<T> implements Filterer<T> {
|
|||
public void remove(T object) {
|
||||
removeList.add(object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,27 +25,26 @@ import java.util.Iterator;
|
|||
* @author Paulo Neves
|
||||
*/
|
||||
interface Filterer<T> extends Iterable<T> {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Gets the filtered collection or array.
|
||||
*
|
||||
* @return the filtered collection or array
|
||||
*/
|
||||
Object getFilteredObject();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the filtered collection or array.
|
||||
*
|
||||
* @return an Iterator
|
||||
*/
|
||||
Iterator<T> iterator();
|
||||
|
||||
/**
|
||||
* Removes the given object from the resulting list.
|
||||
*
|
||||
* @param object the object to be removed
|
||||
*/
|
||||
void remove(T object);
|
||||
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* After-invocation providers for collection and array filtering. Consider using a {@code PostFilter} annotation in
|
||||
* preference.
|
||||
* After-invocation providers for collection and array filtering. Consider using a
|
||||
* {@code PostFilter} annotation in preference.
|
||||
*/
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ public abstract class AbstractPermission implements Permission {
|
|||
// ================================================================================================
|
||||
|
||||
protected final char code;
|
||||
|
||||
protected int mask;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -36,7 +37,6 @@ public abstract class AbstractPermission implements Permission {
|
|||
/**
|
||||
* Sets the permission mask and uses the '*' character to represent active bits when
|
||||
* represented as a bit pattern string.
|
||||
*
|
||||
* @param mask the integer bit mask for the permission
|
||||
*/
|
||||
protected AbstractPermission(int mask) {
|
||||
|
@ -46,7 +46,6 @@ public abstract class AbstractPermission implements Permission {
|
|||
|
||||
/**
|
||||
* Sets the permission mask and uses the specified character for active bits.
|
||||
*
|
||||
* @param mask the integer bit mask for the permission
|
||||
* @param code the character to print for each active bit in the mask (see
|
||||
* {@link Permission#getPattern()})
|
||||
|
@ -88,4 +87,5 @@ public abstract class AbstractPermission implements Permission {
|
|||
public final int hashCode() {
|
||||
return this.mask;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,25 +30,30 @@ import java.io.Serializable;
|
|||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class AccessControlEntryImpl implements AccessControlEntry,
|
||||
AuditableAccessControlEntry {
|
||||
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;
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public AccessControlEntryImpl(Serializable id, Acl acl, Sid sid,
|
||||
Permission permission, boolean granting, boolean auditSuccess,
|
||||
boolean 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");
|
||||
|
@ -93,8 +98,7 @@ public class AccessControlEntryImpl implements AccessControlEntry,
|
|||
}
|
||||
else {
|
||||
// Both this.acl.objectIdentity and rhs.acl.objectIdentity are non-null
|
||||
if (!this.acl.getObjectIdentity()
|
||||
.equals(rhs.getAcl().getObjectIdentity())) {
|
||||
if (!this.acl.getObjectIdentity().equals(rhs.getAcl().getObjectIdentity())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -118,10 +122,8 @@ public class AccessControlEntryImpl implements AccessControlEntry,
|
|||
}
|
||||
}
|
||||
|
||||
if ((this.auditFailure != rhs.isAuditFailure())
|
||||
|| (this.auditSuccess != rhs.isAuditSuccess())
|
||||
|| (this.granting != rhs.isGranting())
|
||||
|| !this.permission.equals(rhs.getPermission())
|
||||
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;
|
||||
}
|
||||
|
@ -202,4 +204,5 @@ public class AccessControlEntryImpl implements AccessControlEntry,
|
|||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,15 +25,19 @@ import org.springframework.security.acls.model.Acl;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface AclAuthorizationStrategy {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
int CHANGE_OWNERSHIP = 0;
|
||||
|
||||
int CHANGE_AUDITING = 1;
|
||||
|
||||
int CHANGE_GENERAL = 2;
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
void securityCheck(Acl acl, int changeType);
|
||||
|
||||
}
|
||||
|
|
|
@ -45,12 +45,16 @@ import java.util.Set;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final GrantedAuthority gaGeneralChanges;
|
||||
|
||||
private final GrantedAuthority gaModifyAuditing;
|
||||
|
||||
private final GrantedAuthority gaTakeOwnership;
|
||||
|
||||
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -59,7 +63,6 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
|||
/**
|
||||
* 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 <code>GrantedAuthority</code>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
|
||||
|
@ -86,14 +89,11 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
|||
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");
|
||||
|| !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);
|
||||
|
@ -138,7 +138,6 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
|||
|
||||
/**
|
||||
* Creates a principal-like sid from the authentication information.
|
||||
*
|
||||
* @param authentication the authentication information that can provide principal and
|
||||
* thus the sid's id will be dependant on the value inside
|
||||
* @return a sid with the ID taken from the authentication information
|
||||
|
@ -151,4 +150,5 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
|||
Assert.notNull(sidRetrievalStrategy, "SidRetrievalStrategy required");
|
||||
this.sidRetrievalStrategy = sidRetrievalStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,9 +70,7 @@ public abstract class AclFormattingUtils {
|
|||
* bit being denoted by character '*'.
|
||||
* <p>
|
||||
* 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) {
|
||||
|
@ -84,22 +82,17 @@ public abstract class AclFormattingUtils {
|
|||
* bit being denoted by the passed character.
|
||||
* <p>
|
||||
* 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),
|
||||
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),
|
||||
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) {
|
||||
|
@ -109,4 +102,5 @@ public abstract class AclFormattingUtils {
|
|||
|
||||
return temp2.replace('0', off).replace('1', on);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,18 +38,27 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private Acl parentAcl;
|
||||
|
||||
private transient AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
|
||||
private transient PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
|
||||
private final List<AccessControlEntry> aces = new ArrayList<>();
|
||||
|
||||
private ObjectIdentity objectIdentity;
|
||||
|
||||
private Serializable id;
|
||||
|
||||
private Sid owner; // OwnershipAcl
|
||||
|
||||
private List<Sid> loadedSids = null; // includes all SIDs the WHERE clause covered,
|
||||
// even if there was no ACE for a SID
|
||||
|
||||
private boolean entriesInheriting = true;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -59,14 +68,13 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
* Minimal constructor, which should be used
|
||||
* {@link org.springframework.security.acls.model.MutableAclService#createAcl(ObjectIdentity)}
|
||||
* .
|
||||
*
|
||||
* @param objectIdentity the object identity this ACL relates to (required)
|
||||
* @param id the primary key assigned to this ACL (required)
|
||||
* @param aclAuthorizationStrategy authorization strategy (required)
|
||||
* @param auditLogger audit logger (required)
|
||||
*/
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy, AuditLogger auditLogger) {
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
|
||||
AuditLogger auditLogger) {
|
||||
Assert.notNull(objectIdentity, "Object Identity required");
|
||||
Assert.notNull(id, "Id required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
|
@ -74,14 +82,12 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
this.objectIdentity = objectIdentity;
|
||||
this.id = id;
|
||||
this.aclAuthorizationStrategy = aclAuthorizationStrategy;
|
||||
this.permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(
|
||||
auditLogger);
|
||||
this.permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Full constructor, which should be used by persistence tools that do not provide
|
||||
* field-level access features.
|
||||
*
|
||||
* @param objectIdentity the object identity this ACL relates to
|
||||
* @param id the primary key assigned to this ACL
|
||||
* @param aclAuthorizationStrategy authorization strategy
|
||||
|
@ -93,10 +99,9 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
* @param entriesInheriting if ACEs from the parent should inherit into this ACL
|
||||
* @param owner the owner (required)
|
||||
*/
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy,
|
||||
PermissionGrantingStrategy grantingStrategy, Acl parentAcl,
|
||||
List<Sid> loadedSids, boolean entriesInheriting, Sid owner) {
|
||||
public AclImpl(ObjectIdentity objectIdentity, Serializable id, AclAuthorizationStrategy aclAuthorizationStrategy,
|
||||
PermissionGrantingStrategy grantingStrategy, Acl parentAcl, List<Sid> loadedSids, boolean entriesInheriting,
|
||||
Sid owner) {
|
||||
Assert.notNull(objectIdentity, "Object Identity required");
|
||||
Assert.notNull(id, "Id required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
|
@ -125,8 +130,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
@Override
|
||||
public void deleteAce(int aceIndex) throws NotFoundException {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
verifyAceIndexExists(aceIndex);
|
||||
|
||||
synchronized (aces) {
|
||||
|
@ -139,30 +143,26 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
throw new NotFoundException("aceIndex must be greater than or equal to zero");
|
||||
}
|
||||
if (aceIndex >= this.aces.size()) {
|
||||
throw new NotFoundException(
|
||||
"aceIndex must refer to an index of the AccessControlEntry list. "
|
||||
throw new NotFoundException("aceIndex must refer to an index of the AccessControlEntry list. "
|
||||
+ "List size is " + aces.size() + ", index was " + aceIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAce(int atIndexLocation, Permission permission, Sid sid,
|
||||
boolean granting) throws NotFoundException {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
public void insertAce(int atIndexLocation, Permission permission, Sid sid, boolean granting)
|
||||
throws NotFoundException {
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.notNull(permission, "Permission required");
|
||||
Assert.notNull(sid, "Sid required");
|
||||
if (atIndexLocation < 0) {
|
||||
throw new NotFoundException(
|
||||
"atIndexLocation must be greater than or equal to zero");
|
||||
throw new NotFoundException("atIndexLocation must be greater than or equal to zero");
|
||||
}
|
||||
if (atIndexLocation > this.aces.size()) {
|
||||
throw new NotFoundException(
|
||||
"atIndexLocation must be less than or equal to the size of the AccessControlEntry collection");
|
||||
}
|
||||
|
||||
AccessControlEntryImpl ace = new AccessControlEntryImpl(null, this, sid,
|
||||
permission, granting, false, false);
|
||||
AccessControlEntryImpl ace = new AccessControlEntryImpl(null, this, sid, permission, granting, false, false);
|
||||
|
||||
synchronized (aces) {
|
||||
this.aces.add(atIndexLocation, ace);
|
||||
|
@ -193,14 +193,13 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
/**
|
||||
* Delegates to the {@link PermissionGrantingStrategy}.
|
||||
*
|
||||
* @throws UnloadedSidException if the passed SIDs are unknown to this ACL because the
|
||||
* ACL was only loaded for a subset of SIDs
|
||||
* @see DefaultPermissionGrantingStrategy
|
||||
*/
|
||||
@Override
|
||||
public boolean isGranted(List<Permission> permission, List<Sid> sids,
|
||||
boolean administrativeMode) throws NotFoundException, UnloadedSidException {
|
||||
public boolean isGranted(List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException, UnloadedSidException {
|
||||
Assert.notEmpty(permission, "Permissions required");
|
||||
Assert.notEmpty(sids, "SIDs required");
|
||||
|
||||
|
@ -208,8 +207,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
throw new UnloadedSidException("ACL was not loaded for one or more SID");
|
||||
}
|
||||
|
||||
return permissionGrantingStrategy.isGranted(this, permission, sids,
|
||||
administrativeMode);
|
||||
return permissionGrantingStrategy.isGranted(this, permission, sids, administrativeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -243,15 +241,13 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
@Override
|
||||
public void setEntriesInheriting(boolean entriesInheriting) {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
this.entriesInheriting = entriesInheriting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(Sid newOwner) {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.notNull(newOwner, "Owner required");
|
||||
this.owner = newOwner;
|
||||
}
|
||||
|
@ -263,10 +259,8 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
@Override
|
||||
public void setParent(Acl newParent) {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.isTrue(newParent == null || !newParent.equals(this),
|
||||
"Cannot be the parent of yourself");
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.isTrue(newParent == null || !newParent.equals(this), "Cannot be the parent of yourself");
|
||||
this.parentAcl = newParent;
|
||||
}
|
||||
|
||||
|
@ -277,8 +271,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
@Override
|
||||
public void updateAce(int aceIndex, Permission permission) throws NotFoundException {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
verifyAceIndexExists(aceIndex);
|
||||
|
||||
synchronized (aces) {
|
||||
|
@ -289,8 +282,7 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
|
||||
@Override
|
||||
public void updateAuditing(int aceIndex, boolean auditSuccess, boolean auditFailure) {
|
||||
aclAuthorizationStrategy.securityCheck(this,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(this, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
verifyAceIndexExists(aceIndex);
|
||||
|
||||
synchronized (aces) {
|
||||
|
@ -306,26 +298,19 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
AclImpl rhs = (AclImpl) obj;
|
||||
if (this.aces.equals(rhs.aces)) {
|
||||
if ((this.parentAcl == null && rhs.parentAcl == null)
|
||||
|| (this.parentAcl != null && this.parentAcl
|
||||
.equals(rhs.parentAcl))) {
|
||||
|| (this.parentAcl != null && this.parentAcl.equals(rhs.parentAcl))) {
|
||||
if ((this.objectIdentity == null && rhs.objectIdentity == null)
|
||||
|| (this.objectIdentity != null && this.objectIdentity
|
||||
.equals(rhs.objectIdentity))) {
|
||||
if ((this.id == null && rhs.id == null)
|
||||
|| (this.id != null && this.id.equals(rhs.id))) {
|
||||
|| (this.objectIdentity != null && this.objectIdentity.equals(rhs.objectIdentity))) {
|
||||
if ((this.id == null && rhs.id == null) || (this.id != null && this.id.equals(rhs.id))) {
|
||||
if ((this.owner == null && rhs.owner == null)
|
||||
|| (this.owner != null && this.owner
|
||||
.equals(rhs.owner))) {
|
||||
|| (this.owner != null && this.owner.equals(rhs.owner))) {
|
||||
if (this.entriesInheriting == rhs.entriesInheriting) {
|
||||
if ((this.loadedSids == null && rhs.loadedSids == null)) {
|
||||
return true;
|
||||
}
|
||||
if (this.loadedSids != null
|
||||
&& (this.loadedSids.size() == rhs.loadedSids
|
||||
.size())) {
|
||||
if (this.loadedSids != null && (this.loadedSids.size() == rhs.loadedSids.size())) {
|
||||
for (int i = 0; i < this.loadedSids.size(); i++) {
|
||||
if (!this.loadedSids.get(i).equals(
|
||||
rhs.loadedSids.get(i))) {
|
||||
if (!this.loadedSids.get(i).equals(rhs.loadedSids.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -345,9 +330,8 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
public int hashCode() {
|
||||
int result = this.parentAcl != null ? this.parentAcl.hashCode() : 0;
|
||||
result = 31 * result + this.aclAuthorizationStrategy.hashCode();
|
||||
result = 31 * result + (this.permissionGrantingStrategy != null ?
|
||||
this.permissionGrantingStrategy.hashCode() :
|
||||
0);
|
||||
result = 31 * result
|
||||
+ (this.permissionGrantingStrategy != null ? this.permissionGrantingStrategy.hashCode() : 0);
|
||||
result = 31 * result + (this.aces != null ? this.aces.hashCode() : 0);
|
||||
result = 31 * result + this.objectIdentity.hashCode();
|
||||
result = 31 * result + this.id.hashCode();
|
||||
|
@ -382,12 +366,9 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
|||
}
|
||||
|
||||
sb.append("inheriting: ").append(this.entriesInheriting).append("; ");
|
||||
sb.append("parent: ").append(
|
||||
(this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity()
|
||||
.toString());
|
||||
sb.append("parent: ").append((this.parentAcl == null) ? "Null" : this.parentAcl.getObjectIdentity().toString());
|
||||
sb.append("; ");
|
||||
sb.append("aclAuthorizationStrategy: ").append(this.aclAuthorizationStrategy)
|
||||
.append("; ");
|
||||
sb.append("aclAuthorizationStrategy: ").append(this.aclAuthorizationStrategy).append("; ");
|
||||
sb.append("permissionGrantingStrategy: ").append(this.permissionGrantingStrategy);
|
||||
sb.append("]");
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ import org.springframework.security.acls.model.AccessControlEntry;
|
|||
*
|
||||
*/
|
||||
public interface AuditLogger {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
void logIfNeeded(boolean granted, AccessControlEntry ace);
|
||||
|
||||
}
|
||||
|
|
|
@ -28,10 +28,15 @@ 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
|
||||
|
||||
protected BasePermission(int mask) {
|
||||
|
@ -41,4 +46,5 @@ public class BasePermission extends AbstractPermission {
|
|||
protected BasePermission(int mask, char code) {
|
||||
super(mask, code);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class ConsoleAuditLogger implements AuditLogger {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -43,4 +44,5 @@ public class ConsoleAuditLogger implements AuditLogger {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ public class CumulativePermission extends AbstractPermission {
|
|||
|
||||
public CumulativePermission clear(Permission permission) {
|
||||
this.mask &= ~permission.getMask();
|
||||
this.pattern = AclFormattingUtils.demergePatterns(this.pattern,
|
||||
permission.getPattern());
|
||||
this.pattern = AclFormattingUtils.demergePatterns(this.pattern, permission.getPattern());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -52,8 +51,7 @@ public class CumulativePermission extends AbstractPermission {
|
|||
|
||||
public CumulativePermission set(Permission permission) {
|
||||
this.mask |= permission.getMask();
|
||||
this.pattern = AclFormattingUtils.mergePatterns(this.pattern,
|
||||
permission.getPattern());
|
||||
this.pattern = AclFormattingUtils.mergePatterns(this.pattern, permission.getPattern());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,9 @@ import org.springframework.util.Assert;
|
|||
* @since 2.0.3
|
||||
*/
|
||||
public class DefaultPermissionFactory implements PermissionFactory {
|
||||
|
||||
private final Map<Integer, Permission> registeredPermissionsByInteger = new HashMap<>();
|
||||
|
||||
private final Map<String, Permission> registeredPermissionsByName = new HashMap<>();
|
||||
|
||||
/**
|
||||
|
@ -57,7 +59,6 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
|||
|
||||
/**
|
||||
* Registers a map of named <tt>Permission</tt> instances.
|
||||
*
|
||||
* @param namedPermissions the map of <tt>Permission</tt>s, keyed by name.
|
||||
*/
|
||||
public DefaultPermissionFactory(Map<String, ? extends Permission> namedPermissions) {
|
||||
|
@ -71,7 +72,6 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
|||
* <p>
|
||||
* 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) {
|
||||
|
@ -130,8 +130,8 @@ public class DefaultPermissionFactory implements PermissionFactory {
|
|||
Permission p = registeredPermissionsByInteger.get(permissionToCheck);
|
||||
|
||||
if (p == null) {
|
||||
throw new IllegalStateException("Mask '" + permissionToCheck
|
||||
+ "' does not have a corresponding static Permission");
|
||||
throw new IllegalStateException(
|
||||
"Mask '" + permissionToCheck + "' does not have a corresponding static Permission");
|
||||
}
|
||||
permission.set(p);
|
||||
}
|
||||
|
|
|
@ -61,20 +61,17 @@ public class DefaultPermissionGrantingStrategy implements PermissionGrantingStra
|
|||
* decide how to handle the permission check. Similarly, if any of the SID arguments
|
||||
* presented to the method were not loaded by the ACL,
|
||||
* <code>UnloadedSidException</code> 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 <code>true</code> denotes the query is for
|
||||
* administrative purposes and no auditing will be undertaken
|
||||
*
|
||||
* @return <code>true</code> if one of the permissions has been granted,
|
||||
* <code>false</code> 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, List<Permission> permission, List<Sid> sids,
|
||||
boolean administrativeMode) throws NotFoundException {
|
||||
public boolean isGranted(Acl acl, List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException {
|
||||
|
||||
final List<AccessControlEntry> aces = acl.getEntries();
|
||||
|
||||
|
@ -87,8 +84,7 @@ public class DefaultPermissionGrantingStrategy implements PermissionGrantingStra
|
|||
|
||||
for (AccessControlEntry ace : aces) {
|
||||
|
||||
if (isGranted(ace, p)
|
||||
&& ace.getSid().equals(sid)) {
|
||||
if (isGranted(ace, p) && ace.getSid().equals(sid)) {
|
||||
// Found a matching ACE, so its authorization decision will
|
||||
// prevail
|
||||
if (ace.isGranting()) {
|
||||
|
@ -137,24 +133,21 @@ public class DefaultPermissionGrantingStrategy implements PermissionGrantingStra
|
|||
}
|
||||
else {
|
||||
// We either have no parent, or we're the uppermost parent
|
||||
throw new NotFoundException(
|
||||
"Unable to locate a matching ACE for passed permissions and SIDs");
|
||||
throw new NotFoundException("Unable to locate a matching ACE for passed permissions and SIDs");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares an ACE Permission to the given Permission.
|
||||
* By default, we compare the Permission masks for exact match.
|
||||
* Subclasses of this strategy can override this behavior and implement
|
||||
* more sophisticated comparisons, e.g. a bitwise comparison for ACEs that grant access.
|
||||
* <pre>{@code
|
||||
* Compares an ACE Permission to the given Permission. By default, we compare the
|
||||
* Permission masks for exact match. Subclasses of this strategy can override this
|
||||
* behavior and implement more sophisticated comparisons, e.g. a bitwise comparison
|
||||
* for ACEs that grant access. <pre>{@code
|
||||
* if (ace.isGranting() && p.getMask() != 0) {
|
||||
* return (ace.getPermission().getMask() & p.getMask()) != 0;
|
||||
* } else {
|
||||
* return ace.getPermission().getMask() == p.getMask();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param ace the ACE from the Acl holding the mask.
|
||||
* @param p the Permission we are checking against.
|
||||
* @return true, if the respective masks are considered to be equal.
|
||||
|
|
|
@ -38,18 +38,20 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class EhCacheBasedAclCache implements AclCache {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final Ehcache cache;
|
||||
|
||||
private PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
|
||||
private AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public EhCacheBasedAclCache(Ehcache cache,
|
||||
PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
public EhCacheBasedAclCache(Ehcache cache, PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy) {
|
||||
Assert.notNull(cache, "Cache required");
|
||||
Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
|
||||
|
@ -144,10 +146,8 @@ public class EhCacheBasedAclCache implements AclCache {
|
|||
|
||||
private MutableAcl initializeTransientFields(MutableAcl value) {
|
||||
if (value instanceof AclImpl) {
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value,
|
||||
this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value,
|
||||
this.permissionGrantingStrategy);
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
|
||||
}
|
||||
|
||||
if (value.getParentAcl() != null) {
|
||||
|
@ -159,4 +159,5 @@ public class EhCacheBasedAclCache implements AclCache {
|
|||
public void clearCache() {
|
||||
cache.removeAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class GrantedAuthoritySid implements Sid {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
|
@ -46,8 +47,7 @@ public class GrantedAuthoritySid implements Sid {
|
|||
|
||||
public GrantedAuthoritySid(GrantedAuthority grantedAuthority) {
|
||||
Assert.notNull(grantedAuthority, "GrantedAuthority required");
|
||||
Assert.notNull(
|
||||
grantedAuthority.getAuthority(),
|
||||
Assert.notNull(grantedAuthority.getAuthority(),
|
||||
"This Sid is only compatible with GrantedAuthoritys that provide a non-null getAuthority()");
|
||||
this.grantedAuthority = grantedAuthority.getAuthority();
|
||||
}
|
||||
|
@ -63,8 +63,7 @@ public class GrantedAuthoritySid implements Sid {
|
|||
|
||||
// Delegate to getGrantedAuthority() to perform actual comparison (both should be
|
||||
// identical)
|
||||
return ((GrantedAuthoritySid) object).getGrantedAuthority().equals(
|
||||
this.getGrantedAuthority());
|
||||
return ((GrantedAuthoritySid) object).getGrantedAuthority().equals(this.getGrantedAuthority());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,4 +79,5 @@ public class GrantedAuthoritySid implements Sid {
|
|||
public String toString() {
|
||||
return "GrantedAuthoritySid[" + this.grantedAuthority + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.springframework.security.acls.domain;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class IdentityUnavailableException extends RuntimeException {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Constructs an <code>IdentityUnavailableException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public IdentityUnavailableException(String msg) {
|
||||
|
@ -36,11 +36,11 @@ public class IdentityUnavailableException extends RuntimeException {
|
|||
/**
|
||||
* Constructs an <code>IdentityUnavailableException</code> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,10 +31,12 @@ import org.springframework.util.ClassUtils;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class ObjectIdentityImpl implements ObjectIdentity {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final String type;
|
||||
|
||||
private Serializable identifier;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -66,9 +68,7 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
* <p>
|
||||
* 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 {
|
||||
|
@ -84,13 +84,11 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
result = method.invoke(object);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IdentityUnavailableException(
|
||||
"Could not extract identity from object " + object, 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");
|
||||
Assert.isInstanceOf(Serializable.class, result, "Getter must provide a return value of type Serializable");
|
||||
this.identifier = (Serializable) result;
|
||||
}
|
||||
|
||||
|
@ -105,9 +103,7 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
* <p>
|
||||
* 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 <code>true</code> if the presented object matches this object
|
||||
*/
|
||||
@Override
|
||||
|
@ -120,8 +116,7 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
|
||||
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()) {
|
||||
if (((Number) identifier).longValue() != ((Number) other.identifier).longValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +142,6 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
|
||||
/**
|
||||
* Important so caching operates properly.
|
||||
*
|
||||
* @return the hash
|
||||
*/
|
||||
@Override
|
||||
|
@ -166,4 +160,5 @@ public class ObjectIdentityImpl implements ObjectIdentity {
|
|||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
|||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImpl implements
|
||||
ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
|
||||
public class ObjectIdentityRetrievalStrategyImpl implements ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -41,4 +41,5 @@ public class ObjectIdentityRetrievalStrategyImpl implements
|
|||
public ObjectIdentity createObjectIdentity(Serializable id, String type) {
|
||||
return new ObjectIdentityImpl(type, id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,9 +32,7 @@ public interface PermissionFactory {
|
|||
/**
|
||||
* Dynamically creates a <code>CumulativePermission</code> or
|
||||
* <code>BasePermission</code> representing the active bits in the passed mask.
|
||||
*
|
||||
* @param mask to build
|
||||
*
|
||||
* @return a Permission representing the requested object
|
||||
*/
|
||||
Permission buildFromMask(int mask);
|
||||
|
@ -42,4 +40,5 @@ public interface PermissionFactory {
|
|||
Permission buildFromName(String name);
|
||||
|
||||
List<Permission> buildFromNames(List<String> names);
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class PrincipalSid implements Sid {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
|
@ -78,4 +79,5 @@ public class PrincipalSid implements Sid {
|
|||
public String toString() {
|
||||
return "PrincipalSid[" + this.principal + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,4 +67,5 @@ public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
|
|||
|
||||
return sids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,18 +39,20 @@ import java.io.Serializable;
|
|||
* @since 3.2
|
||||
*/
|
||||
public class SpringCacheBasedAclCache implements AclCache {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
private PermissionGrantingStrategy permissionGrantingStrategy;
|
||||
|
||||
private AclAuthorizationStrategy aclAuthorizationStrategy;
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public SpringCacheBasedAclCache(Cache cache,
|
||||
PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
public SpringCacheBasedAclCache(Cache cache, PermissionGrantingStrategy permissionGrantingStrategy,
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy) {
|
||||
Assert.notNull(cache, "Cache required");
|
||||
Assert.notNull(permissionGrantingStrategy, "PermissionGrantingStrategy required");
|
||||
|
@ -120,10 +122,8 @@ public class SpringCacheBasedAclCache implements AclCache {
|
|||
|
||||
private MutableAcl initializeTransientFields(MutableAcl value) {
|
||||
if (value instanceof AclImpl) {
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value,
|
||||
this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value,
|
||||
this.permissionGrantingStrategy);
|
||||
FieldUtils.setProtectedFieldValue("aclAuthorizationStrategy", value, this.aclAuthorizationStrategy);
|
||||
FieldUtils.setProtectedFieldValue("permissionGrantingStrategy", value, this.permissionGrantingStrategy);
|
||||
}
|
||||
|
||||
if (value.getParentAcl() != null) {
|
||||
|
@ -135,4 +135,5 @@ public class SpringCacheBasedAclCache implements AclCache {
|
|||
public void clearCache() {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,4 +17,3 @@
|
|||
* Basic implementation of access control lists (ACLs) interfaces.
|
||||
*/
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
|
|
|
@ -31,12 +31,16 @@ import org.springframework.security.acls.model.ObjectIdentity;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility class for helping convert database representations of {@link ObjectIdentity#getIdentifier()} into
|
||||
* the correct Java type as specified by <code>acl_class.class_id_type</code>.
|
||||
* Utility class for helping convert database representations of
|
||||
* {@link ObjectIdentity#getIdentifier()} into the correct Java type as specified by
|
||||
* <code>acl_class.class_id_type</code>.
|
||||
*
|
||||
* @author paulwheeler
|
||||
*/
|
||||
class AclClassIdUtils {
|
||||
|
||||
private static final String DEFAULT_CLASS_ID_TYPE_COLUMN_NAME = "class_id_type";
|
||||
|
||||
private static final Log log = LogFactory.getLog(AclClassIdUtils.class);
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
@ -54,8 +58,8 @@ class AclClassIdUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts the raw type from the database into the right Java type. For most applications the 'raw type' will be Long, for some applications
|
||||
* it could be String.
|
||||
* Converts the raw type from the database into the right Java type. For most
|
||||
* applications the 'raw type' will be Long, for some applications it could be String.
|
||||
* @param identifier The identifier from the database
|
||||
* @param resultSet Result set of the query
|
||||
* @return The identifier in the appropriate target Java type. Typically Long or UUID.
|
||||
|
@ -66,7 +70,8 @@ class AclClassIdUtils {
|
|||
&& canConvertFromStringTo(classIdTypeFrom(resultSet))) {
|
||||
|
||||
identifier = convertFromStringTo((String) identifier, classIdTypeFrom(resultSet));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Assume it should be a Long type
|
||||
identifier = convertToLong(identifier);
|
||||
}
|
||||
|
@ -78,7 +83,8 @@ class AclClassIdUtils {
|
|||
boolean hasClassIdType = false;
|
||||
try {
|
||||
hasClassIdType = classIdTypeFrom(resultSet) != null;
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debug("Unable to obtain the class id type", e);
|
||||
}
|
||||
return hasClassIdType;
|
||||
|
@ -93,7 +99,8 @@ class AclClassIdUtils {
|
|||
if (className != null) {
|
||||
try {
|
||||
targetType = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
log.debug("Unable to find class id type on classpath", e);
|
||||
}
|
||||
}
|
||||
|
@ -109,18 +116,21 @@ class AclClassIdUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts to a {@link Long}, attempting to use the {@link ConversionService} if available.
|
||||
* Converts to a {@link Long}, attempting to use the {@link ConversionService} if
|
||||
* available.
|
||||
* @param identifier The identifier
|
||||
* @return Long version of the identifier
|
||||
* @throws NumberFormatException if the string cannot be parsed to a long.
|
||||
* @throws org.springframework.core.convert.ConversionException if a conversion exception occurred
|
||||
* @throws org.springframework.core.convert.ConversionException if a conversion
|
||||
* exception occurred
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
*/
|
||||
private Long convertToLong(Serializable identifier) {
|
||||
Long idAsLong;
|
||||
if (conversionService.canConvert(identifier.getClass(), Long.class)) {
|
||||
idAsLong = conversionService.convert(identifier, Long.class);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
idAsLong = Long.valueOf(identifier.toString());
|
||||
}
|
||||
return idAsLong;
|
||||
|
@ -136,6 +146,7 @@ class AclClassIdUtils {
|
|||
}
|
||||
|
||||
private static class StringToLongConverter implements Converter<String, Long> {
|
||||
|
||||
@Override
|
||||
public Long convert(String identifierAsString) {
|
||||
if (identifierAsString == null) {
|
||||
|
@ -145,9 +156,11 @@ class AclClassIdUtils {
|
|||
}
|
||||
return Long.parseLong(identifierAsString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class StringToUUIDConverter implements Converter<String, UUID> {
|
||||
|
||||
@Override
|
||||
public UUID convert(String identifierAsString) {
|
||||
if (identifierAsString == null) {
|
||||
|
@ -157,5 +170,7 @@ class AclClassIdUtils {
|
|||
}
|
||||
return UUID.fromString(identifierAsString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@ import org.springframework.util.Assert;
|
|||
* as it is likely to change in future releases and therefore subclassing is unsupported.
|
||||
* <p>
|
||||
* There are two SQL queries executed, one in the <tt>lookupPrimaryKeys</tt> method and
|
||||
* one in <tt>lookupObjectIdentities</tt>. 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
|
||||
* one in <tt>lookupObjectIdentities</tt>. 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.
|
||||
*
|
||||
|
@ -79,21 +79,14 @@ import org.springframework.util.Assert;
|
|||
public class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
private final static String DEFAULT_SELECT_CLAUSE_COLUMNS = "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 ";
|
||||
+ "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 ";
|
||||
|
||||
private final static String DEFAULT_SELECT_CLAUSE_ACL_CLASS_ID_TYPE_COLUMN = ", acl_class.class_id_type ";
|
||||
|
||||
private final static String DEFAULT_SELECT_CLAUSE_FROM = "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 "
|
||||
|
@ -102,8 +95,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
public final static String DEFAULT_SELECT_CLAUSE = DEFAULT_SELECT_CLAUSE_COLUMNS + DEFAULT_SELECT_CLAUSE_FROM;
|
||||
|
||||
public final static String DEFAULT_ACL_CLASS_ID_SELECT_CLAUSE = DEFAULT_SELECT_CLAUSE_COLUMNS +
|
||||
DEFAULT_SELECT_CLAUSE_ACL_CLASS_ID_TYPE_COLUMN + DEFAULT_SELECT_CLAUSE_FROM;
|
||||
public final static String DEFAULT_ACL_CLASS_ID_SELECT_CLAUSE = DEFAULT_SELECT_CLAUSE_COLUMNS
|
||||
+ DEFAULT_SELECT_CLAUSE_ACL_CLASS_ID_TYPE_COLUMN + DEFAULT_SELECT_CLAUSE_FROM;
|
||||
|
||||
private final static String DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE = "(acl_object_identity.id = ?)";
|
||||
|
||||
|
@ -116,20 +109,28 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
// ================================================================================================
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
|
||||
private AclClassIdUtils aclClassIdUtils;
|
||||
|
@ -139,28 +140,24 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
/**
|
||||
* 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));
|
||||
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) {
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy, PermissionGrantingStrategy grantingStrategy) {
|
||||
Assert.notNull(dataSource, "DataSource required");
|
||||
Assert.notNull(aclCache, "AclCache required");
|
||||
Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
|
||||
|
@ -184,8 +181,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
final String endSql = orderByClause;
|
||||
|
||||
StringBuilder sqlStringBldr = new StringBuilder(startSql.length()
|
||||
+ endSql.length() + requiredRepetitions * (repeatingSql.length() + 4));
|
||||
StringBuilder sqlStringBldr = new StringBuilder(
|
||||
startSql.length() + endSql.length() + requiredRepetitions * (repeatingSql.length() + 4));
|
||||
sqlStringBldr.append(startSql);
|
||||
|
||||
for (int i = 1; i <= requiredRepetitions; i++) {
|
||||
|
@ -216,8 +213,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
fieldAcl.set(ace, acl);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(
|
||||
"Could not or set AclImpl on AccessControlEntryImpl fields", e);
|
||||
throw new IllegalStateException("Could not or set AclImpl on AccessControlEntryImpl fields", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,20 +229,17 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
/**
|
||||
* Locates the primary key IDs specified in "findNow", adding AclImpl instances with
|
||||
* StubAclParents to the "acls" Map.
|
||||
*
|
||||
* @param acls the AclImpls (with StubAclParents)
|
||||
* @param findNow Long-based primary keys to retrieve
|
||||
* @param sids
|
||||
*/
|
||||
private void lookupPrimaryKeys(final Map<Serializable, Acl> acls,
|
||||
final Set<Long> findNow, final List<Sid> sids) {
|
||||
private void lookupPrimaryKeys(final Map<Serializable, Acl> acls, final Set<Long> findNow, final List<Sid> sids) {
|
||||
Assert.notNull(acls, "ACLs are required");
|
||||
Assert.notEmpty(findNow, "Items to find now required");
|
||||
|
||||
String sql = computeRepeatingSql(lookupPrimaryKeysWhereClause, findNow.size());
|
||||
|
||||
Set<Long> parentsToLookup = jdbcTemplate.query(sql,
|
||||
ps -> {
|
||||
Set<Long> parentsToLookup = jdbcTemplate.query(sql, ps -> {
|
||||
int i = 0;
|
||||
|
||||
for (Long toFind : findNow) {
|
||||
|
@ -271,19 +264,16 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
* develop a custom {@link LookupStrategy} implementation instead.
|
||||
* <p>
|
||||
* 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 <tt>Map</tt> where keys represent the {@link ObjectIdentity} of the
|
||||
* located {@link Acl} and values are the located {@link Acl} (never <tt>null</tt>
|
||||
* 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<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects,
|
||||
List<Sid> sids) {
|
||||
public final Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids) {
|
||||
Assert.isTrue(batchSize >= 1, "BatchSize must be >= 1");
|
||||
Assert.notEmpty(objects, "Objects to lookup required");
|
||||
|
||||
|
@ -330,11 +320,9 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
}
|
||||
|
||||
// Is it time to load from JDBC the currentBatchToLoad?
|
||||
if ((currentBatchToLoad.size() == this.batchSize)
|
||||
|| ((i + 1) == objects.size())) {
|
||||
if ((currentBatchToLoad.size() == this.batchSize) || ((i + 1) == objects.size())) {
|
||||
if (currentBatchToLoad.size() > 0) {
|
||||
Map<ObjectIdentity, Acl> loadedBatch = lookupObjectIdentities(
|
||||
currentBatchToLoad, sids);
|
||||
Map<ObjectIdentity, Acl> loadedBatch = lookupObjectIdentities(currentBatchToLoad, sids);
|
||||
|
||||
// Add loaded batch (all elements 100% initialized) to results
|
||||
result.putAll(loadedBatch);
|
||||
|
@ -364,8 +352,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
* properly-configured parent ACLs.
|
||||
*
|
||||
*/
|
||||
private Map<ObjectIdentity, Acl> lookupObjectIdentities(
|
||||
final Collection<ObjectIdentity> objectIdentities, List<Sid> sids) {
|
||||
private Map<ObjectIdentity, Acl> lookupObjectIdentities(final Collection<ObjectIdentity> objectIdentities,
|
||||
List<Sid> sids) {
|
||||
Assert.notEmpty(objectIdentities, "Must provide identities to lookup");
|
||||
|
||||
final Map<Serializable, Acl> acls = new HashMap<>(); // contains
|
||||
|
@ -375,11 +363,9 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
// Make the "acls" map contain all requested objectIdentities
|
||||
// (including markers to each parent in the hierarchy)
|
||||
String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause,
|
||||
objectIdentities.size());
|
||||
String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause, objectIdentities.size());
|
||||
|
||||
Set<Long> parentsToLookup = jdbcTemplate.query(sql,
|
||||
ps -> {
|
||||
Set<Long> parentsToLookup = jdbcTemplate.query(sql, ps -> {
|
||||
int i = 0;
|
||||
for (ObjectIdentity oid : objectIdentities) {
|
||||
// Determine prepared statement values for this iteration
|
||||
|
@ -406,10 +392,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
Map<ObjectIdentity, Acl> resultMap = new HashMap<>();
|
||||
|
||||
for (Acl inputAcl : acls.values()) {
|
||||
Assert.isInstanceOf(AclImpl.class, inputAcl,
|
||||
"Map should have contained an AclImpl");
|
||||
Assert.isInstanceOf(Long.class, ((AclImpl) inputAcl).getId(),
|
||||
"Acl.getId() must be Long");
|
||||
Assert.isInstanceOf(AclImpl.class, inputAcl, "Map should have contained an AclImpl");
|
||||
Assert.isInstanceOf(Long.class, ((AclImpl) inputAcl).getId(), "Acl.getId() must be Long");
|
||||
|
||||
Acl result = convert(acls, (Long) ((AclImpl) inputAcl).getId());
|
||||
resultMap.put(result.getObjectIdentity(), result);
|
||||
|
@ -422,7 +406,6 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
* The final phase of converting the <code>Map</code> of <code>AclImpl</code>
|
||||
* instances which contain <code>StubAclParent</code>s into proper, valid
|
||||
* <code>AclImpl</code>s with correct ACL parents.
|
||||
*
|
||||
* @param inputMap the unconverted <code>AclImpl</code>s
|
||||
* @param currentIdentity the current<code>Acl</code> that we wish to convert (this
|
||||
* may be
|
||||
|
@ -434,8 +417,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
// Retrieve this Acl from the InputMap
|
||||
Acl uncastAcl = inputMap.get(currentIdentity);
|
||||
Assert.isInstanceOf(AclImpl.class, uncastAcl,
|
||||
"The inputMap contained a non-AclImpl");
|
||||
Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl");
|
||||
|
||||
AclImpl inputAcl = (AclImpl) uncastAcl;
|
||||
|
||||
|
@ -448,9 +430,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
}
|
||||
|
||||
// Now we have the parent (if there is one), create the true AclImpl
|
||||
AclImpl result = new AclImpl(inputAcl.getObjectIdentity(),
|
||||
inputAcl.getId(), aclAuthorizationStrategy, grantingStrategy,
|
||||
parent, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner());
|
||||
AclImpl result = new AclImpl(inputAcl.getObjectIdentity(), inputAcl.getId(), aclAuthorizationStrategy,
|
||||
grantingStrategy, parent, null, inputAcl.isEntriesInheriting(), inputAcl.getOwner());
|
||||
|
||||
// Copy the "aces" from the input to the destination
|
||||
|
||||
|
@ -477,7 +458,6 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
/**
|
||||
* Creates a particular implementation of {@link Sid} depending on the arguments.
|
||||
*
|
||||
* @param sid the name of the sid representing its unique identifier. In typical ACL
|
||||
* database schema it's located in table {@code acl_sid} table, {@code sid} column.
|
||||
* @param isPrincipal whether it's a user or granted authority like role
|
||||
|
@ -496,7 +476,6 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
* Sets the {@code PermissionFactory} instance which will be used to convert loaded
|
||||
* permission data values to {@code Permission}s. A {@code DefaultPermissionFactory}
|
||||
* will be used by default.
|
||||
*
|
||||
* @param permissionFactory
|
||||
*/
|
||||
public final void setPermissionFactory(PermissionFactory permissionFactory) {
|
||||
|
@ -510,7 +489,6 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
/**
|
||||
* The SQL for the select clause. If customizing in order to modify column names,
|
||||
* schema etc, the other SQL customization fields must also be set to match.
|
||||
*
|
||||
* @param selectClause the select clause, which defaults to
|
||||
* {@link #DEFAULT_SELECT_CLAUSE}.
|
||||
*/
|
||||
|
@ -528,8 +506,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
/**
|
||||
* The SQL for the where clause used in the <tt>lookupObjectIdentities</tt> method.
|
||||
*/
|
||||
public final void setLookupObjectIdentitiesWhereClause(
|
||||
String lookupObjectIdentitiesWhereClause) {
|
||||
public final void setLookupObjectIdentitiesWhereClause(String lookupObjectIdentitiesWhereClause) {
|
||||
this.lookupObjectIdentitiesWhereClause = lookupObjectIdentitiesWhereClause;
|
||||
}
|
||||
|
||||
|
@ -542,7 +519,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
|
||||
public final void setAclClassIdSupported(boolean aclClassIdSupported) {
|
||||
if (aclClassIdSupported) {
|
||||
Assert.isTrue(this.selectClause.equals(DEFAULT_SELECT_CLAUSE), "Cannot set aclClassIdSupported and override the select clause; "
|
||||
Assert.isTrue(this.selectClause.equals(DEFAULT_SELECT_CLAUSE),
|
||||
"Cannot set aclClassIdSupported and override the select clause; "
|
||||
+ "just override the select clause");
|
||||
this.selectClause = DEFAULT_ACL_CLASS_ID_SELECT_CLAUSE;
|
||||
}
|
||||
|
@ -556,7 +534,9 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
// ==================================================================================================
|
||||
|
||||
private class ProcessResultSet implements ResultSetExtractor<Set<Long>> {
|
||||
|
||||
private final Map<Serializable, Acl> acls;
|
||||
|
||||
private final List<Sid> sids;
|
||||
|
||||
ProcessResultSet(Map<Serializable, Acl> acls, List<Sid> sids) {
|
||||
|
@ -612,15 +592,12 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
/**
|
||||
* Accepts the current <code>ResultSet</code> row, and converts it into an
|
||||
* <code>AclImpl</code> that contains a <code>StubAclParent</code>
|
||||
*
|
||||
* @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
|
||||
* @throws ConversionException if can't convert to the desired Java type
|
||||
*/
|
||||
private void convertCurrentResultIntoObject(Map<Serializable, Acl> acls,
|
||||
ResultSet rs) throws SQLException {
|
||||
private void convertCurrentResultIntoObject(Map<Serializable, Acl> acls, ResultSet rs) throws SQLException {
|
||||
Long id = rs.getLong("acl_id");
|
||||
|
||||
// If we already have an ACL for this ID, just create the ACE
|
||||
|
@ -629,11 +606,11 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
if (acl == null) {
|
||||
// Make an AclImpl and pop it into the Map
|
||||
|
||||
// If the Java type is a String, check to see if we can convert it to the target id type, e.g. UUID.
|
||||
// If the Java type is a String, check to see if we can convert it to the
|
||||
// target id type, e.g. UUID.
|
||||
Serializable identifier = (Serializable) rs.getObject("object_id_identity");
|
||||
identifier = aclClassIdUtils.identifierFrom(identifier, rs);
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(
|
||||
rs.getString("class"), identifier);
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString("class"), identifier);
|
||||
|
||||
Acl parentAcl = null;
|
||||
long parentAclId = rs.getLong("parent_object");
|
||||
|
@ -643,11 +620,10 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
}
|
||||
|
||||
boolean entriesInheriting = rs.getBoolean("entries_inheriting");
|
||||
Sid owner = createSid(rs.getBoolean("acl_principal"),
|
||||
rs.getString("acl_sid"));
|
||||
Sid owner = createSid(rs.getBoolean("acl_principal"), rs.getString("acl_sid"));
|
||||
|
||||
acl = new AclImpl(objectIdentity, id, aclAuthorizationStrategy,
|
||||
grantingStrategy, parentAcl, null, entriesInheriting, owner);
|
||||
acl = new AclImpl(objectIdentity, id, aclAuthorizationStrategy, grantingStrategy, parentAcl, null,
|
||||
entriesInheriting, owner);
|
||||
|
||||
acls.put(id, acl);
|
||||
}
|
||||
|
@ -657,8 +633,7 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
// ACE_SID)
|
||||
if (rs.getString("ace_sid") != null) {
|
||||
Long aceId = rs.getLong("ace_id");
|
||||
Sid recipient = createSid(rs.getBoolean("ace_principal"),
|
||||
rs.getString("ace_sid"));
|
||||
Sid recipient = createSid(rs.getBoolean("ace_principal"), rs.getString("ace_sid"));
|
||||
|
||||
int mask = rs.getInt("mask");
|
||||
Permission permission = permissionFactory.buildFromMask(mask);
|
||||
|
@ -666,8 +641,8 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
boolean auditSuccess = rs.getBoolean("audit_success");
|
||||
boolean auditFailure = rs.getBoolean("audit_failure");
|
||||
|
||||
AccessControlEntryImpl ace = new AccessControlEntryImpl(aceId, acl,
|
||||
recipient, permission, granting, auditSuccess, auditFailure);
|
||||
AccessControlEntryImpl ace = new AccessControlEntryImpl(aceId, acl, recipient, permission, granting,
|
||||
auditSuccess, auditFailure);
|
||||
|
||||
// Field acesField = FieldUtils.getField(AclImpl.class, "aces");
|
||||
List<AccessControlEntryImpl> aces = readAces((AclImpl) acl);
|
||||
|
@ -678,9 +653,11 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class StubAclParent implements Acl {
|
||||
|
||||
private final Long id;
|
||||
|
||||
StubAclParent(Long id) {
|
||||
|
@ -711,14 +688,15 @@ public class BasicLookupStrategy implements LookupStrategy {
|
|||
throw new UnsupportedOperationException("Stub only");
|
||||
}
|
||||
|
||||
public boolean isGranted(List<Permission> permission, List<Sid> sids,
|
||||
boolean administrativeMode) throws NotFoundException,
|
||||
UnloadedSidException {
|
||||
public boolean isGranted(List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException, UnloadedSidException {
|
||||
throw new UnsupportedOperationException("Stub only");
|
||||
}
|
||||
|
||||
public boolean isSidLoaded(List<Sid> sids) {
|
||||
throw new UnsupportedOperationException("Stub only");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,18 +45,26 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class JdbcAclService implements AclService {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
protected static final Log log = LogFactory.getLog(JdbcAclService.class);
|
||||
|
||||
private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS = "class.class as class";
|
||||
private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE = DEFAULT_SELECT_ACL_CLASS_COLUMNS + ", class.class_id_type as class_id_type";
|
||||
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, " + DEFAULT_SELECT_ACL_CLASS_COLUMNS
|
||||
|
||||
private static final String DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE = DEFAULT_SELECT_ACL_CLASS_COLUMNS
|
||||
+ ", class.class_id_type as class_id_type";
|
||||
|
||||
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL = "select obj.object_id_identity as obj_id, "
|
||||
+ DEFAULT_SELECT_ACL_CLASS_COLUMNS
|
||||
+ " 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 = ?)";
|
||||
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE = "select obj.object_id_identity as obj_id, " + DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE
|
||||
|
||||
private static final String DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE = "select obj.object_id_identity as obj_id, "
|
||||
+ DEFAULT_SELECT_ACL_CLASS_COLUMNS_WITH_ID_TYPE
|
||||
+ " 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 = ("
|
||||
|
@ -66,9 +74,13 @@ public class JdbcAclService implements AclService {
|
|||
// ================================================================================================
|
||||
|
||||
protected final JdbcOperations jdbcOperations;
|
||||
|
||||
private final LookupStrategy lookupStrategy;
|
||||
|
||||
private boolean aclClassIdSupported;
|
||||
|
||||
private String findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL;
|
||||
|
||||
private AclClassIdUtils aclClassIdUtils;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -91,8 +103,7 @@ public class JdbcAclService implements AclService {
|
|||
|
||||
public List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {
|
||||
Object[] args = { parentIdentity.getIdentifier().toString(), parentIdentity.getType() };
|
||||
List<ObjectIdentity> objects = jdbcOperations.query(findChildrenSql, args,
|
||||
(rs, rowNum) -> {
|
||||
List<ObjectIdentity> objects = jdbcOperations.query(findChildrenSql, args, (rs, rowNum) -> {
|
||||
String javaType = rs.getString("class");
|
||||
Serializable identifier = (Serializable) rs.getObject("obj_id");
|
||||
identifier = aclClassIdUtils.identifierFrom(identifier, rs);
|
||||
|
@ -106,8 +117,7 @@ public class JdbcAclService implements AclService {
|
|||
return objects;
|
||||
}
|
||||
|
||||
public Acl readAclById(ObjectIdentity object, List<Sid> sids)
|
||||
throws NotFoundException {
|
||||
public Acl readAclById(ObjectIdentity object, List<Sid> sids) throws NotFoundException {
|
||||
Map<ObjectIdentity, Acl> map = readAclsById(Collections.singletonList(object), sids);
|
||||
Assert.isTrue(map.containsKey(object),
|
||||
() -> "There should have been an Acl entry for ObjectIdentity " + object);
|
||||
|
@ -119,22 +129,19 @@ public class JdbcAclService implements AclService {
|
|||
return readAclById(object, null);
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects)
|
||||
throws NotFoundException {
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects) throws NotFoundException {
|
||||
return readAclsById(objects, null);
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects,
|
||||
List<Sid> sids) throws NotFoundException {
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
|
||||
throws NotFoundException {
|
||||
Map<ObjectIdentity, Acl> result = lookupStrategy.readAclsById(objects, sids);
|
||||
|
||||
// Check every requested object identity was found (throw NotFoundException if
|
||||
// needed)
|
||||
for (ObjectIdentity oid : objects) {
|
||||
if (!result.containsKey(oid)) {
|
||||
throw new NotFoundException(
|
||||
"Unable to find ACL information for object identity '" + oid
|
||||
+ "'");
|
||||
throw new NotFoundException("Unable to find ACL information for object identity '" + oid + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +150,6 @@ public class JdbcAclService implements AclService {
|
|||
|
||||
/**
|
||||
* Allows customization of the SQL query used to find child object identities.
|
||||
*
|
||||
* @param findChildrenSql
|
||||
*/
|
||||
public void setFindChildrenQuery(String findChildrenSql) {
|
||||
|
@ -156,7 +162,8 @@ public class JdbcAclService implements AclService {
|
|||
// Change the default children select if it hasn't been overridden
|
||||
if (this.findChildrenSql.equals(DEFAULT_SELECT_ACL_WITH_PARENT_SQL)) {
|
||||
this.findChildrenSql = DEFAULT_SELECT_ACL_WITH_PARENT_SQL_WITH_CLASS_ID_TYPE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log.debug("Find children statement has already been overridden, so not overridding the default");
|
||||
}
|
||||
}
|
||||
|
@ -169,4 +176,5 @@ public class JdbcAclService implements AclService {
|
|||
protected boolean isAclClassIdSupported() {
|
||||
return aclClassIdSupported;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,39 +58,52 @@ import org.springframework.util.Assert;
|
|||
* @author Johannes Zlattinger
|
||||
*/
|
||||
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
|
||||
|
||||
private static final String DEFAULT_INSERT_INTO_ACL_CLASS = "insert into acl_class (class) values (?)";
|
||||
|
||||
private static final String DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID = "insert into acl_class (class, class_id_type) values (?, ?)";
|
||||
|
||||
// ~ 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 = DEFAULT_INSERT_INTO_ACL_CLASS;
|
||||
|
||||
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 (?, ?, ?, ?)";
|
||||
+ "(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 = ?";
|
||||
+ "parent_object = ?, owner_sid = ?, entries_inheriting = ?" + " where id = ?";
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy,
|
||||
AclCache aclCache) {
|
||||
public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {
|
||||
super(dataSource, lookupStrategy);
|
||||
Assert.notNull(aclCache, "AclCache required");
|
||||
this.aclCache = aclCache;
|
||||
|
@ -99,14 +112,12 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public MutableAcl createAcl(ObjectIdentity objectIdentity)
|
||||
throws AlreadyExistsException {
|
||||
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");
|
||||
throw new AlreadyExistsException("Object identity '" + objectIdentity + "' already exists");
|
||||
}
|
||||
|
||||
// Need to retrieve the current principal, in order to know who "owns" this ACL
|
||||
|
@ -128,7 +139,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
/**
|
||||
* 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) {
|
||||
|
@ -142,8 +152,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
|
||||
public void setValues(PreparedStatement stmt, int i) throws SQLException {
|
||||
AccessControlEntry entry_ = acl.getEntries().get(i);
|
||||
Assert.isTrue(entry_ instanceof AccessControlEntryImpl,
|
||||
"Unknown ACE class");
|
||||
Assert.isTrue(entry_ instanceof AccessControlEntryImpl, "Unknown ACE class");
|
||||
AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
|
||||
|
||||
stmt.setLong(1, (Long) acl.getId());
|
||||
|
@ -161,7 +170,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
* 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)
|
||||
|
@ -169,22 +177,18 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
|
||||
Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
|
||||
Long classId = createOrRetrieveClassPrimaryKey(object.getType(), true, object.getIdentifier().getClass());
|
||||
jdbcOperations.update(insertObjectIdentity, classId, object.getIdentifier().toString(), sidId,
|
||||
Boolean.TRUE);
|
||||
jdbcOperations.update(insertObjectIdentity, classId, object.getIdentifier().toString(), 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, Class idType) {
|
||||
List<Long> classIds = jdbcOperations.queryForList(selectClassPrimaryKey,
|
||||
new Object[] { type }, Long.class);
|
||||
List<Long> classIds = jdbcOperations.queryForList(selectClassPrimaryKey, new Object[] { type }, Long.class);
|
||||
|
||||
if (!classIds.isEmpty()) {
|
||||
return classIds.get(0);
|
||||
|
@ -193,11 +197,11 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
if (allowCreate) {
|
||||
if (!isAclClassIdSupported()) {
|
||||
jdbcOperations.update(insertClass, type);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
jdbcOperations.update(insertClass, type, idType.getCanonicalName());
|
||||
}
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
|
||||
"Transaction must be running");
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(), "Transaction must be running");
|
||||
return jdbcOperations.queryForObject(classIdentityQuery, Long.class);
|
||||
}
|
||||
|
||||
|
@ -207,12 +211,9 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
/**
|
||||
* Retrieves the primary key from acl_sid, creating a new row if needed and the
|
||||
* allowCreate property is true.
|
||||
*
|
||||
* @param sid to find or create
|
||||
* @param allowCreate true if creation is permitted if not found
|
||||
*
|
||||
* @return the primary key or null if not found
|
||||
*
|
||||
* @throws IllegalArgumentException if the <tt>Sid</tt> is not a recognized
|
||||
* implementation.
|
||||
*/
|
||||
|
@ -244,11 +245,10 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
* @param allowCreate true if creation is permitted if not found
|
||||
* @return the primary key or null if not found
|
||||
*/
|
||||
protected Long createOrRetrieveSidPrimaryKey(String sidName, boolean sidIsPrincipal,
|
||||
boolean allowCreate) {
|
||||
protected Long createOrRetrieveSidPrimaryKey(String sidName, boolean sidIsPrincipal, boolean allowCreate) {
|
||||
|
||||
List<Long> sidIds = jdbcOperations.queryForList(selectSidPrimaryKey, new Object[] {
|
||||
sidIsPrincipal, sidName }, Long.class);
|
||||
List<Long> sidIds = jdbcOperations.queryForList(selectSidPrimaryKey, new Object[] { sidIsPrincipal, sidName },
|
||||
Long.class);
|
||||
|
||||
if (!sidIds.isEmpty()) {
|
||||
return sidIds.get(0);
|
||||
|
@ -256,19 +256,16 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
|
||||
if (allowCreate) {
|
||||
jdbcOperations.update(insertSid, sidIsPrincipal, sidName);
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
|
||||
"Transaction must be running");
|
||||
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(), "Transaction must be running");
|
||||
return jdbcOperations.queryForObject(sidIdentityQuery, Long.class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren)
|
||||
throws ChildrenExistException {
|
||||
public void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren) throws ChildrenExistException {
|
||||
Assert.notNull(objectIdentity, "Object Identity required");
|
||||
Assert.notNull(objectIdentity.getIdentifier(),
|
||||
"Object Identity doesn't provide an identifier");
|
||||
Assert.notNull(objectIdentity.getIdentifier(), "Object Identity doesn't provide an identifier");
|
||||
|
||||
if (deleteChildren) {
|
||||
List<ObjectIdentity> children = findChildren(objectIdentity);
|
||||
|
@ -285,8 +282,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
// We generally don't do this, in the interests of deadlock management
|
||||
List<ObjectIdentity> children = findChildren(objectIdentity);
|
||||
if (children != null) {
|
||||
throw new ChildrenExistException("Cannot delete '" + objectIdentity
|
||||
+ "' (has " + children.size() + " children)");
|
||||
throw new ChildrenExistException(
|
||||
"Cannot delete '" + objectIdentity + "' (has " + children.size() + " children)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +303,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
/**
|
||||
* Deletes all ACEs defined in the acl_entry table belonging to the presented
|
||||
* ObjectIdentity primary key.
|
||||
*
|
||||
* @param oidPrimaryKey the rows in acl_entry to delete
|
||||
*/
|
||||
protected void deleteEntries(Long oidPrimaryKey) {
|
||||
|
@ -319,7 +315,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
* <p>
|
||||
* 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) {
|
||||
|
@ -331,15 +326,13 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
* 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 jdbcOperations.queryForObject(selectObjectIdentityPrimaryKey, Long.class,
|
||||
oid.getType(), oid.getIdentifier().toString());
|
||||
return jdbcOperations.queryForObject(selectObjectIdentityPrimaryKey, Long.class, oid.getType(),
|
||||
oid.getIdentifier().toString());
|
||||
}
|
||||
catch (DataAccessException notFound) {
|
||||
return null;
|
||||
|
@ -387,29 +380,25 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
* Updates an existing acl_object_identity row, with new information presented in the
|
||||
* passed MutableAcl object. Also will create an acl_sid entry if needed for the Sid
|
||||
* that owns the MutableAcl.
|
||||
*
|
||||
* @param acl to modify (a row must already exist in acl_object_identity)
|
||||
*
|
||||
* @throws NotFoundException if the ACL could not be found to update.
|
||||
*/
|
||||
protected void updateObjectIdentity(MutableAcl acl) {
|
||||
Long parentId = null;
|
||||
|
||||
if (acl.getParentAcl() != null) {
|
||||
Assert.isInstanceOf(ObjectIdentityImpl.class, acl.getParentAcl()
|
||||
.getObjectIdentity(),
|
||||
Assert.isInstanceOf(ObjectIdentityImpl.class, acl.getParentAcl().getObjectIdentity(),
|
||||
"Implementation only supports ObjectIdentityImpl");
|
||||
|
||||
ObjectIdentityImpl oii = (ObjectIdentityImpl) acl.getParentAcl()
|
||||
.getObjectIdentity();
|
||||
ObjectIdentityImpl oii = (ObjectIdentityImpl) acl.getParentAcl().getObjectIdentity();
|
||||
parentId = retrieveObjectIdentityPrimaryKey(oii);
|
||||
}
|
||||
|
||||
Assert.notNull(acl.getOwner(), "Owner is required in this implementation");
|
||||
|
||||
Long ownerSid = createOrRetrieveSidPrimaryKey(acl.getOwner(), true);
|
||||
int count = jdbcOperations.update(updateObjectIdentity, parentId, ownerSid,
|
||||
acl.isEntriesInheriting(), acl.getId());
|
||||
int count = jdbcOperations.update(updateObjectIdentity, parentId, ownerSid, acl.isEntriesInheriting(),
|
||||
acl.getId());
|
||||
|
||||
if (count != 1) {
|
||||
throw new NotFoundException("Unable to locate ACL to update");
|
||||
|
@ -419,7 +408,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
/**
|
||||
* Sets the query that will be used to retrieve the identity of a newly created row in
|
||||
* the <tt>acl_class</tt> table.
|
||||
*
|
||||
* @param classIdentityQuery the query, which should return the identifier. Defaults
|
||||
* to <tt>call identity()</tt>
|
||||
*/
|
||||
|
@ -431,7 +419,6 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
/**
|
||||
* Sets the query that will be used to retrieve the identity of a newly created row in
|
||||
* the <tt>acl_sid</tt> table.
|
||||
*
|
||||
* @param sidIdentityQuery the query, which should return the identifier. Defaults to
|
||||
* <tt>call identity()</tt>
|
||||
*/
|
||||
|
@ -440,13 +427,11 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
this.sidIdentityQuery = sidIdentityQuery;
|
||||
}
|
||||
|
||||
public void setDeleteEntryByObjectIdentityForeignKeySql(
|
||||
String deleteEntryByObjectIdentityForeignKey) {
|
||||
public void setDeleteEntryByObjectIdentityForeignKeySql(String deleteEntryByObjectIdentityForeignKey) {
|
||||
this.deleteEntryByObjectIdentityForeignKey = deleteEntryByObjectIdentityForeignKey;
|
||||
}
|
||||
|
||||
public void setDeleteObjectIdentityByPrimaryKeySql(
|
||||
String deleteObjectIdentityByPrimaryKey) {
|
||||
public void setDeleteObjectIdentityByPrimaryKeySql(String deleteObjectIdentityByPrimaryKey) {
|
||||
this.deleteObjectIdentityByPrimaryKey = deleteObjectIdentityByPrimaryKey;
|
||||
}
|
||||
|
||||
|
@ -498,9 +483,11 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
|||
// Change the default insert if it hasn't been overridden
|
||||
if (this.insertClass.equals(DEFAULT_INSERT_INTO_ACL_CLASS)) {
|
||||
this.insertClass = DEFAULT_INSERT_INTO_ACL_CLASS_WITH_ID;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log.debug("Insert class statement has already been overridden, so not overridding the default");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,16 +29,15 @@ import java.util.Map;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface LookupStrategy {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Perform database-specific optimized lookup.
|
||||
*
|
||||
* @param objects the identities to lookup (required)
|
||||
* @param sids the SIDs for which identities are required (may be <tt>null</tt> -
|
||||
* implementations may elect not to provide SID optimisations)
|
||||
*
|
||||
* @return a <tt>Map</tt> where keys represent the {@link ObjectIdentity} of the
|
||||
* located {@link Acl} and values are the located {@link Acl} (never <tt>null</tt>
|
||||
* although some entries may be missing; this method should not throw
|
||||
|
@ -46,4 +45,5 @@ public interface LookupStrategy {
|
|||
* automatically create entries if required)
|
||||
*/
|
||||
Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids);
|
||||
|
||||
}
|
||||
|
|
|
@ -17,4 +17,3 @@
|
|||
* JDBC-based persistence of ACL information
|
||||
*/
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.io.Serializable;
|
|||
*
|
||||
*/
|
||||
public interface AccessControlEntry extends Serializable {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -36,7 +37,6 @@ public interface AccessControlEntry extends Serializable {
|
|||
|
||||
/**
|
||||
* Obtains an identifier that represents this ACE.
|
||||
*
|
||||
* @return the identifier, or <code>null</code> if unsaved
|
||||
*/
|
||||
Serializable getId();
|
||||
|
@ -46,10 +46,10 @@ public interface AccessControlEntry extends Serializable {
|
|||
Sid getSid();
|
||||
|
||||
/**
|
||||
* Indicates the permission is being granted to the relevant Sid. If false,
|
||||
* indicates the permission is being revoked/blocked.
|
||||
*
|
||||
* Indicates the permission is being granted to the relevant Sid. If false, indicates
|
||||
* the permission is being revoked/blocked.
|
||||
* @return true if being granted, false otherwise
|
||||
*/
|
||||
boolean isGranting();
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ public interface Acl extends Serializable {
|
|||
* subset of <tt>Sid</tt>s. The caller is responsible for correctly handling the
|
||||
* result if only a subset of <tt>Sid</tt>s is represented.
|
||||
* </p>
|
||||
*
|
||||
* @return the list of entries represented by the <tt>Acl</tt>, or <tt>null</tt> if
|
||||
* there are no entries presently associated with this <tt>Acl</tt>.
|
||||
*/
|
||||
|
@ -72,7 +71,6 @@ public interface Acl extends Serializable {
|
|||
/**
|
||||
* Obtains the domain object this <tt>Acl</tt> provides entries for. This is immutable
|
||||
* once an <tt>Acl</tt> is created.
|
||||
*
|
||||
* @return the object identity (never <tt>null</tt>)
|
||||
*/
|
||||
ObjectIdentity getObjectIdentity();
|
||||
|
@ -80,7 +78,6 @@ public interface Acl extends Serializable {
|
|||
/**
|
||||
* Determines the owner of the <tt>Acl</tt>. The meaning of ownership varies by
|
||||
* implementation and is unspecified.
|
||||
*
|
||||
* @return the owner (may be <tt>null</tt> if the implementation does not use
|
||||
* ownership concepts)
|
||||
*/
|
||||
|
@ -102,7 +99,6 @@ public interface Acl extends Serializable {
|
|||
* subset of <tt>Sid</tt>s. The caller is responsible for correctly handling the
|
||||
* result if only a subset of <tt>Sid</tt>s is represented.
|
||||
* </p>
|
||||
*
|
||||
* @return the parent <tt>Acl</tt> (may be <tt>null</tt> if this <tt>Acl</tt> does not
|
||||
* have a parent)
|
||||
*/
|
||||
|
@ -118,7 +114,6 @@ public interface Acl extends Serializable {
|
|||
* parent for navigation purposes. Thus, this method denotes whether or not the
|
||||
* navigation relationship also extends to the actual inheritance of entries.
|
||||
* </p>
|
||||
*
|
||||
* @return <tt>true</tt> if parent ACL entries inherit into the current <tt>Acl</tt>
|
||||
*/
|
||||
boolean isEntriesInheriting();
|
||||
|
@ -158,7 +153,6 @@ public interface Acl extends Serializable {
|
|||
* authorization decision for a {@link Sid} that was never loaded in this <tt>Acl</tt>
|
||||
* .
|
||||
* </p>
|
||||
*
|
||||
* @param permission the permission or permissions required (at least one entry
|
||||
* required)
|
||||
* @param sids the security identities held by the principal (at least one entry
|
||||
|
@ -166,17 +160,15 @@ public interface Acl extends Serializable {
|
|||
* @param administrativeMode if <tt>true</tt> denotes the query is for administrative
|
||||
* purposes and no logging or auditing (if supported by the implementation) should be
|
||||
* undertaken
|
||||
*
|
||||
* @return <tt>true</tt> if authorization is granted
|
||||
*
|
||||
* @throws NotFoundException MUST be thrown if an implementation cannot make an
|
||||
* authoritative authorization decision, usually because there is no ACL information
|
||||
* for this particular permission and/or SID
|
||||
* @throws UnloadedSidException thrown if the <tt>Acl</tt> does not have details for
|
||||
* one or more of the <tt>Sid</tt>s passed as arguments
|
||||
*/
|
||||
boolean isGranted(List<Permission> permission, List<Sid> sids,
|
||||
boolean administrativeMode) throws NotFoundException, UnloadedSidException;
|
||||
boolean isGranted(List<Permission> permission, List<Sid> sids, boolean administrativeMode)
|
||||
throws NotFoundException, UnloadedSidException;
|
||||
|
||||
/**
|
||||
* For efficiency reasons an <tt>Acl</tt> may be loaded and <em>not</em> contain
|
||||
|
@ -191,12 +183,11 @@ public interface Acl extends Serializable {
|
|||
* all <tt>Sid</tt>s. This method denotes whether or not the specified <tt>Sid</tt>s
|
||||
* have been loaded or not.
|
||||
* </p>
|
||||
*
|
||||
* @param sids one or more security identities the caller is interest in knowing
|
||||
* whether this <tt>Sid</tt> supports
|
||||
*
|
||||
* @return <tt>true</tt> if every passed <tt>Sid</tt> is represented by this
|
||||
* <tt>Acl</tt> instance
|
||||
*/
|
||||
boolean isSidLoaded(List<Sid> sids);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.Serializable;
|
|||
*
|
||||
*/
|
||||
public interface AclCache {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -40,4 +41,5 @@ public interface AclCache {
|
|||
void putInCache(MutableAcl acl);
|
||||
|
||||
void clearCache();
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ public abstract class AclDataAccessException extends RuntimeException {
|
|||
/**
|
||||
* Constructs an <code>AclDataAccessException</code> with the specified message and
|
||||
* root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
*/
|
||||
|
@ -37,10 +36,10 @@ public abstract class AclDataAccessException extends RuntimeException {
|
|||
/**
|
||||
* Constructs an <code>AclDataAccessException</code> with the specified message and no
|
||||
* root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public AclDataAccessException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,15 +24,14 @@ import java.util.Map;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface AclService {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Locates all object identities that use the specified parent. This is useful for
|
||||
* administration tools.
|
||||
*
|
||||
* @param parentIdentity to locate children of
|
||||
*
|
||||
* @return the children (or <tt>null</tt> if none were found)
|
||||
*/
|
||||
List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity);
|
||||
|
@ -44,12 +43,9 @@ public interface AclService {
|
|||
* implementation's potential ability to filter <tt>Acl</tt> entries based on a
|
||||
* {@link Sid} parameter.
|
||||
* </p>
|
||||
*
|
||||
* @param object to locate an {@link Acl} for
|
||||
*
|
||||
* @return the {@link Acl} for the requested {@link ObjectIdentity} (never
|
||||
* <tt>null</tt>)
|
||||
*
|
||||
* @throws NotFoundException if an {@link Acl} was not found for the requested
|
||||
* {@link ObjectIdentity}
|
||||
*/
|
||||
|
@ -57,14 +53,11 @@ public interface AclService {
|
|||
|
||||
/**
|
||||
* Same as {@link #readAclsById(List, List)} except it returns only a single Acl.
|
||||
*
|
||||
* @param object to locate an {@link Acl} for
|
||||
* @param sids the security identities for which {@link Acl} information is required
|
||||
* (may be <tt>null</tt> to denote all entries)
|
||||
*
|
||||
* @return the {@link Acl} for the requested {@link ObjectIdentity} (never
|
||||
* <tt>null</tt>)
|
||||
*
|
||||
* @throws NotFoundException if an {@link Acl} was not found for the requested
|
||||
* {@link ObjectIdentity}
|
||||
*/
|
||||
|
@ -76,17 +69,13 @@ public interface AclService {
|
|||
* The returned map is keyed on the passed objects, with the values being the
|
||||
* <tt>Acl</tt> instances. Any unknown objects will not have a map key.
|
||||
* </p>
|
||||
*
|
||||
* @param objects the objects to find {@link Acl} information for
|
||||
*
|
||||
* @return a map with exactly one element for each {@link ObjectIdentity} passed as an
|
||||
* argument (never <tt>null</tt>)
|
||||
*
|
||||
* @throws NotFoundException if an {@link Acl} was not found for each requested
|
||||
* {@link ObjectIdentity}
|
||||
*/
|
||||
Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects)
|
||||
throws NotFoundException;
|
||||
Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects) throws NotFoundException;
|
||||
|
||||
/**
|
||||
* Obtains all the <tt>Acl</tt>s that apply for the passed <tt>Object</tt>s, but only
|
||||
|
@ -103,17 +92,14 @@ public interface AclService {
|
|||
* <tt>Acl</tt> instances. Any unknown objects (or objects for which the interested
|
||||
* <tt>Sid</tt>s do not have entries) will not have a map key.
|
||||
* </p>
|
||||
*
|
||||
* @param objects the objects to find {@link Acl} information for
|
||||
* @param sids the security identities for which {@link Acl} information is required
|
||||
* (may be <tt>null</tt> to denote all entries)
|
||||
*
|
||||
* @return a map with exactly one element for each {@link ObjectIdentity} passed as an
|
||||
* argument (never <tt>null</tt>)
|
||||
*
|
||||
* @throws NotFoundException if an {@link Acl} was not found for each requested
|
||||
* {@link ObjectIdentity}
|
||||
*/
|
||||
Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
|
||||
throws NotFoundException;
|
||||
Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids) throws NotFoundException;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class AlreadyExistsException extends AclDataAccessException {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Constructs an <code>AlreadyExistsException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public AlreadyExistsException(String msg) {
|
||||
|
@ -36,11 +36,11 @@ public class AlreadyExistsException extends AclDataAccessException {
|
|||
/**
|
||||
* Constructs an <code>AlreadyExistsException</code> with the specified message and
|
||||
* root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public AlreadyExistsException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,12 @@ package org.springframework.security.acls.model;
|
|||
*
|
||||
*/
|
||||
public interface AuditableAccessControlEntry extends AccessControlEntry {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
boolean isAuditFailure();
|
||||
|
||||
boolean isAuditSuccess();
|
||||
|
||||
}
|
||||
|
|
|
@ -22,8 +22,10 @@ package org.springframework.security.acls.model;
|
|||
*
|
||||
*/
|
||||
public interface AuditableAcl extends MutableAcl {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
void updateAuditing(int aceIndex, boolean auditSuccess, boolean auditFailure);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class ChildrenExistException extends AclDataAccessException {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Constructs an <code>ChildrenExistException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public ChildrenExistException(String msg) {
|
||||
|
@ -36,11 +36,11 @@ public class ChildrenExistException extends AclDataAccessException {
|
|||
/**
|
||||
* Constructs an <code>ChildrenExistException</code> with the specified message and
|
||||
* root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public ChildrenExistException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.Serializable;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface MutableAcl extends Acl {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -33,34 +34,30 @@ public interface MutableAcl extends Acl {
|
|||
|
||||
/**
|
||||
* Obtains an identifier that represents this <tt>MutableAcl</tt>.
|
||||
*
|
||||
* @return the identifier, or <tt>null</tt> if unsaved
|
||||
*/
|
||||
Serializable getId();
|
||||
|
||||
void insertAce(int atIndexLocation, Permission permission, Sid sid, boolean granting)
|
||||
throws NotFoundException;
|
||||
void insertAce(int atIndexLocation, Permission permission, Sid sid, boolean granting) throws NotFoundException;
|
||||
|
||||
/**
|
||||
* Changes the present owner to a different owner.
|
||||
*
|
||||
* @param newOwner the new owner (mandatory; cannot be null)
|
||||
*/
|
||||
void setOwner(Sid newOwner);
|
||||
|
||||
/**
|
||||
* Change the value returned by {@link Acl#isEntriesInheriting()}.
|
||||
*
|
||||
* @param entriesInheriting the new value
|
||||
*/
|
||||
void setEntriesInheriting(boolean entriesInheriting);
|
||||
|
||||
/**
|
||||
* Changes the parent of this ACL.
|
||||
*
|
||||
* @param newParent the new parent
|
||||
*/
|
||||
void setParent(Acl newParent);
|
||||
|
||||
void updateAce(int aceIndex, Permission permission) throws NotFoundException;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,41 +21,35 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface MutableAclService extends AclService {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Creates an empty <code>Acl</code> object in the database. It will have no entries.
|
||||
* The returned object will then be used to add entries.
|
||||
*
|
||||
* @param objectIdentity the object identity to create
|
||||
*
|
||||
* @return an ACL object with its ID set
|
||||
*
|
||||
* @throws AlreadyExistsException if the passed object identity already has a record
|
||||
*/
|
||||
MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Removes the specified entry from the database.
|
||||
*
|
||||
* @param objectIdentity the object identity to remove
|
||||
* @param deleteChildren whether to cascade the delete to children
|
||||
*
|
||||
* @throws ChildrenExistException if the deleteChildren argument was
|
||||
* <code>false</code> but children exist
|
||||
*/
|
||||
void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren)
|
||||
throws ChildrenExistException;
|
||||
void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren) throws ChildrenExistException;
|
||||
|
||||
/**
|
||||
* Changes an existing <code>Acl</code> in the database.
|
||||
*
|
||||
* @param acl to modify
|
||||
*
|
||||
* @throws NotFoundException if the relevant record could not be found (did you
|
||||
* remember to use {@link #createAcl(ObjectIdentity)} to create the object, rather
|
||||
* than creating it with the <code>new</code> keyword?)
|
||||
*/
|
||||
MutableAcl updateAcl(MutableAcl acl) throws NotFoundException;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class NotFoundException extends AclDataAccessException {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Constructs an <code>NotFoundException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public NotFoundException(String msg) {
|
||||
|
@ -36,11 +36,11 @@ public class NotFoundException extends AclDataAccessException {
|
|||
/**
|
||||
* Constructs an <code>NotFoundException</code> with the specified message and root
|
||||
* cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public NotFoundException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ import java.io.Serializable;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface ObjectIdentity extends Serializable {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* @param obj to be compared
|
||||
*
|
||||
* @return <tt>true</tt> if the objects are equal, <tt>false</tt> otherwise
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
|
@ -53,7 +53,6 @@ public interface ObjectIdentity extends Serializable {
|
|||
* identifier with business meaning, as that business meaning may change in the future
|
||||
* such change will cascade to the ACL subsystem data.
|
||||
* </p>
|
||||
*
|
||||
* @return the identifier (unique within this <tt>type</tt>; never <tt>null</tt>)
|
||||
*/
|
||||
Serializable getIdentifier();
|
||||
|
@ -62,7 +61,6 @@ public interface ObjectIdentity extends Serializable {
|
|||
* Obtains the "type" metadata for the domain object. This will often be a Java type
|
||||
* name (an interface or a class) – traditionally it is the name of the domain
|
||||
* object implementation class.
|
||||
*
|
||||
* @return the "type" of the domain object (never <tt>null</tt>).
|
||||
*/
|
||||
String getType();
|
||||
|
@ -72,4 +70,5 @@ public interface ObjectIdentity extends Serializable {
|
|||
* @see Object#hashCode()
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.io.Serializable;
|
|||
public interface ObjectIdentityGenerator {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id the identifier of the domain object, not null
|
||||
* @param type the type of the object (often a class name), not null
|
||||
* @return the identity constructed using the supplied identifier and type
|
||||
|
|
|
@ -24,8 +24,10 @@ package org.springframework.security.acls.model;
|
|||
*
|
||||
*/
|
||||
public interface ObjectIdentityRetrievalStrategy {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
ObjectIdentity getObjectIdentity(Object domainObject);
|
||||
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface OwnershipAcl extends MutableAcl {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
void setOwner(Sid newOwner);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,14 @@ import java.io.Serializable;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface Permission extends Serializable {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
char RESERVED_ON = '~';
|
||||
|
||||
char RESERVED_OFF = '.';
|
||||
|
||||
String THIRTY_TWO_RESERVED_OFF = "................................";
|
||||
|
||||
// ~ Methods
|
||||
|
@ -35,7 +38,6 @@ public interface Permission extends Serializable {
|
|||
|
||||
/**
|
||||
* Returns the bits that represents the permission.
|
||||
*
|
||||
* @return the bits that represent the permission
|
||||
*/
|
||||
int getMask();
|
||||
|
@ -56,8 +58,8 @@ public interface Permission extends Serializable {
|
|||
* This method is only used for user interface and logging purposes. It is not used in
|
||||
* any permission calculations. Therefore, duplication of characters within the output
|
||||
* is permitted.
|
||||
*
|
||||
* @return a 32-character bit pattern
|
||||
*/
|
||||
String getPattern();
|
||||
|
||||
}
|
||||
|
|
|
@ -27,10 +27,9 @@ import java.util.List;
|
|||
public interface PermissionGrantingStrategy {
|
||||
|
||||
/**
|
||||
* Returns true if the supplied strategy decides that the supplied {@code Acl}
|
||||
* grants access based on the supplied list of permissions and sids.
|
||||
* Returns true if the supplied strategy decides that the supplied {@code Acl} grants
|
||||
* access based on the supplied list of permissions and sids.
|
||||
*/
|
||||
boolean isGranted(Acl acl, List<Permission> permission, List<Sid> sids,
|
||||
boolean administrativeMode);
|
||||
boolean isGranted(Acl acl, List<Permission> permission, List<Sid> sids, boolean administrativeMode);
|
||||
|
||||
}
|
||||
|
|
|
@ -31,15 +31,14 @@ import java.io.Serializable;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface Sid extends Serializable {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
/**
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the interface
|
||||
* contract.
|
||||
*
|
||||
* @param obj to be compared
|
||||
*
|
||||
* @return <code>true</code> if the objects are equal, <code>false</code> otherwise
|
||||
*/
|
||||
boolean equals(Object obj);
|
||||
|
@ -47,8 +46,8 @@ public interface Sid extends Serializable {
|
|||
/**
|
||||
* Refer to the <code>java.lang.Object</code> documentation for the interface
|
||||
* contract.
|
||||
*
|
||||
* @return a hash code representation of this object
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@ import org.springframework.security.core.Authentication;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface SidRetrievalStrategy {
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
List<Sid> getSids(Authentication authentication);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ package org.springframework.security.acls.model;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class UnloadedSidException extends AclDataAccessException {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
/**
|
||||
* Constructs an <code>NotFoundException</code> with the specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public UnloadedSidException(String msg) {
|
||||
|
@ -38,11 +38,11 @@ public class UnloadedSidException extends AclDataAccessException {
|
|||
/**
|
||||
* Constructs an <code>NotFoundException</code> with the specified message and root
|
||||
* cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param t root cause
|
||||
*/
|
||||
public UnloadedSidException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
|
||||
* Interfaces and shared classes to manage access control lists (ACLs) for domain object
|
||||
* instances.
|
||||
*/
|
||||
package org.springframework.security.acls.model;
|
||||
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* The Spring Security ACL package which implements instance-based security for domain objects.
|
||||
* The Spring Security ACL package which implements instance-based security for domain
|
||||
* objects.
|
||||
* <p>
|
||||
* Consider using the annotation based approach ({@code @PreAuthorize}, {@code @PostFilter} annotations) combined
|
||||
* with a {@link org.springframework.security.acls.AclPermissionEvaluator} in preference to the older and more verbose
|
||||
* attribute/voter/after-invocation approach from versions before Spring Security 3.0.
|
||||
* Consider using the annotation based approach ({@code @PreAuthorize},
|
||||
* {@code @PostFilter} annotations) combined with a
|
||||
* {@link org.springframework.security.acls.AclPermissionEvaluator} in preference to the
|
||||
* older and more verbose attribute/voter/after-invocation approach from versions before
|
||||
* Spring Security 3.0.
|
||||
*/
|
||||
package org.springframework.security.acls;
|
||||
|
||||
|
|
|
@ -66,13 +66,11 @@ public class AclFormattingUtilsTests {
|
|||
public final void testDemergePatterns() {
|
||||
String original = "...........................A...R";
|
||||
String removeBits = "...............................R";
|
||||
assertThat(AclFormattingUtils.demergePatterns(original, removeBits)).isEqualTo(
|
||||
"...........................A....");
|
||||
assertThat(AclFormattingUtils.demergePatterns(original, removeBits))
|
||||
.isEqualTo("...........................A....");
|
||||
|
||||
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "......")).isEqualTo(
|
||||
"ABCDEF");
|
||||
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL")).isEqualTo(
|
||||
"......");
|
||||
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "......")).isEqualTo("ABCDEF");
|
||||
assertThat(AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL")).isEqualTo("......");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -109,19 +107,15 @@ public class AclFormattingUtilsTests {
|
|||
public final void testMergePatterns() {
|
||||
String original = "...............................R";
|
||||
String extraBits = "...........................A....";
|
||||
assertThat(AclFormattingUtils.mergePatterns(original, extraBits)).isEqualTo(
|
||||
"...........................A...R");
|
||||
assertThat(AclFormattingUtils.mergePatterns(original, extraBits)).isEqualTo("...........................A...R");
|
||||
|
||||
assertThat(AclFormattingUtils.mergePatterns("ABCDEF", "......")).isEqualTo(
|
||||
"ABCDEF");
|
||||
assertThat(AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL")).isEqualTo(
|
||||
"GHIJKL");
|
||||
assertThat(AclFormattingUtils.mergePatterns("ABCDEF", "......")).isEqualTo("ABCDEF");
|
||||
assertThat(AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL")).isEqualTo("GHIJKL");
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testBinaryPrints() {
|
||||
assertThat(AclFormattingUtils.printBinary(15)).isEqualTo(
|
||||
"............................****");
|
||||
assertThat(AclFormattingUtils.printBinary(15)).isEqualTo("............................****");
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_ON);
|
||||
|
@ -137,19 +131,17 @@ public class AclFormattingUtilsTests {
|
|||
catch (IllegalArgumentException notExpected) {
|
||||
}
|
||||
|
||||
assertThat(AclFormattingUtils.printBinary(15, 'x')).isEqualTo(
|
||||
"............................xxxx");
|
||||
assertThat(AclFormattingUtils.printBinary(15, 'x')).isEqualTo("............................xxxx");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintBinaryNegative() {
|
||||
assertThat(AclFormattingUtils.printBinary(0x80000000)).isEqualTo(
|
||||
"*...............................");
|
||||
assertThat(AclFormattingUtils.printBinary(0x80000000)).isEqualTo("*...............................");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintBinaryMinusOne() {
|
||||
assertThat(AclFormattingUtils.printBinary(0xffffffff)).isEqualTo(
|
||||
"********************************");
|
||||
assertThat(AclFormattingUtils.printBinary(0xffffffff)).isEqualTo("********************************");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,8 +44,7 @@ public class AclPermissionCacheOptimizerTests {
|
|||
pco.setObjectIdentityRetrievalStrategy(oidStrat);
|
||||
pco.setSidRetrievalStrategy(sidStrat);
|
||||
Object[] dos = { new Object(), null, new Object() };
|
||||
ObjectIdentity[] oids = { new ObjectIdentityImpl("A", "1"),
|
||||
new ObjectIdentityImpl("A", "2") };
|
||||
ObjectIdentity[] oids = { new ObjectIdentityImpl("A", "1"), new ObjectIdentityImpl("A", "2") };
|
||||
when(oidStrat.getObjectIdentity(dos[0])).thenReturn(oids[0]);
|
||||
when(oidStrat.getObjectIdentity(dos[2])).thenReturn(oids[1]);
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.springframework.security.acls.model.SidRetrievalStrategy;
|
|||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @since 3.0
|
||||
*/
|
||||
|
@ -74,4 +73,5 @@ public class AclPermissionEvaluatorTests {
|
|||
|
||||
Locale.setDefault(systemLocale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,4 +33,5 @@ public final class TargetObjectWithUUID {
|
|||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
@ -36,14 +35,13 @@ import java.util.List;
|
|||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public class AclEntryAfterInvocationCollectionFilteringProviderTests {
|
||||
|
||||
@Test
|
||||
public void objectsAreRemovedIfPermissionDenied() {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(), any(), anyBoolean())).thenReturn(
|
||||
false);
|
||||
when(service.readAclById(any(), any())).thenReturn(
|
||||
acl);
|
||||
when(acl.isGranted(any(), any(), anyBoolean())).thenReturn(false);
|
||||
when(service.readAclById(any(), any())).thenReturn(acl);
|
||||
AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(
|
||||
service, Arrays.asList(mock(Permission.class)));
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
|
@ -51,8 +49,8 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
|
|||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
|
||||
Object returned = provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), new ArrayList(
|
||||
Arrays.asList(new Object(), new Object())));
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"),
|
||||
new ArrayList(Arrays.asList(new Object(), new Object())));
|
||||
assertThat(returned).isInstanceOf(List.class);
|
||||
assertThat(((List) returned)).isEmpty();
|
||||
returned = provider.decide(mock(Authentication.class), new Object(),
|
||||
|
@ -68,10 +66,8 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
|
|||
mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
Object returned = new Object();
|
||||
|
||||
assertThat(returned)
|
||||
.isSameAs(
|
||||
provider.decide(mock(Authentication.class), new Object(),
|
||||
Collections.<ConfigAttribute> emptyList(), returned));
|
||||
assertThat(returned).isSameAs(provider.decide(mock(Authentication.class), new Object(),
|
||||
Collections.<ConfigAttribute>emptyList(), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -81,8 +77,7 @@ public class AclEntryAfterInvocationCollectionFilteringProviderTests {
|
|||
service, Arrays.asList(mock(Permission.class)));
|
||||
|
||||
assertThat(provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
|
||||
.isNull();
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)).isNull();
|
||||
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
|
||||
}
|
||||
|
||||
|
|
|
@ -44,58 +44,46 @@ public class AclEntryAfterInvocationProviderTests {
|
|||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
new AclEntryAfterInvocationProvider(mock(AclService.class),
|
||||
Collections.<Permission> emptyList());
|
||||
new AclEntryAfterInvocationProvider(mock(AclService.class), Collections.<Permission>emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsAllowedIfPermissionIsGranted() {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(
|
||||
true);
|
||||
when(service.readAclById(any(), any())).thenReturn(
|
||||
acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
|
||||
service, Arrays.asList(mock(Permission.class)));
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(true);
|
||||
when(service.readAclById(any(), any())).thenReturn(acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service,
|
||||
Arrays.asList(mock(Permission.class)));
|
||||
provider.setMessageSource(new SpringSecurityMessageSource());
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
provider.setProcessDomainObjectClass(Object.class);
|
||||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
Object returned = new Object();
|
||||
|
||||
assertThat(
|
||||
returned)
|
||||
.isSameAs(
|
||||
provider.decide(mock(Authentication.class), new Object(),
|
||||
assertThat(returned).isSameAs(provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("AFTER_ACL_READ"), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsGrantedIfNoAttributesDefined() {
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
|
||||
mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class),
|
||||
Arrays.asList(mock(Permission.class)));
|
||||
Object returned = new Object();
|
||||
|
||||
assertThat(
|
||||
returned)
|
||||
.isSameAs(
|
||||
provider.decide(mock(Authentication.class), new Object(),
|
||||
Collections.<ConfigAttribute> emptyList(), returned));
|
||||
assertThat(returned).isSameAs(provider.decide(mock(Authentication.class), new Object(),
|
||||
Collections.<ConfigAttribute>emptyList(), returned));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessIsGrantedIfObjectTypeNotSupported() {
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
|
||||
mock(AclService.class), Arrays.asList(mock(Permission.class)));
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class),
|
||||
Arrays.asList(mock(Permission.class)));
|
||||
provider.setProcessDomainObjectClass(String.class);
|
||||
// Not a String
|
||||
Object returned = new Object();
|
||||
|
||||
assertThat(
|
||||
returned)
|
||||
.isSameAs(
|
||||
provider.decide(mock(Authentication.class), new Object(),
|
||||
assertThat(returned).isSameAs(provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("AFTER_ACL_READ"), returned));
|
||||
}
|
||||
|
||||
|
@ -103,15 +91,12 @@ public class AclEntryAfterInvocationProviderTests {
|
|||
public void accessIsDeniedIfPermissionIsNotGranted() {
|
||||
AclService service = mock(AclService.class);
|
||||
Acl acl = mock(Acl.class);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(
|
||||
false);
|
||||
when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(false);
|
||||
// Try a second time with no permissions found
|
||||
when(acl.isGranted(any(), any(List.class), anyBoolean())).thenThrow(
|
||||
new NotFoundException(""));
|
||||
when(service.readAclById(any(), any())).thenReturn(
|
||||
acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
|
||||
service, Arrays.asList(mock(Permission.class)));
|
||||
when(acl.isGranted(any(), any(List.class), anyBoolean())).thenThrow(new NotFoundException(""));
|
||||
when(service.readAclById(any(), any())).thenReturn(acl);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service,
|
||||
Arrays.asList(mock(Permission.class)));
|
||||
provider.setProcessConfigAttribute("MY_ATTRIBUTE");
|
||||
provider.setMessageSource(new SpringSecurityMessageSource());
|
||||
provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class));
|
||||
|
@ -119,8 +104,7 @@ public class AclEntryAfterInvocationProviderTests {
|
|||
provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class));
|
||||
try {
|
||||
provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"),
|
||||
new Object());
|
||||
SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object());
|
||||
fail("Expected Exception");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
|
@ -133,12 +117,12 @@ public class AclEntryAfterInvocationProviderTests {
|
|||
@Test
|
||||
public void nullReturnObjectIsIgnored() {
|
||||
AclService service = mock(AclService.class);
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(
|
||||
service, Arrays.asList(mock(Permission.class)));
|
||||
AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service,
|
||||
Arrays.asList(mock(Permission.class)));
|
||||
|
||||
assertThat(provider.decide(mock(Authentication.class), new Object(),
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null))
|
||||
.isNull();
|
||||
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)).isNull();
|
||||
verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ public class AccessControlImplEntryTests {
|
|||
public void testConstructorRequiredFields() {
|
||||
// Check Acl field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"),
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"), BasePermission.ADMINISTRATION, true,
|
||||
true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -48,8 +48,7 @@ public class AccessControlImplEntryTests {
|
|||
|
||||
// Check Sid field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, mock(Acl.class), null,
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
new AccessControlEntryImpl(null, mock(Acl.class), null, BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -57,8 +56,7 @@ public class AccessControlImplEntryTests {
|
|||
|
||||
// Check Permission field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, mock(Acl.class),
|
||||
new PrincipalSid("johndoe"), null, true, true, true);
|
||||
new AccessControlEntryImpl(null, mock(Acl.class), new PrincipalSid("johndoe"), null, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -71,8 +69,8 @@ public class AccessControlImplEntryTests {
|
|||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
// Create a sample entry
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl,
|
||||
sid, BasePermission.ADMINISTRATION, true, true, true);
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true,
|
||||
true);
|
||||
|
||||
// and check every get() method
|
||||
assertThat(ace.getId()).isEqualTo(1L);
|
||||
|
@ -92,26 +90,26 @@ public class AccessControlImplEntryTests {
|
|||
when(mockAcl.getObjectIdentity()).thenReturn(oid);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl,
|
||||
sid, BasePermission.ADMINISTRATION, true, true, true);
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true,
|
||||
true);
|
||||
|
||||
assertThat(ace).isNotNull();
|
||||
assertThat(ace).isNotEqualTo(100L);
|
||||
assertThat(ace).isEqualTo(ace);
|
||||
assertThat(ace).isEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
|
||||
assertThat(ace).isEqualTo(
|
||||
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(
|
||||
new AccessControlEntryImpl(2L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, new PrincipalSid("scott"),
|
||||
BasePermission.ADMINISTRATION, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(2L, mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl,
|
||||
new PrincipalSid("scott"), BasePermission.ADMINISTRATION, true, true,
|
||||
true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
|
||||
BasePermission.WRITE, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, false, true, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, false, true));
|
||||
assertThat(ace).isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, false));
|
||||
assertThat(ace)
|
||||
.isNotEqualTo(new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.WRITE, true, true, true));
|
||||
assertThat(ace).isNotEqualTo(
|
||||
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, false, true, true));
|
||||
assertThat(ace).isNotEqualTo(
|
||||
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, false, true));
|
||||
assertThat(ace).isNotEqualTo(
|
||||
new AccessControlEntryImpl(1L, mockAcl, sid, BasePermission.ADMINISTRATION, true, true, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
|
@ -31,21 +30,24 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AclAuthorizationStrategyImplTests {
|
||||
|
||||
@Mock
|
||||
Acl acl;
|
||||
|
||||
GrantedAuthority authority;
|
||||
|
||||
AclAuthorizationStrategyImpl strategy;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
authority = new SimpleGrantedAuthority("ROLE_AUTH");
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar", Arrays.asList(authority));
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("foo", "bar",
|
||||
Arrays.asList(authority));
|
||||
authentication.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
|
@ -64,9 +66,12 @@ public class AclAuthorizationStrategyImplTests {
|
|||
|
||||
@SuppressWarnings("serial")
|
||||
class CustomAuthority implements GrantedAuthority {
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return authority.getAuthority();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,20 +35,31 @@ import java.util.*;
|
|||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplTests {
|
||||
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static final List<Permission> READ = Arrays.asList(BasePermission.READ);
|
||||
|
||||
private static final List<Permission> WRITE = Arrays.asList(BasePermission.WRITE);
|
||||
|
||||
private static final List<Permission> CREATE = Arrays.asList(BasePermission.CREATE);
|
||||
|
||||
private static final List<Permission> DELETE = Arrays.asList(BasePermission.DELETE);
|
||||
|
||||
private static final List<Sid> SCOTT = Arrays.asList((Sid) new PrincipalSid("scott"));
|
||||
|
||||
private static final List<Sid> BEN = Arrays.asList((Sid) new PrincipalSid("ben"));
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("joe", "ignored",
|
||||
"ROLE_ADMINISTRATOR");
|
||||
Authentication auth = new TestingAuthenticationToken("joe", "ignored", "ROLE_ADMINISTRATOR");
|
||||
|
||||
AclAuthorizationStrategy authzStrategy;
|
||||
|
||||
PermissionGrantingStrategy pgs;
|
||||
|
||||
AuditLogger mockAuditLogger;
|
||||
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
|
||||
private DefaultPermissionFactory permissionFactory;
|
||||
|
||||
// ~ Methods
|
||||
|
@ -72,8 +83,7 @@ public class AclImplTests {
|
|||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorsRejectNullObjectIdentity() {
|
||||
try {
|
||||
new AclImpl(null, 1, authzStrategy, pgs, null, null, true, new PrincipalSid(
|
||||
"joe"));
|
||||
new AclImpl(null, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -84,8 +94,7 @@ public class AclImplTests {
|
|||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorsRejectNullId() {
|
||||
try {
|
||||
new AclImpl(objectIdentity, null, authzStrategy, pgs, null, null, true,
|
||||
new PrincipalSid("joe"));
|
||||
new AclImpl(objectIdentity, null, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -97,8 +106,8 @@ public class AclImplTests {
|
|||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorsRejectNullAclAuthzStrategy() {
|
||||
try {
|
||||
new AclImpl(objectIdentity, 1, null, new DefaultPermissionGrantingStrategy(
|
||||
mockAuditLogger), null, null, true, new PrincipalSid("joe"));
|
||||
new AclImpl(objectIdentity, 1, null, new DefaultPermissionGrantingStrategy(mockAuditLogger), null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
@ -108,8 +117,7 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void insertAceRejectsNullParameters() {
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
try {
|
||||
acl.insertAce(0, null, new GrantedAuthoritySid("ROLE_IGNORED"), true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
|
@ -126,8 +134,7 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void insertAceAddsElementAtCorrectIndex() {
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
|
||||
// Insert one permission
|
||||
|
@ -137,8 +144,7 @@ public class AclImplTests {
|
|||
assertThat(acl.getEntries()).hasSize(1);
|
||||
assertThat(acl).isEqualTo(acl.getEntries().get(0).getAcl());
|
||||
assertThat(BasePermission.READ).isEqualTo(acl.getEntries().get(0).getPermission());
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST1"));
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST1"));
|
||||
|
||||
// Add a second permission
|
||||
acl.insertAce(1, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST2"), true);
|
||||
|
@ -147,44 +153,36 @@ public class AclImplTests {
|
|||
assertThat(acl.getEntries()).hasSize(2);
|
||||
assertThat(acl).isEqualTo(acl.getEntries().get(1).getAcl());
|
||||
assertThat(BasePermission.READ).isEqualTo(acl.getEntries().get(1).getPermission());
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST2"));
|
||||
|
||||
// Add a third permission, after the first one
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_TEST3"),
|
||||
false);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_TEST3"), false);
|
||||
service.updateAcl(acl);
|
||||
assertThat(acl.getEntries()).hasSize(3);
|
||||
// Check the third entry was added between the two existent ones
|
||||
assertThat(BasePermission.READ).isEqualTo(acl.getEntries().get(0).getPermission());
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST1"));
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST1"));
|
||||
assertThat(BasePermission.WRITE).isEqualTo(acl.getEntries().get(1).getPermission());
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo( new GrantedAuthoritySid(
|
||||
"ROLE_TEST3"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST3"));
|
||||
assertThat(BasePermission.READ).isEqualTo(acl.getEntries().get(2).getPermission());
|
||||
assertThat(acl.getEntries().get(2).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(2).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST2"));
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void insertAceFailsForNonExistentElement() {
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
|
||||
// Insert one permission
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST1"), true);
|
||||
service.updateAcl(acl);
|
||||
|
||||
acl.insertAce(55, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST2"),
|
||||
true);
|
||||
acl.insertAce(55, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST2"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteAceKeepsInitialOrdering() {
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
|
||||
// Add several permissions
|
||||
|
@ -197,20 +195,16 @@ public class AclImplTests {
|
|||
// kept
|
||||
acl.deleteAce(0);
|
||||
assertThat(acl.getEntries()).hasSize(2);
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST3"));
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST3"));
|
||||
|
||||
// Add one more permission and remove the permission in the middle
|
||||
acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_TEST4"), true);
|
||||
service.updateAcl(acl);
|
||||
acl.deleteAce(1);
|
||||
assertThat(acl.getEntries()).hasSize(2);
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid(
|
||||
"ROLE_TEST4"));
|
||||
assertThat(acl.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST2"));
|
||||
assertThat(acl.getEntries().get(1).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST4"));
|
||||
|
||||
// Remove remaining permissions
|
||||
acl.deleteAce(1);
|
||||
|
@ -221,10 +215,9 @@ public class AclImplTests {
|
|||
@Test
|
||||
public void deleteAceFailsForNonExistentElement() {
|
||||
AclAuthorizationStrategyImpl strategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, (1), strategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, (1), strategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
try {
|
||||
acl.deleteAce(99);
|
||||
fail("It should have thrown NotFoundException");
|
||||
|
@ -235,8 +228,7 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void isGrantingRejectsEmptyParameters() {
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
Sid ben = new PrincipalSid("ben");
|
||||
try {
|
||||
acl.isGranted(new ArrayList<>(0), Arrays.asList(ben), false);
|
||||
|
@ -254,28 +246,23 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void isGrantingGrantsAccessForAclWithNoParent() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_GENERAL", "ROLE_GUEST");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_GENERAL", "ROLE_GUEST");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
ObjectIdentity rootOid = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
|
||||
// Create an ACL which owner is not the authenticated principal
|
||||
MutableAcl rootAcl = new AclImpl(rootOid, 1, authzStrategy, pgs, null, null,
|
||||
false, new PrincipalSid("joe"));
|
||||
MutableAcl rootAcl = new AclImpl(rootOid, 1, authzStrategy, pgs, null, null, false, new PrincipalSid("joe"));
|
||||
|
||||
// Grant some permissions
|
||||
rootAcl.insertAce(0, BasePermission.READ, new PrincipalSid("ben"), false);
|
||||
rootAcl.insertAce(1, BasePermission.WRITE, new PrincipalSid("scott"), true);
|
||||
rootAcl.insertAce(2, BasePermission.WRITE, new PrincipalSid("rod"), false);
|
||||
rootAcl.insertAce(3, BasePermission.WRITE, new GrantedAuthoritySid(
|
||||
"WRITE_ACCESS_ROLE"), true);
|
||||
rootAcl.insertAce(3, BasePermission.WRITE, new GrantedAuthoritySid("WRITE_ACCESS_ROLE"), true);
|
||||
|
||||
// Check permissions granting
|
||||
List<Permission> permissions = Arrays.asList(BasePermission.READ,
|
||||
BasePermission.CREATE);
|
||||
List<Sid> sids = Arrays.asList(new PrincipalSid("ben"), new GrantedAuthoritySid(
|
||||
"ROLE_GUEST"));
|
||||
List<Permission> permissions = Arrays.asList(BasePermission.READ, BasePermission.CREATE);
|
||||
List<Sid> sids = Arrays.asList(new PrincipalSid("ben"), new GrantedAuthoritySid("ROLE_GUEST"));
|
||||
assertThat(rootAcl.isGranted(permissions, sids, false)).isFalse();
|
||||
try {
|
||||
rootAcl.isGranted(permissions, SCOTT, false);
|
||||
|
@ -284,14 +271,14 @@ public class AclImplTests {
|
|||
catch (NotFoundException expected) {
|
||||
}
|
||||
assertThat(rootAcl.isGranted(WRITE, SCOTT, false)).isTrue();
|
||||
assertThat(rootAcl.isGranted(WRITE, Arrays.asList(new PrincipalSid("rod"),
|
||||
new GrantedAuthoritySid("WRITE_ACCESS_ROLE")), false)).isFalse();
|
||||
assertThat(rootAcl.isGranted(WRITE, Arrays.asList(new GrantedAuthoritySid(
|
||||
"WRITE_ACCESS_ROLE"), new PrincipalSid("rod")), false)).isTrue();
|
||||
assertThat(rootAcl.isGranted(WRITE,
|
||||
Arrays.asList(new PrincipalSid("rod"), new GrantedAuthoritySid("WRITE_ACCESS_ROLE")), false)).isFalse();
|
||||
assertThat(rootAcl.isGranted(WRITE,
|
||||
Arrays.asList(new GrantedAuthoritySid("WRITE_ACCESS_ROLE"), new PrincipalSid("rod")), false)).isTrue();
|
||||
try {
|
||||
// Change the type of the Sid and check the granting process
|
||||
rootAcl.isGranted(WRITE, Arrays.asList(new GrantedAuthoritySid("rod"),
|
||||
new PrincipalSid("WRITE_ACCESS_ROLE")), false);
|
||||
rootAcl.isGranted(WRITE,
|
||||
Arrays.asList(new GrantedAuthoritySid("rod"), new PrincipalSid("WRITE_ACCESS_ROLE")), false);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -300,8 +287,7 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void isGrantingGrantsAccessForInheritableAcls() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
|
@ -312,16 +298,11 @@ public class AclImplTests {
|
|||
|
||||
// Create ACLs
|
||||
PrincipalSid joe = new PrincipalSid("joe");
|
||||
MutableAcl grandParentAcl = new AclImpl(grandParentOid, 1, authzStrategy, pgs,
|
||||
null, null, false, joe);
|
||||
MutableAcl parentAcl1 = new AclImpl(parentOid1, 2, authzStrategy, pgs, null,
|
||||
null, true, joe);
|
||||
MutableAcl parentAcl2 = new AclImpl(parentOid2, 3, authzStrategy, pgs, null,
|
||||
null, true, joe);
|
||||
MutableAcl childAcl1 = new AclImpl(childOid1, 4, authzStrategy, pgs, null, null,
|
||||
true, joe);
|
||||
MutableAcl childAcl2 = new AclImpl(childOid2, 4, authzStrategy, pgs, null, null,
|
||||
false, joe);
|
||||
MutableAcl grandParentAcl = new AclImpl(grandParentOid, 1, authzStrategy, pgs, null, null, false, joe);
|
||||
MutableAcl parentAcl1 = new AclImpl(parentOid1, 2, authzStrategy, pgs, null, null, true, joe);
|
||||
MutableAcl parentAcl2 = new AclImpl(parentOid2, 3, authzStrategy, pgs, null, null, true, joe);
|
||||
MutableAcl childAcl1 = new AclImpl(childOid1, 4, authzStrategy, pgs, null, null, true, joe);
|
||||
MutableAcl childAcl2 = new AclImpl(childOid2, 4, authzStrategy, pgs, null, null, false, joe);
|
||||
|
||||
// Create hierarchies
|
||||
childAcl2.setParent(childAcl1);
|
||||
|
@ -330,13 +311,10 @@ public class AclImplTests {
|
|||
parentAcl1.setParent(grandParentAcl);
|
||||
|
||||
// Add some permissions
|
||||
grandParentAcl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid(
|
||||
"ROLE_USER_READ"), true);
|
||||
grandParentAcl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
grandParentAcl.insertAce(1, BasePermission.WRITE, new PrincipalSid("ben"), true);
|
||||
grandParentAcl
|
||||
.insertAce(2, BasePermission.DELETE, new PrincipalSid("ben"), false);
|
||||
grandParentAcl.insertAce(3, BasePermission.DELETE, new PrincipalSid("scott"),
|
||||
true);
|
||||
grandParentAcl.insertAce(2, BasePermission.DELETE, new PrincipalSid("ben"), false);
|
||||
grandParentAcl.insertAce(3, BasePermission.DELETE, new PrincipalSid("scott"), true);
|
||||
parentAcl1.insertAce(0, BasePermission.READ, new PrincipalSid("scott"), true);
|
||||
parentAcl1.insertAce(1, BasePermission.DELETE, new PrincipalSid("scott"), false);
|
||||
parentAcl2.insertAce(0, BasePermission.CREATE, new PrincipalSid("ben"), true);
|
||||
|
@ -344,8 +322,7 @@ public class AclImplTests {
|
|||
|
||||
// Check granting process for parent1
|
||||
assertThat(parentAcl1.isGranted(READ, SCOTT, false)).isTrue();
|
||||
assertThat(parentAcl1.isGranted(READ,
|
||||
Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
|
||||
assertThat(parentAcl1.isGranted(READ, Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
|
||||
.isTrue();
|
||||
assertThat(parentAcl1.isGranted(WRITE, BEN, false)).isTrue();
|
||||
assertThat(parentAcl1.isGranted(DELETE, BEN, false)).isFalse();
|
||||
|
@ -358,8 +335,7 @@ public class AclImplTests {
|
|||
|
||||
// Check granting process for child1
|
||||
assertThat(childAcl1.isGranted(CREATE, SCOTT, false)).isTrue();
|
||||
assertThat(childAcl1.isGranted(READ,
|
||||
Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
|
||||
assertThat(childAcl1.isGranted(READ, Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_USER_READ")), false))
|
||||
.isTrue();
|
||||
assertThat(childAcl1.isGranted(DELETE, BEN, false)).isFalse();
|
||||
|
||||
|
@ -372,8 +348,7 @@ public class AclImplTests {
|
|||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
childAcl2.isGranted(CREATE,
|
||||
Arrays.asList((Sid) new PrincipalSid("joe")), false);
|
||||
childAcl2.isGranted(CREATE, Arrays.asList((Sid) new PrincipalSid("joe")), false);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -382,18 +357,14 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void updatedAceValuesAreCorrectlyReflectedInAcl() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
false, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, false, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
acl.insertAce(2, BasePermission.CREATE, new PrincipalSid("ben"), true);
|
||||
service.updateAcl(acl);
|
||||
|
||||
|
@ -414,32 +385,20 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void auditableEntryFlagsAreUpdatedCorrectly() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_AUDITING", "ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_AUDITING", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
false, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, false, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
service.updateAcl(acl);
|
||||
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(0))
|
||||
.isAuditFailure())
|
||||
.isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(1))
|
||||
.isAuditFailure())
|
||||
.isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(0))
|
||||
.isAuditSuccess())
|
||||
.isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(1))
|
||||
.isAuditSuccess())
|
||||
.isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(0)).isAuditFailure()).isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(1)).isAuditFailure()).isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(0)).isAuditSuccess()).isFalse();
|
||||
assertThat(((AuditableAccessControlEntry) acl.getEntries().get(1)).isAuditSuccess()).isFalse();
|
||||
|
||||
// Change each permission
|
||||
((AuditableAcl) acl).updateAuditing(0, true, true);
|
||||
|
@ -452,21 +411,16 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void gettersAndSettersAreConsistent() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, (100));
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, (101));
|
||||
MutableAcl acl = new AclImpl(identity, 1, authzStrategy, pgs, null, null, true,
|
||||
new PrincipalSid("joe"));
|
||||
MutableAcl parentAcl = new AclImpl(identity2, 2, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
MutableAcl acl = new AclImpl(identity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
MutableAcl parentAcl = new AclImpl(identity2, 2, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
MockAclService service = new MockAclService();
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"),
|
||||
true);
|
||||
acl.insertAce(0, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
acl.insertAce(1, BasePermission.WRITE, new GrantedAuthoritySid("ROLE_USER_READ"), true);
|
||||
service.updateAcl(acl);
|
||||
|
||||
assertThat(1).isEqualTo(acl.getId());
|
||||
|
@ -488,50 +442,43 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void isSidLoadedBehavesAsExpected() {
|
||||
List<Sid> loadedSids = Arrays.asList(new PrincipalSid("ben"),
|
||||
new GrantedAuthoritySid("ROLE_IGNORED"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null,
|
||||
loadedSids, true, new PrincipalSid("joe"));
|
||||
List<Sid> loadedSids = Arrays.asList(new PrincipalSid("ben"), new GrantedAuthoritySid("ROLE_IGNORED"));
|
||||
MutableAcl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, loadedSids, true,
|
||||
new PrincipalSid("joe"));
|
||||
|
||||
assertThat(acl.isSidLoaded(loadedSids)).isTrue();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"),
|
||||
new PrincipalSid("ben"))))
|
||||
.isTrue();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid(
|
||||
"ROLE_IGNORED"))))
|
||||
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new PrincipalSid("ben"))))
|
||||
.isTrue();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList((Sid) new GrantedAuthoritySid("ROLE_IGNORED")))).isTrue();
|
||||
assertThat(acl.isSidLoaded(BEN)).isTrue();
|
||||
assertThat(acl.isSidLoaded(null)).isTrue();
|
||||
assertThat(acl.isSidLoaded(new ArrayList<>(0))).isTrue();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
|
||||
"ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_IGNORED"))))
|
||||
assertThat(acl.isSidLoaded(
|
||||
Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_IGNORED"))))
|
||||
.isTrue();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
|
||||
"ROLE_GENERAL"), new GrantedAuthoritySid("ROLE_IGNORED"))))
|
||||
assertThat(acl.isSidLoaded(
|
||||
Arrays.asList(new GrantedAuthoritySid("ROLE_GENERAL"), new GrantedAuthoritySid("ROLE_IGNORED"))))
|
||||
.isFalse();
|
||||
assertThat(acl.isSidLoaded(Arrays.asList(new GrantedAuthoritySid(
|
||||
"ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_GENERAL"))))
|
||||
assertThat(acl.isSidLoaded(
|
||||
Arrays.asList(new GrantedAuthoritySid("ROLE_IGNORED"), new GrantedAuthoritySid("ROLE_GENERAL"))))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void insertAceRaisesNotFoundExceptionForIndexLessThanZero() {
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
acl.insertAce(-1, mock(Permission.class), mock(Sid.class), true);
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void deleteAceRaisesNotFoundExceptionForIndexLessThanZero() {
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
acl.deleteAce(-1);
|
||||
}
|
||||
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void insertAceRaisesNotFoundExceptionForIndexGreaterThanSize() {
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
// Insert at zero, OK.
|
||||
acl.insertAce(0, mock(Permission.class), mock(Sid.class), true);
|
||||
// Size is now 1
|
||||
|
@ -541,8 +488,7 @@ public class AclImplTests {
|
|||
// SEC-1151
|
||||
@Test(expected = NotFoundException.class)
|
||||
public void deleteAceRaisesNotFoundExceptionForIndexEqualToSize() {
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, pgs, null, null, true, new PrincipalSid("joe"));
|
||||
acl.insertAce(0, mock(Permission.class), mock(Sid.class), true);
|
||||
// Size is now 1
|
||||
acl.deleteAce(1);
|
||||
|
@ -551,11 +497,9 @@ public class AclImplTests {
|
|||
// SEC-1795
|
||||
@Test
|
||||
public void changingParentIsSuccessful() {
|
||||
AclImpl parentAcl = new AclImpl(objectIdentity, 1L, authzStrategy,
|
||||
mockAuditLogger);
|
||||
AclImpl parentAcl = new AclImpl(objectIdentity, 1L, authzStrategy, mockAuditLogger);
|
||||
AclImpl childAcl = new AclImpl(objectIdentity, 2L, authzStrategy, mockAuditLogger);
|
||||
AclImpl changeParentAcl = new AclImpl(objectIdentity, 3L, authzStrategy,
|
||||
mockAuditLogger);
|
||||
AclImpl changeParentAcl = new AclImpl(objectIdentity, 3L, authzStrategy, mockAuditLogger);
|
||||
|
||||
childAcl.setParent(parentAcl);
|
||||
childAcl.setParent(changeParentAcl);
|
||||
|
@ -566,9 +510,9 @@ public class AclImplTests {
|
|||
public void maskPermissionGrantingStrategy() {
|
||||
DefaultPermissionGrantingStrategy maskPgs = new MaskPermissionGrantingStrategy(mockAuditLogger);
|
||||
MockAclService service = new MockAclService();
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, maskPgs, null, null,
|
||||
true, new PrincipalSid("joe"));
|
||||
Permission permission = permissionFactory.buildFromMask(BasePermission.READ.getMask() | BasePermission.WRITE.getMask());
|
||||
AclImpl acl = new AclImpl(objectIdentity, 1, authzStrategy, maskPgs, null, null, true, new PrincipalSid("joe"));
|
||||
Permission permission = permissionFactory
|
||||
.buildFromMask(BasePermission.READ.getMask() | BasePermission.WRITE.getMask());
|
||||
Sid sid = new PrincipalSid("ben");
|
||||
acl.insertAce(0, permission, sid, true);
|
||||
service.updateAcl(acl);
|
||||
|
@ -579,7 +523,7 @@ public class AclImplTests {
|
|||
|
||||
@Test
|
||||
public void hashCodeWithoutStackOverFlow() throws Exception {
|
||||
//given
|
||||
// given
|
||||
Sid sid = new PrincipalSid("pSid");
|
||||
ObjectIdentity oid = new ObjectIdentityImpl("type", 1);
|
||||
AclAuthorizationStrategy authStrategy = new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("role"));
|
||||
|
@ -592,7 +536,7 @@ public class AclImplTests {
|
|||
fieldAces.setAccessible(true);
|
||||
List<AccessControlEntryImpl> aces = (List<AccessControlEntryImpl>) fieldAces.get(acl);
|
||||
aces.add(ace);
|
||||
//when - then none StackOverFlowError been raised
|
||||
// when - then none StackOverFlowError been raised
|
||||
ace.hashCode();
|
||||
}
|
||||
|
||||
|
@ -600,6 +544,7 @@ public class AclImplTests {
|
|||
// ==================================================================================================
|
||||
|
||||
private static class MaskPermissionGrantingStrategy extends DefaultPermissionGrantingStrategy {
|
||||
|
||||
MaskPermissionGrantingStrategy(AuditLogger auditLogger) {
|
||||
super(auditLogger);
|
||||
}
|
||||
|
@ -611,25 +556,24 @@ public class AclImplTests {
|
|||
}
|
||||
return super.isGranted(ace, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MockAclService implements MutableAclService {
|
||||
public MutableAcl createAcl(ObjectIdentity objectIdentity)
|
||||
throws AlreadyExistsException {
|
||||
|
||||
public MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren)
|
||||
throws ChildrenExistException {
|
||||
public void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren) throws ChildrenExistException {
|
||||
}
|
||||
|
||||
/*
|
||||
* Mock implementation that populates the aces list with fully initialized
|
||||
* AccessControlEntries
|
||||
*
|
||||
* @see
|
||||
* org.springframework.security.acls.MutableAclService#updateAcl(org.springframework
|
||||
* .security.acls.MutableAcl)
|
||||
* @see org.springframework.security.acls.MutableAclService#updateAcl(org.
|
||||
* springframework .security.acls.MutableAcl)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {
|
||||
|
@ -645,9 +589,8 @@ public class AclImplTests {
|
|||
AccessControlEntry ac = oldAces.get(i);
|
||||
// Just give an ID to all this acl's aces, rest of the fields are just
|
||||
// copied
|
||||
newAces.add(new AccessControlEntryImpl((i + 1), ac.getAcl(), ac
|
||||
.getSid(), ac.getPermission(), ac.isGranting(),
|
||||
((AuditableAccessControlEntry) ac).isAuditSuccess(),
|
||||
newAces.add(new AccessControlEntryImpl((i + 1), ac.getAcl(), ac.getSid(), ac.getPermission(),
|
||||
ac.isGranting(), ((AuditableAccessControlEntry) ac).isAuditSuccess(),
|
||||
((AuditableAccessControlEntry) ac).isAuditFailure()));
|
||||
}
|
||||
}
|
||||
|
@ -666,19 +609,19 @@ public class AclImplTests {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Acl readAclById(ObjectIdentity object, List<Sid> sids)
|
||||
public Acl readAclById(ObjectIdentity object, List<Sid> sids) throws NotFoundException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects) throws NotFoundException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids)
|
||||
throws NotFoundException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects)
|
||||
throws NotFoundException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects,
|
||||
List<Sid> sids) throws NotFoundException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplementationSecurityCheckTests {
|
||||
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
// ~ Methods
|
||||
|
@ -52,50 +53,42 @@ public class AclImplementationSecurityCheckTests {
|
|||
|
||||
@Test
|
||||
public void testSecurityCheckNoACEs() {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_GENERAL", "ROLE_AUDITING", "ROLE_OWNERSHIP");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL", "ROLE_AUDITING",
|
||||
"ROLE_OWNERSHIP");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
Acl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
Acl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
|
||||
// Create another authorization strategy
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority(
|
||||
"ROLE_TWO"), new SimpleGrantedAuthority("ROLE_THREE"));
|
||||
Acl acl2 = new AclImpl(identity, 1L, aclAuthorizationStrategy2,
|
||||
new ConsoleAuditLogger());
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority("ROLE_TWO"),
|
||||
new SimpleGrantedAuthority("ROLE_THREE"));
|
||||
Acl acl2 = new AclImpl(identity, 1L, aclAuthorizationStrategy2, new ConsoleAuditLogger());
|
||||
// Check access in case the principal has no authorization rights
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -105,54 +98,46 @@ public class AclImplementationSecurityCheckTests {
|
|||
@Test
|
||||
public void testSecurityCheckWithMultipleACEs() {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
// Let's give the principal the ADMINISTRATION permission, without
|
||||
// granting access
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, 1L,
|
||||
aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
false);
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
|
||||
// The CHANGE_GENERAL test should pass as the principal has ROLE_GENERAL
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
|
||||
// The CHANGE_AUDITING and CHANGE_OWNERSHIP should fail since the
|
||||
// principal doesn't have these authorities,
|
||||
// nor granting access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Add granting access to this principal
|
||||
aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
true);
|
||||
aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
// and try again for CHANGE_AUDITING - the first ACE's granting flag
|
||||
// (false) will deny this access
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
|
@ -160,23 +145,18 @@ public class AclImplementationSecurityCheckTests {
|
|||
|
||||
// Create another ACL and give the principal the ADMINISTRATION
|
||||
// permission, with granting access
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, 1L,
|
||||
aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
true);
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
|
||||
// The CHANGE_AUDITING test should pass as there is one ACE with
|
||||
// granting access
|
||||
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
|
||||
// Add a deny ACE and test again for CHANGE_AUDITING
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
false);
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
|
@ -184,11 +164,9 @@ public class AclImplementationSecurityCheckTests {
|
|||
}
|
||||
|
||||
// Create an ACL with no ACE
|
||||
MutableAcl aclNoACE = new AclImpl(identity, 1L,
|
||||
aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl aclNoACE = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -196,8 +174,7 @@ public class AclImplementationSecurityCheckTests {
|
|||
}
|
||||
// and still grant access for CHANGE_GENERAL
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -208,31 +185,26 @@ public class AclImplementationSecurityCheckTests {
|
|||
@Test
|
||||
public void testSecurityCheckWithInheritableACEs() {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority(
|
||||
"ROLE_TWO"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_ONE"), new SimpleGrantedAuthority("ROLE_TWO"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
// Let's give the principal an ADMINISTRATION permission, with granting
|
||||
// access
|
||||
MutableAcl parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
true);
|
||||
MutableAcl childAcl = new AclImpl(identity, 2, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
MutableAcl parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
MutableAcl childAcl = new AclImpl(identity, 2, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Check against the 'child' acl, which doesn't offer any authorization
|
||||
// rights on CHANGE_OWNERSHIP
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -244,8 +216,7 @@ public class AclImplementationSecurityCheckTests {
|
|||
childAcl.setParent(parentAcl);
|
||||
childAcl.setEntriesInheriting(true);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -253,18 +224,14 @@ public class AclImplementationSecurityCheckTests {
|
|||
}
|
||||
|
||||
// Create a root parent and link it to the middle parent
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth),
|
||||
true);
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, 1, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
parentAcl.setEntriesInheriting(true);
|
||||
parentAcl.setParent(rootParentAcl);
|
||||
childAcl.setParent(parentAcl);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
|
@ -274,39 +241,36 @@ public class AclImplementationSecurityCheckTests {
|
|||
|
||||
@Test
|
||||
public void testSecurityCheckPrincipalOwner() {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_ONE");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_ONE");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
Acl acl = new AclImpl(identity, 1, aclAuthorizationStrategy,
|
||||
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), null,
|
||||
null, false, new PrincipalSid(auth));
|
||||
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()), null, null, false,
|
||||
new PrincipalSid(auth));
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl,
|
||||
AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,11 +33,15 @@ import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
|||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AuditLoggerTests {
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
private PrintStream console;
|
||||
|
||||
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
|
||||
private ConsoleAuditLogger logger;
|
||||
|
||||
private AuditableAccessControlEntry ace;
|
||||
|
||||
// ~ Methods
|
||||
|
@ -92,4 +96,5 @@ public class AuditLoggerTests {
|
|||
logger.logIfNeeded(false, ace);
|
||||
assertThat(bytes.toString()).startsWith("DENIED due to ACE");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -141,8 +141,7 @@ public class ObjectIdentityImplTests {
|
|||
assertThat(obj).isNotEqualTo("DIFFERENT_OBJECT_TYPE");
|
||||
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(DOMAIN_CLASS, 2L));
|
||||
assertThat(obj).isNotEqualTo(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
1L));
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject", 1L));
|
||||
assertThat(new ObjectIdentityImpl(DOMAIN_CLASS, 1L)).isEqualTo(obj);
|
||||
assertThat(new ObjectIdentityImpl(mockObj)).isEqualTo(obj);
|
||||
}
|
||||
|
@ -182,6 +181,7 @@ public class ObjectIdentityImplTests {
|
|||
// ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
|
@ -191,9 +191,11 @@ public class ObjectIdentityImplTests {
|
|||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MockOtherIdDomainObject {
|
||||
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
|
@ -203,5 +205,7 @@ public class ObjectIdentityImplTests {
|
|||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,5 +56,7 @@ public class ObjectIdentityRetrievalStrategyImplTests {
|
|||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,13 +45,9 @@ public class PermissionTests {
|
|||
public void expectedIntegerValues() {
|
||||
assertThat(BasePermission.READ.getMask()).isEqualTo(1);
|
||||
assertThat(BasePermission.ADMINISTRATION.getMask()).isEqualTo(16);
|
||||
assertThat(
|
||||
new CumulativePermission().set(BasePermission.READ)
|
||||
.set(BasePermission.WRITE).set(BasePermission.CREATE).getMask())
|
||||
.isEqualTo(7);
|
||||
assertThat(
|
||||
new CumulativePermission().set(BasePermission.READ)
|
||||
.set(BasePermission.ADMINISTRATION).getMask())
|
||||
assertThat(new CumulativePermission().set(BasePermission.READ).set(BasePermission.WRITE)
|
||||
.set(BasePermission.CREATE).getMask()).isEqualTo(7);
|
||||
assertThat(new CumulativePermission().set(BasePermission.READ).set(BasePermission.ADMINISTRATION).getMask())
|
||||
.isEqualTo(17);
|
||||
}
|
||||
|
||||
|
@ -65,33 +61,28 @@ public class PermissionTests {
|
|||
public void stringConversion() {
|
||||
permissionFactory.registerPublicPermissions(SpecialPermission.class);
|
||||
|
||||
assertThat(BasePermission.READ.toString())
|
||||
.isEqualTo("BasePermission[...............................R=1]");
|
||||
assertThat(BasePermission.READ.toString()).isEqualTo("BasePermission[...............................R=1]");
|
||||
|
||||
assertThat(
|
||||
BasePermission.ADMINISTRATION.toString())
|
||||
assertThat(BasePermission.ADMINISTRATION.toString())
|
||||
.isEqualTo("BasePermission[...........................A....=16]");
|
||||
|
||||
assertThat(
|
||||
new CumulativePermission().set(BasePermission.READ).toString())
|
||||
assertThat(new CumulativePermission().set(BasePermission.READ).toString())
|
||||
.isEqualTo("CumulativePermission[...............................R=1]");
|
||||
|
||||
assertThat(new CumulativePermission().set(SpecialPermission.ENTER)
|
||||
.set(BasePermission.ADMINISTRATION).toString())
|
||||
assertThat(
|
||||
new CumulativePermission().set(SpecialPermission.ENTER).set(BasePermission.ADMINISTRATION).toString())
|
||||
.isEqualTo("CumulativePermission[..........................EA....=48]");
|
||||
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION)
|
||||
.set(BasePermission.READ).toString())
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString())
|
||||
.isEqualTo("CumulativePermission[...........................A...R=17]");
|
||||
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION)
|
||||
.set(BasePermission.READ).clear(BasePermission.ADMINISTRATION)
|
||||
.toString())
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ)
|
||||
.clear(BasePermission.ADMINISTRATION).toString())
|
||||
.isEqualTo("CumulativePermission[...............................R=1]");
|
||||
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION)
|
||||
.set(BasePermission.READ).clear(BasePermission.ADMINISTRATION)
|
||||
.clear(BasePermission.READ).toString())
|
||||
assertThat(new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ)
|
||||
.clear(BasePermission.ADMINISTRATION).clear(BasePermission.READ).toString())
|
||||
.isEqualTo("CumulativePermission[................................=0]");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,10 +23,13 @@ import org.springframework.security.acls.model.Permission;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class SpecialPermission extends BasePermission {
|
||||
|
||||
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
|
||||
|
||||
public static final Permission LEAVE = new SpecialPermission(1 << 6, 'L');
|
||||
|
||||
protected SpecialPermission(int mask, char code) {
|
||||
super(mask, code);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,15 +47,20 @@ import javax.sql.DataSource;
|
|||
public abstract class AbstractBasicLookupStrategyTests {
|
||||
|
||||
protected static final Sid BEN_SID = new PrincipalSid("ben");
|
||||
|
||||
protected static final String TARGET_CLASS = TargetObject.class.getName();
|
||||
|
||||
protected static final String TARGET_CLASS_WITH_UUID = TargetObjectWithUUID.class.getName();
|
||||
|
||||
protected static final UUID OBJECT_IDENTITY_UUID = UUID.randomUUID();
|
||||
|
||||
protected static final Long OBJECT_IDENTITY_LONG_AS_UUID = 110L;
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private BasicLookupStrategy strategy;
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
// ~ Methods
|
||||
|
@ -99,17 +104,14 @@ public abstract class AbstractBasicLookupStrategyTests {
|
|||
}
|
||||
|
||||
protected AclAuthorizationStrategy aclAuthStrategy() {
|
||||
return new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"));
|
||||
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"));
|
||||
}
|
||||
|
||||
protected EhCacheBasedAclCache aclCache() {
|
||||
return new EhCacheBasedAclCache(getCache(),
|
||||
new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
|
||||
return new EhCacheBasedAclCache(getCache(), new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
|
||||
new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void emptyDatabase() {
|
||||
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 9;"
|
||||
|
@ -302,7 +304,8 @@ public abstract class AbstractBasicLookupStrategyTests {
|
|||
try {
|
||||
foundAcls = strategy.readAclsById(allOids, sids);
|
||||
|
||||
} catch (NotFoundException notExpected) {
|
||||
}
|
||||
catch (NotFoundException notExpected) {
|
||||
fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -34,17 +33,21 @@ import static org.mockito.BDDMockito.given;
|
|||
|
||||
/**
|
||||
* Tests for {@link AclClassIdUtils}.
|
||||
*
|
||||
* @author paulwheeler
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AclClassIdUtilsTests {
|
||||
|
||||
private static final Long DEFAULT_IDENTIFIER = 999L;
|
||||
|
||||
private static final BigInteger BIGINT_IDENTIFIER = new BigInteger("999");
|
||||
|
||||
private static final String DEFAULT_IDENTIFIER_AS_STRING = DEFAULT_IDENTIFIER.toString();
|
||||
|
||||
@Mock
|
||||
private ResultSet resultSet;
|
||||
|
||||
@Mock
|
||||
private ConversionService conversionService;
|
||||
|
||||
|
@ -172,4 +175,5 @@ public class AclClassIdUtilsTests {
|
|||
// when
|
||||
aclClassIdUtils.setConversionService(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||
* @author Paul Wheeler
|
||||
*/
|
||||
public class BasicLookupStrategyTests extends AbstractBasicLookupStrategyTests {
|
||||
private static final BasicLookupStrategyTestsDbHelper DATABASE_HELPER = new BasicLookupStrategyTestsDbHelper();
|
||||
|
||||
private static final BasicLookupStrategyTestsDbHelper DATABASE_HELPER = new BasicLookupStrategyTestsDbHelper();
|
||||
|
||||
@BeforeClass
|
||||
public static void createDatabase() throws Exception {
|
||||
|
@ -50,4 +50,5 @@ public class BasicLookupStrategyTests extends AbstractBasicLookupStrategyTests {
|
|||
public DataSource getDataSource() {
|
||||
return DATABASE_HELPER.getDataSource();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,15 +23,20 @@ import org.springframework.util.FileCopyUtils;
|
|||
|
||||
/**
|
||||
* Helper class to initialize the database for BasicLookupStrategyTests.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @author Paul Wheeler
|
||||
*/
|
||||
public class BasicLookupStrategyTestsDbHelper {
|
||||
|
||||
private static final String ACL_SCHEMA_SQL_FILE = "createAclSchema.sql";
|
||||
|
||||
private static final String ACL_SCHEMA_SQL_FILE_WITH_ACL_CLASS_ID = "createAclSchemaWithAclClassIdType.sql";
|
||||
|
||||
private SingleConnectionDataSource dataSource;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private boolean withAclClassIdType;
|
||||
|
||||
public BasicLookupStrategyTestsDbHelper() {
|
||||
|
@ -48,7 +53,8 @@ public class BasicLookupStrategyTestsDbHelper {
|
|||
if (!withAclClassIdType) {
|
||||
connectionUrl = "jdbc:hsqldb:mem:lookupstrategytest";
|
||||
sqlClassPathResource = ACL_SCHEMA_SQL_FILE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
connectionUrl = "jdbc:hsqldb:mem:lookupstrategytestWithAclClassIdType";
|
||||
sqlClassPathResource = ACL_SCHEMA_SQL_FILE_WITH_ACL_CLASS_ID;
|
||||
|
||||
|
@ -69,4 +75,5 @@ public class BasicLookupStrategyTestsDbHelper {
|
|||
public SingleConnectionDataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -79,8 +79,7 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
|||
|
||||
@Before
|
||||
public void populateDatabaseForAclClassTypeTests() {
|
||||
String query = "INSERT INTO acl_class(ID,CLASS,CLASS_ID_TYPE) VALUES (3,'"
|
||||
+ TARGET_CLASS_WITH_UUID
|
||||
String query = "INSERT INTO acl_class(ID,CLASS,CLASS_ID_TYPE) VALUES (3,'" + TARGET_CLASS_WITH_UUID
|
||||
+ "', 'java.util.UUID');"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,3,'"
|
||||
+ OBJECT_IDENTITY_UUID.toString() + "',null,1,1);"
|
||||
|
@ -94,7 +93,8 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
|||
@Test
|
||||
public void testReadObjectIdentityUsingUuidType() {
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, OBJECT_IDENTITY_UUID);
|
||||
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid),
|
||||
Arrays.asList(BEN_SID));
|
||||
Assert.assertEquals(1, foundAcls.size());
|
||||
Assert.assertNotNull(foundAcls.get(oid));
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
|||
@Test
|
||||
public void testReadObjectIdentityUsingLongTypeWithConversionServiceEnabled() {
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
Map<ObjectIdentity, Acl> foundAcls = uuidEnabledStrategy.readAclsById(Arrays.asList(oid),
|
||||
Arrays.asList(BEN_SID));
|
||||
Assert.assertEquals(1, foundAcls.size());
|
||||
Assert.assertNotNull(foundAcls.get(oid));
|
||||
}
|
||||
|
@ -112,4 +113,5 @@ public class BasicLookupStrategyWithAclClassTypeTests extends AbstractBasicLooku
|
|||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, OBJECT_IDENTITY_LONG_AS_UUID);
|
||||
uuidEnabledStrategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.sql.DataSource;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public class DatabaseSeeder {
|
||||
|
||||
// ~ Constructors
|
||||
// ===================================================================================================
|
||||
|
||||
|
@ -43,4 +44,5 @@ public class DatabaseSeeder {
|
|||
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
template.execute(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,10 +54,12 @@ import org.springframework.test.util.ReflectionTestUtils;
|
|||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
@Mock
|
||||
private Ehcache cache;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Element> element;
|
||||
|
||||
|
@ -67,17 +69,15 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
@Before
|
||||
public void setup() {
|
||||
myCache = new EhCacheBasedAclCache(cache, new DefaultPermissionGrantingStrategy(
|
||||
new ConsoleAuditLogger()), new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_USER")));
|
||||
myCache = new EhCacheBasedAclCache(cache, new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
|
||||
new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
|
||||
acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
acl = new AclImpl(identity, 1L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -87,9 +87,8 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() {
|
||||
new EhCacheBasedAclCache(null, new DefaultPermissionGrantingStrategy(
|
||||
new ConsoleAuditLogger()), new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_USER")));
|
||||
new EhCacheBasedAclCache(null, new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()),
|
||||
new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -152,12 +151,10 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
assertThat(retrieved).isEqualTo(acl);
|
||||
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy",
|
||||
retrieved);
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved);
|
||||
assertThat(retrieved1).isNull();
|
||||
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue(
|
||||
"permissionGrantingStrategy", retrieved);
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue("permissionGrantingStrategy", retrieved);
|
||||
assertThat(retrieved2).isNull();
|
||||
}
|
||||
|
||||
|
@ -175,25 +172,21 @@ public class EhCacheBasedAclCacheTests {
|
|||
verify(cache, times(2)).put(element.capture());
|
||||
assertThat(element.getValue().getKey()).isEqualTo(acl.getId());
|
||||
assertThat(element.getValue().getObjectValue()).isEqualTo(acl);
|
||||
assertThat(element.getAllValues().get(0).getKey()).isEqualTo(
|
||||
acl.getObjectIdentity());
|
||||
assertThat(element.getAllValues().get(0).getKey()).isEqualTo(acl.getObjectIdentity());
|
||||
assertThat(element.getAllValues().get(0).getObjectValue()).isEqualTo(acl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putInCacheAclWithParent() {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
2L);
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, 2L);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, 2L,
|
||||
aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, 2L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
@ -233,10 +226,8 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getId());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy"))
|
||||
.isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy"))
|
||||
.isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -248,8 +239,7 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
@Test
|
||||
public void getFromCacheObjectIdentityPopulatesTransient() {
|
||||
when(cache.get(acl.getObjectIdentity()))
|
||||
.thenReturn(new Element(acl.getId(), acl));
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(), acl));
|
||||
|
||||
myCache.putInCache(acl);
|
||||
|
||||
|
@ -258,16 +248,13 @@ public class EhCacheBasedAclCacheTests {
|
|||
|
||||
MutableAcl fromCache = myCache.getFromCache(acl.getObjectIdentity());
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy"))
|
||||
.isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy"))
|
||||
.isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(fromCache, "permissionGrantingStrategy")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evictCacheSerializable() {
|
||||
when(cache.get(acl.getObjectIdentity()))
|
||||
.thenReturn(new Element(acl.getId(), acl));
|
||||
when(cache.get(acl.getObjectIdentity())).thenReturn(new Element(acl.getId(), acl));
|
||||
|
||||
myCache.evictFromCache(acl.getObjectIdentity());
|
||||
|
||||
|
@ -284,4 +271,5 @@ public class EhCacheBasedAclCacheTests {
|
|||
verify(cache).remove(acl.getId());
|
||||
verify(cache).remove(acl.getObjectIdentity());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,8 +41,7 @@ import static org.mockito.ArgumentMatchers.*;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Unit and Integration tests the ACL JdbcAclService using an
|
||||
* in-memory database.
|
||||
* Unit and Integration tests the ACL JdbcAclService using an in-memory database.
|
||||
*
|
||||
* @author Nena Raab
|
||||
*/
|
||||
|
@ -61,6 +60,7 @@ public class JdbcAclServiceTests {
|
|||
JdbcOperations jdbcOperations;
|
||||
|
||||
private JdbcAclService aclServiceIntegration;
|
||||
|
||||
private JdbcAclService aclService;
|
||||
|
||||
@Before
|
||||
|
@ -72,9 +72,7 @@ public class JdbcAclServiceTests {
|
|||
@Before
|
||||
public void setUpEmbeddedDatabase() {
|
||||
embeddedDatabase = new EmbeddedDatabaseBuilder()//
|
||||
.addScript("createAclSchemaWithAclClassIdType.sql")
|
||||
.addScript("db/sql/test_data_hierarchy.sql")
|
||||
.build();
|
||||
.addScript("createAclSchemaWithAclClassIdType.sql").addScript("db/sql/test_data_hierarchy.sql").build();
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -86,9 +84,7 @@ public class JdbcAclServiceTests {
|
|||
@Test(expected = NotFoundException.class)
|
||||
public void readAclByIdMissingAcl() {
|
||||
Map<ObjectIdentity, Acl> result = new HashMap<>();
|
||||
when(
|
||||
lookupStrategy.readAclsById(anyList(),
|
||||
anyList())).thenReturn(result);
|
||||
when(lookupStrategy.readAclsById(anyList(), anyList())).thenReturn(result);
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(Object.class, 1);
|
||||
List<Sid> sids = Arrays.<Sid>asList(new PrincipalSid("user"));
|
||||
|
||||
|
@ -99,10 +95,8 @@ public class JdbcAclServiceTests {
|
|||
public void findOneChildren() {
|
||||
List<ObjectIdentity> result = new ArrayList<>();
|
||||
result.add(new ObjectIdentityImpl(Object.class, "5577"));
|
||||
Object[] args = {"1", "org.springframework.security.acls.jdbc.JdbcAclServiceTests$MockLongIdDomainObject"};
|
||||
when(
|
||||
jdbcOperations.query(anyString(),
|
||||
aryEq(args), any(RowMapper.class))).thenReturn(result);
|
||||
Object[] args = { "1", "org.springframework.security.acls.jdbc.JdbcAclServiceTests$MockLongIdDomainObject" };
|
||||
when(jdbcOperations.query(anyString(), aryEq(args), any(RowMapper.class))).thenReturn(result);
|
||||
ObjectIdentity objectIdentity = new ObjectIdentityImpl(MockLongIdDomainObject.class, 1L);
|
||||
|
||||
List<ObjectIdentity> objectIdentities = aclService.findChildren(objectIdentity);
|
||||
|
@ -170,10 +164,12 @@ public class JdbcAclServiceTests {
|
|||
List<ObjectIdentity> objectIdentities = aclServiceIntegration.findChildren(objectIdentity);
|
||||
assertThat(objectIdentities.size()).isEqualTo(1);
|
||||
assertThat(objectIdentities.get(0).getType()).isEqualTo("costcenter");
|
||||
assertThat(objectIdentities.get(0).getIdentifier()).isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
|
||||
assertThat(objectIdentities.get(0).getIdentifier())
|
||||
.isEqualTo(UUID.fromString("25d93b3f-c3aa-4814-9d5e-c7c96ced7762"));
|
||||
}
|
||||
|
||||
private class MockLongIdDomainObject {
|
||||
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
|
@ -183,9 +179,11 @@ public class JdbcAclServiceTests {
|
|||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MockUntypedIdDomainObject {
|
||||
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
|
@ -195,5 +193,7 @@ public class JdbcAclServiceTests {
|
|||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,36 +62,38 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @author Andrei Stefan
|
||||
*/
|
||||
@ContextConfiguration(locations = { "/jdbcMutableAclServiceTests-context.xml" })
|
||||
public class JdbcMutableAclServiceTests extends
|
||||
AbstractTransactionalJUnit4SpringContextTests {
|
||||
public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
|
||||
// ~ Constant fields
|
||||
// ================================================================================================
|
||||
|
||||
private static final String TARGET_CLASS = TargetObject.class.getName();
|
||||
|
||||
private final Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_ADMINISTRATOR");
|
||||
private final Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_ADMINISTRATOR");
|
||||
|
||||
public static final String SELECT_ALL_CLASSES = "SELECT * FROM acl_class WHERE class = ?";
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
100L);
|
||||
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
101L);
|
||||
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
102L);
|
||||
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
|
||||
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, 101L);
|
||||
|
||||
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, 102L);
|
||||
|
||||
@Autowired
|
||||
private JdbcMutableAclService jdbcMutableAclService;
|
||||
|
||||
@Autowired
|
||||
private AclCache aclCache;
|
||||
|
||||
@Autowired
|
||||
private LookupStrategy lookupStrategy;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
|
@ -166,8 +168,8 @@ public class JdbcMutableAclServiceTests extends
|
|||
jdbcMutableAclService.updateAcl(child);
|
||||
|
||||
// Let's check if we can read them back correctly
|
||||
Map<ObjectIdentity, Acl> map = jdbcMutableAclService.readAclsById(Arrays.asList(
|
||||
getTopParentOid(), getMiddleParentOid(), getChildOid()));
|
||||
Map<ObjectIdentity, Acl> map = jdbcMutableAclService
|
||||
.readAclsById(Arrays.asList(getTopParentOid(), getMiddleParentOid(), getChildOid()));
|
||||
assertThat(map).hasSize(3);
|
||||
|
||||
// Replace our current objects with their retrieved versions
|
||||
|
@ -257,7 +259,8 @@ public class JdbcMutableAclServiceTests extends
|
|||
}
|
||||
|
||||
// Check the permissions are as they should be
|
||||
assertThat(child.isGranted(delete, pSid, true)).isFalse(); // as earlier permission
|
||||
assertThat(child.isGranted(delete, pSid, true)).isFalse(); // as earlier
|
||||
// permission
|
||||
// overrode
|
||||
assertThat(child.isGranted(Arrays.asList(BasePermission.CREATE), pSid, true)).isTrue();
|
||||
|
||||
|
@ -360,8 +363,7 @@ public class JdbcMutableAclServiceTests extends
|
|||
@Transactional
|
||||
public void createAclForADuplicateDomainObject() {
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
ObjectIdentity duplicateOid = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
100L);
|
||||
ObjectIdentity duplicateOid = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
jdbcMutableAclService.createAcl(duplicateOid);
|
||||
// Try to add the same object second time
|
||||
try {
|
||||
|
@ -419,11 +421,8 @@ public class JdbcMutableAclServiceTests extends
|
|||
|
||||
// Remove the child and check all related database rows were removed accordingly
|
||||
jdbcMutableAclService.deleteAcl(getChildOid(), false);
|
||||
assertThat(
|
||||
jdbcTemplate.queryForList(SELECT_ALL_CLASSES,
|
||||
new Object[] { getTargetClass() })).hasSize(1);
|
||||
assertThat(jdbcTemplate.queryForList("select * from acl_object_identity")
|
||||
).isEmpty();
|
||||
assertThat(jdbcTemplate.queryForList(SELECT_ALL_CLASSES, new Object[] { getTargetClass() })).hasSize(1);
|
||||
assertThat(jdbcTemplate.queryForList("select * from acl_object_identity")).isEmpty();
|
||||
assertThat(jdbcTemplate.queryForList("select * from acl_entry")).isEmpty();
|
||||
|
||||
// Check the cache
|
||||
|
@ -439,8 +438,7 @@ public class JdbcMutableAclServiceTests extends
|
|||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, 101);
|
||||
jdbcMutableAclService.createAcl(oid);
|
||||
|
||||
assertThat(jdbcMutableAclService.readAclById(new ObjectIdentityImpl(
|
||||
TARGET_CLASS, 101L))).isNotNull();
|
||||
assertThat(jdbcMutableAclService.readAclById(new ObjectIdentityImpl(TARGET_CLASS, 101L))).isNotNull();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,8 +447,7 @@ public class JdbcMutableAclServiceTests extends
|
|||
@Test
|
||||
@Transactional
|
||||
public void childrenAreClearedFromCacheWhenParentIsUpdated() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_ADMINISTRATOR");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_ADMINISTRATOR");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
|
@ -474,7 +471,8 @@ public class JdbcMutableAclServiceTests extends
|
|||
child = (MutableAcl) jdbcMutableAclService.readAclById(childOid);
|
||||
parent = (MutableAcl) child.getParentAcl();
|
||||
|
||||
assertThat(parent.getEntries()).hasSize(2).withFailMessage("Fails because child has a stale reference to its parent");
|
||||
assertThat(parent.getEntries()).hasSize(2)
|
||||
.withFailMessage("Fails because child has a stale reference to its parent");
|
||||
assertThat(parent.getEntries().get(0).getPermission().getMask()).isEqualTo(1);
|
||||
assertThat(parent.getEntries().get(0).getSid()).isEqualTo(new PrincipalSid("ben"));
|
||||
assertThat(parent.getEntries().get(1).getPermission().getMask()).isEqualTo(1);
|
||||
|
@ -487,34 +485,28 @@ public class JdbcMutableAclServiceTests extends
|
|||
@Test
|
||||
@Transactional
|
||||
public void childrenAreClearedFromCacheWhenParentisUpdated2() {
|
||||
Authentication auth = new TestingAuthenticationToken("system", "secret",
|
||||
"ROLE_IGNORED");
|
||||
Authentication auth = new TestingAuthenticationToken("system", "secret", "ROLE_IGNORED");
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
ObjectIdentityImpl rootObject = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
1L);
|
||||
ObjectIdentityImpl rootObject = new ObjectIdentityImpl(TARGET_CLASS, 1L);
|
||||
|
||||
MutableAcl parent = jdbcMutableAclService.createAcl(rootObject);
|
||||
MutableAcl child = jdbcMutableAclService.createAcl(new ObjectIdentityImpl(
|
||||
TARGET_CLASS, 2L));
|
||||
MutableAcl child = jdbcMutableAclService.createAcl(new ObjectIdentityImpl(TARGET_CLASS, 2L));
|
||||
child.setParent(parent);
|
||||
jdbcMutableAclService.updateAcl(child);
|
||||
|
||||
parent.insertAce(0, BasePermission.ADMINISTRATION, new GrantedAuthoritySid(
|
||||
"ROLE_ADMINISTRATOR"), true);
|
||||
parent.insertAce(0, BasePermission.ADMINISTRATION, new GrantedAuthoritySid("ROLE_ADMINISTRATOR"), true);
|
||||
jdbcMutableAclService.updateAcl(parent);
|
||||
|
||||
parent.insertAce(1, BasePermission.DELETE, new PrincipalSid("terry"), true);
|
||||
jdbcMutableAclService.updateAcl(parent);
|
||||
|
||||
child = (MutableAcl) jdbcMutableAclService.readAclById(new ObjectIdentityImpl(
|
||||
TARGET_CLASS, 2L));
|
||||
child = (MutableAcl) jdbcMutableAclService.readAclById(new ObjectIdentityImpl(TARGET_CLASS, 2L));
|
||||
|
||||
parent = (MutableAcl) child.getParentAcl();
|
||||
|
||||
assertThat(parent.getEntries()).hasSize(2);
|
||||
assertThat(parent.getEntries().get(0).getPermission().getMask()).isEqualTo(16);
|
||||
assertThat(parent.getEntries()
|
||||
.get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_ADMINISTRATOR"));
|
||||
assertThat(parent.getEntries().get(0).getSid()).isEqualTo(new GrantedAuthoritySid("ROLE_ADMINISTRATOR"));
|
||||
assertThat(parent.getEntries().get(1).getPermission().getMask()).isEqualTo(8);
|
||||
assertThat(parent.getEntries().get(1).getSid()).isEqualTo(new PrincipalSid("terry"));
|
||||
}
|
||||
|
@ -522,18 +514,15 @@ public class JdbcMutableAclServiceTests extends
|
|||
@Test
|
||||
@Transactional
|
||||
public void cumulativePermissions() {
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored",
|
||||
"ROLE_ADMINISTRATOR");
|
||||
Authentication auth = new TestingAuthenticationToken("ben", "ignored", "ROLE_ADMINISTRATOR");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
110L);
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, 110L);
|
||||
MutableAcl topParent = jdbcMutableAclService.createAcl(topParentOid);
|
||||
|
||||
// Add an ACE permission entry
|
||||
Permission cm = new CumulativePermission().set(BasePermission.READ).set(
|
||||
BasePermission.ADMINISTRATION);
|
||||
Permission cm = new CumulativePermission().set(BasePermission.READ).set(BasePermission.ADMINISTRATION);
|
||||
assertThat(cm.getMask()).isEqualTo(17);
|
||||
Sid benSid = new PrincipalSid(auth);
|
||||
topParent.insertAce(0, cm, benSid, true);
|
||||
|
@ -551,15 +540,12 @@ public class JdbcMutableAclServiceTests extends
|
|||
|
||||
@Test
|
||||
public void testProcessingCustomSid() {
|
||||
CustomJdbcMutableAclService customJdbcMutableAclService = spy(new CustomJdbcMutableAclService(
|
||||
dataSource, lookupStrategy, aclCache));
|
||||
CustomJdbcMutableAclService customJdbcMutableAclService = spy(
|
||||
new CustomJdbcMutableAclService(dataSource, lookupStrategy, aclCache));
|
||||
CustomSid customSid = new CustomSid("Custom sid");
|
||||
when(
|
||||
customJdbcMutableAclService.createOrRetrieveSidPrimaryKey("Custom sid",
|
||||
false, false)).thenReturn(1L);
|
||||
when(customJdbcMutableAclService.createOrRetrieveSidPrimaryKey("Custom sid", false, false)).thenReturn(1L);
|
||||
|
||||
Long result = customJdbcMutableAclService.createOrRetrieveSidPrimaryKey(
|
||||
customSid, false);
|
||||
Long result = customJdbcMutableAclService.createOrRetrieveSidPrimaryKey(customSid, false);
|
||||
|
||||
assertThat(new Long(1L)).isEqualTo(result);
|
||||
}
|
||||
|
@ -570,8 +556,7 @@ public class JdbcMutableAclServiceTests extends
|
|||
*/
|
||||
private class CustomJdbcMutableAclService extends JdbcMutableAclService {
|
||||
|
||||
private CustomJdbcMutableAclService(DataSource dataSource,
|
||||
LookupStrategy lookupStrategy, AclCache aclCache) {
|
||||
private CustomJdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) {
|
||||
super(dataSource, lookupStrategy, aclCache);
|
||||
}
|
||||
|
||||
|
@ -591,6 +576,7 @@ public class JdbcMutableAclServiceTests extends
|
|||
}
|
||||
return createOrRetrieveSidPrimaryKey(sidName, isPrincipal, allowCreate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Authentication getAuth() {
|
||||
|
@ -600,4 +586,5 @@ public class JdbcMutableAclServiceTests extends
|
|||
protected JdbcMutableAclService getJdbcMutableAclService() {
|
||||
return jdbcMutableAclService;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,20 +28,21 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Integration tests the ACL system using ACL class id type of UUID and using an in-memory database.
|
||||
* Integration tests the ACL system using ACL class id type of UUID and using an in-memory
|
||||
* database.
|
||||
*
|
||||
* @author Paul Wheeler
|
||||
*/
|
||||
@ContextConfiguration(locations = {"/jdbcMutableAclServiceTestsWithAclClass-context.xml"})
|
||||
@ContextConfiguration(locations = { "/jdbcMutableAclServiceTestsWithAclClass-context.xml" })
|
||||
public class JdbcMutableAclServiceTestsWithAclClassId extends JdbcMutableAclServiceTests {
|
||||
|
||||
private static final String TARGET_CLASS_WITH_UUID = TargetObjectWithUUID.class.getName();
|
||||
|
||||
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
|
||||
UUID.randomUUID());
|
||||
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
|
||||
UUID.randomUUID());
|
||||
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID,
|
||||
UUID.randomUUID());
|
||||
private final ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, UUID.randomUUID());
|
||||
|
||||
private final ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, UUID.randomUUID());
|
||||
|
||||
private final ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, UUID.randomUUID());
|
||||
|
||||
@Override
|
||||
protected String getSqlClassPathResource() {
|
||||
|
@ -77,7 +78,8 @@ public class JdbcMutableAclServiceTestsWithAclClassId extends JdbcMutableAclServ
|
|||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, id);
|
||||
getJdbcMutableAclService().createAcl(oid);
|
||||
|
||||
assertThat(getJdbcMutableAclService().readAclById(new ObjectIdentityImpl(
|
||||
TARGET_CLASS_WITH_UUID, id))).isNotNull();
|
||||
assertThat(getJdbcMutableAclService().readAclById(new ObjectIdentityImpl(TARGET_CLASS_WITH_UUID, id)))
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.*;
|
|||
* @author Marten Deinum
|
||||
*/
|
||||
public class SpringCacheBasedAclCacheTests {
|
||||
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
@ -76,16 +77,14 @@ public class SpringCacheBasedAclCacheTests {
|
|||
Map realCache = (Map) cache.getNativeCache();
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 100L);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(
|
||||
auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache,
|
||||
permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
|
||||
auditLogger);
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy,
|
||||
aclAuthorizationStrategy);
|
||||
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
assertThat(realCache).isEmpty();
|
||||
myCache.putInCache(acl);
|
||||
|
@ -96,8 +95,7 @@ public class SpringCacheBasedAclCacheTests {
|
|||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, 101L);
|
||||
MutableAcl acl2 = new AclImpl(identity2, 2L,
|
||||
aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl acl2 = new AclImpl(identity2, 2L, aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
|
||||
|
@ -123,28 +121,23 @@ public class SpringCacheBasedAclCacheTests {
|
|||
Cache cache = getCache();
|
||||
Map realCache = (Map) cache.getNativeCache();
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
"ROLE_GENERAL");
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, 1L);
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS,
|
||||
2L);
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, 2L);
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority(
|
||||
"ROLE_AUDITING"), new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(
|
||||
auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache,
|
||||
permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy,
|
||||
aclAuthorizationStrategy);
|
||||
|
||||
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy,
|
||||
auditLogger);
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, 2L,
|
||||
aclAuthorizationStrategy, auditLogger);
|
||||
MutableAcl acl = new AclImpl(identity, 1L, aclAuthorizationStrategy, auditLogger);
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, 2L, aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
|
@ -156,16 +149,14 @@ public class SpringCacheBasedAclCacheTests {
|
|||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(1L);
|
||||
assertThat(aclFromCache).isEqualTo(acl);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertThat(FieldUtils.getFieldValue(aclFromCache.getParentAcl(),
|
||||
"aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(FieldUtils.getFieldValue(aclFromCache.getParentAcl(),
|
||||
"permissionGrantingStrategy")).isNotNull();
|
||||
assertThat(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "permissionGrantingStrategy")).isNotNull();
|
||||
assertThat(myCache.getFromCache(identity)).isEqualTo(acl);
|
||||
assertThat(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(2L);
|
||||
assertThat(parentAclFromCache).isEqualTo(parentAcl);
|
||||
assertThat(FieldUtils.getFieldValue(parentAclFromCache,
|
||||
"aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy")).isNotNull();
|
||||
assertThat(myCache.getFromCache(identityParent)).isEqualTo(parentAcl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.springframework.security.acls.model.Sid;
|
|||
|
||||
/**
|
||||
* This class is example of custom {@link Sid} implementation
|
||||
*
|
||||
* @author Mikhail Stryzhonok
|
||||
*/
|
||||
public class CustomSid implements Sid {
|
||||
|
@ -36,4 +37,5 @@ public class CustomSid implements Sid {
|
|||
public void setSid(String sid) {
|
||||
this.sid = sid;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SidRetrievalStrategyTests {
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password",
|
||||
"A", "B", "C");
|
||||
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
@ -69,8 +69,7 @@ public class SidRetrievalStrategyTests {
|
|||
public void roleHierarchyIsUsedWhenSet() {
|
||||
RoleHierarchy rh = mock(RoleHierarchy.class);
|
||||
List rhAuthorities = AuthorityUtils.createAuthorityList("D");
|
||||
when(rh.getReachableGrantedAuthorities(anyCollection()))
|
||||
.thenReturn(rhAuthorities);
|
||||
when(rh.getReachableGrantedAuthorities(anyCollection())).thenReturn(rhAuthorities);
|
||||
SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
|
||||
|
||||
List<Sid> sids = strat.getSids(authentication);
|
||||
|
@ -79,4 +78,5 @@ public class SidRetrievalStrategyTests {
|
|||
assertThat(sids.get(0) instanceof PrincipalSid).isTrue();
|
||||
assertThat(((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority()).isEqualTo("D");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,16 +67,14 @@ public class SidTests {
|
|||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken(null,
|
||||
"password");
|
||||
Authentication authentication = new TestingAuthenticationToken(null, "password");
|
||||
new PrincipalSid(authentication);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe",
|
||||
"password");
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
new PrincipalSid(authentication);
|
||||
// throws no exception
|
||||
}
|
||||
|
@ -140,18 +138,15 @@ public class SidTests {
|
|||
|
||||
@Test
|
||||
public void testPrincipalSidEquals() {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe",
|
||||
"password");
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
assertThat(principalSid.equals(null)).isFalse();
|
||||
assertThat(principalSid.equals("DIFFERENT_TYPE_OBJECT")).isFalse();
|
||||
assertThat(principalSid.equals(principalSid)).isTrue();
|
||||
assertThat(principalSid.equals(new PrincipalSid(authentication))).isTrue();
|
||||
assertThat(principalSid.equals(new PrincipalSid(
|
||||
new TestingAuthenticationToken("johndoe", null)))).isTrue();
|
||||
assertThat(principalSid.equals(new PrincipalSid(
|
||||
new TestingAuthenticationToken("scott", null)))).isFalse();
|
||||
assertThat(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("johndoe", null)))).isTrue();
|
||||
assertThat(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("scott", null)))).isFalse();
|
||||
assertThat(principalSid.equals(new PrincipalSid("johndoe"))).isTrue();
|
||||
assertThat(principalSid.equals(new PrincipalSid("scott"))).isFalse();
|
||||
}
|
||||
|
@ -165,27 +160,22 @@ public class SidTests {
|
|||
assertThat(gaSid.equals("DIFFERENT_TYPE_OBJECT")).isFalse();
|
||||
assertThat(gaSid.equals(gaSid)).isTrue();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid(ga))).isTrue();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid(
|
||||
new SimpleGrantedAuthority("ROLE_TEST")))).isTrue();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid(
|
||||
new SimpleGrantedAuthority("ROLE_NOT_EQUAL")))).isFalse();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST")))).isTrue();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_NOT_EQUAL")))).isFalse();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid("ROLE_TEST"))).isTrue();
|
||||
assertThat(gaSid.equals(new GrantedAuthoritySid("ROLE_NOT_EQUAL"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrincipalSidHashCode() {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe",
|
||||
"password");
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
assertThat(principalSid.hashCode()).isEqualTo("johndoe".hashCode());
|
||||
assertThat(principalSid.hashCode()).isEqualTo(
|
||||
new PrincipalSid("johndoe").hashCode());
|
||||
assertThat(principalSid.hashCode()).isNotEqualTo(
|
||||
new PrincipalSid("scott").hashCode());
|
||||
assertThat(principalSid.hashCode()).isNotEqualTo(new PrincipalSid(
|
||||
new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
assertThat(principalSid.hashCode()).isEqualTo(new PrincipalSid("johndoe").hashCode());
|
||||
assertThat(principalSid.hashCode()).isNotEqualTo(new PrincipalSid("scott").hashCode());
|
||||
assertThat(principalSid.hashCode())
|
||||
.isNotEqualTo(new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -194,18 +184,15 @@ public class SidTests {
|
|||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
assertThat(gaSid.hashCode()).isEqualTo("ROLE_TEST".hashCode());
|
||||
assertThat(gaSid.hashCode()).isEqualTo(
|
||||
new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
assertThat(gaSid.hashCode()).isNotEqualTo(
|
||||
new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
assertThat(gaSid.hashCode()).isNotEqualTo(new GrantedAuthoritySid(
|
||||
new SimpleGrantedAuthority("ROLE_TEST_2")).hashCode());
|
||||
assertThat(gaSid.hashCode()).isEqualTo(new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
assertThat(gaSid.hashCode()).isNotEqualTo(new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
assertThat(gaSid.hashCode())
|
||||
.isNotEqualTo(new GrantedAuthoritySid(new SimpleGrantedAuthority("ROLE_TEST_2")).hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetters() {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe",
|
||||
"password");
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
PrincipalSid principalSid = new PrincipalSid(authentication);
|
||||
GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_TEST");
|
||||
GrantedAuthoritySid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
@ -243,6 +230,7 @@ public class SidTests {
|
|||
}
|
||||
|
||||
static class CustomAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
private CustomToken principal;
|
||||
|
||||
CustomAuthenticationToken(CustomToken principal, Collection<GrantedAuthority> authorities) {
|
||||
|
@ -264,9 +252,11 @@ public class SidTests {
|
|||
public String getName() {
|
||||
return principal.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class CustomToken {
|
||||
|
||||
private String name;
|
||||
|
||||
CustomToken(String name) {
|
||||
|
@ -276,5 +266,7 @@ public class SidTests {
|
|||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,36 +50,37 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
|
|||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @since 3.0.3
|
||||
*/
|
||||
public class AnnotationSecurityAspectTests {
|
||||
|
||||
private AffirmativeBased adm;
|
||||
|
||||
private @Mock AuthenticationManager authman;
|
||||
private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "",
|
||||
"ROLE_A");
|
||||
|
||||
private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "", "ROLE_A");
|
||||
|
||||
// private TestingAuthenticationToken bob = new TestingAuthenticationToken("bob", "",
|
||||
// "ROLE_B");
|
||||
private AspectJMethodSecurityInterceptor interceptor;
|
||||
|
||||
private SecuredImpl secured = new SecuredImpl();
|
||||
|
||||
private SecuredImplSubclass securedSub = new SecuredImplSubclass();
|
||||
|
||||
private PrePostSecured prePostSecured = new PrePostSecured();
|
||||
|
||||
@Before
|
||||
public final void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
interceptor = new AspectJMethodSecurityInterceptor();
|
||||
AccessDecisionVoter[] voters = new AccessDecisionVoter[] {
|
||||
new RoleVoter(),
|
||||
new PreInvocationAuthorizationAdviceVoter(
|
||||
new ExpressionBasedPreInvocationAdvice()) };
|
||||
adm = new AffirmativeBased(
|
||||
Arrays.<AccessDecisionVoter<? extends Object>> asList(voters));
|
||||
AccessDecisionVoter[] voters = new AccessDecisionVoter[] { new RoleVoter(),
|
||||
new PreInvocationAuthorizationAdviceVoter(new ExpressionBasedPreInvocationAdvice()) };
|
||||
adm = new AffirmativeBased(Arrays.<AccessDecisionVoter<? extends Object>>asList(voters));
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
interceptor.setAuthenticationManager(authman);
|
||||
interceptor
|
||||
.setSecurityMetadataSource(new SecuredAnnotationSecurityMetadataSource());
|
||||
interceptor.setSecurityMetadataSource(new SecuredAnnotationSecurityMetadataSource());
|
||||
AnnotationSecurityAspect secAspect = AnnotationSecurityAspect.aspectOf();
|
||||
secAspect.setSecurityInterceptor(interceptor);
|
||||
}
|
||||
|
@ -151,23 +152,25 @@ public class AnnotationSecurityAspectTests {
|
|||
|
||||
private void configureForElAnnotations() {
|
||||
DefaultMethodSecurityExpressionHandler eh = new DefaultMethodSecurityExpressionHandler();
|
||||
interceptor
|
||||
.setSecurityMetadataSource(new PrePostAnnotationSecurityMetadataSource(
|
||||
new ExpressionBasedAnnotationAttributeFactory(eh)));
|
||||
interceptor.setSecurityMetadataSource(
|
||||
new PrePostAnnotationSecurityMetadataSource(new ExpressionBasedAnnotationAttributeFactory(eh)));
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
AfterInvocationProviderManager aim = new AfterInvocationProviderManager();
|
||||
aim.setProviders(Arrays.asList(new PostInvocationAdviceProvider(
|
||||
new ExpressionBasedPostInvocationAdvice(eh))));
|
||||
aim.setProviders(Arrays.asList(new PostInvocationAdviceProvider(new ExpressionBasedPostInvocationAdvice(eh))));
|
||||
interceptor.setAfterInvocationManager(aim);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface SecuredInterface {
|
||||
|
||||
@Secured("ROLE_X")
|
||||
void securedMethod();
|
||||
|
||||
}
|
||||
|
||||
class SecuredImpl implements SecuredInterface {
|
||||
|
||||
// Not really secured because AspectJ doesn't inherit annotations from interfaces
|
||||
public void securedMethod() {
|
||||
}
|
||||
|
@ -188,18 +191,22 @@ class SecuredImpl implements SecuredInterface {
|
|||
public void publicCallsPrivate() {
|
||||
privateMethod();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SecuredImplSubclass extends SecuredImpl {
|
||||
|
||||
protected void protectedMethod() {
|
||||
}
|
||||
|
||||
public void publicCallsPrivate() {
|
||||
super.publicCallsPrivate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PrePostSecured {
|
||||
|
||||
@PreAuthorize("denyAll")
|
||||
public void denyAllMethod() {
|
||||
}
|
||||
|
@ -207,8 +214,8 @@ class PrePostSecured {
|
|||
@PostFilter("filterObject.startsWith('a')")
|
||||
public List<String> postFilterMethod() {
|
||||
ArrayList<String> objects = new ArrayList<>();
|
||||
objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine",
|
||||
"orange" }));
|
||||
objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine", "orange" }));
|
||||
return objects;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,4 +32,5 @@ public final class SamlServiceProperties extends ServiceProperties {
|
|||
super.setArtifactParameter(DEFAULT_SAML_ARTIFACT_PARAMETER);
|
||||
super.setServiceParameter(DEFAULT_SAML_SERVICE_PARAMETER);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ public class ServiceProperties implements InitializingBean {
|
|||
* <pre>
|
||||
* https://www.mycompany.com/application/login/cas
|
||||
* </pre>
|
||||
*
|
||||
* @return the URL of the service the user is authenticating to
|
||||
*/
|
||||
public final String getService() {
|
||||
|
@ -81,7 +80,6 @@ public class ServiceProperties implements InitializingBean {
|
|||
* ticket was generated as a consequence of an explicit login. High security
|
||||
* applications would probably set this to <code>true</code>. Defaults to
|
||||
* <code>false</code>, providing automated single sign on.
|
||||
*
|
||||
* @return whether to send the <code>renew</code> parameter to CAS
|
||||
*/
|
||||
public final boolean isSendRenew() {
|
||||
|
@ -103,7 +101,6 @@ public class ServiceProperties implements InitializingBean {
|
|||
/**
|
||||
* Configures the Request Parameter to look for when attempting to see if a CAS ticket
|
||||
* was sent from the server.
|
||||
*
|
||||
* @param artifactParameter the id to use. Default is "ticket".
|
||||
*/
|
||||
public final void setArtifactParameter(final String artifactParameter) {
|
||||
|
@ -113,7 +110,6 @@ public class ServiceProperties implements InitializingBean {
|
|||
/**
|
||||
* Configures the Request parameter to look for when attempting to send a request to
|
||||
* CAS.
|
||||
*
|
||||
* @return the service parameter to use. Default is "service".
|
||||
*/
|
||||
public final String getServiceParameter() {
|
||||
|
@ -132,11 +128,10 @@ public class ServiceProperties implements InitializingBean {
|
|||
* If true, then any non-null artifact (ticket) should be authenticated. Additionally,
|
||||
* the service will be determined dynamically in order to ensure the service matches
|
||||
* the expected value for this artifact.
|
||||
*
|
||||
* @param authenticateAllArtifacts
|
||||
*/
|
||||
public final void setAuthenticateAllArtifacts(
|
||||
final boolean authenticateAllArtifacts) {
|
||||
public final void setAuthenticateAllArtifacts(final boolean authenticateAllArtifacts) {
|
||||
this.authenticateAllArtifacts = authenticateAllArtifacts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,4 +53,5 @@ public final class CasAssertionAuthenticationToken extends AbstractAuthenticatio
|
|||
public Assertion getAssertion() {
|
||||
return this.assertion;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
* @author Scott Battaglia
|
||||
*/
|
||||
public class CasAuthenticationProvider implements AuthenticationProvider,
|
||||
InitializingBean, MessageSourceAware {
|
||||
public class CasAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -67,36 +67,39 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
private AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService;
|
||||
|
||||
private final UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
|
||||
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
private StatelessTicketCache statelessTicketCache = new NullStatelessTicketCache();
|
||||
|
||||
private String key;
|
||||
|
||||
private TicketValidator ticketValidator;
|
||||
|
||||
private ServiceProperties serviceProperties;
|
||||
|
||||
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(this.authenticationUserDetailsService,
|
||||
"An authenticationUserDetailsService must be set");
|
||||
Assert.notNull(this.authenticationUserDetailsService, "An authenticationUserDetailsService must be set");
|
||||
Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
|
||||
Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set");
|
||||
Assert.hasText(
|
||||
this.key,
|
||||
Assert.hasText(this.key,
|
||||
"A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
|
||||
Assert.notNull(this.messages, "A message source must be set");
|
||||
}
|
||||
|
||||
public Authentication authenticate(Authentication authentication)
|
||||
throws AuthenticationException {
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
if (!supports(authentication.getClass())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (authentication instanceof UsernamePasswordAuthenticationToken
|
||||
&& (!CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER
|
||||
.equals(authentication.getPrincipal().toString()) && !CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER
|
||||
&& (!CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER.equals(authentication.getPrincipal().toString())
|
||||
&& !CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER
|
||||
.equals(authentication.getPrincipal().toString()))) {
|
||||
// UsernamePasswordAuthenticationToken not CAS related
|
||||
return null;
|
||||
|
@ -104,30 +107,25 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
|
||||
// If an existing CasAuthenticationToken, just check we created it
|
||||
if (authentication instanceof CasAuthenticationToken) {
|
||||
if (this.key.hashCode() == ((CasAuthenticationToken) authentication)
|
||||
.getKeyHash()) {
|
||||
if (this.key.hashCode() == ((CasAuthenticationToken) authentication).getKeyHash()) {
|
||||
return authentication;
|
||||
}
|
||||
else {
|
||||
throw new BadCredentialsException(
|
||||
messages.getMessage("CasAuthenticationProvider.incorrectKey",
|
||||
throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.incorrectKey",
|
||||
"The presented CasAuthenticationToken does not contain the expected key"));
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure credentials are presented
|
||||
if ((authentication.getCredentials() == null)
|
||||
|| "".equals(authentication.getCredentials())) {
|
||||
throw new BadCredentialsException(messages.getMessage(
|
||||
"CasAuthenticationProvider.noServiceTicket",
|
||||
if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) {
|
||||
throw new BadCredentialsException(messages.getMessage("CasAuthenticationProvider.noServiceTicket",
|
||||
"Failed to provide a CAS service ticket to validate"));
|
||||
}
|
||||
|
||||
boolean stateless = false;
|
||||
|
||||
if (authentication instanceof UsernamePasswordAuthenticationToken
|
||||
&& CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER.equals(authentication
|
||||
.getPrincipal())) {
|
||||
&& CasAuthenticationFilter.CAS_STATELESS_IDENTIFIER.equals(authentication.getPrincipal())) {
|
||||
stateless = true;
|
||||
}
|
||||
|
||||
|
@ -135,8 +133,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
|
||||
if (stateless) {
|
||||
// Try to obtain from cache
|
||||
result = statelessTicketCache.getByTicketId(authentication.getCredentials()
|
||||
.toString());
|
||||
result = statelessTicketCache.getByTicketId(authentication.getCredentials().toString());
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
|
@ -152,17 +149,14 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
return result;
|
||||
}
|
||||
|
||||
private CasAuthenticationToken authenticateNow(final Authentication authentication)
|
||||
throws AuthenticationException {
|
||||
private CasAuthenticationToken authenticateNow(final Authentication authentication) throws AuthenticationException {
|
||||
try {
|
||||
final Assertion assertion = this.ticketValidator.validate(authentication
|
||||
.getCredentials().toString(), getServiceUrl(authentication));
|
||||
final Assertion assertion = this.ticketValidator.validate(authentication.getCredentials().toString(),
|
||||
getServiceUrl(authentication));
|
||||
final UserDetails userDetails = loadUserByAssertion(assertion);
|
||||
userDetailsChecker.check(userDetails);
|
||||
return new CasAuthenticationToken(this.key, userDetails,
|
||||
authentication.getCredentials(),
|
||||
authoritiesMapper.mapAuthorities(userDetails.getAuthorities()),
|
||||
userDetails, assertion);
|
||||
return new CasAuthenticationToken(this.key, userDetails, authentication.getCredentials(),
|
||||
authoritiesMapper.mapAuthorities(userDetails.getAuthorities()), userDetails, assertion);
|
||||
}
|
||||
catch (final TicketValidationException e) {
|
||||
throw new BadCredentialsException(e.getMessage(), e);
|
||||
|
@ -174,15 +168,13 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
* {@link ServiceAuthenticationDetails}, then
|
||||
* {@link ServiceAuthenticationDetails#getServiceUrl()} is used. Otherwise, the
|
||||
* {@link ServiceProperties#getService()} is used.
|
||||
*
|
||||
* @param authentication
|
||||
* @return
|
||||
*/
|
||||
private String getServiceUrl(Authentication authentication) {
|
||||
String serviceUrl;
|
||||
if (authentication.getDetails() instanceof ServiceAuthenticationDetails) {
|
||||
serviceUrl = ((ServiceAuthenticationDetails) authentication.getDetails())
|
||||
.getServiceUrl();
|
||||
serviceUrl = ((ServiceAuthenticationDetails) authentication.getDetails()).getServiceUrl();
|
||||
}
|
||||
else if (serviceProperties == null) {
|
||||
throw new IllegalStateException(
|
||||
|
@ -205,13 +197,11 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
* Template method for retrieving the UserDetails based on the assertion. Default is
|
||||
* to call configured userDetailsService and pass the username. Deployers can override
|
||||
* this method and retrieve the user based on any criteria they desire.
|
||||
*
|
||||
* @param assertion The CAS Assertion.
|
||||
* @return the UserDetails.
|
||||
*/
|
||||
protected UserDetails loadUserByAssertion(final Assertion assertion) {
|
||||
final CasAssertionAuthenticationToken token = new CasAssertionAuthenticationToken(
|
||||
assertion, "");
|
||||
final CasAssertionAuthenticationToken token = new CasAssertionAuthenticationToken(assertion, "");
|
||||
return this.authenticationUserDetailsService.loadUserDetails(token);
|
||||
}
|
||||
|
||||
|
@ -220,8 +210,7 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
* Sets the UserDetailsService to use. This is a convenience method to invoke
|
||||
*/
|
||||
public void setUserDetailsService(final UserDetailsService userDetailsService) {
|
||||
this.authenticationUserDetailsService = new UserDetailsByNameServiceWrapper(
|
||||
userDetailsService);
|
||||
this.authenticationUserDetailsService = new UserDetailsByNameServiceWrapper(userDetailsService);
|
||||
}
|
||||
|
||||
public void setAuthenticationUserDetailsService(
|
||||
|
@ -266,10 +255,9 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||
}
|
||||
|
||||
public boolean supports(final Class<?> authentication) {
|
||||
return (UsernamePasswordAuthenticationToken.class
|
||||
.isAssignableFrom(authentication))
|
||||
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication))
|
||||
|| (CasAuthenticationToken.class.isAssignableFrom(authentication))
|
||||
|| (CasAssertionAuthenticationToken.class
|
||||
.isAssignableFrom(authentication));
|
||||
|| (CasAssertionAuthenticationToken.class.isAssignableFrom(authentication));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,17 +32,20 @@ import org.springframework.util.Assert;
|
|||
* @author Ben Alex
|
||||
* @author Scott Battaglia
|
||||
*/
|
||||
public class CasAuthenticationToken extends AbstractAuthenticationToken implements
|
||||
Serializable {
|
||||
public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
private final Object credentials;
|
||||
|
||||
private final Object principal;
|
||||
|
||||
private final UserDetails userDetails;
|
||||
|
||||
private final int keyHash;
|
||||
|
||||
private final Assertion assertion;
|
||||
|
||||
// ~ Constructors
|
||||
|
@ -50,7 +53,6 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
|
|||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param key to identify if this object made by a given
|
||||
* {@link CasAuthenticationProvider}
|
||||
* @param principal typically the UserDetails object (cannot be <code>null</code>)
|
||||
|
@ -66,16 +68,14 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
|
|||
* principal and how to obtain a proxy ticket for the user.
|
||||
* @throws IllegalArgumentException if a <code>null</code> was passed
|
||||
*/
|
||||
public CasAuthenticationToken(final String key, final Object principal,
|
||||
final Object credentials,
|
||||
final Collection<? extends GrantedAuthority> authorities,
|
||||
final UserDetails userDetails, final Assertion assertion) {
|
||||
public CasAuthenticationToken(final String key, final Object principal, final Object credentials,
|
||||
final Collection<? extends GrantedAuthority> authorities, final UserDetails userDetails,
|
||||
final Assertion assertion) {
|
||||
this(extractKeyHash(key), principal, credentials, authorities, userDetails, assertion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor for Jackson Deserialization support
|
||||
*
|
||||
* @param keyHash hashCode of provided key to identify if this object made by a given
|
||||
* {@link CasAuthenticationProvider}
|
||||
* @param principal typically the UserDetails object (cannot be <code>null</code>)
|
||||
|
@ -92,18 +92,14 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
|
|||
* @throws IllegalArgumentException if a <code>null</code> was passed
|
||||
* @since 4.2
|
||||
*/
|
||||
private CasAuthenticationToken(final Integer keyHash, final Object principal,
|
||||
final Object credentials,
|
||||
final Collection<? extends GrantedAuthority> authorities,
|
||||
final UserDetails userDetails, final Assertion assertion) {
|
||||
private CasAuthenticationToken(final Integer keyHash, final Object principal, final Object credentials,
|
||||
final Collection<? extends GrantedAuthority> authorities, final UserDetails userDetails,
|
||||
final Assertion assertion) {
|
||||
super(authorities);
|
||||
|
||||
if ((principal == null)
|
||||
|| "".equals(principal) || (credentials == null)
|
||||
|| "".equals(credentials) || (authorities == null)
|
||||
|| (userDetails == null) || (assertion == null)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot pass null or empty values to constructor");
|
||||
if ((principal == null) || "".equals(principal) || (credentials == null) || "".equals(credentials)
|
||||
|| (authorities == null) || (userDetails == null) || (assertion == null)) {
|
||||
throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
|
||||
}
|
||||
|
||||
this.keyHash = keyHash;
|
||||
|
@ -187,4 +183,5 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
|
|||
|
||||
return (sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,12 +25,13 @@ import org.springframework.beans.factory.InitializingBean;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Caches tickets using a Spring IoC defined <a
|
||||
* href="https://www.ehcache.org/">EHCACHE</a>.
|
||||
* Caches tickets using a Spring IoC defined
|
||||
* <a href="https://www.ehcache.org/">EHCACHE</a>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class EhCacheBasedTicketCache implements StatelessTicketCache, InitializingBean {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -52,8 +53,7 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, Initializi
|
|||
final Element element = cache.get(serviceTicket);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cache hit: " + (element != null) + "; service ticket: "
|
||||
+ serviceTicket);
|
||||
logger.debug("Cache hit: " + (element != null) + "; service ticket: " + serviceTicket);
|
||||
}
|
||||
|
||||
return element == null ? null : (CasAuthenticationToken) element.getValue();
|
||||
|
@ -88,4 +88,5 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache, Initializi
|
|||
public void setCache(final Ehcache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ package org.springframework.security.cas.authentication;
|
|||
* are not using the stateless session management.
|
||||
*
|
||||
* @author Scott Battaglia
|
||||
*
|
||||
* @see CasAuthenticationProvider
|
||||
*/
|
||||
public final class NullStatelessTicketCache implements StatelessTicketCache {
|
||||
|
@ -56,4 +55,5 @@ public final class NullStatelessTicketCache implements StatelessTicketCache {
|
|||
public void removeTicketFromCache(final String serviceTicket) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,11 +28,11 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
*/
|
||||
public class SpringCacheBasedTicketCache implements StatelessTicketCache {
|
||||
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(SpringCacheBasedTicketCache.class);
|
||||
private static final Log logger = LogFactory.getLog(SpringCacheBasedTicketCache.class);
|
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
@ -51,12 +51,10 @@ public class SpringCacheBasedTicketCache implements StatelessTicketCache {
|
|||
// ========================================================================================================
|
||||
|
||||
public CasAuthenticationToken getByTicketId(final String serviceTicket) {
|
||||
final Cache.ValueWrapper element = serviceTicket != null ? cache
|
||||
.get(serviceTicket) : null;
|
||||
final Cache.ValueWrapper element = serviceTicket != null ? cache.get(serviceTicket) : null;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Cache hit: " + (element != null) + "; service ticket: "
|
||||
+ serviceTicket);
|
||||
logger.debug("Cache hit: " + (element != null) + "; service ticket: " + serviceTicket);
|
||||
}
|
||||
|
||||
return element == null ? null : (CasAuthenticationToken) element.get();
|
||||
|
@ -83,4 +81,5 @@ public class SpringCacheBasedTicketCache implements StatelessTicketCache {
|
|||
public void removeTicketFromCache(final String serviceTicket) {
|
||||
cache.evict(serviceTicket);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ package org.springframework.security.cas.authentication;
|
|||
* @author Ben Alex
|
||||
*/
|
||||
public interface StatelessTicketCache {
|
||||
|
||||
// ~ Methods ================================================================
|
||||
|
||||
/**
|
||||
|
@ -68,7 +69,6 @@ public interface StatelessTicketCache {
|
|||
* <P>
|
||||
* If not found, returns a <code>null</code><code>CasAuthenticationToken</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return the fully populated authentication token
|
||||
*/
|
||||
CasAuthenticationToken getByTicketId(String serviceTicket);
|
||||
|
@ -80,7 +80,6 @@ public interface StatelessTicketCache {
|
|||
* The {@link CasAuthenticationToken#getCredentials()} method is used to retrieve the
|
||||
* service ticket number.
|
||||
* </p>
|
||||
*
|
||||
* @param token to be added to the cache
|
||||
*/
|
||||
void putTicketInCache(CasAuthenticationToken token);
|
||||
|
@ -91,10 +90,9 @@ public interface StatelessTicketCache {
|
|||
*
|
||||
* <P>
|
||||
* Implementations should use {@link CasAuthenticationToken#getCredentials()} to
|
||||
* obtain the ticket and then delegate to the
|
||||
* {@link #removeTicketFromCache(String)} method.
|
||||
* obtain the ticket and then delegate to the {@link #removeTicketFromCache(String)}
|
||||
* method.
|
||||
* </p>
|
||||
*
|
||||
* @param token to be removed
|
||||
*/
|
||||
void removeTicketFromCache(CasAuthenticationToken token);
|
||||
|
@ -107,8 +105,8 @@ public interface StatelessTicketCache {
|
|||
* This is in case applications wish to provide a session termination capability for
|
||||
* their stateless clients.
|
||||
* </p>
|
||||
*
|
||||
* @param serviceTicket to be removed
|
||||
*/
|
||||
void removeTicketFromCache(String serviceTicket);
|
||||
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue