Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c696df36e | |||
| fb76868da5 | |||
| a7a1b889ce |
+1
-16
@@ -1,21 +1,6 @@
|
||||
target/
|
||||
*/src/*/java/META-INF
|
||||
*/src/META-INF/
|
||||
*/src/*/java/META-INF/
|
||||
.classpath
|
||||
.springBeans
|
||||
.project
|
||||
.DS_Store
|
||||
.settings/
|
||||
.idea/
|
||||
out/
|
||||
bin/
|
||||
intellij/
|
||||
build/
|
||||
*.log
|
||||
*.log.*
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.gradle/
|
||||
atlassian-ide-plugin.xml
|
||||
*.log
|
||||
@@ -1,10 +1,10 @@
|
||||
// Acl Module build file
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
compile project(':core'),
|
||||
"net.sf.ehcache:ehcache:$ehcacheVersion",
|
||||
"org.springframework:spring-aop:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-core:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion"
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<version>@pomVersion@</version>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
|
||||
@@ -80,6 +80,7 @@ import org.springframework.util.StringUtils;
|
||||
* <p>All comparisons and prefixes are case sensitive.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclEntryVoter extends AbstractAclVoter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.security.core.Authentication;
|
||||
* {@link org.springframework.security.acls.AclEntryVoter AclEntryVoter}.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AclPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
* Abstract {@link AfterInvocationProvider} which provides commonly-used ACL-related services.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AbstractAclProvider implements AfterInvocationProvider {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
+3
-1
@@ -38,7 +38,8 @@ import org.springframework.security.core.Authentication;
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclService</code> and ensure the
|
||||
* principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean) Acl.isGranted()}
|
||||
* principal is {@link org.springframework.security.acls.Acl#isGranted(List,
|
||||
* List, boolean) Acl.isGranted(Permission[], Sid[], boolean)}
|
||||
* when presenting the {@link #requirePermission} array to that method.
|
||||
* <p>
|
||||
* If the principal does not have permission, that element will not be included in the returned
|
||||
@@ -56,6 +57,7 @@ import org.springframework.security.core.Authentication;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclEntryAfterInvocationCollectionFilteringProvider extends AbstractAclProvider {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
+5
-4
@@ -39,10 +39,11 @@ import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
* <p>
|
||||
* This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
|
||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the <tt>AclService</tt> and ensure the
|
||||
* principal is {@link org.springframework.security.acls.model.Acl#isGranted(List, List, boolean)
|
||||
* Acl.isGranted(List, List, boolean)} when presenting the {@link #requirePermission} array to that method.
|
||||
* principal is {@link org.springframework.security.acls.Acl#isGranted(List,
|
||||
List, boolean) Acl.isGranted(Permission[], Sid[], boolean)}
|
||||
* when presenting the {@link #requirePermission} array to that method.
|
||||
* <p>
|
||||
* Often users will set up an <code>AclEntryAfterInvocationProvider</code> with a {@link
|
||||
* Often users will setup an <code>AclEntryAfterInvocationProvider</code> with a {@link
|
||||
* #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a {@link #requirePermission} of
|
||||
* <code>BasePermission.READ</code>. These are also the defaults.
|
||||
* <p>
|
||||
@@ -108,7 +109,7 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme
|
||||
|
||||
logger.debug("Denying access");
|
||||
|
||||
throw new AccessDeniedException(messages.getMessage("AclEntryAfterInvocationProvider.noPermission",
|
||||
throw new AccessDeniedException(messages.getMessage("BasicAclEntryAfterInvocationProvider.noPermission",
|
||||
new Object[] {authentication.getName(), returnedObject},
|
||||
"Authentication {0} has NO permissions to the domain object {1}"));
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
class ArrayFilterer<T> implements Filterer<T> {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
class CollectionFilterer<T> implements Filterer<T> {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Iterator;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Paulo Neves
|
||||
* @version $Id$
|
||||
*/
|
||||
interface Filterer<T> extends Iterable<T> {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* After-invocation providers for collection and array filtering. Consider using a {@code PostFilter} annotation in
|
||||
* preference.
|
||||
*/
|
||||
package org.springframework.security.acls.afterinvocation;
|
||||
|
||||
+4
-3
@@ -29,6 +29,7 @@ import java.io.Serializable;
|
||||
* An immutable default implementation of <code>AccessControlEntry</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccessControlEntryImpl implements AccessControlEntry, AuditableAccessControlEntry {
|
||||
//~ Instance fields ================================================================================================
|
||||
@@ -76,7 +77,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
if (rhs.getAcl() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Both this.acl and rhs.acl are non-null, so do a comparison
|
||||
if (this.acl.getObjectIdentity() == null) {
|
||||
if (rhs.acl.getObjectIdentity() != null) {
|
||||
@@ -90,7 +91,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.id == null) {
|
||||
if (rhs.id != null) {
|
||||
return false;
|
||||
@@ -107,7 +108,7 @@ public class AccessControlEntryImpl implements AccessControlEntry, AuditableAcce
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((this.auditFailure != rhs.isAuditFailure()) || (this.auditSuccess != rhs.isAuditSuccess())
|
||||
|| (this.granting != rhs.isGranting())
|
||||
|| !this.permission.equals(rhs.getPermission()) || !this.sid.equals(rhs.getSid())) {
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ import org.springframework.security.acls.model.Acl;
|
||||
* adminstrative methods on the <code>AclImpl</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclAuthorizationStrategy {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ import org.springframework.util.Assert;
|
||||
* {@link GrantedAuthority} and injected into the constructor.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.util.Assert;
|
||||
* Utility methods for displaying ACL information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class AclFormattingUtils {
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* Base implementation of <code>Acl</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
//~ Instance fields ================================================================================================
|
||||
@@ -379,15 +380,15 @@ public class AclImpl implements Acl, MutableAcl, AuditableAcl, OwnershipAcl {
|
||||
if (obj instanceof AclImpl) {
|
||||
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))) {
|
||||
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))) {
|
||||
if ((this.owner == null && rhs.owner == null) || (this.owner != null && this.owner.equals(rhs.owner))) {
|
||||
if ((this.parentAcl == null && rhs.parentAcl == null) || (this.parentAcl.equals(rhs.parentAcl))) {
|
||||
if ((this.objectIdentity == null && rhs.objectIdentity == null) || (this.objectIdentity.equals(rhs.objectIdentity))) {
|
||||
if ((this.id == null && rhs.id == null) || (this.id.equals(rhs.id))) {
|
||||
if ((this.owner == null && rhs.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.size() == rhs.loadedSids.size()) {
|
||||
for (int i = 0; i < this.loadedSids.size(); i++) {
|
||||
if (!this.loadedSids.get(i).equals(rhs.loadedSids.get(i))) {
|
||||
return false;
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.security.acls.model.AccessControlEntry;
|
||||
* Used by <code>AclImpl</code> to log audit events.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditLogger {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BasePermission extends AbstractPermission {
|
||||
public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.util.Assert;
|
||||
* A basic implementation of {@link AuditLogger}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ConsoleAuditLogger implements AuditLogger {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
+5
-4
@@ -19,10 +19,11 @@ import org.springframework.security.acls.model.Permission;
|
||||
|
||||
/**
|
||||
* Represents a <code>Permission</code> that is constructed at runtime from other permissions.
|
||||
*
|
||||
*
|
||||
* <p>Methods return <code>this</code>, in order to facilitate method chaining.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CumulativePermission extends AbstractPermission {
|
||||
|
||||
@@ -31,7 +32,7 @@ public class CumulativePermission extends AbstractPermission {
|
||||
public CumulativePermission() {
|
||||
super(0, ' ');
|
||||
}
|
||||
|
||||
|
||||
public CumulativePermission clear(Permission permission) {
|
||||
this.mask &= ~permission.getMask();
|
||||
this.pattern = AclFormattingUtils.demergePatterns(this.pattern, permission.getPattern());
|
||||
@@ -45,14 +46,14 @@ public class CumulativePermission extends AbstractPermission {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CumulativePermission set(Permission permission) {
|
||||
this.mask |= permission.getMask();
|
||||
this.pattern = AclFormattingUtils.mergePatterns(this.pattern, permission.getPattern());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.util.Assert;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedAclCache implements AclCache {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.util.Assert;
|
||||
* wish to provide an alternative <code>Sid</code> implementation that uses some other identifier.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class GrantedAuthoritySid implements Sid {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ package org.springframework.security.acls.domain;
|
||||
* Thrown if an ACL identity could not be extracted from an object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class IdentityUnavailableException extends RuntimeException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.util.ClassUtils;
|
||||
* reflection to build the identity information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ObjectIdentityImpl implements ObjectIdentity {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
* that uses the constructors of {@link ObjectIdentityImpl} to create the {@link ObjectIdentity}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImpl implements ObjectIdentityRetrievalStrategy, ObjectIdentityGenerator {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.util.Assert;
|
||||
* objects may wish to provide an alternative <code>Sid</code> implementation that uses some other identifier.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PrincipalSid implements Sid {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* The returned array will always contain the {@link PrincipalSid} before any {@link GrantedAuthoritySid} elements.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* Basic implementation of access control lists (ACLs) interfaces.
|
||||
*/
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Basic implementation of access control lists (ACLs) interfaces.
|
||||
</body>
|
||||
</html>
|
||||
@@ -72,6 +72,7 @@ import org.springframework.util.Assert;
|
||||
* generated by the the default values.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class BasicLookupStrategy implements LookupStrategy {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.util.Assert;
|
||||
* detect changed parameters easily.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JdbcAclService implements AclService {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Johannes Zlattinger
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JdbcMutableAclService extends JdbcAclService implements MutableAclService {
|
||||
//~ Instance fields ================================================================================================
|
||||
@@ -155,10 +156,10 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the primary key from {@code acl_class}, creating a new row if needed and the
|
||||
* {@code allowCreate} property is {@code true}.
|
||||
* Retrieves the primary key from acl_class, creating a new row if needed and the allowCreate property is
|
||||
* true.
|
||||
*
|
||||
* @param type to find or create an entry for (often the fully-qualified class name)
|
||||
* @param clazz to find or create an entry for (this implementation uses the fully-qualified class name String)
|
||||
* @param allowCreate true if creation is permitted if not found
|
||||
*
|
||||
* @return the primary key or null if not found
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Map;
|
||||
* Performs lookups for {@link org.springframework.security.acls.model.AclService}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface LookupStrategy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* JDBC-based persistence of ACL information
|
||||
*/
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
JDBC-based persistence of ACL information.
|
||||
</body>
|
||||
</html>
|
||||
@@ -27,6 +27,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AccessControlEntry extends Serializable {
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Implementing classes may elect to return instances that represent
|
||||
* Implementing classes may elect to return instances that represent
|
||||
* {@link org.springframework.security.acls.model.Permission} information for either
|
||||
* some OR all {@link org.springframework.security.acls.model.Sid}
|
||||
* instances. Therefore, an instance may NOT necessarily contain ALL <tt>Sid</tt>s
|
||||
@@ -39,22 +39,23 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Acl extends Serializable {
|
||||
|
||||
/**
|
||||
* Returns all of the entries represented by the present <tt>Acl</tt>. Entries associated with
|
||||
* the <tt>Acl</tt> parents are not returned.
|
||||
*
|
||||
*
|
||||
* <p>This method is typically used for administrative purposes.</p>
|
||||
*
|
||||
*
|
||||
* <p>The order that entries appear in the array is important for methods declared in the
|
||||
* {@link MutableAcl} interface. Furthermore, some implementations MAY use ordering as
|
||||
* part of advanced permission checking.</p>
|
||||
*
|
||||
*
|
||||
* <p>Do <em>NOT</em> use this method for making authorization decisions. Instead use {@link
|
||||
* #isGranted(List, List, boolean)}.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a 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>
|
||||
@@ -83,11 +84,11 @@ public interface Acl extends Serializable {
|
||||
/**
|
||||
* A domain object may have a parent for the purpose of ACL inheritance. If there is a parent, its ACL can
|
||||
* be accessed via this method. In turn, the parent's parent (grandparent) can be accessed and so on.
|
||||
*
|
||||
*
|
||||
* <p>This method solely represents the presence of a navigation hierarchy between the parent <tt>Acl</tt> and this
|
||||
* <tt>Acl</tt>. For actual inheritance to take place, the {@link #isEntriesInheriting()} must also be
|
||||
* <tt>true</tt>.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a 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>
|
||||
@@ -110,13 +111,13 @@ public interface Acl extends Serializable {
|
||||
/**
|
||||
* This is the actual authorization logic method, and must be used whenever ACL authorization decisions are
|
||||
* required.
|
||||
*
|
||||
*
|
||||
* <p>An array of <tt>Sid</tt>s are presented, representing security identifies of the current
|
||||
* principal. In addition, an array of <tt>Permission</tt>s is presented which will have one or more bits set
|
||||
* in order to indicate the permissions needed for an affirmative authorization decision. An array is presented
|
||||
* because holding <em>any</em> of the <tt>Permission</tt>s inside the array will be sufficient for an
|
||||
* affirmative authorization.</p>
|
||||
*
|
||||
*
|
||||
* <p>The actual approach used to make authorization decisions is left to the implementation and is not
|
||||
* specified by this interface. For example, an implementation <em>MAY</em> search the current ACL in the order
|
||||
* the ACL entries have been stored. If a single entry is found that has the same active bits as are shown in a
|
||||
@@ -126,9 +127,9 @@ public interface Acl extends Serializable {
|
||||
* ACL, provided that {@link #isEntriesInheriting()} is <tt>true</tt>, the authorization decision may be
|
||||
* passed to the parent ACL. If there is no matching entry, the implementation MAY throw an exception, or make a
|
||||
* predefined authorization decision.</p>
|
||||
*
|
||||
*
|
||||
* <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of <tt>Sid</tt>s,
|
||||
* although the implementation is permitted to throw one of the signature-defined exceptions if the method
|
||||
* although the implementation is permitted to throw one of the signature-defined exceptions if the method
|
||||
* is called requesting an authorization decision for a {@link Sid} that was never loaded in this <tt>Acl</tt>.
|
||||
* </p>
|
||||
*
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.io.Serializable;
|
||||
* A caching layer for {@link JdbcAclService}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AclCache {
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ package org.springframework.security.acls.model;
|
||||
* Abstract base class for Acl data operations.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AclDataAccessException extends RuntimeException {
|
||||
@@ -13,7 +14,7 @@ public abstract class AclDataAccessException extends RuntimeException {
|
||||
* message and root cause.
|
||||
*
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
* @param t the root cause
|
||||
*/
|
||||
public AclDataAccessException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
* Provides retrieval of {@link Acl} instances.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface AclService {
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -37,7 +38,7 @@ public interface AclService {
|
||||
List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity);
|
||||
|
||||
/**
|
||||
* Same as {@link #readAclsById(List)} except it returns only a single Acl.
|
||||
* Same as {@link #readAclsById(Java.util.List<ObjectIdentity>)} except it returns only a single Acl.
|
||||
* <p>
|
||||
* This method should not be called as it does not leverage the underlying implementation's potential ability to
|
||||
* filter <tt>Acl</tt> entries based on a {@link Sid} parameter.</p>
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an <code>Acl</code> entry already exists for the object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AlreadyExistsException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+1
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Represents an ACE that provides auditing information.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditableAccessControlEntry extends AccessControlEntry {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* A mutable ACL that provides audit capabilities.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface AuditableAcl extends MutableAcl {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an {@link Acl} cannot be deleted because children <code>Acl</code>s exist.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ChildrenExistException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.Serializable;
|
||||
* before allowing access to its methods.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface MutableAcl extends Acl {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.springframework.security.acls.model;
|
||||
* Provides support for creating and storing <code>Acl</code> instances.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface MutableAclService extends AclService {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.acls.model;
|
||||
* Thrown if an ACL-related object cannot be found.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class NotFoundException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface ObjectIdentity extends Serializable {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
+4
-3
@@ -4,13 +4,14 @@ import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy which creates an {@link ObjectIdentity} from an object identifier (such as a primary key)
|
||||
* Strategy which creates an <tt>ObjectIdentity</tt> from an object identifier (such as a primary key)
|
||||
* and type information.
|
||||
* <p>
|
||||
* Differs from {@link ObjectIdentityRetrievalStrategy} in that it is used in situations when the actual object
|
||||
* instance isn't available.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface ObjectIdentityGenerator {
|
||||
@@ -18,8 +19,8 @@ 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 information.
|
||||
* @param type the type of the object (usually a class name), not null
|
||||
* @return
|
||||
*/
|
||||
ObjectIdentity createObjectIdentity(Serializable id, String type);
|
||||
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ package org.springframework.security.acls.model;
|
||||
* will be returned for a particular domain object
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*
|
||||
*/
|
||||
public interface ObjectIdentityRetrievalStrategy {
|
||||
|
||||
@@ -24,6 +24,7 @@ package org.springframework.security.acls.model;
|
||||
* well as assign a new owner.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface OwnershipAcl extends MutableAcl {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.Serializable;
|
||||
* Represents a permission granted to a <tt>Sid</tt> for a given domain object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Permission extends Serializable {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface Sid extends Serializable {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.security.core.Authentication;
|
||||
* for an {@link Authentication}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SidRetrievalStrategy {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.springframework.security.acls.model;
|
||||
* the caller has requested details for an unloaded <code>Sid</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class UnloadedSidException extends AclDataAccessException {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/**
|
||||
* Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
|
||||
*/
|
||||
package org.springframework.security.acls.model;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Interfaces and shared classes to manage access control lists (ACLs) for domain object instances.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.security.acls;
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
-- ACL schema sql used in HSQLDB
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
|
||||
create table acl_sid(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal));
|
||||
|
||||
create table acl_class(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
class varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
-- ACL schema sql used in HSQLDB
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
|
||||
create table acl_sid(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal));
|
||||
|
||||
create table acl_class(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
class varchar_ignorecase(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigint generated by default as identity(start with 100) not null primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
-- ACL Schema SQL for PostgreSQL
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
create table acl_sid(
|
||||
id bigserial not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal)
|
||||
);
|
||||
|
||||
create table acl_class(
|
||||
id bigserial not null primary key,
|
||||
class varchar(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigserial primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigserial primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
-- ACL Schema SQL for PostgreSQL
|
||||
|
||||
-- drop table acl_entry;
|
||||
-- drop table acl_object_identity;
|
||||
-- drop table acl_class;
|
||||
-- drop table acl_sid;
|
||||
|
||||
create table acl_sid(
|
||||
id bigserial not null primary key,
|
||||
principal boolean not null,
|
||||
sid varchar(100) not null,
|
||||
constraint unique_uk_1 unique(sid,principal)
|
||||
);
|
||||
|
||||
create table acl_class(
|
||||
id bigserial not null primary key,
|
||||
class varchar(100) not null,
|
||||
constraint unique_uk_2 unique(class)
|
||||
);
|
||||
|
||||
create table acl_object_identity(
|
||||
id bigserial primary key,
|
||||
object_id_class bigint not null,
|
||||
object_id_identity bigint not null,
|
||||
parent_object bigint,
|
||||
owner_sid bigint,
|
||||
entries_inheriting boolean not null,
|
||||
constraint unique_uk_3 unique(object_id_class,object_id_identity),
|
||||
constraint foreign_fk_1 foreign key(parent_object)references acl_object_identity(id),
|
||||
constraint foreign_fk_2 foreign key(object_id_class)references acl_class(id),
|
||||
constraint foreign_fk_3 foreign key(owner_sid)references acl_sid(id)
|
||||
);
|
||||
|
||||
create table acl_entry(
|
||||
id bigserial primary key,
|
||||
acl_object_identity bigint not null,
|
||||
ace_order int not null,
|
||||
sid bigint not null,
|
||||
mask integer not null,
|
||||
granting boolean not null,
|
||||
audit_success boolean not null,
|
||||
audit_failure boolean not null,
|
||||
constraint unique_uk_4 unique(acl_object_identity,ace_order),
|
||||
constraint foreign_fk_4 foreign key(acl_object_identity) references acl_object_identity(id),
|
||||
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
|
||||
);
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
-- Not required. Just shows the sort of queries being sent to DB.
|
||||
|
||||
|
||||
select acl_object_identity.object_id_identity,
|
||||
acl_entry.ace_order,
|
||||
acl_object_identity.id as acl_id,
|
||||
acl_object_identity.parent_object,
|
||||
acl_object_identity,
|
||||
entries_inheriting,
|
||||
acl_entry.id as ace_id,
|
||||
acl_entry.mask,
|
||||
acl_entry.granting,
|
||||
acl_entry.audit_success,
|
||||
acl_entry.audit_failure,
|
||||
acl_sid.principal as ace_principal,
|
||||
acl_sid.sid as ace_sid,
|
||||
acli_sid.principal as acl_principal,
|
||||
acli_sid.sid as acl_sid,
|
||||
acl_class.class
|
||||
|
||||
from acl_object_identity,
|
||||
acl_sid acli_sid,
|
||||
acl_class
|
||||
|
||||
left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity
|
||||
left join acl_sid on acl_entry.sid = acl_sid.id
|
||||
|
||||
where
|
||||
acli_sid.id = acl_object_identity.owner_sid
|
||||
|
||||
and acl_class.id = acl_object_identity.object_id_class
|
||||
|
||||
and (
|
||||
|
||||
(acl_object_identity.object_id_identity = 1 and acl_class.class = 'sample.contact.contact')
|
||||
or
|
||||
(acl_object_identity.object_id_identity = 2000 and acl_class.class = 'sample.contact.contact')
|
||||
|
||||
) order by acl_object_identity.object_id_identity asc, acl_entry.ace_order asc
|
||||
-- Not required. Just shows the sort of queries being sent to DB.
|
||||
|
||||
|
||||
select acl_object_identity.object_id_identity,
|
||||
acl_entry.ace_order,
|
||||
acl_object_identity.id as acl_id,
|
||||
acl_object_identity.parent_object,
|
||||
acl_object_identity,
|
||||
entries_inheriting,
|
||||
acl_entry.id as ace_id,
|
||||
acl_entry.mask,
|
||||
acl_entry.granting,
|
||||
acl_entry.audit_success,
|
||||
acl_entry.audit_failure,
|
||||
acl_sid.principal as ace_principal,
|
||||
acl_sid.sid as ace_sid,
|
||||
acli_sid.principal as acl_principal,
|
||||
acli_sid.sid as acl_sid,
|
||||
acl_class.class
|
||||
|
||||
from acl_object_identity,
|
||||
acl_sid acli_sid,
|
||||
acl_class
|
||||
|
||||
left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity
|
||||
left join acl_sid on acl_entry.sid = acl_sid.id
|
||||
|
||||
where
|
||||
acli_sid.id = acl_object_identity.owner_sid
|
||||
|
||||
and acl_class.id = acl_object_identity.object_id_class
|
||||
|
||||
and (
|
||||
|
||||
(acl_object_identity.object_id_identity = 1 and acl_class.class = 'sample.contact.contact')
|
||||
or
|
||||
(acl_object_identity.object_id_identity = 2000 and acl_class.class = 'sample.contact.contact')
|
||||
|
||||
) order by acl_object_identity.object_id_identity asc, acl_entry.ace_order asc
|
||||
|
||||
+127
-127
@@ -1,127 +1,127 @@
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import org.springframework.security.acls.domain.AclFormattingUtils;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link AclFormattingUtils}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclFormattingUtilsTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public final void testDemergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testDemergePatterns() throws Exception {
|
||||
String original = "...........................A...R";
|
||||
String removeBits = "...............................R";
|
||||
Assert.assertEquals("...........................A....", AclFormattingUtils
|
||||
.demergePatterns(original, removeBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.demergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("......", AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testMergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testMergePatterns() throws Exception {
|
||||
String original = "...............................R";
|
||||
String extraBits = "...........................A....";
|
||||
Assert.assertEquals("...........................A...R", AclFormattingUtils
|
||||
.mergePatterns(original, extraBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.mergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("GHIJKL", AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testBinaryPrints() throws Exception {
|
||||
Assert.assertEquals("............................****", AclFormattingUtils.printBinary(15));
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_ON);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
Assert.assertEquals("............................xxxx", AclFormattingUtils.printBinary(15, 'x'));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls;
|
||||
|
||||
import org.springframework.security.acls.domain.AclFormattingUtils;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link AclFormattingUtils}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclFormattingUtilsTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public final void testDemergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.demergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testDemergePatterns() throws Exception {
|
||||
String original = "...........................A...R";
|
||||
String removeBits = "...............................R";
|
||||
Assert.assertEquals("...........................A....", AclFormattingUtils
|
||||
.demergePatterns(original, removeBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.demergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("......", AclFormattingUtils.demergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testMergePatternsParametersConstraints() throws Exception {
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns(null, "SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", null);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "LONGER SOME STRING");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.mergePatterns("SOME STRING", "SAME LENGTH");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public final void testMergePatterns() throws Exception {
|
||||
String original = "...............................R";
|
||||
String extraBits = "...........................A....";
|
||||
Assert.assertEquals("...........................A...R", AclFormattingUtils
|
||||
.mergePatterns(original, extraBits));
|
||||
|
||||
Assert.assertEquals("ABCDEF", AclFormattingUtils.mergePatterns("ABCDEF", "......"));
|
||||
Assert.assertEquals("GHIJKL", AclFormattingUtils.mergePatterns("ABCDEF", "GHIJKL"));
|
||||
}
|
||||
|
||||
public final void testBinaryPrints() throws Exception {
|
||||
Assert.assertEquals("............................****", AclFormattingUtils.printBinary(15));
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_ON);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
AclFormattingUtils.printBinary(15, Permission.RESERVED_OFF);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
Assert.assertEquals("............................xxxx", AclFormattingUtils.printBinary(15, 'x'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.security.core.Authentication;
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AclPermissionEvaluatorTests {
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.springframework.security.acls;
|
||||
* Dummy domain object class
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class TargetObject {
|
||||
|
||||
|
||||
+105
-104
@@ -1,104 +1,105 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessControlEntryImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AccessControlImplEntryTests {
|
||||
Mockery jmock = new JUnit4Mockery();
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testConstructorRequiredFields() {
|
||||
// Check Acl field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"),
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Sid field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), null,
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Permission field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), new PrincipalSid("johndoe"), null,
|
||||
true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessControlEntryImplGetters() {
|
||||
Acl mockAcl = jmock.mock(Acl.class);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
// Create a sample entry
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
// and check every get() method
|
||||
assertEquals(new Long(1), ace.getId());
|
||||
assertEquals(mockAcl, ace.getAcl());
|
||||
assertEquals(sid, ace.getSid());
|
||||
assertTrue(ace.isGranting());
|
||||
assertEquals(BasePermission.ADMINISTRATION, ace.getPermission());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditFailure());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
final Acl mockAcl = jmock.mock(Acl.class);
|
||||
final ObjectIdentity oid = jmock.mock(ObjectIdentity.class);
|
||||
jmock.checking(new Expectations() {{
|
||||
allowing(mockAcl).getObjectIdentity(); will(returnValue(oid));
|
||||
}});
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
assertFalse(ace.equals(null));
|
||||
assertFalse(ace.equals(new Long(100)));
|
||||
assertTrue(ace.equals(ace));
|
||||
assertTrue(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(2), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, new PrincipalSid("scott"),
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.WRITE, true,
|
||||
true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, false, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, false, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, false)));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
|
||||
/**
|
||||
* Tests for {@link AccessControlEntryImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AccessControlImplEntryTests {
|
||||
Mockery jmock = new JUnit4Mockery();
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void testConstructorRequiredFields() {
|
||||
// Check Acl field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, null, new PrincipalSid("johndoe"),
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Sid field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), null,
|
||||
BasePermission.ADMINISTRATION, true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Permission field is present
|
||||
try {
|
||||
new AccessControlEntryImpl(null, jmock.mock(Acl.class), new PrincipalSid("johndoe"), null,
|
||||
true, true, true);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessControlEntryImplGetters() {
|
||||
Acl mockAcl = jmock.mock(Acl.class);
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
// Create a sample entry
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
// and check every get() method
|
||||
assertEquals(new Long(1), ace.getId());
|
||||
assertEquals(mockAcl, ace.getAcl());
|
||||
assertEquals(sid, ace.getSid());
|
||||
assertTrue(ace.isGranting());
|
||||
assertEquals(BasePermission.ADMINISTRATION, ace.getPermission());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditFailure());
|
||||
assertTrue(((AuditableAccessControlEntry) ace).isAuditSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
final Acl mockAcl = jmock.mock(Acl.class);
|
||||
final ObjectIdentity oid = jmock.mock(ObjectIdentity.class);
|
||||
jmock.checking(new Expectations() {{
|
||||
allowing(mockAcl).getObjectIdentity(); will(returnValue(oid));
|
||||
}});
|
||||
Sid sid = new PrincipalSid("johndoe");
|
||||
|
||||
AccessControlEntry ace = new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.ADMINISTRATION,
|
||||
true, true, true);
|
||||
|
||||
assertFalse(ace.equals(null));
|
||||
assertFalse(ace.equals(new Long(100)));
|
||||
assertTrue(ace.equals(ace));
|
||||
assertTrue(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(2), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, new PrincipalSid("scott"),
|
||||
BasePermission.ADMINISTRATION, true, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid, BasePermission.WRITE, true,
|
||||
true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, false, true, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, false, true)));
|
||||
assertFalse(ace.equals(new AccessControlEntryImpl(new Long(1), mockAcl, sid,
|
||||
BasePermission.ADMINISTRATION, true, true, false)));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+260
-260
@@ -1,260 +1,260 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl}
|
||||
* security checks.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplementationSecurityCheckTests extends TestCase {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void testSecurityCheckNoACEs() throws Exception {
|
||||
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, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
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 GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_THREE") });
|
||||
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
|
||||
// Check access in case the principal has no authorization rights
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithMultipleACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal the ADMINISTRATION permission, without
|
||||
// granting access
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), 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);
|
||||
|
||||
// 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);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Add granting access to this principal
|
||||
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);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Create another ACL and give the principal the ADMINISTRATION
|
||||
// permission, with granting access
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), 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);
|
||||
|
||||
// Add a deny ACE and test again for CHANGE_AUDITING
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
|
||||
// Create an ACL with no ACE
|
||||
MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
// and still grant access for CHANGE_GENERAL
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithInheritableACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal an ADMINISTRATION permission, with granting
|
||||
// access
|
||||
MutableAcl parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
MutableAcl childAcl = new AclImpl(identity, new Long(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);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
// Link the child with its parent and test again against the
|
||||
// CHANGE_OWNERSHIP right
|
||||
childAcl.setParent(parentAcl);
|
||||
childAcl.setEntriesInheriting(true);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
// Create a root parent and link it to the middle parent
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, new Long(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);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckPrincipalOwner() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_ONE"),
|
||||
new GrantedAuthorityImpl("ROLE_ONE") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null,
|
||||
false, new PrincipalSid(auth));
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl}
|
||||
* security checks.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AclImplementationSecurityCheckTests extends TestCase {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void testSecurityCheckNoACEs() throws Exception {
|
||||
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, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
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 GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_THREE") });
|
||||
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
|
||||
// Check access in case the principal has no authorization rights
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithMultipleACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal the ADMINISTRATION permission, without
|
||||
// granting access
|
||||
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), 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);
|
||||
|
||||
// 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);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Add granting access to this principal
|
||||
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);
|
||||
Assert.fail("It should have thrown AccessDeniedException");
|
||||
}
|
||||
catch (AccessDeniedException expected) {
|
||||
}
|
||||
|
||||
// Create another ACL and give the principal the ADMINISTRATION
|
||||
// permission, with granting access
|
||||
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), 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);
|
||||
|
||||
// Add a deny ACE and test again for CHANGE_AUDITING
|
||||
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
|
||||
// Create an ACL with no ACE
|
||||
MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
// and still grant access for CHANGE_GENERAL
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckWithInheritableACEs() throws Exception {
|
||||
// Create a simple authentication with ROLE_GENERAL
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password",
|
||||
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
// Authorization strategy will require a different role for each access
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
// Let's give the principal an ADMINISTRATION permission, with granting
|
||||
// access
|
||||
MutableAcl parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
|
||||
MutableAcl childAcl = new AclImpl(identity, new Long(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);
|
||||
Assert.fail("It should have thrown NotFoundException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
// Link the child with its parent and test again against the
|
||||
// CHANGE_OWNERSHIP right
|
||||
childAcl.setParent(parentAcl);
|
||||
childAcl.setEntriesInheriting(true);
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
// Create a root parent and link it to the middle parent
|
||||
MutableAcl rootParentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
|
||||
new ConsoleAuditLogger());
|
||||
parentAcl = new AclImpl(identity, new Long(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);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSecurityCheckPrincipalOwner() throws Exception {
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_ONE"),
|
||||
new GrantedAuthorityImpl("ROLE_ONE") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
|
||||
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null,
|
||||
false, new PrincipalSid(auth));
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
catch (NotFoundException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
try {
|
||||
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (AccessDeniedException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown AccessDeniedException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +1,92 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
|
||||
/**
|
||||
* Test class for {@link ConsoleAuditLogger}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class AuditLoggerTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
private Mockery jmock = new JUnit4Mockery();
|
||||
private PrintStream console;
|
||||
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
private ConsoleAuditLogger logger;
|
||||
private AuditableAccessControlEntry ace;
|
||||
private Expectations aceRequiresAudit;
|
||||
private Expectations aceDoesntRequireAudit;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
logger = new ConsoleAuditLogger();
|
||||
ace = jmock.mock(AuditableAccessControlEntry.class);
|
||||
aceRequiresAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(true));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(true));
|
||||
}};
|
||||
aceDoesntRequireAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(false));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(false));
|
||||
}};
|
||||
|
||||
console = System.out;
|
||||
System.setOut(new PrintStream(bytes));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.setOut(console);
|
||||
bytes.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAuditableAceIsIgnored() {
|
||||
AccessControlEntry ace = jmock.mock(AccessControlEntry.class);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertTrue(bytes.toString().startsWith("GRANTED due to ACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertTrue(bytes.toString().startsWith("DENIED due to ACE"));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.model.AccessControlEntry;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
|
||||
/**
|
||||
* Test class for {@link ConsoleAuditLogger}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class AuditLoggerTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
private Mockery jmock = new JUnit4Mockery();
|
||||
private PrintStream console;
|
||||
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
private ConsoleAuditLogger logger;
|
||||
private AuditableAccessControlEntry ace;
|
||||
private Expectations aceRequiresAudit;
|
||||
private Expectations aceDoesntRequireAudit;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
logger = new ConsoleAuditLogger();
|
||||
ace = jmock.mock(AuditableAccessControlEntry.class);
|
||||
aceRequiresAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(true));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(true));
|
||||
}};
|
||||
aceDoesntRequireAudit = new Expectations() {{
|
||||
allowing(ace).isAuditSuccess(); will(returnValue(false));
|
||||
allowing(ace).isAuditFailure(); will(returnValue(false));
|
||||
}};
|
||||
|
||||
console = System.out;
|
||||
System.setOut(new PrintStream(bytes));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.setOut(console);
|
||||
bytes.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonAuditableAceIsIgnored() {
|
||||
AccessControlEntry ace = jmock.mock(AccessControlEntry.class);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsNotLoggedIfAceDoesntRequireSuccessAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsLoggedIfAceRequiresSuccessAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(true, ace);
|
||||
assertTrue(bytes.toString().startsWith("GRANTED due to ACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsntLoggedIfAceDoesntRequireFailureAudit() throws Exception {
|
||||
jmock.checking(aceDoesntRequireAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertEquals(0, bytes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failureIsLoggedIfAceRequiresFailureAudit() throws Exception {
|
||||
jmock.checking(aceRequiresAudit);
|
||||
logger.logIfNeeded(false, ace);
|
||||
assertTrue(bytes.toString().startsWith("DENIED due to ACE"));
|
||||
}
|
||||
}
|
||||
|
||||
+189
-189
@@ -1,189 +1,189 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.IdentityUnavailableException;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ObjectIdentityImplTests {
|
||||
|
||||
private static final String DOMAIN_CLASS =
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockIdDomainObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void constructorsRespectRequiredFields() throws Exception {
|
||||
// Check one-argument constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl(null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check String-Serializable constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Serializable parameter is not null
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// The correct way of using String-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check the Class-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(MockIdDomainObject.class, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gettersReturnExpectedValues() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
assertEquals(Long.valueOf(1), obj.getIdentifier());
|
||||
assertEquals(MockIdDomainObject.class.getName(), obj.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIdMethodConstraints() throws Exception {
|
||||
// Check the getId() method is present
|
||||
try {
|
||||
new ObjectIdentityImpl("A_STRING_OBJECT");
|
||||
fail("It should have thrown IdentityUnavailableException");
|
||||
}
|
||||
catch (IdentityUnavailableException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a non-null value
|
||||
MockIdDomainObject mockId = new MockIdDomainObject();
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new MockIdDomainObject());
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new Long(100));
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsInvalidTypeParameter() throws Exception {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
MockIdDomainObject mockObj = new MockIdDomainObject();
|
||||
mockObj.setId(Long.valueOf(1));
|
||||
|
||||
String string = "SOME_STRING";
|
||||
assertNotSame(obj, string);
|
||||
assertFalse(obj.equals(null));
|
||||
assertFalse(obj.equals("DIFFERENT_OBJECT_TYPE"));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2))));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
Long.valueOf(1))));
|
||||
assertEquals(new ObjectIdentityImpl(DOMAIN_CLASS,Long.valueOf(1)), obj);
|
||||
assertEquals(obj, new ObjectIdentityImpl(mockObj));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
|
||||
assertFalse(obj.hashCode() == obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndIntegerIdsWithSameValueAreEqualAndHaveSameHashcode() {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, new Long(5));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, new Integer(5));
|
||||
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalStringIdsAreEqualAndHaveSameHashcode() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, "1000");
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringAndNumericIdsAreNotEqual() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertFalse(obj.equals(obj2));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockOtherIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.IdentityUnavailableException;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityImpl}.
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityImplTests {
|
||||
|
||||
private static final String DOMAIN_CLASS =
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockIdDomainObject";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void constructorsRespectRequiredFields() throws Exception {
|
||||
// Check one-argument constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl(null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check String-Serializable constructor required field
|
||||
try {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// Check Serializable parameter is not null
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// The correct way of using String-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check the Class-Serializable constructor
|
||||
try {
|
||||
new ObjectIdentityImpl(MockIdDomainObject.class, null);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gettersReturnExpectedValues() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
assertEquals(Long.valueOf(1), obj.getIdentifier());
|
||||
assertEquals(MockIdDomainObject.class.getName(), obj.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIdMethodConstraints() throws Exception {
|
||||
// Check the getId() method is present
|
||||
try {
|
||||
new ObjectIdentityImpl("A_STRING_OBJECT");
|
||||
fail("It should have thrown IdentityUnavailableException");
|
||||
}
|
||||
catch (IdentityUnavailableException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a non-null value
|
||||
MockIdDomainObject mockId = new MockIdDomainObject();
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new MockIdDomainObject());
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
// getId() should return a Serializable object
|
||||
mockId.setId(new Long(100));
|
||||
try {
|
||||
new ObjectIdentityImpl(mockId);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsInvalidTypeParameter() throws Exception {
|
||||
new ObjectIdentityImpl("", Long.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(1));
|
||||
MockIdDomainObject mockObj = new MockIdDomainObject();
|
||||
mockObj.setId(Long.valueOf(1));
|
||||
|
||||
String string = "SOME_STRING";
|
||||
assertNotSame(obj, string);
|
||||
assertFalse(obj.equals(null));
|
||||
assertFalse(obj.equals("DIFFERENT_OBJECT_TYPE"));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(DOMAIN_CLASS, Long.valueOf(2))));
|
||||
assertFalse(obj.equals(new ObjectIdentityImpl(
|
||||
"org.springframework.security.acls.domain.ObjectIdentityImplTests$MockOtherIdDomainObject",
|
||||
Long.valueOf(1))));
|
||||
assertEquals(new ObjectIdentityImpl(DOMAIN_CLASS,Long.valueOf(1)), obj);
|
||||
assertEquals(obj, new ObjectIdentityImpl(mockObj));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashcodeIsDifferentForDifferentJavaTypes() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, Long.valueOf(1));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(String.class, Long.valueOf(1));
|
||||
assertFalse(obj.hashCode() == obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longAndIntegerIdsWithSameValueAreEqualAndHaveSameHashcode() {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, new Long(5));
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, new Integer(5));
|
||||
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalStringIdsAreEqualAndHaveSameHashcode() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, "1000");
|
||||
assertEquals(obj, obj2);
|
||||
assertEquals(obj.hashCode(), obj2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringAndNumericIdsAreNotEqual() throws Exception {
|
||||
ObjectIdentity obj = new ObjectIdentityImpl(Object.class, "1000");
|
||||
ObjectIdentity obj2 = new ObjectIdentityImpl(Object.class, Long.valueOf(1000));
|
||||
assertFalse(obj.equals(obj2));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class MockOtherIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-42
@@ -1,42 +1,42 @@
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImplTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testObjectIdentityCreation() throws Exception {
|
||||
MockIdDomainObject domain = new MockIdDomainObject();
|
||||
domain.setId(new Integer(1));
|
||||
|
||||
ObjectIdentityRetrievalStrategy retStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
ObjectIdentity identity = retStrategy.getObjectIdentity(domain);
|
||||
|
||||
assertNotNull(identity);
|
||||
assertEquals(identity, new ObjectIdentityImpl(domain));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
@SuppressWarnings("unused")
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.domain;
|
||||
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.ObjectIdentityRetrievalStrategy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link ObjectIdentityRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class ObjectIdentityRetrievalStrategyImplTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testObjectIdentityCreation() throws Exception {
|
||||
MockIdDomainObject domain = new MockIdDomainObject();
|
||||
domain.setId(new Integer(1));
|
||||
|
||||
ObjectIdentityRetrievalStrategy retStrategy = new ObjectIdentityRetrievalStrategyImpl();
|
||||
ObjectIdentity identity = retStrategy.getObjectIdentity(domain);
|
||||
|
||||
assertNotNull(identity);
|
||||
assertEquals(identity, new ObjectIdentityImpl(domain));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockIdDomainObject {
|
||||
private Object id;
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* Tests classes associated with Permission.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PermissionTests {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.security.acls.model.Permission;
|
||||
* A test permission.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SpecialPermission extends BasePermission {
|
||||
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
|
||||
|
||||
+312
-312
@@ -1,312 +1,312 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.BasePermission;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.DefaultPermissionFactory;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link BasicLookupStrategy}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class BasicLookupStrategyTests {
|
||||
|
||||
private static final Sid BEN_SID = new PrincipalSid("ben");
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static JdbcTemplate jdbcTemplate;
|
||||
private BasicLookupStrategy strategy;
|
||||
private static SingleConnectionDataSource dataSource;
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createDatabase() throws Exception {
|
||||
dataSource = new SingleConnectionDataSource("jdbc:hsqldb:mem:lookupstrategytest", "sa", "", true);
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
|
||||
Resource resource = new ClassPathResource("createAclSchema.sql");
|
||||
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() throws Exception {
|
||||
dataSource.destroy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void populateDatabase() {
|
||||
String query = "INSERT INTO acl_sid(ID,PRINCIPAL,SID) VALUES (1,1,'ben');"
|
||||
+ "INSERT INTO acl_class(ID,CLASS) VALUES (2,'" + TARGET_CLASS + "');"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (1,2,100,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (2,2,101,1,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (3,2,102,2,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (1,1,0,1,1,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (2,1,1,1,2,0,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (3,2,0,1,8,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (4,3,0,1,8,0,0,0);";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeBeans() {
|
||||
EhCacheBasedAclCache cache = new EhCacheBasedAclCache(getCache());
|
||||
AclAuthorizationStrategy authorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"), new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"),
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR") });
|
||||
strategy = new BasicLookupStrategy(dataSource, cache, authorizationStrategy, new ConsoleAuditLogger());
|
||||
strategy.setPermissionFactory(new DefaultPermissionFactory());
|
||||
}
|
||||
|
||||
@After
|
||||
public void emptyDatabase() {
|
||||
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 7;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 6;" + "DELETE FROM acl_object_identity WHERE ID = 5;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 4;" + "DELETE FROM acl_object_identity WHERE ID = 3;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 2;" + "DELETE FROM acl_object_identity WHERE ID = 1;"
|
||||
+ "DELETE FROM acl_class;" + "DELETE FROM acl_sid;";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("basiclookuptestcache");
|
||||
cache.removeAll();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(102));
|
||||
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalFromCacheOnly() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Objects were put in cache
|
||||
strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
// Let's empty the database to force acls retrieval from cache
|
||||
emptyDatabase();
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithCustomBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Set a batch size to allow multiple database queries in order to retrieve all acls
|
||||
((BasicLookupStrategy) this.strategy).setBatchSize(1);
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
private void checkEntries(ObjectIdentity topParentOid, ObjectIdentity middleParentOid, ObjectIdentity childOid,
|
||||
Map<ObjectIdentity, Acl> map) throws Exception {
|
||||
Assert.assertEquals(3, map.size());
|
||||
|
||||
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
|
||||
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
|
||||
MutableAcl child = (MutableAcl) map.get(childOid);
|
||||
|
||||
// Check the retrieved versions has IDs
|
||||
Assert.assertNotNull(topParent.getId());
|
||||
Assert.assertNotNull(middleParent.getId());
|
||||
Assert.assertNotNull(child.getId());
|
||||
|
||||
// Check their parents were correctly retrieved
|
||||
Assert.assertNull(topParent.getParentAcl());
|
||||
Assert.assertEquals(topParentOid, middleParent.getParentAcl().getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, child.getParentAcl().getObjectIdentity());
|
||||
|
||||
// Check their ACEs were correctly retrieved
|
||||
Assert.assertEquals(2, topParent.getEntries().size());
|
||||
Assert.assertEquals(1, middleParent.getEntries().size());
|
||||
Assert.assertEquals(1, child.getEntries().size());
|
||||
|
||||
// Check object identities were correctly retrieved
|
||||
Assert.assertEquals(topParentOid, topParent.getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, middleParent.getObjectIdentity());
|
||||
Assert.assertEquals(childOid, child.getObjectIdentity());
|
||||
|
||||
// Check each entry
|
||||
Assert.assertTrue(topParent.isEntriesInheriting());
|
||||
Assert.assertEquals(topParent.getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getPermission(), BasePermission.READ);
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getId(), new Long(2));
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getPermission(), BasePermission.WRITE);
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isGranting());
|
||||
|
||||
Assert.assertTrue(middleParent.isEntriesInheriting());
|
||||
Assert.assertEquals(middleParent.getId(), new Long(2));
|
||||
Assert.assertEquals(middleParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getId(), new Long(3));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertTrue(child.isEntriesInheriting());
|
||||
Assert.assertEquals(child.getId(), new Long(3));
|
||||
Assert.assertEquals(child.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(child.getEntries().get(0).getId(), new Long(4));
|
||||
Assert.assertEquals(child.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(child.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertFalse((child.getEntries().get(0)).isGranting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParentsAreRetrievedWhenChildIsLoaded() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,103,1,1,1);";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(103));
|
||||
|
||||
// Retrieve the child
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(childOid), null);
|
||||
|
||||
// Check that the child and all its parents were retrieved
|
||||
Assert.assertNotNull(map.get(childOid));
|
||||
Assert.assertEquals(childOid, ((Acl) map.get(childOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(middleParentOid));
|
||||
Assert.assertEquals(middleParentOid, ((Acl) map.get(middleParentOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(topParentOid));
|
||||
Assert.assertEquals(topParentOid, ((Acl) map.get(topParentOid)).getObjectIdentity());
|
||||
|
||||
// The second parent shouldn't have been retrieved
|
||||
Assert.assertNull(map.get(middleParent2Oid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test created from SEC-590.
|
||||
*/
|
||||
@Test
|
||||
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (5,2,105,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,106,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (7,2,107,5,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,1,1,0,0)";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
ObjectIdentity parent1Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(105));
|
||||
ObjectIdentity parent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(106));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(107));
|
||||
|
||||
// First lookup only child, thus populating the cache with grandParent, parent1 and child
|
||||
List<Permission> checkPermission = Arrays.asList(BasePermission.READ);
|
||||
List<Sid> sids = Arrays.asList(BEN_SID);
|
||||
List<ObjectIdentity> childOids = Arrays.asList(childOid);
|
||||
|
||||
strategy.setBatchSize(6);
|
||||
Map<ObjectIdentity, Acl> foundAcls = strategy.readAclsById(childOids, sids);
|
||||
|
||||
Acl foundChildAcl = (Acl) foundAcls.get(childOid);
|
||||
Assert.assertNotNull(foundChildAcl);
|
||||
Assert.assertTrue(foundChildAcl.isGranted(checkPermission, sids, false));
|
||||
|
||||
// Search for object identities has to be done in the following order: last element have to be one which
|
||||
// is already in cache and the element before it must not be stored in cache
|
||||
List<ObjectIdentity> allOids = Arrays.asList(grandParentOid, parent1Oid, parent2Oid, childOid);
|
||||
try {
|
||||
foundAcls = strategy.readAclsById(allOids, sids);
|
||||
Assert.assertTrue(true);
|
||||
} catch (NotFoundException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
Acl foundParent2Acl = (Acl) foundAcls.get(parent2Oid);
|
||||
Assert.assertNotNull(foundParent2Acl);
|
||||
Assert.assertTrue(foundParent2Acl.isGranted(checkPermission, sids, false));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void nullOwnerIsNotSupported() {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,null,1);";
|
||||
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
|
||||
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
}
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.BasePermission;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.DefaultPermissionFactory;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Acl;
|
||||
import org.springframework.security.acls.model.AuditableAccessControlEntry;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.NotFoundException;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.Permission;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link BasicLookupStrategy}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class BasicLookupStrategyTests {
|
||||
|
||||
private static final Sid BEN_SID = new PrincipalSid("ben");
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static JdbcTemplate jdbcTemplate;
|
||||
private BasicLookupStrategy strategy;
|
||||
private static SingleConnectionDataSource dataSource;
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
cacheManager.addCache(new Cache("basiclookuptestcache", 500, false, false, 30, 30));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createDatabase() throws Exception {
|
||||
dataSource = new SingleConnectionDataSource("jdbc:hsqldb:mem:lookupstrategytest", "sa", "", true);
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
|
||||
Resource resource = new ClassPathResource("createAclSchema.sql");
|
||||
String sql = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void dropDatabase() throws Exception {
|
||||
dataSource.destroy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void populateDatabase() {
|
||||
String query = "INSERT INTO acl_sid(ID,PRINCIPAL,SID) VALUES (1,1,'ben');"
|
||||
+ "INSERT INTO acl_class(ID,CLASS) VALUES (2,'" + TARGET_CLASS + "');"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (1,2,100,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (2,2,101,1,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (3,2,102,2,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (1,1,0,1,1,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (2,1,1,1,2,0,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (3,2,0,1,8,1,0,0);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (4,3,0,1,8,0,0,0);";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeBeans() {
|
||||
EhCacheBasedAclCache cache = new EhCacheBasedAclCache(getCache());
|
||||
AclAuthorizationStrategy authorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"), new GrantedAuthorityImpl("ROLE_ADMINISTRATOR"),
|
||||
new GrantedAuthorityImpl("ROLE_ADMINISTRATOR") });
|
||||
strategy = new BasicLookupStrategy(dataSource, cache, authorizationStrategy, new ConsoleAuditLogger());
|
||||
strategy.setPermissionFactory(new DefaultPermissionFactory());
|
||||
}
|
||||
|
||||
@After
|
||||
public void emptyDatabase() {
|
||||
String query = "DELETE FROM acl_entry;" + "DELETE FROM acl_object_identity WHERE ID = 7;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 6;" + "DELETE FROM acl_object_identity WHERE ID = 5;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 4;" + "DELETE FROM acl_object_identity WHERE ID = 3;"
|
||||
+ "DELETE FROM acl_object_identity WHERE ID = 2;" + "DELETE FROM acl_object_identity WHERE ID = 1;"
|
||||
+ "DELETE FROM acl_class;" + "DELETE FROM acl_sid;";
|
||||
jdbcTemplate.execute(query);
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("basiclookuptestcache");
|
||||
cache.removeAll();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(102));
|
||||
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalFromCacheOnly() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Objects were put in cache
|
||||
strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
// Let's empty the database to force acls retrieval from cache
|
||||
emptyDatabase();
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAclsRetrievalWithCustomBatchSize() throws Exception {
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
|
||||
// Set a batch size to allow multiple database queries in order to retrieve all acls
|
||||
((BasicLookupStrategy) this.strategy).setBatchSize(1);
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(topParentOid, middleParentOid, childOid), null);
|
||||
checkEntries(topParentOid, middleParentOid, childOid, map);
|
||||
}
|
||||
|
||||
private void checkEntries(ObjectIdentity topParentOid, ObjectIdentity middleParentOid, ObjectIdentity childOid,
|
||||
Map<ObjectIdentity, Acl> map) throws Exception {
|
||||
Assert.assertEquals(3, map.size());
|
||||
|
||||
MutableAcl topParent = (MutableAcl) map.get(topParentOid);
|
||||
MutableAcl middleParent = (MutableAcl) map.get(middleParentOid);
|
||||
MutableAcl child = (MutableAcl) map.get(childOid);
|
||||
|
||||
// Check the retrieved versions has IDs
|
||||
Assert.assertNotNull(topParent.getId());
|
||||
Assert.assertNotNull(middleParent.getId());
|
||||
Assert.assertNotNull(child.getId());
|
||||
|
||||
// Check their parents were correctly retrieved
|
||||
Assert.assertNull(topParent.getParentAcl());
|
||||
Assert.assertEquals(topParentOid, middleParent.getParentAcl().getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, child.getParentAcl().getObjectIdentity());
|
||||
|
||||
// Check their ACEs were correctly retrieved
|
||||
Assert.assertEquals(2, topParent.getEntries().size());
|
||||
Assert.assertEquals(1, middleParent.getEntries().size());
|
||||
Assert.assertEquals(1, child.getEntries().size());
|
||||
|
||||
// Check object identities were correctly retrieved
|
||||
Assert.assertEquals(topParentOid, topParent.getObjectIdentity());
|
||||
Assert.assertEquals(middleParentOid, middleParent.getObjectIdentity());
|
||||
Assert.assertEquals(childOid, child.getObjectIdentity());
|
||||
|
||||
// Check each entry
|
||||
Assert.assertTrue(topParent.isEntriesInheriting());
|
||||
Assert.assertEquals(topParent.getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getId(), new Long(1));
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getPermission(), BasePermission.READ);
|
||||
Assert.assertEquals(topParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) topParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getId(), new Long(2));
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getPermission(), BasePermission.WRITE);
|
||||
Assert.assertEquals(topParent.getEntries().get(1).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isAuditSuccess());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) topParent.getEntries().get(1)).isGranting());
|
||||
|
||||
Assert.assertTrue(middleParent.isEntriesInheriting());
|
||||
Assert.assertEquals(middleParent.getId(), new Long(2));
|
||||
Assert.assertEquals(middleParent.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getId(), new Long(3));
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(middleParent.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertTrue(((AuditableAccessControlEntry) middleParent.getEntries().get(0)).isGranting());
|
||||
|
||||
Assert.assertTrue(child.isEntriesInheriting());
|
||||
Assert.assertEquals(child.getId(), new Long(3));
|
||||
Assert.assertEquals(child.getOwner(), new PrincipalSid("ben"));
|
||||
Assert.assertEquals(child.getEntries().get(0).getId(), new Long(4));
|
||||
Assert.assertEquals(child.getEntries().get(0).getPermission(), BasePermission.DELETE);
|
||||
Assert.assertEquals(child.getEntries().get(0).getSid(), new PrincipalSid("ben"));
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditFailure());
|
||||
Assert.assertFalse(((AuditableAccessControlEntry) child.getEntries().get(0)).isAuditSuccess());
|
||||
Assert.assertFalse((child.getEntries().get(0)).isGranting());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParentsAreRetrievedWhenChildIsLoaded() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,103,1,1,1);";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity topParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
ObjectIdentity middleParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(101));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(102));
|
||||
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(103));
|
||||
|
||||
// Retrieve the child
|
||||
Map<ObjectIdentity, Acl> map = this.strategy.readAclsById(Arrays.asList(childOid), null);
|
||||
|
||||
// Check that the child and all its parents were retrieved
|
||||
Assert.assertNotNull(map.get(childOid));
|
||||
Assert.assertEquals(childOid, ((Acl) map.get(childOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(middleParentOid));
|
||||
Assert.assertEquals(middleParentOid, ((Acl) map.get(middleParentOid)).getObjectIdentity());
|
||||
Assert.assertNotNull(map.get(topParentOid));
|
||||
Assert.assertEquals(topParentOid, ((Acl) map.get(topParentOid)).getObjectIdentity());
|
||||
|
||||
// The second parent shouldn't have been retrieved
|
||||
Assert.assertNull(map.get(middleParent2Oid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test created from SEC-590.
|
||||
*/
|
||||
@Test
|
||||
public void testReadAllObjectIdentitiesWhenLastElementIsAlreadyCached() throws Exception {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (5,2,105,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (6,2,106,4,1,1);"
|
||||
+ "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (7,2,107,5,1,1);"
|
||||
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,1,1,0,0)";
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity grandParentOid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
ObjectIdentity parent1Oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(105));
|
||||
ObjectIdentity parent2Oid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(106));
|
||||
ObjectIdentity childOid = new ObjectIdentityImpl(TARGET_CLASS, new Integer(107));
|
||||
|
||||
// First lookup only child, thus populating the cache with grandParent, parent1 and child
|
||||
List<Permission> checkPermission = Arrays.asList(BasePermission.READ);
|
||||
List<Sid> sids = Arrays.asList(BEN_SID);
|
||||
List<ObjectIdentity> childOids = Arrays.asList(childOid);
|
||||
|
||||
strategy.setBatchSize(6);
|
||||
Map<ObjectIdentity, Acl> foundAcls = strategy.readAclsById(childOids, sids);
|
||||
|
||||
Acl foundChildAcl = (Acl) foundAcls.get(childOid);
|
||||
Assert.assertNotNull(foundChildAcl);
|
||||
Assert.assertTrue(foundChildAcl.isGranted(checkPermission, sids, false));
|
||||
|
||||
// Search for object identities has to be done in the following order: last element have to be one which
|
||||
// is already in cache and the element before it must not be stored in cache
|
||||
List<ObjectIdentity> allOids = Arrays.asList(grandParentOid, parent1Oid, parent2Oid, childOid);
|
||||
try {
|
||||
foundAcls = strategy.readAclsById(allOids, sids);
|
||||
Assert.assertTrue(true);
|
||||
} catch (NotFoundException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown NotFoundException");
|
||||
}
|
||||
|
||||
Acl foundParent2Acl = (Acl) foundAcls.get(parent2Oid);
|
||||
Assert.assertNotNull(foundParent2Acl);
|
||||
Assert.assertTrue(foundParent2Acl.isGranted(checkPermission, sids, false));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void nullOwnerIsNotSupported() {
|
||||
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,null,1);";
|
||||
|
||||
jdbcTemplate.execute(query);
|
||||
|
||||
ObjectIdentity oid = new ObjectIdentityImpl(TARGET_CLASS, new Long(104));
|
||||
|
||||
strategy.readAclsById(Arrays.asList(oid), Arrays.asList(BEN_SID));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.sql.DataSource;
|
||||
* Seeds the database for {@link JdbcMutableAclServiceTests}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DatabaseSeeder {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+267
-266
@@ -1,266 +1,267 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.addCache(new Cache("ehcachebasedacltests", 0, true, false, 600, 300));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("ehcachebasedacltests");
|
||||
cache.removeAll();
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new EhCacheBasedAclCache(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodsRejectNullParameters() throws Exception {
|
||||
Ehcache cache = new MockEhcache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.evictFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.evictFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.getFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.getFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
MutableAcl acl = null;
|
||||
myCache.putInCache(acl);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
// SEC-527
|
||||
@Test
|
||||
public void testDiskSerializationOfMutableAclObjectInstance() throws Exception {
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Serialization test
|
||||
File file = File.createTempFile("SEC_TEST", ".object");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(acl);
|
||||
oos.close();
|
||||
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
MutableAcl retrieved = (MutableAcl) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
assertEquals(acl, retrieved);
|
||||
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved);
|
||||
assertEquals(null, retrieved1);
|
||||
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue("auditLogger", retrieved);
|
||||
assertEquals(null, retrieved2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(new Long(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(new Long(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, new Long(102)));
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
myCache.evictFromCache(new Long(1));
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(new Long(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(cache.getSize(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, new Long(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertTrue(cache.isElementOnDisk(Long.valueOf(1)));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(Long.valueOf(1)));
|
||||
cache.flush();
|
||||
// Wait for the spool to be written to disk (it's asynchronous)
|
||||
Map spool = (Map) FieldUtils.getFieldValue(cache, "diskStore.spool");
|
||||
|
||||
while(spool.size() > 0) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(new Long(1));
|
||||
// For the checks on transient fields, we need to be sure that the object is being loaded from the cache,
|
||||
// not from the ehcache spool or elsewhere...
|
||||
assertFalse(acl == aclFromCache);
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "auditLogger"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(new Long(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockEhcache extends Cache {
|
||||
public MockEhcache() {
|
||||
super("cache", 0, true, true, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
||||
import org.springframework.security.acls.domain.AclImpl;
|
||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
||||
import org.springframework.security.acls.domain.ObjectIdentityImpl;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
|
||||
/**
|
||||
* Tests {@link EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EhCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new CacheManager();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.addCache(new Cache("ehcachebasedacltests", 0, true, false, 600, 300));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownCacheManager() {
|
||||
cacheManager.removalAll();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Ehcache getCache() {
|
||||
Ehcache cache = cacheManager.getCache("ehcachebasedacltests");
|
||||
cache.removeAll();
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new EhCacheBasedAclCache(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodsRejectNullParameters() throws Exception {
|
||||
Ehcache cache = new MockEhcache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.evictFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.evictFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Serializable id = null;
|
||||
myCache.getFromCache(id);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectIdentity obj = null;
|
||||
myCache.getFromCache(obj);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
MutableAcl acl = null;
|
||||
myCache.putInCache(acl);
|
||||
fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
// SEC-527
|
||||
@Test
|
||||
public void testDiskSerializationOfMutableAclObjectInstance() throws Exception {
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
// Serialization test
|
||||
File file = File.createTempFile("SEC_TEST", ".object");
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(acl);
|
||||
oos.close();
|
||||
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
MutableAcl retrieved = (MutableAcl) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
assertEquals(acl, retrieved);
|
||||
|
||||
Object retrieved1 = FieldUtils.getProtectedFieldValue("aclAuthorizationStrategy", retrieved);
|
||||
assertEquals(null, retrieved1);
|
||||
|
||||
Object retrieved2 = FieldUtils.getProtectedFieldValue("auditLogger", retrieved);
|
||||
assertEquals(null, retrieved2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(new Long(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, new Long(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(new Long(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, new Long(102)));
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
|
||||
myCache.evictFromCache(new Long(1));
|
||||
assertEquals(cache.getSize(), 2);
|
||||
assertEquals(2, cache.getDiskStoreSize());
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(new Long(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(cache.getSize(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Ehcache cache = getCache();
|
||||
EhCacheBasedAclCache myCache = new EhCacheBasedAclCache(cache);
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, new Long(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, new Long(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
|
||||
new GrantedAuthorityImpl("ROLE_GENERAL") });
|
||||
MutableAcl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, cache.getDiskStoreSize());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(cache.getSize(), 4);
|
||||
assertEquals(4, cache.getDiskStoreSize());
|
||||
assertTrue(cache.isElementOnDisk(acl.getObjectIdentity()));
|
||||
assertTrue(cache.isElementOnDisk(Long.valueOf(1)));
|
||||
assertFalse(cache.isElementInMemory(acl.getObjectIdentity()));
|
||||
assertFalse(cache.isElementInMemory(Long.valueOf(1)));
|
||||
cache.flush();
|
||||
// Wait for the spool to be written to disk (it's asynchronous)
|
||||
Map spool = (Map) FieldUtils.getFieldValue(cache, "diskStore.spool");
|
||||
|
||||
while(spool.size() > 0) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(new Long(1));
|
||||
// For the checks on transient fields, we need to be sure that the object is being loaded from the cache,
|
||||
// not from the ehcache spool or elsewhere...
|
||||
assertFalse(acl == aclFromCache);
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "auditLogger"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(new Long(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockEhcache extends Cache {
|
||||
public MockEhcache() {
|
||||
super("cache", 0, true, true, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Andrei Stefan
|
||||
* @version $Id:JdbcMutableAclServiceTests.java 1754 2006-11-17 02:01:21Z benalex $
|
||||
*/
|
||||
@ContextConfiguration(locations={"/jdbcMutableAclServiceTests-context.xml"})
|
||||
public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
|
||||
+66
-66
@@ -1,66 +1,66 @@
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link SidRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SidRetrievalStrategyTests {
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void correctSidsAreRetrieved() throws Exception {
|
||||
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
|
||||
List<Sid> sids = retrStrategy.getSids(authentication);
|
||||
|
||||
assertNotNull(sids);
|
||||
assertEquals(4, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
|
||||
for (int i = 1; i < sids.size(); i++) {
|
||||
assertTrue(sids.get(i) instanceof GrantedAuthoritySid);
|
||||
}
|
||||
|
||||
assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
|
||||
assertEquals("A", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
assertEquals("B", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
|
||||
assertEquals("C", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roleHierarchyIsUsedWhenSet() throws Exception {
|
||||
RoleHierarchy rh = mock(RoleHierarchy.class);
|
||||
List<GrantedAuthority> rhAuthorities = AuthorityUtils.createAuthorityList("D");
|
||||
when(rh.getReachableGrantedAuthorities(anyList())).thenReturn(rhAuthorities);
|
||||
SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
|
||||
|
||||
List<Sid> sids = strat.getSids(authentication);
|
||||
assertEquals(2, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
assertEquals("D", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.acls.model.SidRetrievalStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link SidRetrievalStrategyImpl}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SidRetrievalStrategyTests {
|
||||
Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Test
|
||||
public void correctSidsAreRetrieved() throws Exception {
|
||||
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
|
||||
List<Sid> sids = retrStrategy.getSids(authentication);
|
||||
|
||||
assertNotNull(sids);
|
||||
assertEquals(4, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
|
||||
for (int i = 1; i < sids.size(); i++) {
|
||||
assertTrue(sids.get(i) instanceof GrantedAuthoritySid);
|
||||
}
|
||||
|
||||
assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
|
||||
assertEquals("A", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
assertEquals("B", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
|
||||
assertEquals("C", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roleHierarchyIsUsedWhenSet() throws Exception {
|
||||
RoleHierarchy rh = mock(RoleHierarchy.class);
|
||||
List<GrantedAuthority> rhAuthorities = AuthorityUtils.createAuthorityList("D");
|
||||
when(rh.getReachableGrantedAuthorities(anyList())).thenReturn(rhAuthorities);
|
||||
SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
|
||||
|
||||
List<Sid> sids = strat.getSids(authentication);
|
||||
assertEquals(2, sids.size());
|
||||
assertNotNull(sids.get(0));
|
||||
assertTrue(sids.get(0) instanceof PrincipalSid);
|
||||
assertEquals("D", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,190 +1,190 @@
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
|
||||
public class SidTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testPrincipalSidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new PrincipalSid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("johndoe");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one Authentication-argument constructor
|
||||
try {
|
||||
Authentication authentication = null;
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken(null, "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new GrantedAuthoritySid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("ROLE_TEST");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one GrantedAuthority-argument constructor
|
||||
try {
|
||||
GrantedAuthority ga = null;
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl(null);
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPrincipalSidEquals() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertFalse(principalSid.equals(null));
|
||||
Assert.assertFalse(principalSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(principalSid.equals(principalSid));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(authentication)));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("johndoe", null))));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("scott", null))));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid("johndoe")));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid("scott")));
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidEquals() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertFalse(gaSid.equals(null));
|
||||
Assert.assertFalse(gaSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(gaSid.equals(gaSid));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(ga)));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST"))));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_NOT_EQUAL"))));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid("ROLE_TEST")));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid("ROLE_NOT_EQUAL")));
|
||||
}
|
||||
|
||||
public void testPrincipalSidHashCode() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertTrue(principalSid.hashCode() == new String("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() == new PrincipalSid("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid("scott").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidHashCode() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue(gaSid.hashCode() == new String("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() == new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST_2")).hashCode());
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
PrincipalSid principalSid = new PrincipalSid(authentication);
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
GrantedAuthoritySid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue("johndoe".equals(principalSid.getPrincipal()));
|
||||
Assert.assertFalse("scott".equals(principalSid.getPrincipal()));
|
||||
|
||||
Assert.assertTrue("ROLE_TEST".equals(gaSid.getGrantedAuthority()));
|
||||
Assert.assertFalse("ROLE_TEST2".equals(gaSid.getGrantedAuthority()));
|
||||
}
|
||||
}
|
||||
package org.springframework.security.acls.sid;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.acls.domain.GrantedAuthoritySid;
|
||||
import org.springframework.security.acls.domain.PrincipalSid;
|
||||
import org.springframework.security.acls.model.Sid;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.GrantedAuthorityImpl;
|
||||
|
||||
public class SidTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testPrincipalSidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new PrincipalSid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new PrincipalSid("johndoe");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one Authentication-argument constructor
|
||||
try {
|
||||
Authentication authentication = null;
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken(null, "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
new PrincipalSid(authentication);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidConstructorsRequiredFields() throws Exception {
|
||||
// Check one String-argument constructor
|
||||
try {
|
||||
String string = null;
|
||||
new GrantedAuthoritySid(string);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("");
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new GrantedAuthoritySid("ROLE_TEST");
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
|
||||
// Check one GrantedAuthority-argument constructor
|
||||
try {
|
||||
GrantedAuthority ga = null;
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl(null);
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.fail("It should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
new GrantedAuthoritySid(ga);
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
catch (IllegalArgumentException notExpected) {
|
||||
Assert.fail("It shouldn't have thrown IllegalArgumentException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPrincipalSidEquals() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertFalse(principalSid.equals(null));
|
||||
Assert.assertFalse(principalSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(principalSid.equals(principalSid));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(authentication)));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("johndoe", null))));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid(new TestingAuthenticationToken("scott", null))));
|
||||
Assert.assertTrue(principalSid.equals(new PrincipalSid("johndoe")));
|
||||
Assert.assertFalse(principalSid.equals(new PrincipalSid("scott")));
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidEquals() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertFalse(gaSid.equals(null));
|
||||
Assert.assertFalse(gaSid.equals("DIFFERENT_TYPE_OBJECT"));
|
||||
Assert.assertTrue(gaSid.equals(gaSid));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(ga)));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST"))));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_NOT_EQUAL"))));
|
||||
Assert.assertTrue(gaSid.equals(new GrantedAuthoritySid("ROLE_TEST")));
|
||||
Assert.assertFalse(gaSid.equals(new GrantedAuthoritySid("ROLE_NOT_EQUAL")));
|
||||
}
|
||||
|
||||
public void testPrincipalSidHashCode() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
Sid principalSid = new PrincipalSid(authentication);
|
||||
|
||||
Assert.assertTrue(principalSid.hashCode() == new String("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() == new PrincipalSid("johndoe").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid("scott").hashCode());
|
||||
Assert.assertTrue(principalSid.hashCode() != new PrincipalSid(new TestingAuthenticationToken("scott", "password")).hashCode());
|
||||
}
|
||||
|
||||
public void testGrantedAuthoritySidHashCode() throws Exception {
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
Sid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue(gaSid.hashCode() == new String("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() == new GrantedAuthoritySid("ROLE_TEST").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid("ROLE_TEST_2").hashCode());
|
||||
Assert.assertTrue(gaSid.hashCode() != new GrantedAuthoritySid(new GrantedAuthorityImpl("ROLE_TEST_2")).hashCode());
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
Authentication authentication = new TestingAuthenticationToken("johndoe", "password");
|
||||
PrincipalSid principalSid = new PrincipalSid(authentication);
|
||||
GrantedAuthority ga = new GrantedAuthorityImpl("ROLE_TEST");
|
||||
GrantedAuthoritySid gaSid = new GrantedAuthoritySid(ga);
|
||||
|
||||
Assert.assertTrue("johndoe".equals(principalSid.getPrincipal()));
|
||||
Assert.assertFalse("scott".equals(principalSid.getPrincipal()));
|
||||
|
||||
Assert.assertTrue("ROLE_TEST".equals(gaSid.getGrantedAuthority()));
|
||||
Assert.assertFalse("ROLE_TEST2".equals(gaSid.getGrantedAuthority()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing business beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
-->
|
||||
|
||||
<beans>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName" value="aclCache"/>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
|
||||
<!-- Uncomment to use PostgreSQL
|
||||
<property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))"/>
|
||||
<property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))"/>
|
||||
-->
|
||||
</bean>
|
||||
|
||||
<!-- PostgreSQL DataSource configuration
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.postgresql.Driver"/>
|
||||
<property name="url" value="jdbc:postgresql://localhost:5432/acltest"/>
|
||||
<property name="username" value="acltest"/>
|
||||
<property name="password" value="acltest"/>
|
||||
</bean>
|
||||
-->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:acltest"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<!--
|
||||
- Application context containing business beans.
|
||||
-
|
||||
- Used by all artifacts.
|
||||
-
|
||||
- $Id:applicationContext-test.xml 1754 2006-11-17 02:01:21Z benalex $
|
||||
-->
|
||||
|
||||
<beans>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
|
||||
<property name="cacheManager">
|
||||
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
|
||||
</property>
|
||||
<property name="cacheName" value="aclCache"/>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
<constructor-arg ref="aclAuthorizationStrategy"/>
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclAuthorizationStrategy" class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
<bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
|
||||
<constructor-arg value="ROLE_ADMINISTRATOR"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
<constructor-arg ref="lookupStrategy"/>
|
||||
<constructor-arg ref="aclCache"/>
|
||||
|
||||
<!-- Uncomment to use PostgreSQL
|
||||
<property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))"/>
|
||||
<property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))"/>
|
||||
-->
|
||||
</bean>
|
||||
|
||||
<!-- PostgreSQL DataSource configuration
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.postgresql.Driver"/>
|
||||
<property name="url" value="jdbc:postgresql://localhost:5432/acltest"/>
|
||||
<property name="username" value="acltest"/>
|
||||
<property name="password" value="acltest"/>
|
||||
</bean>
|
||||
-->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:acltest"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
+12
-14
@@ -1,5 +1,3 @@
|
||||
Implementation-Title: org.springframework.security.acls
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.acls
|
||||
Bundle-Name: Spring Security Acls
|
||||
Bundle-Vendor: SpringSource
|
||||
@@ -9,15 +7,15 @@ Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aopalliance.*;version="${aopAllianceRange}",
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.access.*;version="${secRange}",
|
||||
org.springframework.security.util.*;version="${secRange}",
|
||||
org.springframework.context.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.dao.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.jdbc.core.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.transaction.support.*;version="${springRange}";resolution:=optional,
|
||||
org.springframework.util.*;version="${springRange}";resolution:=optional,
|
||||
net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
|
||||
javax.sql.*;version="0";resolution:=optional
|
||||
org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
|
||||
org.springframework.security.core.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.security.access.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.security.util.*;version="[${version}, 3.1.0)",
|
||||
org.springframework.context.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
|
||||
org.springframework.dao.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
|
||||
org.springframework.jdbc.core.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
|
||||
org.springframework.transaction.support.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
|
||||
org.springframework.util.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
|
||||
net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional,
|
||||
javax.sql.*;version="0";resolution:=optional
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion"
|
||||
}
|
||||
+8
-4
@@ -5,12 +5,16 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<version>@pomVersion@</version>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>spring-security-aspects</artifactId>
|
||||
<name>Spring Security - Aspects</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
@@ -18,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<version>@pomVersion@</version>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
@@ -35,12 +39,12 @@
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<version>1.6.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<version>1.6.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
|
||||
+8
-18
@@ -2,12 +2,11 @@ package org.springframework.security.access.intercept.aspectj.aspect;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.access.prepost.*;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJCallback;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ aspect using Spring Security @Secured annotation
|
||||
* Concrete AspectJ transaction aspect using Spring Security @Secured annotation
|
||||
* for JDK 1.5+.
|
||||
*
|
||||
* <p>
|
||||
@@ -17,8 +16,8 @@ import org.springframework.security.access.intercept.aspectj.AspectJMethodSecuri
|
||||
* interfaces are <i>not</i> inherited. This will vary from Spring AOP.
|
||||
*
|
||||
* @author Mike Wiesner
|
||||
* @author Luke Taylor
|
||||
* @since 3.1
|
||||
* @since 1.0
|
||||
* @version $Id$
|
||||
*/
|
||||
public aspect AnnotationSecurityAspect implements InitializingBean {
|
||||
|
||||
@@ -35,19 +34,11 @@ public aspect AnnotationSecurityAspect implements InitializingBean {
|
||||
private pointcut executionOfSecuredMethod() :
|
||||
execution(* *(..)) && @annotation(Secured);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with Pre/Post annotations.
|
||||
*/
|
||||
private pointcut executionOfPrePostAnnotatedMethod() :
|
||||
execution(* *(..)) && (@annotation(PreAuthorize) || @annotation(PreFilter)
|
||||
|| @annotation(PostAuthorize) || @annotation(PostFilter));
|
||||
|
||||
private pointcut securedMethodExecution() :
|
||||
executionOfAnyPublicMethodInAtSecuredType() ||
|
||||
executionOfSecuredMethod() ||
|
||||
executionOfPrePostAnnotatedMethod();
|
||||
executionOfSecuredMethod();
|
||||
|
||||
private AspectJMethodSecurityInterceptor securityInterceptor;
|
||||
private AspectJSecurityInterceptor securityInterceptor;
|
||||
|
||||
Object around(): securedMethodExecution() {
|
||||
if (this.securityInterceptor == null) {
|
||||
@@ -63,14 +54,13 @@ public aspect AnnotationSecurityAspect implements InitializingBean {
|
||||
return this.securityInterceptor.invoke(thisJoinPoint, callback);
|
||||
}
|
||||
|
||||
public void setSecurityInterceptor(AspectJMethodSecurityInterceptor securityInterceptor) {
|
||||
public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
|
||||
this.securityInterceptor = securityInterceptor;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.securityInterceptor == null) {
|
||||
if (this.securityInterceptor == null)
|
||||
throw new IllegalArgumentException("securityInterceptor required");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
package org.springframework.security.access.intercept.aspectj.aspect;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.security.access.AccessDecisionManager;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource;
|
||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory;
|
||||
import org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter;
|
||||
import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource;
|
||||
import org.springframework.security.access.vote.AffirmativeBased;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @since 3.0.3
|
||||
*/
|
||||
public class AnnotationSecurityAspectTests {
|
||||
private @Mock AccessDecisionManager adm;
|
||||
private @Mock AuthenticationManager authman;
|
||||
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 PrePostSecured prePostSecured = new PrePostSecured();
|
||||
|
||||
@Before
|
||||
public final void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
interceptor = new AspectJMethodSecurityInterceptor();
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
interceptor.setAuthenticationManager(authman);
|
||||
interceptor.setSecurityMetadataSource(new SecuredAnnotationSecurityMetadataSource());
|
||||
AnnotationSecurityAspect secAspect = AnnotationSecurityAspect.aspectOf();
|
||||
secAspect.setSecurityInterceptor(interceptor);
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void securedInterfaceMethodAllowsAllAccess() throws Exception {
|
||||
secured.securedMethod();
|
||||
}
|
||||
|
||||
@Test(expected=AuthenticationCredentialsNotFoundException.class)
|
||||
public void securedClassMethodDeniesUnauthenticatedAccess() throws Exception {
|
||||
secured.securedClassMethod();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void securedClassMethodAllowsAccessToRoleA() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(anne);
|
||||
secured.securedClassMethod();
|
||||
}
|
||||
|
||||
// SEC-1262
|
||||
@Test(expected=AccessDeniedException.class)
|
||||
public void denyAllPreAuthorizeDeniesAccess() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(anne);
|
||||
interceptor.setSecurityMetadataSource(new PrePostAnnotationSecurityMetadataSource(
|
||||
new ExpressionBasedAnnotationAttributeFactory(new DefaultMethodSecurityExpressionHandler())));
|
||||
AffirmativeBased adm = new AffirmativeBased();
|
||||
AccessDecisionVoter[] voters = new AccessDecisionVoter[]
|
||||
{new PreInvocationAuthorizationAdviceVoter(new ExpressionBasedPreInvocationAdvice())};
|
||||
adm.setDecisionVoters(Arrays.asList(voters));
|
||||
interceptor.setAccessDecisionManager(adm);
|
||||
prePostSecured.denyAllMethod();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
@Secured("ROLE_A")
|
||||
public void securedClassMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
class PrePostSecured {
|
||||
|
||||
@PreAuthorize("denyAll")
|
||||
public void denyAllMethod() {
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
Implementation-Title: org.springframework.security.aspects
|
||||
Implementation-Version: ${version}
|
||||
Bundle-SymbolicName: org.springframework.security.aspects
|
||||
Bundle-Name: Spring Security Aspects
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Version: ${version}
|
||||
Ignored-Existing-Headers:
|
||||
Import-Package,
|
||||
Export-Package
|
||||
Import-Template:
|
||||
org.aspectj.*;version="${aspectjRange}";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="${cloggingRange}",
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.access.intercept.aspectj;version="${secRange}",
|
||||
org.springframework.beans.factory;version="${springRange}"
|
||||
+33
-70
@@ -1,84 +1,47 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'base'
|
||||
import org.gradle.api.tasks.diagnostics.GraphvizReportRenderer
|
||||
|
||||
usePlugin('java')
|
||||
|
||||
version = '3.0.0.CI-SNAPSHOT'
|
||||
|
||||
description = 'Spring Security'
|
||||
allprojects {
|
||||
ext.releaseBuild = version.endsWith('RELEASE')
|
||||
ext.snapshotBuild = version.endsWith('SNAPSHOT')
|
||||
|
||||
group = 'org.springframework.security'
|
||||
|
||||
repositories {
|
||||
mavenRepo name:'localRepo', urls:'file:///Users/luke/.m2/repository'
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
// Set up different subproject lists for individual configuration
|
||||
ext.javaProjects = subprojects.findAll { project -> project.name != 'docs' && project.name != 'faq' && project.name != 'manual' }
|
||||
ext.sampleProjects = subprojects.findAll { project -> project.name.startsWith('spring-security-samples') }
|
||||
ext.itestProjects = subprojects.findAll { project -> project.name.startsWith('itest') }
|
||||
ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
|
||||
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj')]
|
||||
configure(javaProjects) {
|
||||
apply from: "$rootDir/gradle/javaprojects.gradle"
|
||||
}
|
||||
subprojects {
|
||||
usePlugin 'java'
|
||||
usePlugin 'project-reports'
|
||||
|
||||
springVersion = '3.0.0.RELEASE'
|
||||
springLdapVersion = '1.3.0.RELEASE'
|
||||
ehcacheVersion = '1.6.2'
|
||||
aspectjVersion = '1.6.5'
|
||||
apacheDsVersion = '1.5.5'
|
||||
|
||||
configure(coreModuleProjects) {
|
||||
// Gives better names in structure101 jar diagram
|
||||
sourceSets.main.output.classesDir = new File(buildDir, "classes/" + project.name.substring("spring-security".length() + 1))
|
||||
apply plugin: 'bundlor'
|
||||
bundlor.expansions = bundlorProperties
|
||||
apply from: "$rootDir/gradle/maven-deployment.gradle"
|
||||
apply plugin: 'emma'
|
||||
}
|
||||
/* dependencyReport {
|
||||
renderer = new GraphvizReportRenderer()
|
||||
}*/
|
||||
|
||||
task coreBuild {
|
||||
dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'build' }
|
||||
}
|
||||
dependencies {
|
||||
compile 'commons-logging:commons-logging:1.1.1'
|
||||
|
||||
configure (aspectjProjects) {
|
||||
apply plugin: 'aspectj'
|
||||
}
|
||||
|
||||
// Task for creating the distro zip
|
||||
|
||||
task dist(type: Zip) {
|
||||
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') }
|
||||
classifier = 'dist'
|
||||
evaluationDependsOn(':docs')
|
||||
def zipRootDir = "${project.name}-$version"
|
||||
into(zipRootDir) {
|
||||
from(rootDir) {
|
||||
include '*.txt'
|
||||
}
|
||||
into('docs') {
|
||||
with(project(':docs').apiSpec)
|
||||
with(project(':docs:manual').spec)
|
||||
}
|
||||
into('dist') {
|
||||
from coreModuleProjects.collect {project -> project.libsDir }
|
||||
from project(':spring-security-samples-tutorial').libsDir
|
||||
from project(':spring-security-samples-contacts').libsDir
|
||||
}
|
||||
testCompile 'junit:junit:4.7',
|
||||
'org.mockito:mockito-core:1.7',
|
||||
'org.jmock:jmock:2.5.1',
|
||||
'org.jmock:jmock-junit4:2.5.1',
|
||||
'org.hamcrest:hamcrest-core:1.1',
|
||||
'org.hamcrest:hamcrest-library:1.1',
|
||||
"org.springframework:spring-test:$springVersion"
|
||||
}
|
||||
|
||||
test {
|
||||
options.fork(forkMode: ForkMode.ONCE, jvmArgs: ["-ea", '-Xms128m', '-Xmx1g', '-XX:MaxPermSize=128m', '-XX:+HeapDumpOnOutOfMemoryError'])
|
||||
}
|
||||
|
||||
group = 'org.springframework.security'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives dist
|
||||
archives project(':docs').docsZip
|
||||
archives project(':docs').schemaZip
|
||||
}
|
||||
|
||||
apply from: "$rootDir/gradle/ide-integration.gradle"
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '1.9'
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
apply plugin: 'groovy'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'SpringSource Enterprise Release'
|
||||
url = 'http://repository.springsource.com/maven/bundles/release'
|
||||
}
|
||||
maven {
|
||||
name = 'SpringSource Enterprise External'
|
||||
url = 'http://repository.springsource.com/maven/bundles/external'
|
||||
}
|
||||
}
|
||||
|
||||
// Docbook Plugin
|
||||
dependencies {
|
||||
def fopDeps = [ 'org.apache.xmlgraphics:fop:0.95-1@jar',
|
||||
'org.apache.xmlgraphics:xmlgraphics-commons:1.3',
|
||||
'org.apache.xmlgraphics:batik-bridge:1.7@jar',
|
||||
'org.apache.xmlgraphics:batik-util:1.7@jar',
|
||||
'org.apache.xmlgraphics:batik-css:1.7@jar',
|
||||
'org.apache.xmlgraphics:batik-dom:1.7',
|
||||
'org.apache.xmlgraphics:batik-svg-dom:1.7@jar',
|
||||
'org.apache.avalon.framework:avalon-framework-api:4.3.1']
|
||||
groovy localGroovy()
|
||||
compile gradleApi(),
|
||||
'xml-resolver:xml-resolver:1.2',
|
||||
'xerces:xercesImpl:2.9.1',
|
||||
'saxon:saxon:6.5.3',
|
||||
'net.java.dev.jets3t:jets3t:0.6.1',
|
||||
fopDeps
|
||||
|
||||
runtime 'net.sf.xslthl:xslthl:2.0.1',
|
||||
'net.sf.docbook:docbook-xsl:1.75.2:ns-resources@zip'
|
||||
}
|
||||
|
||||
// GAE
|
||||
dependencies {
|
||||
compile 'com.google.appengine:appengine-tools-sdk:1.4.2'
|
||||
}
|
||||
|
||||
dependencies{
|
||||
compile "emma:emma:2.0.5312"
|
||||
}
|
||||
|
||||
// Bundlor
|
||||
dependencies {
|
||||
compile 'com.springsource.bundlor:com.springsource.bundlor:1.0.0.RELEASE',
|
||||
'com.springsource.bundlor:com.springsource.bundlor.blint:1.0.0.RELEASE'
|
||||
}
|
||||
|
||||
task ide(type: Copy) {
|
||||
from configurations.runtime
|
||||
into 'ide'
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package aspectj
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
|
||||
import org.gradle.plugins.ide.eclipse.GenerateEclipseProject
|
||||
import org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
import org.gradle.plugins.ide.eclipse.model.BuildCommand
|
||||
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
class AspectJPlugin implements Plugin<Project> {
|
||||
|
||||
void apply(Project project) {
|
||||
if (!project.hasProperty('aspectjVersion')) {
|
||||
throw new GradleException("You must set the property 'aspectjVersion' before applying the aspectj plugin")
|
||||
}
|
||||
|
||||
if (project.configurations.findByName('ajtools') == null) {
|
||||
project.configurations.add('ajtools')
|
||||
project.dependencies {
|
||||
ajtools "org.aspectj:aspectjtools:${project.aspectjVersion}"
|
||||
compile "org.aspectj:aspectjrt:${project.aspectjVersion}"
|
||||
}
|
||||
}
|
||||
|
||||
if (project.configurations.findByName('aspectpath') == null) {
|
||||
project.configurations.add('aspectpath')
|
||||
}
|
||||
|
||||
project.tasks.add(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
|
||||
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||
dependsOn project.processResources
|
||||
sourceSet = project.sourceSets.main
|
||||
inputs.files(sourceSet.java.srcDirs)
|
||||
outputs.dir(sourceSet.output.classesDir)
|
||||
aspectPath = project.configurations.aspectpath
|
||||
}
|
||||
project.tasks.compileJava.deleteAllActions()
|
||||
project.tasks.compileJava.dependsOn project.tasks.compileAspect
|
||||
|
||||
project.tasks.add(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
|
||||
dependsOn project.processTestResources, project.compileJava, project.jar
|
||||
sourceSet = project.sourceSets.test
|
||||
inputs.files(sourceSet.java.srcDirs)
|
||||
outputs.dir(sourceSet.output.classesDir)
|
||||
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
|
||||
}
|
||||
project.tasks.compileTestJava.deleteAllActions()
|
||||
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
|
||||
|
||||
project.tasks.withType(GenerateEclipseProject) {
|
||||
project.eclipse.project.file.whenMerged { p ->
|
||||
p.natures.add(0, 'org.eclipse.ajdt.ui.ajnature')
|
||||
p.buildCommands = [new BuildCommand('org.eclipse.ajdt.core.ajbuilder')]
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.withType(GenerateEclipseClasspath) {
|
||||
project.eclipse.classpath.file.whenMerged { classpath ->
|
||||
def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
|
||||
def projectPath = entry.path.replaceAll('/','')
|
||||
project.rootProject.allprojects.find{ p->
|
||||
if(p.plugins.findPlugin(EclipsePlugin)) {
|
||||
return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
entries.each { entry->
|
||||
entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Ajc extends DefaultTask {
|
||||
SourceSet sourceSet
|
||||
FileCollection aspectPath
|
||||
|
||||
Ajc() {
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
def compile() {
|
||||
logger.info("Running ajc ...")
|
||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
|
||||
ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.output.classesDir.absolutePath,
|
||||
source: project.convention.plugins.java.sourceCompatibility,
|
||||
target: project.convention.plugins.java.targetCompatibility,
|
||||
aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
|
||||
sourceroots {
|
||||
sourceSet.java.srcDirs.each {
|
||||
pathelement(location: it.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
package bundlor
|
||||
|
||||
import com.springsource.bundlor.ClassPath
|
||||
import com.springsource.bundlor.ManifestGenerator
|
||||
import com.springsource.bundlor.ManifestWriter
|
||||
import com.springsource.bundlor.blint.ManifestValidator
|
||||
import com.springsource.bundlor.blint.support.DefaultManifestValidatorContributorsFactory
|
||||
import com.springsource.bundlor.blint.support.StandardManifestValidator
|
||||
import com.springsource.bundlor.support.DefaultManifestGeneratorContributorsFactory
|
||||
import com.springsource.bundlor.support.StandardManifestGenerator
|
||||
import com.springsource.bundlor.support.classpath.FileSystemClassPath
|
||||
import com.springsource.bundlor.support.manifestwriter.FileSystemManifestWriter
|
||||
import com.springsource.bundlor.support.properties.EmptyPropertiesSource
|
||||
import com.springsource.bundlor.support.properties.FileSystemPropertiesSource
|
||||
import com.springsource.bundlor.support.properties.PropertiesPropertiesSource
|
||||
import com.springsource.bundlor.support.properties.PropertiesSource
|
||||
import com.springsource.bundlor.util.BundleManifestUtils
|
||||
import com.springsource.util.parser.manifest.ManifestContents
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
class BundlorPlugin implements Plugin<Project> {
|
||||
void apply(Project project) {
|
||||
Task bundlor = project.tasks.add('bundlor', Bundlor.class)
|
||||
bundlor.setDescription('Generates OSGi manifest using bundlor tool')
|
||||
bundlor.dependsOn(project.classes)
|
||||
project.jar.dependsOn bundlor
|
||||
}
|
||||
}
|
||||
|
||||
public class Bundlor extends DefaultTask {
|
||||
@InputFile
|
||||
@Optional
|
||||
File manifestTemplate
|
||||
|
||||
@OutputDirectory
|
||||
File bundlorDir = new File("${project.buildDir}/bundlor")
|
||||
|
||||
@OutputFile
|
||||
File manifest = project.file("${bundlorDir}/META-INF/MANIFEST.MF")
|
||||
|
||||
@Input
|
||||
Map<String,String> expansions = [:]
|
||||
|
||||
@InputFile
|
||||
@Optional
|
||||
File osgiProfile
|
||||
|
||||
@InputFiles
|
||||
@Optional
|
||||
FileCollection inputPaths
|
||||
|
||||
@Input
|
||||
boolean failOnWarnings = false
|
||||
|
||||
Bundlor() {
|
||||
manifestTemplate = new File(project.projectDir, 'template.mf')
|
||||
|
||||
if (!manifestTemplate.exists()) {
|
||||
logger.info("No bundlor template for project " + project.name)
|
||||
manifestTemplate = null
|
||||
}
|
||||
|
||||
inputPaths = project.files(project.sourceSets.main.output.classesDir)
|
||||
|
||||
if (manifestTemplate != null) {
|
||||
project.jar.manifest.from manifest
|
||||
project.jar.inputs.files manifest
|
||||
}
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void createManifest() {
|
||||
if (manifestTemplate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
logging.captureStandardOutput(LogLevel.INFO)
|
||||
|
||||
project.mkdir(bundlorDir)
|
||||
|
||||
//String inputPath = project.sourceSets.main.classesDir
|
||||
|
||||
List<ClassPath> inputClassPath = [] as List;
|
||||
|
||||
ManifestWriter manifestWriter = new FileSystemManifestWriter(project.file(bundlorDir.absolutePath));
|
||||
ManifestContents mfTemplate = BundleManifestUtils.getManifest(manifestTemplate);
|
||||
|
||||
inputPaths.each {f ->
|
||||
inputClassPath.add(new FileSystemClassPath(f))
|
||||
}
|
||||
|
||||
// Must be a better way of doing this...
|
||||
Properties p = new Properties()
|
||||
expansions.each {entry ->
|
||||
p.setProperty(entry.key, entry.value as String)
|
||||
}
|
||||
|
||||
PropertiesSource expansionProps = new PropertiesPropertiesSource(p)
|
||||
PropertiesSource osgiProfileProps = osgiProfile == null ? new EmptyPropertiesSource() :
|
||||
new FileSystemPropertiesSource(osgiProfile);
|
||||
|
||||
ManifestGenerator manifestGenerator = new StandardManifestGenerator(
|
||||
DefaultManifestGeneratorContributorsFactory.create(expansionProps, osgiProfileProps));
|
||||
|
||||
ManifestContents mf = manifestGenerator.generate(mfTemplate, inputClassPath.toArray(new ClassPath[inputClassPath.size()]));
|
||||
|
||||
try {
|
||||
manifestWriter.write(mf);
|
||||
} finally {
|
||||
manifestWriter.close();
|
||||
}
|
||||
|
||||
ManifestValidator manifestValidator = new StandardManifestValidator(DefaultManifestValidatorContributorsFactory.create());
|
||||
|
||||
List<String> warnings = manifestValidator.validate(mf);
|
||||
|
||||
if (warnings.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.warn("Bundlor Warnings:");
|
||||
for (String warning : warnings) {
|
||||
logger.warn(" " + warning);
|
||||
}
|
||||
|
||||
if (failOnWarnings) {
|
||||
throw new GradleException("Bundlor returned warnings. Please fix manifest template at " + manifestTemplate.absolutePath + " and try again.")
|
||||
}
|
||||
}
|
||||
|
||||
def inputPath(FileCollection paths) {
|
||||
inputPaths = project.files(inputPaths, paths)
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
package docbook;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.tasks.*;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.apache.xml.resolver.CatalogManager;
|
||||
import org.apache.xml.resolver.tools.CatalogResolver;
|
||||
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import java.net.*;
|
||||
|
||||
import org.apache.fop.apps.*;
|
||||
|
||||
import com.icl.saxon.TransformerFactoryImpl;
|
||||
|
||||
/**
|
||||
* Gradle Docbook plugin implementation.
|
||||
* <p>
|
||||
* Creates three tasks: docbookHtml, docbookHtmlSingle and docbookPdf. Each task takes a single File on
|
||||
* which it operates.
|
||||
*/
|
||||
class DocbookPlugin implements Plugin<Project> {
|
||||
public void apply(Project project) {
|
||||
// Add the plugin tasks to the project
|
||||
Task docbookHtml = project.tasks.add('docbookHtml', DocbookHtml.class);
|
||||
docbookHtml.setDescription('Generates chunked docbook html output');
|
||||
|
||||
Task docbookHtmlSingle = project.tasks.add('docbookHtmlSingle', Docbook.class);
|
||||
docbookHtmlSingle.setDescription('Generates single page docbook html output')
|
||||
docbookHtmlSingle.suffix = '-single'
|
||||
|
||||
Task docbookFoPdf = project.tasks.add("docbookFoPdf", DocbookFoPdf.class);
|
||||
docbookFoPdf.setDescription('Generates PDF output');
|
||||
docbookFoPdf.extension = 'fo'
|
||||
|
||||
Task docbook = project.tasks.add("docbook", DefaultTask.class);
|
||||
docbook.dependsOn (docbookHtml, docbookHtmlSingle, docbookFoPdf)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public class Docbook extends DefaultTask {
|
||||
|
||||
@Input
|
||||
String extension = 'html';
|
||||
|
||||
@Input
|
||||
String suffix = '';
|
||||
|
||||
@Input
|
||||
boolean XIncludeAware = true;
|
||||
|
||||
@Input
|
||||
boolean highlightingEnabled = true;
|
||||
|
||||
String admonGraphicsPath;
|
||||
|
||||
String imgSrcPath;
|
||||
|
||||
@InputDirectory
|
||||
File sourceDirectory = new File(project.getProjectDir(), "src/docbook");
|
||||
|
||||
@Input
|
||||
String sourceFileName;
|
||||
|
||||
@InputFile
|
||||
File stylesheet;
|
||||
|
||||
@OutputDirectory
|
||||
File docsDir = new File(project.getBuildDir(), "docs");
|
||||
|
||||
@TaskAction
|
||||
public final void transform() {
|
||||
SAXParserFactory factory = new org.apache.xerces.jaxp.SAXParserFactoryImpl();
|
||||
factory.setXIncludeAware(XIncludeAware);
|
||||
docsDir.mkdirs();
|
||||
|
||||
File srcFile = new File(filterDocbookSources(sourceDirectory), sourceFileName);
|
||||
String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + suffix + '.' + extension;
|
||||
|
||||
File outputFile = new File(getDocsDir(), outputFilename);
|
||||
|
||||
Result result = new StreamResult(outputFile.getAbsolutePath());
|
||||
CatalogResolver resolver = new CatalogResolver(createCatalogManager());
|
||||
InputSource inputSource = new InputSource(srcFile.getAbsolutePath());
|
||||
|
||||
XMLReader reader = factory.newSAXParser().getXMLReader();
|
||||
reader.setEntityResolver(resolver);
|
||||
TransformerFactory transformerFactory = new TransformerFactoryImpl();
|
||||
transformerFactory.setURIResolver(resolver);
|
||||
URL url = stylesheet.toURL();
|
||||
Source source = new StreamSource(url.openStream(), url.toExternalForm());
|
||||
Transformer transformer = transformerFactory.newTransformer(source);
|
||||
|
||||
if (highlightingEnabled) {
|
||||
File highlightingDir = new File(getProject().getBuildDir(), "highlighting");
|
||||
if (!highlightingDir.exists()) {
|
||||
highlightingDir.mkdirs();
|
||||
extractHighlightFiles(highlightingDir);
|
||||
}
|
||||
|
||||
transformer.setParameter("highlight.xslthl.config", new File(highlightingDir, "xslthl-config.xml").toURI().toURL());
|
||||
}
|
||||
|
||||
if (admonGraphicsPath != null) {
|
||||
transformer.setParameter("admon.graphics", "1");
|
||||
transformer.setParameter("admon.graphics.path", admonGraphicsPath);
|
||||
}
|
||||
|
||||
if (imgSrcPath != null) {
|
||||
transformer.setParameter("img.src.path", imgSrcPath);
|
||||
}
|
||||
|
||||
preTransform(transformer, srcFile, outputFile);
|
||||
|
||||
transformer.transform(new SAXSource(reader, inputSource), result);
|
||||
|
||||
postTransform(outputFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceDir directory of unfiltered sources
|
||||
* @return directory of filtered sources
|
||||
* @author Chris Beams
|
||||
*/
|
||||
private File filterDocbookSources(File sourceDir) {
|
||||
def docbookWorkDir = new File("${project.buildDir}/reference-work")
|
||||
|
||||
docbookWorkDir.mkdirs()
|
||||
|
||||
// copy everything but springsecurity.xml
|
||||
project.copy {
|
||||
into(docbookWorkDir)
|
||||
from(sourceDir) { exclude '**/springsecurity.xml' }
|
||||
}
|
||||
// copy index.xml and expand ${...} variables along the way
|
||||
// e.g.: ${version} needs to be replaced in the header
|
||||
project.copy {
|
||||
into(docbookWorkDir)
|
||||
from(sourceDir) { include '**/springsecurity.xml' }
|
||||
expand(version: "${project.version}")
|
||||
}
|
||||
|
||||
return docbookWorkDir
|
||||
}
|
||||
|
||||
private void extractHighlightFiles(File toDir) {
|
||||
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
|
||||
URL[] urls = cl.getURLs();
|
||||
URL docbookZip = null;
|
||||
|
||||
for (URL url : urls) {
|
||||
if (url.toString().contains("docbook-xsl-")) {
|
||||
docbookZip = url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (docbookZip == null) {
|
||||
throw new GradleException("Docbook zip file not found");
|
||||
}
|
||||
|
||||
ZipFile zipFile = new ZipFile(new File(docbookZip.toURI()));
|
||||
|
||||
Enumeration e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry ze = (ZipEntry) e.nextElement();
|
||||
if (ze.getName().matches(".*/highlighting/.*\\.xml")) {
|
||||
String filename = ze.getName().substring(ze.getName().lastIndexOf("/highlighting/") + 14);
|
||||
copyFile(zipFile.getInputStream(ze), new File(toDir, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyFile(InputStream source, File destFile) {
|
||||
destFile.createNewFile();
|
||||
FileOutputStream to = null;
|
||||
try {
|
||||
to = new FileOutputStream(destFile);
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
|
||||
while ((bytesRead = source.read(buffer)) > 0) {
|
||||
to.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} finally {
|
||||
if (source != null) {
|
||||
source.close();
|
||||
}
|
||||
if (to != null) {
|
||||
to.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void preTransform(Transformer transformer, File sourceFile, File outputFile) {
|
||||
}
|
||||
|
||||
protected void postTransform(File outputFile) {
|
||||
}
|
||||
|
||||
private CatalogManager createCatalogManager() {
|
||||
CatalogManager manager = new CatalogManager();
|
||||
manager.setIgnoreMissingProperties(true);
|
||||
ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String docbookCatalogName = "docbook/catalog.xml";
|
||||
URL docbookCatalog = classLoader.getResource(docbookCatalogName);
|
||||
|
||||
if (docbookCatalog == null) {
|
||||
throw new IllegalStateException("Docbook catalog " + docbookCatalogName + " could not be found in " + classLoader);
|
||||
}
|
||||
|
||||
builder.append(docbookCatalog.toExternalForm());
|
||||
|
||||
Enumeration enumeration = classLoader.getResources("/catalog.xml");
|
||||
while (enumeration.hasMoreElements()) {
|
||||
builder.append(';');
|
||||
URL resource = (URL) enumeration.nextElement();
|
||||
builder.append(resource.toExternalForm());
|
||||
}
|
||||
String catalogFiles = builder.toString();
|
||||
manager.setCatalogFiles(catalogFiles);
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
class DocbookHtml extends Docbook {
|
||||
|
||||
@Override
|
||||
protected void preTransform(Transformer transformer, File sourceFile, File outputFile) {
|
||||
String rootFilename = outputFile.getName();
|
||||
rootFilename = rootFilename.substring(0, rootFilename.lastIndexOf('.'));
|
||||
transformer.setParameter("root.filename", rootFilename);
|
||||
transformer.setParameter("base.dir", outputFile.getParent() + File.separator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
class DocbookFoPdf extends Docbook {
|
||||
|
||||
/**
|
||||
* <a href="http://xmlgraphics.apache.org/fop/0.95/embedding.html#render">From the FOP usage guide</a>
|
||||
*/
|
||||
@Override
|
||||
protected void postTransform(File foFile) {
|
||||
FopFactory fopFactory = FopFactory.newInstance();
|
||||
|
||||
OutputStream out = null;
|
||||
final File pdfFile = getPdfOutputFile(foFile);
|
||||
logger.debug("Transforming 'fo' file "+ foFile + " to PDF: " + pdfFile);
|
||||
|
||||
try {
|
||||
out = new BufferedOutputStream(new FileOutputStream(pdfFile));
|
||||
|
||||
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
|
||||
|
||||
TransformerFactory factory = TransformerFactory.newInstance();
|
||||
Transformer transformer = factory.newTransformer();
|
||||
|
||||
Source src = new StreamSource(foFile);
|
||||
|
||||
Result res = new SAXResult(fop.getDefaultHandler());
|
||||
|
||||
transformer.transform(src, res);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/* if (!foFile.delete()) {
|
||||
logger.warn("Failed to delete 'fo' file " + foFile);
|
||||
}*/
|
||||
}
|
||||
|
||||
private File getPdfOutputFile(File foFile) {
|
||||
String name = foFile.getAbsolutePath();
|
||||
return new File(name.substring(0, name.length() - 2) + "pdf");
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package emma;
|
||||
|
||||
import org.gradle.api.*
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.Input
|
||||
import com.vladium.emma.instr.InstrProcessor
|
||||
import com.vladium.emma.report.ReportProcessor
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import com.vladium.util.XProperties;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
class EmmaPlugin implements Plugin<Project> {
|
||||
|
||||
void apply(Project project) {
|
||||
Project rootProject = project.rootProject
|
||||
def emmaMetaDataFile = "${rootProject.buildDir}/emma/emma.em"
|
||||
def emmaCoverageFile = "${rootProject.buildDir}/emma/emma.ec"
|
||||
|
||||
if (project.configurations.findByName('emma_rt') == null) {
|
||||
project.configurations.add('emma_rt')
|
||||
project.dependencies {
|
||||
emma_rt 'emma:emma:2.0.5312'
|
||||
}
|
||||
}
|
||||
|
||||
project.task('emmaInstrument') {
|
||||
dependsOn project.classes
|
||||
|
||||
doFirst {
|
||||
InstrProcessor processor = InstrProcessor.create ();
|
||||
String[] classesDirPath = [project.sourceSets.main.output.classesDir.absolutePath]
|
||||
|
||||
processor.setInstrPath(classesDirPath, false);
|
||||
processor.setOutMode(InstrProcessor.OutMode.OUT_MODE_COPY);
|
||||
processor.setInstrOutDir("${project.buildDir}/emma/classes");
|
||||
processor.setMetaOutFile(emmaMetaDataFile);
|
||||
processor.setMetaOutMerge(true);
|
||||
//processor.setInclExclFilter (null);
|
||||
processor.run();
|
||||
}
|
||||
}
|
||||
|
||||
// Modify test tasks in the project to generate coverage data
|
||||
project.afterEvaluate {
|
||||
if (project.hasProperty('coverage') && ['on','true'].contains(project.properties.coverage)) {
|
||||
project.tasks.withType(Test.class).each { task ->
|
||||
task.dependsOn project.emmaInstrument
|
||||
task.configure() {
|
||||
jvmArgs '-Dsec.log.level=DEBUG', "-Demma.coverage.out.file=$emmaCoverageFile"
|
||||
jvmArgs '-Demma.verbosity.level=quiet'
|
||||
}
|
||||
task.doFirst {
|
||||
classpath = project.files("${project.buildDir}/emma/classes") + project.configurations.emma_rt + classpath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Task> reportTasks = rootProject.getTasksByName('coverageReport', false) as List;
|
||||
CoverageReport task;
|
||||
|
||||
if (reportTasks.isEmpty()) {
|
||||
task = rootProject.tasks.add('coverageReport', CoverageReport.class);
|
||||
task.dataPath = [emmaMetaDataFile, emmaCoverageFile];
|
||||
} else {
|
||||
task = reportTasks[0];
|
||||
}
|
||||
|
||||
task.modules.add(project);
|
||||
}
|
||||
}
|
||||
|
||||
class CoverageReport extends DefaultTask {
|
||||
@Input
|
||||
List<Project> modules = [];
|
||||
|
||||
@Input
|
||||
String[] dataPath;
|
||||
|
||||
@TaskAction
|
||||
void generateReport() {
|
||||
def buildDir = project.rootProject.buildDir
|
||||
|
||||
if (!buildDir.exists()) {
|
||||
throw new GradleException("No coverage data. Run gradle with -Pcoverage=on if using coverageReport");
|
||||
}
|
||||
|
||||
ReportProcessor processor = ReportProcessor.create ();
|
||||
processor.setDataPath(dataPath)
|
||||
|
||||
def srcPath = []
|
||||
modules.each {module->
|
||||
module.sourceSets.main.java.srcDirs.each {
|
||||
srcPath.add(it.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
processor.setSourcePath(srcPath as String[]);
|
||||
|
||||
|
||||
def types = ['txt', 'html']
|
||||
processor.setReportTypes(types as String[]);
|
||||
XProperties properties = new XProperties();
|
||||
properties.setProperty('report.html.out.file', "$buildDir/emma/coverage.html");
|
||||
properties.setProperty('report.txt.out.file', "$buildDir/emma/coverage.txt");
|
||||
processor.setPropertyOverrides(properties)
|
||||
|
||||
processor.run()
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package gae;
|
||||
|
||||
import com.google.appengine.tools.admin.AppCfg
|
||||
import org.gradle.api.*;
|
||||
|
||||
class GaePlugin implements Plugin<Project> {
|
||||
public void apply(Project project) {
|
||||
if (!project.hasProperty('appEngineSdkRoot')) {
|
||||
println "'appEngineSdkRoot' must be set in gradle.properties"
|
||||
} else {
|
||||
System.setProperty('appengine.sdk.root', project.property('appEngineSdkRoot'))
|
||||
}
|
||||
|
||||
File explodedWar = new File(project.buildDir, "gae-exploded")
|
||||
|
||||
project.task('gaeDeploy') << {
|
||||
AppCfg.main("update", explodedWar.toString())
|
||||
}
|
||||
|
||||
project.gaeDeploy.dependsOn project.war
|
||||
|
||||
project.war.doLast {
|
||||
ant.unzip(src: project.war.archivePath, dest: explodedWar)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=aspectj.AspectJPlugin
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=bundlor.BundlorPlugin
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=docbook.DocbookPlugin
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=emma.EmmaPlugin
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=gae.GaePlugin
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-security-core'),
|
||||
project(':spring-security-web'),
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
compile project(':core'),
|
||||
project(':web'),
|
||||
"javax.servlet:servlet-api:2.5",
|
||||
"org.springframework:spring-core:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.jasig.cas:cas-client-core:3.1.9",
|
||||
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||
|
||||
provided 'javax.servlet:servlet-api:2.5'
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-parent</artifactId>
|
||||
<version>@pomVersion@</version>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
</parent>
|
||||
<artifactId>spring-security-cas-client</artifactId>
|
||||
<name>Spring Security - CAS support</name>
|
||||
@@ -36,7 +36,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jasig.cas</groupId>
|
||||
<artifactId>cas-client-core</artifactId>
|
||||
<version>3.1.10</version>
|
||||
<version>3.1.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user