SEC-1015: Removed acl package from core and also related taglib declaration and implementation class (AclTag).

This commit is contained in:
Luke Taylor 2008-11-11 09:21:51 +00:00
parent e5b1073501
commit 0ba690fb0e
48 changed files with 56 additions and 7097 deletions

View File

@ -1,29 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl;
import java.io.Serializable;
/**
* Marker interface representing an access control list entry associated with a
* specific domain object instance.
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface AclEntry extends Serializable {}

View File

@ -1,52 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl;
import org.springframework.security.Authentication;
/**
* Obtains the <code>AclEntry</code> instances that apply to a particular
* domain object instance.
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface AclManager {
//~ Methods ========================================================================================================
/**
* Obtains the ACLs that apply to the specified domain instance.
*
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
*
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
*/
AclEntry[] getAcls(Object domainInstance);
/**
* Obtains the ACLs that apply to the specified domain instance, but only including those ACLs which have
* been granted to the presented <code>Authentication</code> object
*
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
* @param authentication the prncipal for which ACL information should be filtered (never <code>null</code>)
*
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
* <code>null</code>) if no such ACLs are found
*/
AclEntry[] getAcls(Object domainInstance, Authentication authentication);
}

View File

@ -1,68 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl;
import org.springframework.security.Authentication;
/**
* Indicates a class can process a given domain object instance and
* authoritatively return the ACLs that apply.
*
* <P>
* Implementations are typically called from the {@link AclProviderManager}.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface AclProvider {
//~ Methods ========================================================================================================
/**
* Obtains the ACLs that apply to the specified domain instance.<P>Will never be called unless the {@link
* #supports(Object)} method returned <code>true</code>.</p>
*
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
*
* @return the ACLs that apply, or <code>null</code> if no ACLs apply to the specified domain instance
*/
AclEntry[] getAcls(Object domainInstance);
/**
* Obtains the ACLs that apply to the specified domain instance and presented <code>Authentication</code>
* object.<P>Will never be called unless the {@link #supports(Object)} method returned <code>true</code>.</p>
*
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
* @param authentication the prncipal for which ACL information should be filtered (never <code>null</code>)
*
* @return only those ACLs applying to the domain instance that have been granted to the principal (or
* <code>null</code>) if no such ACLs are found
*/
AclEntry[] getAcls(Object domainInstance, Authentication authentication);
/**
* Indicates whether this <code>AclProvider</code> can authoritatively return ACL information for the
* specified domain object instance.
*
* @param domainInstance the instance for which ACL information is required (never <code>null</code>)
*
* @return <code>true</code> if this provider is authoritative for the specified domain object instance,
* <code>false</code> otherwise
*/
boolean supports(Object domainInstance);
}

View File

@ -1,135 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl;
import org.springframework.security.Authentication;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.util.Iterator;
import java.util.List;
/**
* Iterates through a list of {@link AclProvider}s to locate the ACLs that apply to a given domain object instance.<P>If
* no compatible provider is found, it is assumed that no ACLs apply for the specified domain object instance and
* <code>null</code> is returned.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class AclProviderManager implements AclManager, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(AclProviderManager.class);
//~ Instance fields ================================================================================================
private List providers;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
checkIfValidList(this.providers);
}
private void checkIfValidList(List listToCheck) {
Assert.notEmpty(listToCheck, "A list of AclManagers is required");
}
public AclEntry[] getAcls(Object domainInstance) {
Assert.notNull(domainInstance, "domainInstance is null - violating interface contract");
Iterator iter = providers.iterator();
while (iter.hasNext()) {
AclProvider provider = (AclProvider) iter.next();
if (provider.supports(domainInstance)) {
if (logger.isDebugEnabled()) {
logger.debug("ACL lookup using " + provider.getClass().getName());
}
return provider.getAcls(domainInstance);
}
}
if (logger.isDebugEnabled()) {
logger.debug("No AclProvider found for " + domainInstance.toString());
}
return null;
}
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
Assert.notNull(domainInstance, "domainInstance is null - violating interface contract");
Assert.notNull(authentication, "authentication is null - violating interface contract");
Iterator iter = providers.iterator();
while (iter.hasNext()) {
AclProvider provider = (AclProvider) iter.next();
if (provider.supports(domainInstance)) {
if (logger.isDebugEnabled()) {
logger.debug("ACL lookup using " + provider.getClass().getName());
}
return provider.getAcls(domainInstance, authentication);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Provider " + provider.toString() + " does not support " + domainInstance);
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("No AclProvider found for " + domainInstance.toString());
}
return null;
}
public List getProviders() {
return this.providers;
}
/**
* Sets the {@link AclProvider} objects to be used for ACL determinations.
*
* @param newList that should be used for ACL determinations
*
* @throws IllegalArgumentException if an invalid provider was included in the list
*/
public void setProviders(List newList) {
checkIfValidList(newList);
Iterator iter = newList.iterator();
while (iter.hasNext()) {
Object currentObject = iter.next();
Assert.isInstanceOf(AclProvider.class, currentObject, "Invalid Acl Provider. ");
}
this.providers = newList;
}
}

View File

@ -1,252 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import java.util.Arrays;
/**
* Abstract implementation of {@link BasicAclEntry}.<P>Provides core bit mask handling methods.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public abstract class AbstractBasicAclEntry implements BasicAclEntry {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(AbstractBasicAclEntry.class);
//~ Instance fields ================================================================================================
private AclObjectIdentity aclObjectIdentity;
private AclObjectIdentity aclObjectParentIdentity;
private Object recipient;
private int[] validPermissions;
private int mask = 0; // default means no permissions
//~ Constructors ===================================================================================================
public AbstractBasicAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity,
AclObjectIdentity aclObjectParentIdentity, int mask) {
Assert.notNull(recipient, "recipient cannot be null");
Assert.notNull(aclObjectIdentity, "aclObjectIdentity cannot be null");
validPermissions = getValidPermissions();
Arrays.sort(validPermissions);
for (int i = 0; i < validPermissions.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("Valid permission: " + printPermissionsBlock(validPermissions[i]) + " "
+ printBinary(validPermissions[i]) + " (" + validPermissions[i] + ")");
}
}
this.recipient = recipient;
this.aclObjectIdentity = aclObjectIdentity;
this.aclObjectParentIdentity = aclObjectParentIdentity;
this.mask = mask;
}
/**
* A protected constructor for use by Hibernate.
*/
protected AbstractBasicAclEntry() {
validPermissions = getValidPermissions();
Arrays.sort(validPermissions);
}
//~ Methods ========================================================================================================
public int addPermission(int permissionToAdd) {
return addPermissions(new int[] {permissionToAdd});
}
public int addPermissions(int[] permissionsToAdd) {
if (logger.isDebugEnabled()) {
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask
+ ")");
}
for (int i = 0; i < permissionsToAdd.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("Add permission: " + printPermissionsBlock(permissionsToAdd[i]) + " "
+ printBinary(permissionsToAdd[i]) + " (" + permissionsToAdd[i] + ")");
}
this.mask |= permissionsToAdd[i];
}
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
throw new IllegalArgumentException("Resulting permission set will be invalid.");
} else {
if (logger.isDebugEnabled()) {
logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " ("
+ mask + ")");
}
return this.mask;
}
}
public int deletePermission(int permissionToDelete) {
return deletePermissions(new int[] {permissionToDelete});
}
public int deletePermissions(int[] permissionsToDelete) {
if (logger.isDebugEnabled()) {
logger.debug("BEFORE Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " (" + mask
+ ")");
}
for (int i = 0; i < permissionsToDelete.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("Delete permission: " + printPermissionsBlock(permissionsToDelete[i]) + " "
+ printBinary(permissionsToDelete[i]) + " (" + permissionsToDelete[i] + ")");
}
this.mask &= ~permissionsToDelete[i];
}
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
throw new IllegalArgumentException("Resulting permission set will be invalid.");
} else {
if (logger.isDebugEnabled()) {
logger.debug("AFTER Permissions: " + printPermissionsBlock(mask) + " " + printBinary(mask) + " ("
+ mask + ")");
}
return this.mask;
}
}
public AclObjectIdentity getAclObjectIdentity() {
return this.aclObjectIdentity;
}
public AclObjectIdentity getAclObjectParentIdentity() {
return this.aclObjectParentIdentity;
}
public int getMask() {
return this.mask;
}
public Object getRecipient() {
return this.recipient;
}
/**
* Subclasses must indicate the permissions they support. Each base permission should be an integer with a
* base 2. ie: the first permission is 2^^0 (1), the second permission is 2^^1 (2), the third permission is 2^^2
* (4) etc. Each base permission should be exposed by the subclass as a <code>public static final int</code>. It
* is further recommended that valid combinations of permissions are also exposed as <code>public static final
* int</code>s.<P>This method returns all permission integers that are allowed to be used together. <B>This
* must include any combinations of valid permissions</b>. So if the permissions indicated by 2^^2 (4) and 2^^1
* (2) can be used together, one of the integers returned by this method must be 6 (4 + 2). Otherwise attempts to
* set the permission will be rejected, as the final resulting mask will be rejected.</p>
* <P>Whilst it may seem unduly time onerous to return every valid permission <B>combination</B>, doing so
* delivers maximum flexibility in ensuring ACLs only reflect logical combinations. For example, it would be
* inappropriate to grant a "read" and "write" permission along with an "unrestricted" permission, as the latter
* implies the former permissions.</p>
*
* @return <b>every</b> valid combination of permissions
*/
public abstract int[] getValidPermissions();
public boolean isPermitted(int permissionToCheck) {
return isPermitted(this.mask, permissionToCheck);
}
protected boolean isPermitted(int maskToCheck, int permissionToCheck) {
return ((maskToCheck & permissionToCheck) == permissionToCheck);
}
private String printBinary(int i) {
String s = Integer.toString(i, 2);
String pattern = "................................";
String temp1 = pattern.substring(0, pattern.length() - s.length());
String temp2 = temp1 + s;
return temp2.replace('0', '.');
}
/**
* Outputs the permissions in a human-friendly format. For example, this method may return "CR-D" to
* indicate the passed integer permits create, permits read, does not permit update, and permits delete.
*
* @param i the integer containing the mask which should be printed
*
* @return the human-friend formatted block
*/
public abstract String printPermissionsBlock(int i);
/**
* Outputs the permissions in human-friendly format for the current <code>AbstractBasicAclEntry</code>'s
* mask.
*
* @return the human-friendly formatted block for this instance
*/
public String printPermissionsBlock() {
return printPermissionsBlock(this.mask);
}
public void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity) {
this.aclObjectIdentity = aclObjectIdentity;
}
public void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity) {
this.aclObjectParentIdentity = aclObjectParentIdentity;
}
public void setMask(int mask) {
this.mask = mask;
}
public void setRecipient(Object recipient) {
this.recipient = recipient;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append("[").append(aclObjectIdentity).append(",").append(recipient);
sb.append("=").append(printPermissionsBlock(mask)).append(" ");
sb.append(printBinary(mask)).append(" (");
sb.append(mask).append(")").append("]");
return sb.toString();
}
public int togglePermission(int permissionToToggle) {
this.mask ^= permissionToToggle;
if (Arrays.binarySearch(validPermissions, this.mask) < 0) {
throw new IllegalArgumentException("Resulting permission set will be invalid.");
} else {
return this.mask;
}
}
}

View File

@ -1,65 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import java.io.Serializable;
/**
* Interface representing the identity of an individual domain object instance.
*
* <P>
* It should be noted that <code>AclObjectIdentity</code> instances are created
* in various locations throughout the package. As
* <code>AclObjectIdentity</code>s are used as the key for caching, it is
* essential that implementations provide methods so that object-equality
* rather than reference-equality can be relied upon by caches. In other
* words, a cache can consider two <code>AclObjectIdentity</code>s equal if
* <code>identity1.equals(identity2)</code>, rather than reference-equality of
* <code>identity1==identity2</code>.
* </p>
*
* <P>
* In practical terms this means you must implement the standard
* <code>java.lang.Object</code> methods shown below. Depending on your
* cache's internal structure, you may also need to implement special
* interfaces such as <code>java.util.Comparator</code> or
* <code>java.lang.Comparable</code>.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface AclObjectIdentity extends Serializable {
//~ Methods ========================================================================================================
/**
* Refer to the <code>java.lang.Object</code> documentation for the interface contract.
*
* @param obj to be compared
*
* @return <code>true</code> if the objects are equal, <code>false</code> otherwise
*/
boolean equals(Object obj);
/**
* Refer to the <code>java.lang.Object</code> documentation for the interface contract.
*
* @return a hash code representation of this object
*/
int hashCode();
}

View File

@ -1,42 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
/**
* Indicates a domain object instance is able to provide {@link
* AclObjectIdentity} information.
*
* <P>
* Domain objects must implement this interface if they wish to provide an
* <code>AclObjectIdentity</code> rather than it being determined by relying
* classes. Specifically, the {@link BasicAclProvider} detects and uses this
* interface.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface AclObjectIdentityAware {
//~ Methods ========================================================================================================
/**
* Retrieves the <code>AclObjectIdentity</code> for this instance.
*
* @return the ACL object identity for this instance (can never be <code>null</code>)
*/
AclObjectIdentity getAclObjectIdentity();
}

View File

@ -1,53 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
/**
* Represents a data access object that can return the {@link BasicAclEntry}s
* applying to a given ACL object identity.
*
* <P>
* <code>BasicAclDao</code> implementations are responsible for interpreting a
* given {@link AclObjectIdentity} and being able to lookup and return the
* corresponding {@link BasicAclEntry}[]s.
* </p>
*
* <P>
* <code>BasicAclDao</code>s many, but are not required to, allow the backend
* ACL repository to specify the class of <code>BasicAclEntry</code>
* implementations that should be returned.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface BasicAclDao {
//~ Methods ========================================================================================================
/**
* Obtains the ACLs that apply to the specified domain instance.<P>Does <b>not</b> perform caching, include
* ACLs from any inheritance hierarchy or filter returned objects based on effective permissions. Implementations
* are solely responsible for returning ACLs found in the ACL repository for the specified object identity.</p>
*
* @param aclObjectIdentity the domain object instance that ACL information is being requested for (never
* <code>null</code>)
*
* @return the ACLs that apply (no <code>null</code>s are permitted in the array), or <code>null</code> if no ACLs
* could be found for the specified ACL object identity
*/
BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);
}

View File

@ -1,116 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.security.acl.AclEntry;
/**
* Represents an entry in an access control list.
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface BasicAclEntry extends AclEntry {
//~ Methods ========================================================================================================
/**
* Indicates the domain object instance that is subject of this <code>BasicAclEntry</code>. This
* information may be of interest to relying classes (voters and business methods) that wish to know the actual
* origination of the ACL entry (so as to distinguish individual ACL entries from others contributed by the
* inheritance hierarchy).
*
* @return the ACL object identity that is subject of this ACL entry (never <code>null</code>)
*/
AclObjectIdentity getAclObjectIdentity();
/**
* Indicates any ACL parent of the domain object instance. This is used by <code>BasicAclProvider</code> to
* walk the inheritance hierarchy. An domain object instance need <b>not</b> have a parent.
*
* @return the ACL object identity that is the parent of this ACL entry (may be <code>null</code> if no parent
* should be consulted)
*/
AclObjectIdentity getAclObjectParentIdentity();
/**
* Access control lists in this package are based on bit masking. The integer value of the bit mask can be
* obtained from this method.
*
* @return the bit mask applicable to this ACL entry (zero indicates a bit mask where no permissions have been
* granted)
*/
int getMask();
/**
* A domain object instance will usually have multiple <code>BasicAclEntry</code>s. Each separate
* <code>BasicAclEntry</code> applies to a particular "recipient". Typical examples of recipients include (but do
* not necessarily have to include) usernames, role names, complex granted authorities etc.<P><B>It is
* essential that only one <code>BasicAclEntry</code> exists for a given recipient</B>. Otherwise conflicts as to
* the mask that should apply to a given recipient will occur.</p>
* <P>This method indicates which recipient this <code>BasicAclEntry</code> applies to. The returned
* object type will vary depending on the type of recipient. For instance, it might be a <code>String</code>
* containing a username, or a <code>GrantedAuthorityImpl</code> containing a complex granted authority that is
* being granted the permissions contained in this access control entry. The {@link EffectiveAclsResolver} and
* {@link BasicAclProvider#getAcls(Object,org.springframework.security.Authentication)} can process the different recipient
* types and return only those that apply to a specified <code>Authentication</code> object.</p>
*
* @return the recipient of this access control list entry (never <code>null</code>)
*/
Object getRecipient();
/**
* Determine if the mask of this entry includes this permission or not
*
* @param permissionToCheck
*
* @return if the entry's mask includes this permission
*/
boolean isPermitted(int permissionToCheck);
/**
* This setter should <B>only</B> be used by DAO implementations.
*
* @param aclObjectIdentity an object which can be used to uniquely identify the domain object instance subject of
* this ACL entry
*/
void setAclObjectIdentity(AclObjectIdentity aclObjectIdentity);
/**
* This setter should <B>only</B> be used by DAO implementations.
*
* @param aclObjectParentIdentity an object which represents the parent of the domain object instance subject of
* this ACL entry, or <code>null</code> if either the domain object instance has no parent or its parent
* should be not used to compute an inheritance hierarchy
*/
void setAclObjectParentIdentity(AclObjectIdentity aclObjectParentIdentity);
/**
* This setter should <B>only</B> be used by DAO implementations.
*
* @param mask the integer representing the permissions bit mask
*/
void setMask(int mask);
/**
* This setter should <B>only</B> be used by DAO implementations.
*
* @param recipient a representation of the recipient of this ACL entry that makes sense to an
* <code>EffectiveAclsResolver</code> implementation
*/
void setRecipient(Object recipient);
}

View File

@ -1,62 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
/**
* Provides a cache of {@link BasicAclEntry} objects.
*
* <P>
* Implementations should provide appropriate methods to set their cache
* parameters (eg time-to-live) and/or force removal of entities before their
* normal expiration. These are not part of the
* <code>BasicAclEntryCache</code> interface contract because they vary
* depending on the type of caching system used (eg in-memory vs disk vs
* cluster vs hybrid).
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface BasicAclEntryCache {
//~ Methods ========================================================================================================
/**
* Obtains an array of {@link BasicAclEntry}s from the cache.
*
* @param aclObjectIdentity which should be obtained from the cache
*
* @return any applicable <code>BasicAclEntry</code>s (no <code>null</code>s are permitted in the returned array)
* or <code>null</code> if the object identity could not be found or if the cache entry has expired
*/
BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity);
/**
* Places an array of {@link BasicAclEntry}s in the cache.<P>No <code>null</code>s are allowed in the
* passed array. If any <code>null</code> is passed, the implementation may throw an exception.</p>
*
* @param basicAclEntry the ACL entries to cache (the key will be extracted from the {@link
* BasicAclEntry#getAclObjectIdentity()} method
*/
void putEntriesInCache(BasicAclEntry[] basicAclEntry);
/**
* Removes all ACL entries related to an {@link AclObjectIdentity} from the cache.
*
* @param aclObjectIdentity which should be removed from the cache
*/
void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity);
}

View File

@ -1,73 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.dao.DataAccessException;
/**
* Represents a more extensive data access object
* for {@link BasicAclEntry}s.
*
* <p>
* <code>BasicAclExtendedDao</code> implementations are responsible for interpreting a
* a given {@link AclObjectIdentity}.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface BasicAclExtendedDao extends BasicAclDao {
//~ Methods ========================================================================================================
/**
* Changes the permission mask assigned to the <code>BasicAclEntry</code> associated with the specified
* <code>AclObjectIdentity</code> and recipient <code>Object</code>.
*
* @param aclObjectIdentity to locate the relevant <code>BasicAclEntry</code>
* @param recipient to locate the relevant <code>BasicAclEntry</code>
* @param newMask indicating the new permission
*
* @throws DataAccessException DOCUMENT ME!
*/
void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
throws DataAccessException;
void create(BasicAclEntry basicAclEntry) throws DataAccessException;
/**
* Deletes <b>all</b> entries associated with the specified <code>AclObjectIdentity</code>.
*
* @param aclObjectIdentity to delete, including any <code>BasicAclEntry</code>s
*
* @throws DataAccessException DOCUMENT ME!
*/
void delete(AclObjectIdentity aclObjectIdentity)
throws DataAccessException;
/**
* Deletes the <code>BasicAclEntry</code> associated with the specified <code>AclObjectIdentity</code> and
* recipient <code>Object</code>.
*
* @param aclObjectIdentity to delete
* @param recipient to delete
*
* @throws DataAccessException DOCUMENT ME!
*/
void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
throws DataAccessException;
}

View File

@ -1,345 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.security.Authentication;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclProvider;
import org.springframework.security.acl.basic.cache.NullAclEntryCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Retrieves access control lists (ACL) entries for domain object instances from a data access object (DAO).
* <p>
* This implementation will provide ACL lookup services for any object that it can determine the {@link
* AclObjectIdentity} for by calling the {@link #obtainIdentity(Object)} method. Subclasses can override this method
* if they only want the <code>BasicAclProvider</code> responding to particular domain object instances.
* </p>
* <p>
* <code>BasicAclProvider</code> will walk an inheritance hierarchy if a <code>BasicAclEntry</code> returned by
* the DAO indicates it has a parent. NB: inheritance occurs at a <i>domain instance object</i> level. It does not
* occur at an ACL recipient level. This means <b>all</b><code>BasicAclEntry</code>s for a given domain instance
* object <b>must</b> have the <b>same</b> parent identity, or <b>all</b><code>BasicAclEntry</code>s must have
* <code>null</code> as their parent identity.
* </p>
* <p>
* A cache should be used. This is provided by the {@link BasicAclEntryCache}. <code>BasicAclProvider</code> by
* default is setup to use the {@link NullAclEntryCache}, which performs no caching.
* </p>
* <p>To implement the {@link #getAcls(Object, Authentication)} method, <code>BasicAclProvider</code> requires a
* {@link EffectiveAclsResolver} to be configured against it. By default the {@link
* GrantedAuthorityEffectiveAclsResolver} is used.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class BasicAclProvider implements AclProvider, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(BasicAclProvider.class);
/** Marker added to the cache to indicate an AclObjectIdentity has no corresponding BasicAclEntry[]s */
private static final String RECIPIENT_FOR_CACHE_EMPTY = "RESERVED_RECIPIENT_NOBODY";
//~ Instance fields ================================================================================================
/** Must be set to an appropriate data access object. Defaults to <code>null</code>. */
private BasicAclDao basicAclDao;
private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache();
private Class defaultAclObjectIdentityClass = NamedEntityObjectIdentity.class;
private Class restrictSupportToClass = null;
private EffectiveAclsResolver effectiveAclsResolver = new GrantedAuthorityEffectiveAclsResolver();
//~ Methods ========================================================================================================
public void afterPropertiesSet() {
Assert.notNull(basicAclDao, "basicAclDao required");
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
Assert.notNull(basicAclEntryCache, "basicAclEntryCache required");
Assert.notNull(effectiveAclsResolver, "effectiveAclsResolver required");
Assert.notNull(defaultAclObjectIdentityClass, "defaultAclObjectIdentityClass required");
Assert.isTrue(AclObjectIdentity.class.isAssignableFrom(this.defaultAclObjectIdentityClass),
"defaultAclObjectIdentityClass must implement AclObjectIdentity");
try {
Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class});
} catch (NoSuchMethodException nsme) {
throw new IllegalArgumentException(
"defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!");
}
}
public AclEntry[] getAcls(Object domainInstance) {
Map map = new HashMap();
AclObjectIdentity aclIdentity = obtainIdentity(domainInstance);
Assert.notNull(aclIdentity, "domainInstance is not supported by this provider");
if (logger.isDebugEnabled()) {
logger.debug("Looking up: " + aclIdentity.toString());
}
BasicAclEntry[] instanceAclEntries = lookup(aclIdentity);
// Exit if there is no ACL information or parent for this instance
if (instanceAclEntries == null) {
return null;
}
// Add the leaf objects to the Map, keyed on recipient
for (int i = 0; i < instanceAclEntries.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("Explicit add: " + instanceAclEntries[i].toString());
}
map.put(instanceAclEntries[i].getRecipient(), instanceAclEntries[i]);
}
AclObjectIdentity parent = instanceAclEntries[0].getAclObjectParentIdentity();
while (parent != null) {
BasicAclEntry[] parentAclEntries = lookup(parent);
if (logger.isDebugEnabled()) {
logger.debug("Parent lookup: " + parent.toString());
}
// Exit loop if parent couldn't be found (unexpected condition)
if (parentAclEntries == null) {
if (logger.isDebugEnabled()) {
logger.debug("Parent could not be found in ACL repository");
}
break;
}
// Now add each _NEW_ recipient to the list
for (int i = 0; i < parentAclEntries.length; i++) {
if (!map.containsKey(parentAclEntries[i].getRecipient())) {
if (logger.isDebugEnabled()) {
logger.debug("Added parent to map: " + parentAclEntries[i].toString());
}
map.put(parentAclEntries[i].getRecipient(), parentAclEntries[i]);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Did NOT add parent to map: " + parentAclEntries[i].toString());
}
}
}
// Prepare for next iteration of while loop
parent = parentAclEntries[0].getAclObjectParentIdentity();
}
Collection collection = map.values();
return (AclEntry[]) collection.toArray(new AclEntry[] {});
}
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
AclEntry[] allAcls = (AclEntry[]) this.getAcls(domainInstance);
return this.effectiveAclsResolver.resolveEffectiveAcls(allAcls, authentication);
}
public BasicAclDao getBasicAclDao() {
return basicAclDao;
}
public BasicAclEntryCache getBasicAclEntryCache() {
return basicAclEntryCache;
}
public Class getDefaultAclObjectIdentityClass() {
return defaultAclObjectIdentityClass;
}
public EffectiveAclsResolver getEffectiveAclsResolver() {
return effectiveAclsResolver;
}
public Class getRestrictSupportToClass() {
return restrictSupportToClass;
}
private BasicAclEntry[] lookup(AclObjectIdentity aclObjectIdentity) {
BasicAclEntry[] result = basicAclEntryCache.getEntriesFromCache(aclObjectIdentity);
if (result != null) {
if (result[0].getRecipient().equals(RECIPIENT_FOR_CACHE_EMPTY)) {
return null;
} else {
return result;
}
}
result = basicAclDao.getAcls(aclObjectIdentity);
if (result == null) {
SimpleAclEntry[] emptyAclEntries = {
new SimpleAclEntry(RECIPIENT_FOR_CACHE_EMPTY, aclObjectIdentity, null, 0)
};
basicAclEntryCache.putEntriesInCache(emptyAclEntries);
return null;
}
basicAclEntryCache.putEntriesInCache(result);
return result;
}
/**
* This method looks up the <code>AclObjectIdentity</code> of a passed domain object instance.<P>This
* implementation attempts to obtain the <code>AclObjectIdentity</code> via reflection inspection of the class for
* the {@link AclObjectIdentityAware} interface. If this fails, an attempt is made to construct a {@link
* #getDefaultAclObjectIdentityClass()} object by passing the domain instance object into its constructor.</p>
*
* @param domainInstance the domain object instance (never <code>null</code>)
*
* @return an ACL object identity, or <code>null</code> if one could not be obtained
*/
protected AclObjectIdentity obtainIdentity(Object domainInstance) {
if (domainInstance instanceof AclObjectIdentityAware) {
AclObjectIdentityAware aclObjectIdentityAware = (AclObjectIdentityAware) domainInstance;
if (logger.isDebugEnabled()) {
logger.debug("domainInstance: " + domainInstance + " cast to AclObjectIdentityAware");
}
return aclObjectIdentityAware.getAclObjectIdentity();
}
try {
Constructor constructor = defaultAclObjectIdentityClass.getConstructor(new Class[] {Object.class});
if (logger.isDebugEnabled()) {
logger.debug("domainInstance: " + domainInstance
+ " attempting to pass to constructor: " + constructor);
}
return (AclObjectIdentity) constructor.newInstance(new Object[] {domainInstance});
} catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("Error attempting construction of " + defaultAclObjectIdentityClass + ": "
+ ex.getMessage(), ex);
if (ex.getCause() != null) {
logger.debug("Cause: " + ex.getCause().getMessage(), ex.getCause());
}
}
return null;
}
}
public void setBasicAclDao(BasicAclDao basicAclDao) {
this.basicAclDao = basicAclDao;
}
public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) {
this.basicAclEntryCache = basicAclEntryCache;
}
/**
* Allows selection of the <code>AclObjectIdentity</code> class that an attempt should be made to construct
* if the passed object does not implement <code>AclObjectIdentityAware</code>.<P>NB: Any
* <code>defaultAclObjectIdentityClass</code><b>must</b> provide a public constructor that accepts an
* <code>Object</code>. Otherwise it is not possible for the <code>BasicAclProvider</code> to try to create the
* <code>AclObjectIdentity</code> instance at runtime.</p>
*
* @param defaultAclObjectIdentityClass
*/
public void setDefaultAclObjectIdentityClass(Class defaultAclObjectIdentityClass) {
this.defaultAclObjectIdentityClass = defaultAclObjectIdentityClass;
}
public void setEffectiveAclsResolver(EffectiveAclsResolver effectiveAclsResolver) {
this.effectiveAclsResolver = effectiveAclsResolver;
}
/**
* If set to a value other than <code>null</code>, the {@link #supports(Object)} method will <b>only</b>
* support the indicates class. This is useful if you wish to wire multiple <code>BasicAclProvider</code>s in a
* list of <code>AclProviderManager.providers</code> but only have particular instances respond to particular
* domain object types.
*
* @param restrictSupportToClass the class to restrict this <code>BasicAclProvider</code> to service request for,
* or <code>null</code> (the default) if the <code>BasicAclProvider</code> should respond to every class
* presented
*/
public void setRestrictSupportToClass(Class restrictSupportToClass) {
this.restrictSupportToClass = restrictSupportToClass;
}
/**
* Indicates support for the passed object.<p>An object will only be supported if it (i) is allowed to be
* supported as defined by the {@link #setRestrictSupportToClass(Class)} method, <b>and</b> (ii) if an
* <code>AclObjectIdentity</code> is returned by {@link #obtainIdentity(Object)} for that object.</p>
*
* @param domainInstance the instance to check
*
* @return <code>true</code> if this provider supports the passed object, <code>false</code> otherwise
*/
public boolean supports(Object domainInstance) {
if (domainInstance == null) {
if (logger.isDebugEnabled()) {
logger.debug("domainInstance is null");
}
return false;
}
if ((restrictSupportToClass != null) && !restrictSupportToClass.isAssignableFrom(domainInstance.getClass())) {
if (logger.isDebugEnabled()) {
logger.debug("domainInstance not instance of " + restrictSupportToClass);
}
return false;
}
if (obtainIdentity(domainInstance) == null) {
if (logger.isDebugEnabled()) {
logger.debug("obtainIdentity returned null");
}
return false;
} else {
if (logger.isDebugEnabled()) {
logger.debug("obtainIdentity returned " + obtainIdentity(domainInstance));
}
return true;
}
}
}

View File

@ -1,62 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.security.Authentication;
import org.springframework.security.acl.AclEntry;
/**
* Determines the ACLs that are effective for a given
* <code>Authentication</code> object.
*
* <P>
* Implementations will vary depending on their ability to interpret the
* "recipient" object types contained in {@link BasicAclEntry} instances, and
* how those recipient object types correspond to
* <code>Authentication</code>-presented principals and granted authorities.
* </p>
*
* <P>
* Implementations should not filter the resulting ACL list from lower-order
* permissions. So if a resulting ACL list grants a "read" permission, an
* "unlimited" permission and a "zero" permission (due to the effective ACLs
* for different granted authorities held by the <code>Authentication</code>
* object), all three permissions would be returned as distinct
* <code>BasicAclEntry</code> instances. It is the responsibility of the
* relying classes (voters and business methods) to ignore or handle
* lower-order permissions in a business logic dependent manner.
* </p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public interface EffectiveAclsResolver {
//~ Methods ========================================================================================================
/**
* Determines the ACLs that apply to the presented <code>Authentication</code> object.
*
* @param allAcls every ACL assigned to a domain object instance
* @param filteredBy the principal (populated with <code>GrantedAuthority</code>s along with any other members that
* relate to role or group membership) that effective ACLs should be returned for
*
* @return the ACLs that apply to the presented principal, or <code>null</code> if there are none after filtering
*/
AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy);
}

View File

@ -1,135 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.userdetails.UserDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.List;
import java.util.Vector;
/**
* Simple implementation of {@link EffectiveAclsResolver}.<P>This implementation does not need to understand the
* "recipient" types presented in a <code>BasicAclEntry</code> because it merely delegates to the detected {@link
* Authentication#getPrincipal()} or {@link Authentication#getAuthorities()}. The principal object or granted
* authorities object has its <code>Object.equals(recipient)</code> method called to make the decision as to whether
* the recipient in the <code>BasicAclEntry</code> is the same as the principal or granted authority.
* <p>
* This class should prove an adequate ACLs resolver if you're using standard Spring Security classes. This is
* because the typical <code>Authentication</code> token is <code>UsernamePasswordAuthenticationToken</code>, which
* for its <code>principal</code> is usually a <code>String</code>. The <code>GrantedAuthorityImpl</code> is typically
* used for granted authorities, which tests for equality based on a <code>String</code>. This means
* <code>BasicAclDao</code>s simply need to return a <code>String</code> to represent the recipient. If you use
* non-<code>String</code> objects, you will probably require an alternative <code>EffectiveAclsResolver</code>.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class GrantedAuthorityEffectiveAclsResolver implements EffectiveAclsResolver {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(GrantedAuthorityEffectiveAclsResolver.class);
//~ Methods ========================================================================================================
public AclEntry[] resolveEffectiveAcls(AclEntry[] allAcls, Authentication filteredBy) {
if ((allAcls == null) || (allAcls.length == 0)) {
return null;
}
List list = new Vector();
if (logger.isDebugEnabled()) {
logger.debug("Locating AclEntry[]s (from set of " + ((allAcls == null) ? 0 : allAcls.length)
+ ") that apply to Authentication: " + filteredBy);
}
for (int i = 0; i < allAcls.length; i++) {
if (!(allAcls[i] instanceof BasicAclEntry)) {
continue;
}
Object recipient = ((BasicAclEntry) allAcls[i]).getRecipient();
// Allow the Authentication's getPrincipal to decide whether
// the presented recipient is "equal" (allows BasicAclDaos to
// return Strings rather than proper objects in simple cases)
if (filteredBy.getPrincipal().equals(recipient)) {
if (logger.isDebugEnabled()) {
logger.debug("Principal matches AclEntry recipient: " + recipient);
}
list.add(allAcls[i]);
} else if (filteredBy.getPrincipal() instanceof UserDetails
&& ((UserDetails) filteredBy.getPrincipal()).getUsername().equals(recipient)) {
if (logger.isDebugEnabled()) {
logger.debug("Principal (from UserDetails) matches AclEntry recipient: " + recipient);
}
list.add(allAcls[i]);
} else {
// No direct match against principal; try each authority.
// As with the principal, allow each of the Authentication's
// granted authorities to decide whether the presented
// recipient is "equal"
List<GrantedAuthority >authorities = filteredBy.getAuthorities();
if ((authorities == null) || (authorities.size() == 0)) {
if (logger.isDebugEnabled()) {
logger.debug("Did not match principal and there are no granted authorities, "
+ "so cannot compare with recipient: " + recipient);
}
continue;
}
for (int k = 0; k < authorities.size(); k++) {
if (authorities.get(k).equals(recipient)) {
if (logger.isDebugEnabled()) {
logger.debug("GrantedAuthority: " + authorities.get(k) + " matches recipient: " + recipient);
}
list.add(allAcls[i]);
}
}
}
}
// return null if appropriate (as per interface contract)
if (list.size() > 0) {
if (logger.isDebugEnabled()) {
logger.debug("Returning effective AclEntry array with " + list.size() + " elements");
}
return (BasicAclEntry[]) list.toArray(new BasicAclEntry[] {});
} else {
if (logger.isDebugEnabled()) {
logger.debug("Returning null AclEntry array as zero effective AclEntrys found");
}
return null;
}
}
}

View File

@ -1,153 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Simple implementation of {@link AclObjectIdentity}.<P>Uses <code>String</code>s to store the identity of the
* domain object instance. Also offers a constructor that uses reflection to build the identity information.</p>
* @deprecated Use new spring-security-acl module instead
*/
public class NamedEntityObjectIdentity implements AclObjectIdentity {
//~ Instance fields ================================================================================================
private String classname;
private String id;
//~ Constructors ===================================================================================================
public NamedEntityObjectIdentity(String classname, String id) {
Assert.hasText(classname, "classname required");
Assert.hasText(id, "id required");
this.classname = classname;
this.id = id;
}
/**
* Creates the <code>NamedEntityObjectIdentity</code> based on the passed
* object instance. The passed object must provide a <code>getId()</code>
* method, otherwise an exception will be thrown.
*
* @param object the domain object instance to create an identity for
*
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public NamedEntityObjectIdentity(Object object) throws IllegalAccessException, InvocationTargetException {
Assert.notNull(object, "object cannot be null");
this.classname = (getPackageName(object.getClass().getName()) == null)
? ClassUtils.getShortName(object.getClass())
: (getPackageName(object.getClass().getName()) + "." + ClassUtils.getShortName(object.getClass()));
Class clazz = object.getClass();
try {
Method method = clazz.getMethod("getId", new Class[] {});
Object result = method.invoke(object, new Object[] {});
this.id = result.toString();
} catch (NoSuchMethodException nsme) {
throw new IllegalArgumentException("Object of class '" + clazz
+ "' does not provide the required getId() method: " + object);
}
}
//~ Methods ========================================================================================================
/**
* Important so caching operates properly.<P>Considers an object of the same class equal if it has the same
* <code>classname</code> and <code>id</code> properties.</p>
*
* @param arg0 object to compare
*
* @return <code>true</code> if the presented object matches this object
*/
public boolean equals(Object arg0) {
if (arg0 == null) {
return false;
}
if (!(arg0 instanceof NamedEntityObjectIdentity)) {
return false;
}
NamedEntityObjectIdentity other = (NamedEntityObjectIdentity) arg0;
if (this.getId().equals(other.getId()) && this.getClassname().equals(other.getClassname())) {
return true;
}
return false;
}
/**
* Indicates the classname portion of the object identity.
*
* @return the classname (never <code>null</code>)
*/
public String getClassname() {
return classname;
}
/**
* Indicates the instance identity portion of the object identity.
*
* @return the instance identity (never <code>null</code>)
*/
public String getId() {
return id;
}
private String getPackageName(String className) {
Assert.hasLength(className, "class name must not be empty");
int lastDotIndex = className.lastIndexOf(".");
if (lastDotIndex == -1) {
return null;
}
return className.substring(0, lastDotIndex);
}
/**
* Important so caching operates properly.
*
* @return the hash of the classname and id
*/
public int hashCode() {
StringBuffer sb = new StringBuffer();
sb.append(this.classname).append(this.id);
return sb.toString().hashCode();
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(this.getClass().getName()).append("[");
sb.append("Classname: ").append(this.classname);
sb.append("; Identity: ").append(this.id).append("]");
return sb.toString();
}
}

View File

@ -1,151 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Stores some privileges typical of a domain object.
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class SimpleAclEntry extends AbstractBasicAclEntry {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(SimpleAclEntry.class);
// Base permissions we permit
public static final int NOTHING = 0;
public static final int ADMINISTRATION = (int) Math.pow(2, 0);
public static final int READ = (int) Math.pow(2, 1);
public static final int WRITE = (int) Math.pow(2, 2);
public static final int CREATE = (int) Math.pow(2, 3);
public static final int DELETE = (int) Math.pow(2, 4);
// Combinations of base permissions we permit
public static final int READ_WRITE_CREATE_DELETE = READ | WRITE | CREATE | DELETE;
public static final int READ_WRITE_CREATE = READ | WRITE | CREATE;
public static final int READ_WRITE = READ | WRITE;
public static final int READ_WRITE_DELETE = READ | WRITE | DELETE;
// Array required by the abstract superclass via getValidPermissions()
private static final int[] VALID_PERMISSIONS = {
NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE,
READ_WRITE, READ_WRITE_DELETE
};
private static final String[] VALID_PERMISSIONS_AS_STRING = {
"NOTHING", "ADMINISTRATION", "READ", "WRITE", "CREATE", "DELETE", "READ_WRITE_CREATE_DELETE",
"READ_WRITE_CREATE", "READ_WRITE", "READ_WRITE_DELETE" };
//~ Constructors ===================================================================================================
/**
* Allows {@link BasicAclDao} implementations to construct this object
* using <code>newInstance()</code>.
*
* <P>
* Normal classes should <B>not</B> use this default constructor.
* </p>
*/
public SimpleAclEntry() {
super();
}
public SimpleAclEntry(Object recipient, AclObjectIdentity aclObjectIdentity,
AclObjectIdentity aclObjectParentIdentity, int mask) {
super(recipient, aclObjectIdentity, aclObjectParentIdentity, mask);
}
//~ Methods ========================================================================================================
/**
* @return a copy of the permissions array, changes to the values won't affect this class.
*/
public int[] getValidPermissions() {
return (int[]) VALID_PERMISSIONS.clone();
}
public String printPermissionsBlock(int i) {
StringBuffer sb = new StringBuffer();
if (isPermitted(i, ADMINISTRATION)) {
sb.append('A');
} else {
sb.append('-');
}
if (isPermitted(i, READ)) {
sb.append('R');
} else {
sb.append('-');
}
if (isPermitted(i, WRITE)) {
sb.append('W');
} else {
sb.append('-');
}
if (isPermitted(i, CREATE)) {
sb.append('C');
} else {
sb.append('-');
}
if (isPermitted(i, DELETE)) {
sb.append('D');
} else {
sb.append('-');
}
return sb.toString();
}
/**
* Parse a permission {@link String} literal and return associated value.
*
* @param permission one of the field names that represent a permission: <code>ADMINISTRATION</code>,
* <code>READ</code>, <code>WRITE</code>,...
* @return the value associated to that permission
* @throws IllegalArgumentException if argument is not a valid permission
*/
public static int parsePermission(String permission) {
for (int i = 0; i < VALID_PERMISSIONS_AS_STRING.length; i++) {
if (VALID_PERMISSIONS_AS_STRING[i].equalsIgnoreCase(permission)) {
return VALID_PERMISSIONS[i];
}
}
throw new IllegalArgumentException("Permission provided does not exist: " + permission);
}
/**
* Parse a list of permission {@link String} literals and return associated values.
*
* @param permissions array with permissions as {@link String}
* @see #parsePermission(String) for valid values
*/
public static int[] parsePermissions(String[] permissions) {
int[] requirepermissionAsIntArray = new int[permissions.length];
for (int i = 0; i < requirepermissionAsIntArray.length; i++) {
requirepermissionAsIntArray[i] = parsePermission(permissions[i]);
}
return requirepermissionAsIntArray;
}
}

View File

@ -1,69 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.util.Assert;
import java.io.Serializable;
/**
* Used by {@link EhCacheBasedAclEntryCache} to store the array of <code>BasicAclEntry</code>s in the cache.<P>This
* is necessary because caches store a single object per key, not an array.</p>
* <P>This class uses value object semantics. ie: construction-based initialisation without any setters for the
* properties.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class BasicAclEntryHolder implements Serializable {
//~ Instance fields ================================================================================================
private BasicAclEntry[] basicAclEntries;
//~ Constructors ===================================================================================================
/**
* Constructs the <code>BasicAclEntryHolder</code>.
*
* @param aclEntries to cache (any <code>null</code>s will cause an
* exception, which should not be a problem as the contract for
* <code>BasicAclEntryCache</code> allows exceptions if
* <code>null</code>s are presented)
*
* @throws IllegalArgumentException if a <code>null</code> exists anywhere
* in the <code>aclEntries</code> or if a <code>null</code> is
* passed to the constructor
*/
public BasicAclEntryHolder(BasicAclEntry[] aclEntries) {
Assert.notNull(aclEntries, "aclEntries cannot be null");
for (int i = 0; i < aclEntries.length; i++) {
Assert.notNull(aclEntries[i], "aclEntries cannot be null");
}
this.basicAclEntries = aclEntries;
}
//~ Methods ========================================================================================================
public BasicAclEntry[] getBasicAclEntries() {
return basicAclEntries;
}
}

View File

@ -1,108 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Element;
import net.sf.ehcache.Ehcache;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.BasicAclEntryCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.util.Assert;
/**
* Caches <code>BasicAclEntry</code>s using a Spring IoC defined <A
* HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class EhCacheBasedAclEntryCache implements BasicAclEntryCache, InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class);
//~ Instance fields ================================================================================================
private Ehcache cache;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache mandatory");
}
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
Element element = null;
try {
element = cache.get(aclObjectIdentity);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException("Cache failure: " + cacheException.getMessage());
}
// Return null if cache element has expired or not found
if (element == null) {
if (logger.isDebugEnabled()) {
logger.debug("Cache miss: " + aclObjectIdentity);
}
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Cache hit: " + (element != null) + "; object: " + aclObjectIdentity);
}
BasicAclEntryHolder holder = (BasicAclEntryHolder) element.getValue();
return holder.getBasicAclEntries();
}
public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
Element element = new Element(basicAclEntry[0].getAclObjectIdentity(), holder);
if (logger.isDebugEnabled()) {
logger.debug("Cache put: " + element.getKey());
}
cache.put(element);
}
public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
cache.remove(aclObjectIdentity);
}
public Ehcache getCache() {
return cache;
}
public void setCache(Ehcache cache) {
this.cache = cache;
}
}

View File

@ -1,58 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.BasicAclEntryCache;
/**
* Does not perform any caching.<P><B>Do not use in production settings</B>, as ACL queries are likely to be
* extensive.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class NullAclEntryCache implements BasicAclEntryCache {
//~ Methods ========================================================================================================
/**
* As nothing ever stored in the cache, will always return <code>null</code>.
*
* @param aclObjectIdentity ignored
*
* @return always <code>null</code>
*/
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
return null;
}
/**
* Meets method signature but doesn't store in any cache.
*
* @param basicAclEntry ignored
*/
public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {}
/**
* Meets method signature but doesn't remove from cache.
*
* @param aclObjectIdentity ignored
*/
public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) {}
}

View File

@ -1,5 +0,0 @@
<html>
<body>
Caches ACL information for the <code>BasicAclProvider</code>.
</body>
</html>

View File

@ -1,400 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.jdbc;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclDao;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContextException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.util.Assert;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Vector;
import javax.sql.DataSource;
/**
* Retrieves ACL details from a JDBC location.
* <p>
* A default database structure is assumed. This may be overridden by setting the default query strings to use.
* If this does not provide enough flexibility, another strategy would be to subclass this class and override the
* {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.
* </p>
* @deprecated Use new spring-security-acl module instead
*/
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
//~ Static fields/initializers =====================================================================================
public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___";
public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY =
"SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
public static final String DEF_OBJECT_PROPERTIES_QUERY =
"SELECT CHILD.ID, "
+ "CHILD.OBJECT_IDENTITY, "
+ "CHILD.ACL_CLASS, "
+ "PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY "
+ "FROM acl_object_identity as CHILD "
+ "LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id "
+ "WHERE CHILD.object_identity = ?";
private static final Log logger = LogFactory.getLog(JdbcDaoImpl.class);
//~ Instance fields ================================================================================================
protected MappingSqlQuery aclsByObjectIdentity;
protected MappingSqlQuery objectProperties;
private String aclsByObjectIdentityQuery;
private String objectPropertiesQuery;
//~ Constructors ===================================================================================================
public JdbcDaoImpl() {
aclsByObjectIdentityQuery = DEF_ACLS_BY_OBJECT_IDENTITY_QUERY;
objectPropertiesQuery = DEF_OBJECT_PROPERTIES_QUERY;
}
//~ Methods ========================================================================================================
/**
* Responsible for covering a <code>AclObjectIdentity</code> to a <code>String</code> that can be located
* in the RDBMS.
*
* @param aclObjectIdentity to locate
*
* @return the object identity as a <code>String</code>
*/
protected String convertAclObjectIdentityToString(AclObjectIdentity aclObjectIdentity) {
// Ensure we can process this type of AclObjectIdentity
Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity,
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: " + aclObjectIdentity
+ ")");
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
// Compose the String we expect to find in the RDBMS
return neoi.getClassname() + ":" + neoi.getId();
}
/**
* Constructs an individual <code>BasicAclEntry</code> from the passed <code>AclDetailsHolder</code>s.<P>Guarantees
* to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
*
* @param propertiesInformation mandatory information about which instance to create, the object identity, and the
* parent object identity (<code>null</code> or empty <code>String</code>s prohibited for
* <code>aclClass</code> and <code>aclObjectIdentity</code>
* @param aclInformation optional information about the individual ACL record (if <code>null</code> only an
* "inheritence marker" instance is returned which will include a recipient of {@link
* #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not <code>null</code>, it is prohibited to present
* <code>null</code> or an empty <code>String</code> for <code>recipient</code>)
*
* @return a fully populated instance suitable for use by external objects
*
* @throws IllegalArgumentException if the indicated ACL class could not be created
*/
private BasicAclEntry createBasicAclEntry(AclDetailsHolder propertiesInformation, AclDetailsHolder aclInformation) {
BasicAclEntry entry;
try {
entry = (BasicAclEntry) propertiesInformation.getAclClass().newInstance();
} catch (InstantiationException ie) {
throw new IllegalArgumentException(ie.getMessage());
} catch (IllegalAccessException iae) {
throw new IllegalArgumentException(iae.getMessage());
}
entry.setAclObjectIdentity(propertiesInformation.getAclObjectIdentity());
entry.setAclObjectParentIdentity(propertiesInformation.getAclObjectParentIdentity());
if (aclInformation == null) {
// this is an inheritence marker instance only
entry.setMask(0);
entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
} else {
// this is an individual ACL entry
entry.setMask(aclInformation.getMask());
entry.setRecipient(aclInformation.getRecipient());
}
return entry;
}
/**
* Returns the ACLs associated with the requested <code>AclObjectIdentity</code>.<P>The {@link
* BasicAclEntry}s returned by this method will have <code>String</code>-based recipients. This will not be a
* problem if you are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which is the default
* configured against <code>BasicAclProvider</code>.</p>
* <P>This method will only return ACLs for requests where the <code>AclObjectIdentity</code> is of type
* {@link NamedEntityObjectIdentity}. Of course, you can subclass or replace this class and support your own
* custom <code>AclObjectIdentity</code> types.</p>
*
* @param aclObjectIdentity for which ACL information is required (cannot be <code>null</code> and must be an
* instance of <code>NamedEntityObjectIdentity</code>)
*
* @return the ACLs that apply (without any <code>null</code>s inside the array), or <code>null</code> if not found
* or if an incompatible <code>AclObjectIdentity</code> was requested
*/
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
String aclObjectIdentityString;
try {
aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
} catch (IllegalArgumentException unsupported) {
return null; // pursuant to contract described in JavaDocs above
}
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
List objects = objectProperties.execute(aclObjectIdentityString);
if (objects.size() == 0) {
// this is an unknown object identity string
return null;
}
// Cast to an object properties holder (there should only be one record)
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0);
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
List acls = aclsByObjectIdentity.execute(propertiesInformation.getForeignKeyId());
if (acls.size() == 0) {
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation, null)};
} else {
// return the individual ACL instances
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {});
List toReturnAcls = new Vector();
for (int i = 0; i < aclHolders.length; i++) {
toReturnAcls.add(createBasicAclEntry(propertiesInformation, aclHolders[i]));
}
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
}
}
public MappingSqlQuery getAclsByObjectIdentity() {
return aclsByObjectIdentity;
}
public String getAclsByObjectIdentityQuery() {
return aclsByObjectIdentityQuery;
}
public String getObjectPropertiesQuery() {
return objectPropertiesQuery;
}
protected void initDao() throws ApplicationContextException {
initMappingSqlQueries();
}
/**
* Extension point to allow other MappingSqlQuery objects to be substituted in a subclass
*/
protected void initMappingSqlQueries() {
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource()));
setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
}
public void setAclsByObjectIdentity(MappingSqlQuery aclsByObjectIdentityQuery) {
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
}
/**
* Allows the default query string used to retrieve ACLs based on object identity to be overriden, if
* default table or column names need to be changed. The default query is {@link
* #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure that all returned columns are mapped
* back to the same column names as in the default query.
*
* @param queryString The query string to set
*/
public void setAclsByObjectIdentityQuery(String queryString) {
aclsByObjectIdentityQuery = queryString;
}
public void setObjectProperties(MappingSqlQuery objectPropertiesQuery) {
this.objectProperties = objectPropertiesQuery;
}
public void setObjectPropertiesQuery(String queryString) {
objectPropertiesQuery = queryString;
}
//~ Inner Classes ==================================================================================================
/**
* Used to hold details of a domain object instance's properties, or an individual ACL entry.<P>Not all
* properties will be set. The actual properties set will depend on which <code>MappingSqlQuery</code> creates the
* object.</p>
* <P>Does not enforce <code>null</code>s or empty <code>String</code>s as this is performed by the
* <code>MappingSqlQuery</code> objects (or preferably the backend RDBMS via schema constraints).</p>
*/
protected final class AclDetailsHolder {
private AclObjectIdentity aclObjectIdentity;
private AclObjectIdentity aclObjectParentIdentity;
private Class aclClass;
private Object recipient;
private int mask;
private long foreignKeyId;
/**
* Record details of an individual ACL entry (usually from the
* ACL_PERMISSION table)
*
* @param recipient the recipient
* @param mask the integer to be masked
*/
public AclDetailsHolder(Object recipient, int mask) {
this.recipient = recipient;
this.mask = mask;
}
/**
* Record details of a domain object instance's properties (usually
* from the ACL_OBJECT_IDENTITY table)
*
* @param foreignKeyId used by the
* <code>AclsByObjectIdentityMapping</code> to locate the
* individual ACL entries
* @param aclObjectIdentity the object identity of the domain object
* instance
* @param aclObjectParentIdentity the object identity of the domain
* object instance's parent
* @param aclClass the class of which a new instance which should be
* created for each individual ACL entry (or an inheritence
* "holder" class if there are no ACL entries)
*/
public AclDetailsHolder(long foreignKeyId, AclObjectIdentity aclObjectIdentity,
AclObjectIdentity aclObjectParentIdentity, Class aclClass) {
this.foreignKeyId = foreignKeyId;
this.aclObjectIdentity = aclObjectIdentity;
this.aclObjectParentIdentity = aclObjectParentIdentity;
this.aclClass = aclClass;
}
public Class getAclClass() {
return aclClass;
}
public AclObjectIdentity getAclObjectIdentity() {
return aclObjectIdentity;
}
public AclObjectIdentity getAclObjectParentIdentity() {
return aclObjectParentIdentity;
}
public long getForeignKeyId() {
return foreignKeyId;
}
public int getMask() {
return mask;
}
public Object getRecipient() {
return recipient;
}
}
/**
* Query object to look up individual ACL entries.<P>Returns the generic <code>AclDetailsHolder</code>
* object.</p>
* <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
* <P>The executed SQL requires the following information be made available from the indicated
* placeholders: 1. RECIPIENT, 2. MASK.</p>
*/
protected class AclsByObjectIdentityMapping extends MappingSqlQuery {
protected AclsByObjectIdentityMapping(DataSource ds) {
super(ds, aclsByObjectIdentityQuery);
declareParameter(new SqlParameter(Types.BIGINT));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
String recipient = rs.getString(1);
int mask = rs.getInt(2);
Assert.hasText(recipient, "recipient required");
return new AclDetailsHolder(recipient, mask);
}
}
/**
* Query object to look up properties for an object identity.<P>Returns the generic
* <code>AclDetailsHolder</code> object.</p>
* <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
* <P>The executed SQL requires the following information be made available from the indicated
* placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.</p>
*/
protected class ObjectPropertiesMapping extends MappingSqlQuery {
protected ObjectPropertiesMapping(DataSource ds) {
super(ds, objectPropertiesQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
private AclObjectIdentity buildIdentity(String identity) {
if (identity == null) {
// Must be an empty parent, so return null
return null;
}
int delim = identity.lastIndexOf(":");
String classname = identity.substring(0, delim);
String id = identity.substring(delim + 1);
return new NamedEntityObjectIdentity(classname, id);
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
long id = rs.getLong(1); // required
String objectIdentity = rs.getString(2); // required
String aclClass = rs.getString(3); // required
String parentObjectIdentity = rs.getString(4); // optional
Assert.hasText(objectIdentity,
"required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty");
Assert.hasText(aclClass, "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
Class aclClazz;
try {
aclClazz = this.getClass().getClassLoader().loadClass(aclClass);
} catch (ClassNotFoundException cnf) {
throw new IllegalArgumentException(cnf.getMessage());
}
return new AclDetailsHolder(id,
buildIdentity(objectIdentity), buildIdentity(parentObjectIdentity), aclClazz);
}
}
}

View File

@ -1,464 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.jdbc;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.BasicAclEntryCache;
import org.springframework.security.acl.basic.BasicAclExtendedDao;
import org.springframework.security.acl.basic.cache.NullAclEntryCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContextException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;
import org.springframework.util.Assert;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Iterator;
import java.util.List;
import javax.sql.DataSource;
/**
* <p>Extension of the base {@link JdbcDaoImpl}, which implements {@link BasicAclExtendedDao}.</p>
* <p>A default database structure is assumed. This may be overridden by setting the default query strings to use.</p>
* <p>If you are using a cache with <code>BasicAclProvider</code>, you should specify that cache via {@link
* #setBasicAclEntryCache(BasicAclEntryCache)}. This will cause cache evictions (removals) to take place whenever a
* DAO mutator method is called.</p>
* <p>This implementation works with <code>String</code> based recipients and {@link
* org.springframework.security.acl.basic.NamedEntityObjectIdentity} only. The latter can be changed by overriding {@link
* #convertAclObjectIdentityToString(AclObjectIdentity)}.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class JdbcExtendedDaoImpl extends JdbcDaoImpl implements BasicAclExtendedDao {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class);
public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT =
"DELETE FROM acl_object_identity WHERE id = ?";
public static final String DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT =
"INSERT INTO acl_object_identity (object_identity, parent_object, acl_class) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_DELETE_STATEMENT =
"DELETE FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
public static final String DEF_ACL_PERMISSION_INSERT_STATEMENT =
"INSERT INTO acl_permission (acl_object_identity, recipient, mask) VALUES (?, ?, ?)";
public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT =
"UPDATE acl_permission SET mask = ? WHERE id = ?";
public static final String DEF_LOOKUP_PERMISSION_ID_QUERY =
"SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
//~ Instance fields ================================================================================================
private AclObjectIdentityDelete aclObjectIdentityDelete;
private AclObjectIdentityInsert aclObjectIdentityInsert;
private AclPermissionDelete aclPermissionDelete;
private AclPermissionInsert aclPermissionInsert;
private AclPermissionUpdate aclPermissionUpdate;
private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache();
private MappingSqlQuery lookupPermissionIdMapping;
private String aclObjectIdentityDeleteStatement;
private String aclObjectIdentityInsertStatement;
private String aclPermissionDeleteStatement;
private String aclPermissionInsertStatement;
private String aclPermissionUpdateStatement;
private String lookupPermissionIdQuery;
//~ Constructors ===================================================================================================
public JdbcExtendedDaoImpl() {
aclObjectIdentityDeleteStatement = DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT;
aclObjectIdentityInsertStatement = DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT;
aclPermissionDeleteStatement = DEF_ACL_PERMISSION_DELETE_STATEMENT;
aclPermissionInsertStatement = DEF_ACL_PERMISSION_INSERT_STATEMENT;
aclPermissionUpdateStatement = DEF_ACL_PERMISSION_UPDATE_STATEMENT;
lookupPermissionIdQuery = DEF_LOOKUP_PERMISSION_ID_QUERY;
}
//~ Methods ========================================================================================================
public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask)
throws DataAccessException {
basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
// Retrieve applicable acl_permission.id
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), recipient.toString());
if (permissionId == -1) {
throw new DataRetrievalFailureException("Could not locate existing acl_permission for aclObjectIdentity: "
+ aclObjectIdentity + ", recipient: " + recipient.toString());
}
// Change permission
aclPermissionUpdate.update(new Long(permissionId), newMask);
}
public void create(BasicAclEntry basicAclEntry) throws DataAccessException {
// Create acl_object_identity record if required
createAclObjectIdentityIfRequired(basicAclEntry);
// Only continue if a recipient is specifed (null recipient indicates
// just wanted to ensure the acl_object_identity was created)
if (basicAclEntry.getRecipient() == null) {
return;
}
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry.getAclObjectIdentity());
// Ensure there isn't an existing record for this recipient
long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), basicAclEntry.getRecipient());
if (permissionId != -1) {
throw new DataIntegrityViolationException("Recipient '" + basicAclEntry.getRecipient()
+ "' already exists for aclObjectIdentity ID " + aclDetailsHolder.getForeignKeyId()
+ " (permission ID " + ")");
}
// Create acl_permission
aclPermissionInsert.insert(new Long(aclDetailsHolder.getForeignKeyId()),
basicAclEntry.getRecipient().toString(), new Integer(basicAclEntry.getMask()));
}
/**
* Convenience method that creates an acl_object_identity record if required.
*
* @param basicAclEntry containing the <code>AclObjectIdentity</code> to create
*
* @throws DataAccessException
*/
private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry)
throws DataAccessException {
basicAclEntryCache.removeEntriesFromCache(basicAclEntry.getAclObjectIdentity());
String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry.getAclObjectIdentity());
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
List objects = objectProperties.execute(aclObjectIdentityString);
if (objects.size() == 0) {
if (basicAclEntry.getAclObjectParentIdentity() != null) {
AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry.getAclObjectParentIdentity());
// Must create the acl_object_identity record
aclObjectIdentityInsert.insert(aclObjectIdentityString, new Long(parentDetails.getForeignKeyId()),
basicAclEntry.getClass().getName());
} else {
// Must create the acl_object_identity record
aclObjectIdentityInsert.insert(aclObjectIdentityString, null, basicAclEntry.getClass().getName());
}
}
}
public void delete(AclObjectIdentity aclObjectIdentity)
throws DataAccessException {
basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
// Retrieve all acl_permissions applying to this acl_object_identity
Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder.getForeignKeyId()).iterator();
// Delete all existing acl_permissions applying to this acl_object_identity
while (acls.hasNext()) {
AclDetailsHolder permission = (AclDetailsHolder) acls.next();
delete(aclObjectIdentity, permission.getRecipient());
}
// Delete acl_object_identity
aclObjectIdentityDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()));
}
public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
throws DataAccessException {
basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity);
// Retrieve acl_object_identity record details
AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
// Delete acl_permission
aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()), recipient.toString());
}
public AclObjectIdentityDelete getAclObjectIdentityDelete() {
return aclObjectIdentityDelete;
}
public String getAclObjectIdentityDeleteStatement() {
return aclObjectIdentityDeleteStatement;
}
public AclObjectIdentityInsert getAclObjectIdentityInsert() {
return aclObjectIdentityInsert;
}
public String getAclObjectIdentityInsertStatement() {
return aclObjectIdentityInsertStatement;
}
public AclPermissionDelete getAclPermissionDelete() {
return aclPermissionDelete;
}
public String getAclPermissionDeleteStatement() {
return aclPermissionDeleteStatement;
}
public AclPermissionInsert getAclPermissionInsert() {
return aclPermissionInsert;
}
public String getAclPermissionInsertStatement() {
return aclPermissionInsertStatement;
}
public AclPermissionUpdate getAclPermissionUpdate() {
return aclPermissionUpdate;
}
public String getAclPermissionUpdateStatement() {
return aclPermissionUpdateStatement;
}
public BasicAclEntryCache getBasicAclEntryCache() {
return basicAclEntryCache;
}
public MappingSqlQuery getLookupPermissionIdMapping() {
return lookupPermissionIdMapping;
}
public String getLookupPermissionIdQuery() {
return lookupPermissionIdQuery;
}
protected void initDao() throws ApplicationContextException {
super.initDao();
lookupPermissionIdMapping = new LookupPermissionIdMapping(getDataSource());
aclPermissionInsert = new AclPermissionInsert(getDataSource());
aclObjectIdentityInsert = new AclObjectIdentityInsert(getDataSource());
aclPermissionDelete = new AclPermissionDelete(getDataSource());
aclObjectIdentityDelete = new AclObjectIdentityDelete(getDataSource());
aclPermissionUpdate = new AclPermissionUpdate(getDataSource());
}
/**
* Convenience method that obtains a given acl_object_identity record.
*
* @param aclObjectIdentity to lookup
*
* @return details of the record
*
* @throws DataRetrievalFailureException if record could not be found
*/
private AclDetailsHolder lookupAclDetailsHolder(AclObjectIdentity aclObjectIdentity)
throws DataRetrievalFailureException {
String aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
List objects = objectProperties.execute(aclObjectIdentityString);
if (objects.size() == 0) {
throw new DataRetrievalFailureException("aclObjectIdentity not found: " + aclObjectIdentityString);
}
// Should only be one record
return (AclDetailsHolder) objects.get(0);
}
/**
* Convenience method to lookup the acl_permission applying to a given acl_object_identity.id and
* acl_permission.recipient.
*
* @param aclObjectIdentityId to locate
* @param recipient to locate
*
* @return the acl_permission.id of the record, or -1 if not found
*
* @throws DataAccessException DOCUMENT ME!
*/
private long lookupPermissionId(long aclObjectIdentityId, Object recipient)
throws DataAccessException {
List list = lookupPermissionIdMapping.execute(new Object[] {new Long(aclObjectIdentityId), recipient});
if (list.size() == 0) {
return -1;
}
return ((Long) list.get(0)).longValue();
}
public void setAclObjectIdentityDelete(AclObjectIdentityDelete aclObjectIdentityDelete) {
this.aclObjectIdentityDelete = aclObjectIdentityDelete;
}
public void setAclObjectIdentityDeleteStatement(String aclObjectIdentityDeleteStatement) {
this.aclObjectIdentityDeleteStatement = aclObjectIdentityDeleteStatement;
}
public void setAclObjectIdentityInsert(AclObjectIdentityInsert aclObjectIdentityInsert) {
this.aclObjectIdentityInsert = aclObjectIdentityInsert;
}
public void setAclObjectIdentityInsertStatement(String aclObjectIdentityInsertStatement) {
this.aclObjectIdentityInsertStatement = aclObjectIdentityInsertStatement;
}
public void setAclPermissionDelete(AclPermissionDelete aclPermissionDelete) {
this.aclPermissionDelete = aclPermissionDelete;
}
public void setAclPermissionDeleteStatement(String aclPermissionDeleteStatement) {
this.aclPermissionDeleteStatement = aclPermissionDeleteStatement;
}
public void setAclPermissionInsert(AclPermissionInsert aclPermissionInsert) {
this.aclPermissionInsert = aclPermissionInsert;
}
public void setAclPermissionInsertStatement(String aclPermissionInsertStatement) {
this.aclPermissionInsertStatement = aclPermissionInsertStatement;
}
public void setAclPermissionUpdate(AclPermissionUpdate aclPermissionUpdate) {
this.aclPermissionUpdate = aclPermissionUpdate;
}
public void setAclPermissionUpdateStatement(String aclPermissionUpdateStatement) {
this.aclPermissionUpdateStatement = aclPermissionUpdateStatement;
}
public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) {
Assert.notNull(basicAclEntryCache, "Cache cannot be set to null");
this.basicAclEntryCache = basicAclEntryCache;
}
public void setLookupPermissionIdMapping(MappingSqlQuery lookupPermissionIdMapping) {
this.lookupPermissionIdMapping = lookupPermissionIdMapping;
}
public void setLookupPermissionIdQuery(String lookupPermissionIdQuery) {
this.lookupPermissionIdQuery = lookupPermissionIdQuery;
}
//~ Inner Classes ==================================================================================================
protected class AclObjectIdentityDelete extends SqlUpdate {
protected AclObjectIdentityDelete(DataSource ds) {
super(ds, aclObjectIdentityDeleteStatement);
declareParameter(new SqlParameter(Types.BIGINT));
compile();
}
protected void delete(Long aclObjectIdentity) throws DataAccessException {
super.update(aclObjectIdentity.intValue());
}
}
protected class AclObjectIdentityInsert extends SqlUpdate {
protected AclObjectIdentityInsert(DataSource ds) {
super(ds, aclObjectIdentityInsertStatement);
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected void insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass)
throws DataAccessException {
Object[] objs = new Object[] {objectIdentity, parentAclObjectIdentity, aclClass};
super.update(objs);
}
}
protected class AclPermissionDelete extends SqlUpdate {
protected AclPermissionDelete(DataSource ds) {
super(ds, aclPermissionDeleteStatement);
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected void delete(Long aclObjectIdentity, String recipient)
throws DataAccessException {
super.update(new Object[] {aclObjectIdentity, recipient});
}
}
protected class AclPermissionInsert extends SqlUpdate {
protected AclPermissionInsert(DataSource ds) {
super(ds, aclPermissionInsertStatement);
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected void insert(Long aclObjectIdentity, String recipient, Integer mask)
throws DataAccessException {
Object[] objs = new Object[] {aclObjectIdentity, recipient, mask};
super.update(objs);
}
}
protected class AclPermissionUpdate extends SqlUpdate {
protected AclPermissionUpdate(DataSource ds) {
super(ds, aclPermissionUpdateStatement);
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected void update(Long aclPermissionId, Integer newMask)
throws DataAccessException {
super.update(newMask.intValue(), aclPermissionId.intValue());
}
}
protected class LookupPermissionIdMapping extends MappingSqlQuery {
protected LookupPermissionIdMapping(DataSource ds) {
super(ds, lookupPermissionIdQuery);
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
return new Long(rs.getLong(1));
}
}
}

View File

@ -1,5 +0,0 @@
<html>
<body>
JDBC-based data access object for ACL information.
</body>
</html>

View File

@ -1,5 +0,0 @@
<html>
<body>
Access control list implementation based on integer bit masks.
</body>
</html>

View File

@ -1,15 +0,0 @@
<html>
<body>
Enables retrieval of access control lists (ACLs) for domain object instances.
<P>The goal of this package is to locate the <code>AclEntry</code>s
that apply to a given domain object instance.
</P>
<P>
An <code>AclManager</code> has ultimate resposibility for obtaining the
<code>AclEntry</code>s instances, with a provider-based implementation
available via the <code>AclProviderManager</code> class (and
its <code>AclProvider</code> interface.</P>
</body>
</html>

View File

@ -1,232 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.afterinvocation;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.AccessDeniedException;
import org.springframework.security.Authentication;
import org.springframework.security.AuthorizationServiceException;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.util.Assert;
/**
* <p>Given a <code>Collection</code> of domain object instances returned from a secure object invocation, remove
* any <code>Collection</code> elements the principal does not have appropriate permission to access as defined by the
* {@link AclManager}.</p>
* <p>The <code>AclManager</code> is used to retrieve the access control list (ACL) permissions associated with
* each <code>Collection</code> domain object instance element for the current <code>Authentication</code> object.
* This class is designed to process {@link AclEntry}s that are subclasses of {@link
* org.springframework.security.acl.basic.BasicAclEntry} only. Generally these are obtained by using the {@link
* org.springframework.security.acl.basic.BasicAclProvider}.</p>
* <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>AclManager</code> and ensure the
* principal is {@link org.springframework.security.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link
* #requirePermission}s for each <code>Collection</code> element. If the principal does not have at least one of the
* permissions, that element will not be included in the returned <code>Collection</code>.</p>
* <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
* #processConfigAttribute} of <code>AFTER_ACL_COLLECTION_READ</code> and a {@link #requirePermission} of
* <code>SimpleAclEntry.READ</code>. These are also the defaults.</p>
* <p>The <code>AclManager</code> is allowed to return any implementations of <code>AclEntry</code> it wishes.
* However, this provider will only be able to validate against <code>BasicAclEntry</code>s, and thus a
* <code>Collection</code> element will be filtered from the resulting <code>Collection</code> if no
* <code>AclEntry</code> is of type <code>BasicAclEntry</code>.</p>
* <p>If the provided <code>returnObject</code> is <code>null</code>, a <code>null</code><code>Collection</code>
* will be returned. If the provided <code>returnObject</code> is not a <code>Collection</code>, an {@link
* AuthorizationServiceException} will be thrown.</p>
* <p>All comparisons and prefixes are case sensitive.</p>
*
* @author Ben Alex
* @author Paulo Neves
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements AfterInvocationProvider,
InitializingBean {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationCollectionFilteringProvider.class);
//~ Instance fields ================================================================================================
private AclManager aclManager;
private Class processDomainObjectClass = Object.class;
private String processConfigAttribute = "AFTER_ACL_COLLECTION_READ";
private int[] requirePermission = {SimpleAclEntry.READ};
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
Assert.notNull(aclManager, "An aclManager is mandatory");
if ((requirePermission == null) || (requirePermission.length == 0)) {
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
}
}
public Object decide(Authentication authentication, Object object, List<ConfigAttribute> config,
Object returnedObject) throws AccessDeniedException {
Iterator iter = config.iterator();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr)) {
// Need to process the Collection for this invocation
if (returnedObject == null) {
if (logger.isDebugEnabled()) {
logger.debug("Return object is null, skipping");
}
return null;
}
Filterer filterer = null;
if (returnedObject instanceof Collection) {
Collection collection = (Collection) returnedObject;
filterer = new CollectionFilterer(collection);
} else if (returnedObject.getClass().isArray()) {
Object[] array = (Object[]) returnedObject;
filterer = new ArrayFilterer(array);
} else {
throw new AuthorizationServiceException("A Collection or an array (or null) was required as the "
+ "returnedObject, but the returnedObject was: " + returnedObject);
}
// Locate unauthorised Collection elements
Iterator collectionIter = filterer.iterator();
while (collectionIter.hasNext()) {
Object domainObject = collectionIter.next();
boolean hasPermission = false;
if (domainObject == null) {
hasPermission = true;
} else if (!processDomainObjectClass.isAssignableFrom(domainObject.getClass())) {
hasPermission = true;
} else {
AclEntry[] acls = aclManager.getAcls(domainObject, authentication);
if ((acls != null) && (acls.length != 0)) {
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
// See if principal has any of the required permissions
for (int y = 0; y < requirePermission.length; y++) {
if (processableAcl.isPermitted(requirePermission[y])) {
hasPermission = true;
if (logger.isDebugEnabled()) {
logger.debug("Principal is authorised for element: " + domainObject
+ " due to ACL: " + processableAcl.toString());
}
}
}
}
}
}
if (!hasPermission) {
filterer.remove(domainObject);
if (logger.isDebugEnabled()) {
logger.debug("Principal is NOT authorised for element: " + domainObject);
}
}
}
}
return filterer.getFilteredObject();
}
}
return returnedObject;
}
public AclManager getAclManager() {
return aclManager;
}
public String getProcessConfigAttribute() {
return processConfigAttribute;
}
public int[] getRequirePermission() {
return requirePermission;
}
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
this.processDomainObjectClass = processDomainObjectClass;
}
public void setRequirePermission(int[] requirePermission) {
this.requirePermission = requirePermission;
}
/**
* Allow setting permissions with String literals instead of integers as {@link
* #setRequirePermission(int[])}
*
* @param requiredPermissions permission literals
*
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
*/
public void setRequirePermissionFromString(String[] requiredPermissions) {
setRequirePermission(SimpleAclEntry.parsePermissions(requiredPermissions));
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
return true;
} else {
return false;
}
}
/**
* This implementation supports any type of class, because it does not query the presented secure object.
*
* @param clazz the secure object
*
* @return always <code>true</code>
*/
public boolean supports(Class<? extends Object> clazz) {
return true;
}
}

View File

@ -1,216 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.afterinvocation;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.AccessDeniedException;
import org.springframework.security.Authentication;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.util.Assert;
/**
* <p>Given a domain object instance returned from a secure object invocation, ensures the principal has
* appropriate permission as defined by the {@link AclManager}.</p>
* <p>The <code>AclManager</code> is used to retrieve the access control list (ACL) permissions associated with a
* domain object instance for the current <code>Authentication</code> object. This class is designed to process {@link
* AclEntry}s that are subclasses of {@link org.springframework.security.acl.basic.BasicAclEntry} only. Generally these are
* obtained by using the {@link org.springframework.security.acl.basic.BasicAclProvider}.</p>
* <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>AclManager</code> and ensure the
* principal is {@link org.springframework.security.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link
* #requirePermission}s.</p>
* <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
* #processConfigAttribute} of <code>AFTER_ACL_READ</code> and a {@link #requirePermission} of
* <code>SimpleAclEntry.READ</code>. These are also the defaults.</p>
* <p>If the principal does not have sufficient permissions, an <code>AccessDeniedException</code> will be thrown.</p>
* <p>The <code>AclManager</code> is allowed to return any implementations of <code>AclEntry</code> it wishes.
* However, this provider will only be able to validate against <code>BasicAclEntry</code>s, and thus access will be
* denied if no <code>AclEntry</code> is of type <code>BasicAclEntry</code>.</p>
* <p>If the provided <code>returnObject</code> is <code>null</code>, permission will always be granted and
* <code>null</code> will be returned.</p>
* <p>All comparisons and prefixes are case sensitive.</p>
*
* @deprecated Use new spring-security-acl module instead
*/
public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean,
MessageSourceAware {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class);
//~ Instance fields ================================================================================================
private AclManager aclManager;
private Class processDomainObjectClass = Object.class;
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private String processConfigAttribute = "AFTER_ACL_READ";
private int[] requirePermission = {SimpleAclEntry.READ};
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
Assert.notNull(aclManager, "An aclManager is mandatory");
Assert.notNull(messages, "A message source must be set");
if ((requirePermission == null) || (requirePermission.length == 0)) {
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
}
}
public Object decide(Authentication authentication, Object object, List<ConfigAttribute> config,
Object returnedObject) throws AccessDeniedException {
Iterator iter = config.iterator();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr)) {
// Need to make an access decision on this invocation
if (returnedObject == null) {
// AclManager interface contract prohibits nulls
// As they have permission to null/nothing, grant access
if (logger.isDebugEnabled()) {
logger.debug("Return object is null, skipping");
}
return null;
}
if (!processDomainObjectClass.isAssignableFrom(returnedObject.getClass())) {
if (logger.isDebugEnabled()) {
logger.debug("Return object is not applicable for this provider, skipping");
}
return null;
}
AclEntry[] acls = aclManager.getAcls(returnedObject, authentication);
if ((acls == null) || (acls.length == 0)) {
throw new AccessDeniedException(messages.getMessage(
"BasicAclEntryAfterInvocationProvider.noPermission",
new Object[] {authentication.getName(), returnedObject},
"Authentication {0} has NO permissions at all to the domain object {1}", LocaleContextHolder.getLocale()));
}
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
// See if principal has any of the required permissions
for (int y = 0; y < requirePermission.length; y++) {
if (processableAcl.isPermitted(requirePermission[y])) {
if (logger.isDebugEnabled()) {
logger.debug("Principal DOES have permission to return object: " + returnedObject
+ " due to ACL: " + processableAcl.toString());
}
return returnedObject;
}
}
}
}
// No permissions match
throw new AccessDeniedException(messages.getMessage(
"BasicAclEntryAfterInvocationProvider.insufficientPermission",
new Object[] {authentication.getName(), returnedObject},
"Authentication {0} has ACL permissions to the domain object, "
+ "but not the required ACL permission to the domain object {1}", LocaleContextHolder.getLocale()));
}
}
return returnedObject;
}
public AclManager getAclManager() {
return aclManager;
}
public String getProcessConfigAttribute() {
return processConfigAttribute;
}
public int[] getRequirePermission() {
return requirePermission;
}
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
public void setProcessDomainObjectClass(Class processDomainObjectClass) {
Assert.notNull(processDomainObjectClass, "processDomainObjectClass cannot be set to null");
this.processDomainObjectClass = processDomainObjectClass;
}
public void setRequirePermission(int[] requirePermission) {
this.requirePermission = requirePermission;
}
/**
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
*
* @param requiredPermissions Permission literals
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
*/
public void setRequirePermissionFromString(String[] requiredPermissions) {
setRequirePermission(SimpleAclEntry.parsePermissions(requiredPermissions));
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
return true;
} else {
return false;
}
}
/**
* This implementation supports any type of class, because it does not query the presented secure object.
*
* @param clazz the secure object
*
* @return always <code>true</code>
*/
public boolean supports(Class<? extends Object> clazz) {
return true;
}
}

View File

@ -1,264 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.vote;
import org.springframework.security.Authentication;
import org.springframework.security.AuthorizationServiceException;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
/**
* <p>Given a domain object instance passed as a method argument, ensures the principal has appropriate permission
* as defined by the {@link AclManager}.</p>
* <p>The <code>AclManager</code> is used to retrieve the access control list (ACL) permissions associated with a
* domain object instance for the current <code>Authentication</code> object. This class is designed to process {@link
* AclEntry}s that are subclasses of {@link org.springframework.security.acl.basic.BasicAclEntry} only. Generally these are
* obtained by using the {@link org.springframework.security.acl.basic.BasicAclProvider}.</p>
* <p>The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link
* #processConfigAttribute}. The provider will then locate the first method argument of type {@link
* #processDomainObjectClass}. Assuming that method argument is non-null, the provider will then lookup the ACLs from
* the <code>AclManager</code> and ensure the principal is {@link
* org.springframework.security.acl.basic.BasicAclEntry#isPermitted(int)} for at least one of the {@link #requirePermission}s.</p>
* <p>If the method argument is <code>null</code>, the voter will abstain from voting. If the method argument
* could not be found, an {@link org.springframework.security.AuthorizationServiceException} will be thrown.</p>
* <p>In practical terms users will typically setup a number of <code>BasicAclEntryVoter</code>s. Each will have a
* different {@link #processDomainObjectClass}, {@link #processConfigAttribute} and {@link #requirePermission}
* combination. For example, a small application might employ the following instances of
* <code>BasicAclEntryVoter</code>:
* <ul>
* <li>Process domain object class <code>BankAccount</code>, configuration attribute
* <code>VOTE_ACL_BANK_ACCONT_READ</code>, require permission <code>SimpleAclEntry.READ</code></li>
* <li>Process domain object class <code>BankAccount</code>, configuration attribute
* <code>VOTE_ACL_BANK_ACCOUNT_WRITE</code>, require permission list <code>SimpleAclEntry.WRITE</code> and
* <code>SimpleAclEntry.CREATE</code> (allowing the principal to have <b>either</b> of these two permissions</li>
* <li>Process domain object class <code>Customer</code>, configuration attribute
* <code>VOTE_ACL_CUSTOMER_READ</code>, require permission <code>SimpleAclEntry.READ</code></li>
* <li>Process domain object class <code>Customer</code>, configuration attribute
* <code>VOTE_ACL_CUSTOMER_WRITE</code>, require permission list <code>SimpleAclEntry.WRITE</code> and
* <code>SimpleAclEntry.CREATE</code></li>
* </ul>
* Alternatively, you could have used a common superclass or interface for the {@link #processDomainObjectClass}
* if both <code>BankAccount</code> and <code>Customer</code> had common parents.</p>
* <p>If the principal does not have sufficient permissions, the voter will vote to deny access.</p>
* <p>The <code>AclManager</code> is allowed to return any implementations of <code>AclEntry</code> it wishes.
* However, this provider will only be able to validate against <code>AbstractBasicAclEntry</code>s, and thus a vote
* to deny access will be made if no <code>AclEntry</code> is of type <code>AbstractBasicAclEntry</code>.</p>
* <p>All comparisons and prefixes are case sensitive.</p>
*
* @author Ben Alex
* @version $Id$
* @deprecated Use new spring-security-acl module instead
*/
public class BasicAclEntryVoter extends AbstractAclVoter implements InitializingBean {
//~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(BasicAclEntryVoter.class);
//~ Instance fields ================================================================================================
private AclManager aclManager;
private String internalMethod;
private String processConfigAttribute;
private int[] requirePermission;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
Assert.notNull(aclManager, "An aclManager is mandatory");
if ((requirePermission == null) || (requirePermission.length == 0)) {
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
}
}
public AclManager getAclManager() {
return aclManager;
}
/**
* Optionally specifies a method of the domain object that will be used to obtain a contained domain
* object. That contained domain object will be used for the ACL evaluation. This is useful if a domain object
* contains a parent that an ACL evaluation should be targeted for, instead of the child domain object (which
* perhaps is being created and as such does not yet have any ACL permissions)
*
* @return <code>null</code> to use the domain object, or the name of a method (that requires no arguments) that
* should be invoked to obtain an <code>Object</code> which will be the domain object used for ACL
* evaluation
*/
public String getInternalMethod() {
return internalMethod;
}
public String getProcessConfigAttribute() {
return processConfigAttribute;
}
public int[] getRequirePermission() {
return requirePermission;
}
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public void setInternalMethod(String internalMethod) {
this.internalMethod = internalMethod;
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
public void setRequirePermission(int[] requirePermission) {
this.requirePermission = requirePermission;
}
/**
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
*
* @param requirePermission Permission literals
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
*/
public void setRequirePermissionFromString(String[] requirePermission) {
setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission));
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
return true;
} else {
return false;
}
}
public int vote(Authentication authentication, Object object, List<ConfigAttribute> attributes) {
Iterator iter = attributes.iterator();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (this.supports(attr)) {
// Need to make an access decision on this invocation
// Attempt to locate the domain object instance to process
Object domainObject = getDomainObjectInstance(object);
// If domain object is null, vote to abstain
if (domainObject == null) {
if (logger.isDebugEnabled()) {
logger.debug("Voting to abstain - domainObject is null");
}
return AccessDecisionVoter.ACCESS_ABSTAIN;
}
// Evaluate if we are required to use an inner domain object
if ((internalMethod != null) && !"".equals(internalMethod)) {
try {
Class clazz = domainObject.getClass();
Method method = clazz.getMethod(internalMethod, new Class[] {});
domainObject = method.invoke(domainObject, new Object[] {});
} catch (NoSuchMethodException nsme) {
throw new AuthorizationServiceException("Object of class '" + domainObject.getClass()
+ "' does not provide the requested internalMethod: " + internalMethod);
} catch (IllegalAccessException iae) {
if (logger.isDebugEnabled()) {
logger.debug("IllegalAccessException", iae);
if (iae.getCause() != null) {
logger.debug("Cause: " + iae.getCause().getMessage(), iae.getCause());
}
}
throw new AuthorizationServiceException("Problem invoking internalMethod: " + internalMethod
+ " for object: " + domainObject);
} catch (InvocationTargetException ite) {
if (logger.isDebugEnabled()) {
logger.debug("InvocationTargetException", ite);
if (ite.getCause() != null) {
logger.debug("Cause: " + ite.getCause().getMessage(), ite.getCause());
}
}
throw new AuthorizationServiceException("Problem invoking internalMethod: " + internalMethod
+ " for object: " + domainObject);
}
}
// Obtain the ACLs applicable to the domain object
AclEntry[] acls = aclManager.getAcls(domainObject, authentication);
// If principal has no permissions for domain object, deny
if ((acls == null) || (acls.length == 0)) {
if (logger.isDebugEnabled()) {
logger.debug("Voting to deny access - no ACLs returned for this principal");
}
return AccessDecisionVoter.ACCESS_DENIED;
}
// Principal has some permissions for domain object, check them
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
// See if principal has any of the required permissions
for (int y = 0; y < requirePermission.length; y++) {
if (processableAcl.isPermitted(requirePermission[y])) {
if (logger.isDebugEnabled()) {
logger.debug("Voting to grant access");
}
return AccessDecisionVoter.ACCESS_GRANTED;
}
}
}
}
// No permissions match
if (logger.isDebugEnabled()) {
logger.debug(
"Voting to deny access - ACLs returned, but insufficient permissions for this principal");
}
return AccessDecisionVoter.ACCESS_DENIED;
}
}
// No configuration attribute matched, so abstain
return AccessDecisionVoter.ACCESS_ABSTAIN;
}
}

View File

@ -1,61 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
/**
* Returns the indicated collection of <code>AclEntry</code>s when the given <code>Authentication</code> principal
* is presented for the indicated domain <code>Object</code> instance.
*
* @author Ben Alex
* @version $Id$
*/
public class MockAclManager implements AclManager {
//~ Instance fields ================================================================================================
private Object object;
private Object principal;
private AclEntry[] acls;
//~ Constructors ===================================================================================================
public MockAclManager(Object domainObject, Object principal, AclEntry[] acls) {
this.object = domainObject;
this.principal = principal;
this.acls = acls;
}
//~ Methods ========================================================================================================
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
if (domainInstance.equals(object) && authentication.getPrincipal().equals(principal)) {
return acls;
} else {
return null;
}
}
public AclEntry[] getAcls(Object domainInstance) {
if (domainInstance.equals(object)) {
return acls;
} else {
return null;
}
}
}

View File

@ -1,202 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl;
import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link AclProviderManager}.
*
* @author Ben Alex
* @version $Id$
*/
public class AclProviderManagerTests extends TestCase {
//~ Constructors ===================================================================================================
public AclProviderManagerTests() {
super();
}
public AclProviderManagerTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
private AclProviderManager makeProviderManager() {
MockProvider provider1 = new MockProvider();
List providers = new Vector();
providers.add(provider1);
AclProviderManager mgr = new AclProviderManager();
mgr.setProviders(providers);
return mgr;
}
public final void setUp() throws Exception {
super.setUp();
}
public void testAclLookupFails() {
AclProviderManager mgr = makeProviderManager();
assertNull(mgr.getAcls(new Integer(5)));
}
public void testAclLookupForGivenAuthenticationSuccess() {
AclProviderManager mgr = makeProviderManager();
assertNotNull(mgr.getAcls("STRING", new UsernamePasswordAuthenticationToken("rod", "not used")));
}
public void testAclLookupSuccess() {
AclProviderManager mgr = makeProviderManager();
assertNotNull(mgr.getAcls("STRING"));
}
public void testRejectsNulls() {
AclProviderManager mgr = new AclProviderManager();
try {
mgr.getAcls(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
mgr.getAcls(null, new UsernamePasswordAuthenticationToken("rod", "not used"));
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
mgr.getAcls("SOME_DOMAIN_INSTANCE", null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testReturnsNullIfNoSupportingProvider() {
AclProviderManager mgr = makeProviderManager();
assertNull(mgr.getAcls(new Integer(4), new UsernamePasswordAuthenticationToken("rod", "not used")));
assertNull(mgr.getAcls(new Integer(4)));
}
public void testStartupFailsIfProviderListNotContainingProviders()
throws Exception {
List providers = new Vector();
providers.add("THIS_IS_NOT_A_PROVIDER");
AclProviderManager mgr = new AclProviderManager();
try {
mgr.setProviders(providers);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfProviderListNotSet()
throws Exception {
AclProviderManager mgr = new AclProviderManager();
try {
mgr.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfProviderListNull() throws Exception {
AclProviderManager mgr = new AclProviderManager();
try {
mgr.setProviders(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testSuccessfulStartup() throws Exception {
AclProviderManager mgr = makeProviderManager();
mgr.afterPropertiesSet();
assertTrue(true);
assertEquals(1, mgr.getProviders().size());
}
//~ Inner Classes ==================================================================================================
private class MockProvider implements AclProvider {
private UsernamePasswordAuthenticationToken rod = new UsernamePasswordAuthenticationToken("rod",
"not used",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO"), new GrantedAuthorityImpl("ROLE_BAR")});
private SimpleAclEntry entry100rod = new SimpleAclEntry(rod.getPrincipal(),
new NamedEntityObjectIdentity("OBJECT", "100"), null, 2);
private UsernamePasswordAuthenticationToken scott = new UsernamePasswordAuthenticationToken("scott",
"not used",
new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_FOO"),
new GrantedAuthorityImpl("ROLE_MANAGER")
});
private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott.getPrincipal(),
new NamedEntityObjectIdentity("OBJECT", "100"), null, 4);
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
if (authentication.getPrincipal().equals(scott.getPrincipal())) {
return new AclEntry[] {entry100Scott};
}
if (authentication.getPrincipal().equals(rod.getPrincipal())) {
return new AclEntry[] {entry100rod};
}
return null;
}
public AclEntry[] getAcls(Object domainInstance) {
return new AclEntry[] {entry100rod, entry100Scott};
}
/**
* Only supports <code>Object</code>s of type <code>String</code>
*
* @param domainInstance DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean supports(Object domainInstance) {
return (domainInstance instanceof String);
}
}
}

View File

@ -1,391 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.PopulatedDatabase;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.basic.cache.BasicAclEntryHolder;
import org.springframework.security.acl.basic.cache.NullAclEntryCache;
import org.springframework.security.acl.basic.jdbc.JdbcDaoImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import java.util.HashMap;
import java.util.Map;
/**
* Tests {@link BasicAclProvider}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicAclProviderTests extends TestCase {
//~ Static fields/initializers =====================================================================================
public static final String OBJECT_IDENTITY = "org.springframework.security.acl.DomainObject";
//~ Constructors ===================================================================================================
public BasicAclProviderTests() {
super();
}
public BasicAclProviderTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicAclProviderTests.class);
}
private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {
JdbcDaoImpl dao = new JdbcDaoImpl();
dao.setDataSource(PopulatedDatabase.getDataSource());
dao.afterPropertiesSet();
return dao;
}
public final void setUp() throws Exception {
super.setUp();
}
public void testCachingUsedProperly() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
MockCache cache = new MockCache();
provider.setBasicAclEntryCache(cache);
assertEquals(0, cache.getGets());
assertEquals(0, cache.getGetsHits());
assertEquals(0, cache.getPuts());
assertEquals(0, cache.getBackingMap().size());
Object object = new MockDomain(1); // has no parents
provider.getAcls(object);
assertEquals(1, cache.getGets());
assertEquals(0, cache.getGetsHits());
assertEquals(1, cache.getPuts());
assertEquals(1, cache.getBackingMap().size());
provider.getAcls(object);
assertEquals(2, cache.getGets());
assertEquals(1, cache.getGetsHits());
assertEquals(1, cache.getPuts());
assertEquals(1, cache.getBackingMap().size());
object = new MockDomain(1000); // does not exist
provider.getAcls(object);
assertEquals(3, cache.getGets());
assertEquals(1, cache.getGetsHits());
assertEquals(2, cache.getPuts());
assertEquals(2, cache.getBackingMap().size());
provider.getAcls(object);
assertEquals(4, cache.getGets());
assertEquals(2, cache.getGetsHits());
assertEquals(2, cache.getPuts());
assertEquals(2, cache.getBackingMap().size());
provider.getAcls(object);
assertEquals(5, cache.getGets());
assertEquals(3, cache.getGetsHits());
assertEquals(2, cache.getPuts());
assertEquals(2, cache.getBackingMap().size());
}
public void testExceptionThrownIfUnsupportedObjectIsSubmitted()
throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
// this one should NOT be supported, as it has no getId() method
assertFalse(provider.supports(new Integer(34)));
// try anyway
try {
provider.getAcls(new Integer(34));
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGetAclsForInstanceNotFound() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
Object object = new MockDomain(546464646);
AclEntry[] acls = provider.getAcls(object);
assertNull(acls);
}
public void testGetAclsForInstanceWithParentLevels()
throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
Object object = new MockDomain(6);
AclEntry[] acls = provider.getAcls(object);
assertEquals(2, acls.length);
assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
assertEquals(1, ((BasicAclEntry) acls[0]).getMask());
assertEquals("ROLE_SUPERVISOR", ((BasicAclEntry) acls[1]).getRecipient());
}
public void testGetAclsForInstanceWithParentLevelsButNoDirectAclsAgainstInstance()
throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
Object object = new MockDomain(5);
AclEntry[] acls = provider.getAcls(object);
assertEquals(3, acls.length);
assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
assertEquals(14, ((BasicAclEntry) acls[0]).getMask());
assertEquals("ROLE_SUPERVISOR", ((BasicAclEntry) acls[1]).getRecipient());
assertEquals(1, ((BasicAclEntry) acls[1]).getMask());
assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, ((BasicAclEntry) acls[2]).getRecipient());
}
public void testGetAclsWithAuthentication() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
Authentication scott = new UsernamePasswordAuthenticationToken("scott", "unused");
Object object = new MockDomain(6);
AclEntry[] acls = provider.getAcls(object, scott);
assertEquals(1, acls.length);
assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
}
public void testGettersSetters() {
BasicAclProvider provider = new BasicAclProvider();
assertEquals(NullAclEntryCache.class, provider.getBasicAclEntryCache().getClass());
assertEquals(NamedEntityObjectIdentity.class, provider.getDefaultAclObjectIdentityClass());
assertEquals(GrantedAuthorityEffectiveAclsResolver.class, provider.getEffectiveAclsResolver().getClass());
provider.setBasicAclEntryCache(null);
assertNull(provider.getBasicAclEntryCache());
provider.setDefaultAclObjectIdentityClass(null);
assertNull(provider.getDefaultAclObjectIdentityClass());
provider.setEffectiveAclsResolver(null);
assertNull(provider.getEffectiveAclsResolver());
provider.setBasicAclDao(new MockDao());
assertNotNull(provider.getBasicAclDao());
assertNull(provider.getRestrictSupportToClass());
provider.setRestrictSupportToClass(SomeDomain.class);
assertEquals(SomeDomain.class, provider.getRestrictSupportToClass());
}
public void testStartupFailsIfNullAclDao() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfNullEffectiveAclsResolver()
throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
provider.setEffectiveAclsResolver(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfNullEntryCache() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
provider.setBasicAclEntryCache(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfProblemWithAclObjectIdentityClass()
throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
// check nulls rejected
provider.setDefaultAclObjectIdentityClass(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
// check non-AclObjectIdentity classes are also rejected
provider.setDefaultAclObjectIdentityClass(String.class);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
// check AclObjectIdentity class without constructor accepting a
// domain object is also rejected
provider.setDefaultAclObjectIdentityClass(MockAclObjectIdentity.class);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!",
expected.getMessage());
}
}
public void testSupports() throws Exception {
BasicAclProvider provider = new BasicAclProvider();
provider.setBasicAclDao(makePopulatedJdbcDao());
// this one should NOT be supported, as it has no getId() method
assertFalse(provider.supports(new Integer(34)));
// this one SHOULD be supported, as it has a getId() method
assertTrue(provider.supports(new SomeDomain()));
// this one SHOULD be supported, as it implements AclObjectIdentityAware
assertTrue(provider.supports(new MockDomain(4)));
// now restrict the provider to only respond to SomeDomain.class requests
provider.setRestrictSupportToClass(SomeDomain.class);
assertEquals(SomeDomain.class, provider.getRestrictSupportToClass());
// this one SHOULD be supported, as it has a getId() method AND it meets the restrictSupportToClass criteria
assertTrue(provider.supports(new SomeDomain()));
// this one should NOT be suported, as whilst it implement AclObjectIdentityAware (as proven earlier in the test), it does NOT meet the restrictSupportToClass criteria
assertFalse(provider.supports(new MockDomain(4)));
}
public void testSupportsReturnsNullIfObjectNull() {
BasicAclProvider provider = new BasicAclProvider();
assertFalse(provider.supports(new Integer(34)));
}
//~ Inner Classes ==================================================================================================
private class MockCache implements BasicAclEntryCache {
private Map map = new HashMap();
private int gets = 0;
private int getsHits = 0;
private int puts = 0;
public Map getBackingMap() {
return map;
}
public BasicAclEntry[] getEntriesFromCache(AclObjectIdentity aclObjectIdentity) {
gets++;
Object result = map.get(aclObjectIdentity);
if (result == null) {
return null;
}
getsHits++;
BasicAclEntryHolder holder = (BasicAclEntryHolder) result;
return holder.getBasicAclEntries();
}
public int getGets() {
return gets;
}
public int getGetsHits() {
return getsHits;
}
public int getPuts() {
return puts;
}
public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
puts++;
BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
map.put(basicAclEntry[0].getAclObjectIdentity(), holder);
}
public void removeEntriesFromCache(AclObjectIdentity aclObjectIdentity) {}
}
private class MockDao implements BasicAclDao {
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
return null;
}
}
private class MockDomain implements AclObjectIdentityAware {
private int id;
public MockDomain(int id) {
this.id = id;
}
public AclObjectIdentity getAclObjectIdentity() {
return new NamedEntityObjectIdentity(OBJECT_IDENTITY, new Integer(id).toString());
}
}
}

View File

@ -1,132 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import junit.framework.TestCase;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.User;
/**
* Tests {@link GrantedAuthorityEffectiveAclsResolver}.
*
* @author Ben Alex
* @version $Id$
*/
public class GrantedAuthorityEffectiveAclsResolverTests extends TestCase {
//~ Instance fields ================================================================================================
private SimpleAclEntry entry100RoleEverybody = new SimpleAclEntry("ROLE_EVERYBODY",
new NamedEntityObjectIdentity("OBJECT", "100"), null, 14);
private SimpleAclEntry entry100RoleOne = new SimpleAclEntry("ROLE_ONE",
new NamedEntityObjectIdentity("OBJECT", "100"), null, 0);
private SimpleAclEntry entry100RoleTwo = new SimpleAclEntry("ROLE_TWO",
new NamedEntityObjectIdentity("OBJECT", "100"), null, 2);
private UsernamePasswordAuthenticationToken scott = new UsernamePasswordAuthenticationToken("scott", "not used",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_TWO")});
private SimpleAclEntry entry100Scott = new SimpleAclEntry(scott.getPrincipal(),
new NamedEntityObjectIdentity("OBJECT", "100"), null, 4);
private UsernamePasswordAuthenticationToken dianne = new UsernamePasswordAuthenticationToken("dianne", "not used");
private UsernamePasswordAuthenticationToken rod = new UsernamePasswordAuthenticationToken("rod",
"not used",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_ONE")});
private SimpleAclEntry entry100rod = new SimpleAclEntry(rod.getPrincipal(),
new NamedEntityObjectIdentity("OBJECT", "100"), null, 2);
private UsernamePasswordAuthenticationToken scottWithUserDetails = new UsernamePasswordAuthenticationToken(new User(
"scott", "NOT_USED", true, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY")}), "not used",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_EVERYBODY"), new GrantedAuthorityImpl("ROLE_TWO")});
// convenience group
private SimpleAclEntry[] acls = {
entry100rod, entry100Scott, entry100RoleEverybody, entry100RoleOne, entry100RoleTwo
};
//~ Constructors ===================================================================================================
public GrantedAuthorityEffectiveAclsResolverTests() {
super();
}
public GrantedAuthorityEffectiveAclsResolverTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(GrantedAuthorityEffectiveAclsResolverTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testResolveAclsForDianneWhoHasANullForAuthorities() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
assertNull(resolver.resolveEffectiveAcls(acls, dianne));
}
public void testResolveAclsForrod() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
assertEquals(3, resolver.resolveEffectiveAcls(acls, rod).length);
assertEquals(entry100rod, resolver.resolveEffectiveAcls(acls, rod)[0]);
assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, rod)[1]);
assertEquals(entry100RoleOne, resolver.resolveEffectiveAcls(acls, rod)[2]);
}
public void testResolveAclsForScottWithStringObjectAsPrincipal() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
assertEquals(3, resolver.resolveEffectiveAcls(acls, scott).length);
assertEquals(entry100Scott, resolver.resolveEffectiveAcls(acls, scott)[0]);
assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, scott)[1]);
assertEquals(entry100RoleTwo, resolver.resolveEffectiveAcls(acls, scott)[2]);
}
public void testResolveAclsForScottWithUserDetailsObjectAsPrincipal() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
assertEquals(3, resolver.resolveEffectiveAcls(acls, scottWithUserDetails).length);
assertEquals(entry100Scott, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[0]);
assertEquals(entry100RoleEverybody, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[1]);
assertEquals(entry100RoleTwo, resolver.resolveEffectiveAcls(acls, scottWithUserDetails)[2]);
}
public void testResolveAclsReturnsNullIfNoAclsInFirstPlace() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
assertNull(resolver.resolveEffectiveAcls(null, scott));
}
public void testSkipsNonBasicAclEntryObjects() {
GrantedAuthorityEffectiveAclsResolver resolver = new GrantedAuthorityEffectiveAclsResolver();
AclEntry[] basicAcls = {
entry100rod, entry100Scott, entry100RoleEverybody, entry100RoleOne, new MockAcl(), entry100RoleTwo
};
assertEquals(3, resolver.resolveEffectiveAcls(basicAcls, rod).length);
}
//~ Inner Classes ==================================================================================================
private class MockAcl implements AclEntry {
// does nothing
}
}

View File

@ -1,27 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
/**
* Implements <code>AclObjectIdentity</code> but is incompatible with <code>BasicAclProvider</code> because it
* cannot be constructed by passing in a domain object instance.
*
* @author Ben Alex
* @version $Id$
*/
public class MockAclObjectIdentity implements AclObjectIdentity {
// has no "public MockAclObjectIdentity(Object object)" constructor!
}

View File

@ -1,134 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import junit.framework.TestCase;
/**
* Tests {@link NamedEntityObjectIdentity}.
*
* @author Ben Alex
* @version $Id$
*/
public class NamedEntityObjectIdentityTests extends TestCase {
//~ Constructors ===================================================================================================
public NamedEntityObjectIdentityTests() {
super();
}
public NamedEntityObjectIdentityTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(NamedEntityObjectIdentityTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testConstructionViaReflection() throws Exception {
SomeDomain domainObject = new SomeDomain();
domainObject.setId(34);
NamedEntityObjectIdentity name = new NamedEntityObjectIdentity(domainObject);
assertEquals("34", name.getId());
assertEquals(domainObject.getClass().getName(), name.getClassname());
name.toString();
}
public void testConstructionViaReflectionFailsIfNoGetIdMethod()
throws Exception {
try {
new NamedEntityObjectIdentity(new Integer(45));
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testConstructionViaReflectionFailsIfNullPassed()
throws Exception {
try {
new NamedEntityObjectIdentity(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testEquality() {
NamedEntityObjectIdentity original = new NamedEntityObjectIdentity("foo", "12");
assertFalse(original.equals(null));
assertFalse(original.equals(new Integer(354)));
assertFalse(original.equals(new NamedEntityObjectIdentity("foo", "23232")));
assertTrue(original.equals(new NamedEntityObjectIdentity("foo", "12")));
assertTrue(original.equals(original));
}
public void testNoArgConstructorDoesntExist() {
Class clazz = NamedEntityObjectIdentity.class;
try {
clazz.getDeclaredConstructor((Class[]) null);
fail("Should have thrown NoSuchMethodException");
} catch (NoSuchMethodException expected) {
assertTrue(true);
}
}
public void testNormalConstructionRejectedIfInvalidArguments()
throws Exception {
try {
new NamedEntityObjectIdentity(null, "12");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new NamedEntityObjectIdentity("classname", null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new NamedEntityObjectIdentity("", "12");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new NamedEntityObjectIdentity("classname", "");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testNormalOperation() {
NamedEntityObjectIdentity name = new NamedEntityObjectIdentity("domain", "id");
assertEquals("domain", name.getClassname());
assertEquals("id", name.getId());
}
}

View File

@ -1,207 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
import junit.framework.TestCase;
/**
* Tests {@link SimpleAclEntry}.
*
* @author Ben Alex
* @version $Id$
*/
public class SimpleAclEntryTests extends TestCase {
//~ Constructors ===================================================================================================
public SimpleAclEntryTests() {
super();
}
public SimpleAclEntryTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(SimpleAclEntryTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testCorrectOperation() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0);
assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION));
acl.addPermission(SimpleAclEntry.ADMINISTRATION);
assertTrue(acl.isPermitted(SimpleAclEntry.ADMINISTRATION));
assertFalse(acl.isPermitted(SimpleAclEntry.CREATE));
assertFalse(acl.isPermitted(SimpleAclEntry.DELETE));
assertFalse(acl.isPermitted(SimpleAclEntry.READ));
assertFalse(acl.isPermitted(SimpleAclEntry.WRITE));
assertEquals("A----", acl.printPermissionsBlock());
acl.deletePermission(SimpleAclEntry.ADMINISTRATION);
assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION));
assertEquals("-----", acl.printPermissionsBlock());
acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE});
acl.addPermission(SimpleAclEntry.CREATE);
assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION));
assertTrue(acl.isPermitted(SimpleAclEntry.CREATE));
assertFalse(acl.isPermitted(SimpleAclEntry.DELETE));
assertTrue(acl.isPermitted(SimpleAclEntry.READ));
assertTrue(acl.isPermitted(SimpleAclEntry.WRITE));
assertEquals("-RWC-", acl.printPermissionsBlock());
acl.deletePermission(SimpleAclEntry.CREATE);
acl.deletePermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE});
assertEquals("-----", acl.printPermissionsBlock());
acl.togglePermission(SimpleAclEntry.CREATE);
assertTrue(acl.isPermitted(SimpleAclEntry.CREATE));
assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION));
acl.togglePermission(SimpleAclEntry.CREATE);
assertFalse(acl.isPermitted(SimpleAclEntry.CREATE));
acl.togglePermission(SimpleAclEntry.DELETE);
assertTrue(acl.isPermitted(SimpleAclEntry.DELETE));
assertEquals("----D", acl.printPermissionsBlock());
}
public void testDetectsNullOnMainConstructor() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
try {
new SimpleAclEntry(recipient, null, null, 2);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new SimpleAclEntry(null, objectIdentity, null, 2);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() {
SimpleAclEntry acl = new SimpleAclEntry();
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "693");
acl.setAclObjectIdentity(objectIdentity);
assertEquals(objectIdentity, acl.getAclObjectIdentity());
AclObjectIdentity parentObjectIdentity = new NamedEntityObjectIdentity("domain", "13");
acl.setAclObjectParentIdentity(parentObjectIdentity);
assertEquals(parentObjectIdentity, acl.getAclObjectParentIdentity());
acl.setMask(2);
assertEquals(2, acl.getMask());
acl.setRecipient("scott");
assertEquals("scott", acl.getRecipient());
}
public void testRejectsInvalidMasksInAddMethod() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 4);
try {
acl.addPermission(Integer.MAX_VALUE);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testRejectsInvalidMasksInDeleteMethod() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0);
acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE});
try {
acl.deletePermission(SimpleAclEntry.READ); // can't write if we can't read
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testRejectsInvalidMasksInTogglePermissionMethod() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0);
acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE});
try {
acl.togglePermission(SimpleAclEntry.READ); // can't write if we can't read
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testToString() {
String recipient = "rod";
AclObjectIdentity objectIdentity = new NamedEntityObjectIdentity("domain", "12");
SimpleAclEntry acl = new SimpleAclEntry(recipient, objectIdentity, null, 0);
acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE});
assertTrue(acl.toString().endsWith("rod=-RWC- ............................111. (14)]"));
}
public void testParsePermission() {
assertPermission("NOTHING", SimpleAclEntry.NOTHING);
assertPermission("ADMINISTRATION", SimpleAclEntry.ADMINISTRATION);
assertPermission("READ", SimpleAclEntry.READ);
assertPermission("WRITE", SimpleAclEntry.WRITE);
assertPermission("CREATE", SimpleAclEntry.CREATE);
assertPermission("DELETE", SimpleAclEntry.DELETE);
assertPermission("READ_WRITE_DELETE", SimpleAclEntry.READ_WRITE_DELETE);
}
public void testParsePermissionWrongValues() {
try {
SimpleAclEntry.parsePermission("X");
fail(IllegalArgumentException.class.getName() + " must have been thrown.");
} catch (IllegalArgumentException e) {
// expected
}
}
private void assertPermission(String permission, int value) {
assertEquals(value, SimpleAclEntry.parsePermission(permission));
}
/**
* Check that the value returned by {@link SimpleAclEntry#getValidPermissions()} is not modifiable.
*/
public void testGetPermissions() {
SimpleAclEntry acl = new SimpleAclEntry("", new NamedEntityObjectIdentity("x", "x"), null, 0);
int[] permissions = acl.getValidPermissions();
int i = permissions[0];
permissions[0] -= 100;
assertEquals("Value returned by getValidPermissions can be modified", i, acl.getValidPermissions()[0]);
}
}

View File

@ -1,38 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic;
/**
* Simple object to use when testing <code>NamedEntityObjectIdentity</code>.
*
* @author Ben Alex
* @version $Id$
*/
public class SomeDomain {
//~ Instance fields ================================================================================================
private int id;
//~ Methods ========================================================================================================
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}

View File

@ -1,66 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import junit.framework.TestCase;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.SimpleAclEntry;
/**
* Tests {@link BasicAclEntryHolder}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicAclEntryHolderTests extends TestCase {
//~ Constructors ===================================================================================================
public BasicAclEntryHolderTests() {
super();
}
public BasicAclEntryHolderTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicAclEntryHolderTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testRejectsNull() throws Exception {
try {
new BasicAclEntryHolder(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new BasicAclEntryHolder(new BasicAclEntry[] {new SimpleAclEntry(), null, new SimpleAclEntry()});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
}

View File

@ -1,106 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Cache;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Tests {@link EhCacheBasedAclEntryCache}.
*
* @author Ben Alex
* @version $Id$
*/
public class EhCacheBasedAclEntryCacheTests {
//~ Static fields/initializers =====================================================================================
private static final AclObjectIdentity OBJECT_100 = new NamedEntityObjectIdentity("OBJECT", "100");
private static final AclObjectIdentity OBJECT_200 = new NamedEntityObjectIdentity("OBJECT", "200");
private static final BasicAclEntry OBJECT_100_ROD = new SimpleAclEntry("rod", OBJECT_100, null, 2);
private static final BasicAclEntry OBJECT_100_SCOTT = new SimpleAclEntry("scott", OBJECT_100, null, 4);
private static final BasicAclEntry OBJECT_200_PETER = new SimpleAclEntry("peter", OBJECT_200, null, 4);
private static CacheManager cacheManager;
//~ Methods ========================================================================================================
@BeforeClass
public static void initCacheManaer() {
cacheManager = new CacheManager();
cacheManager.addCache(new Cache("ehcachebasedacltests", 500, false, false, 30, 30));
}
@AfterClass
public static void shutdownCacheManager() {
cacheManager.removalAll();
cacheManager.shutdown();
}
private Ehcache getCache() {
Ehcache cache = cacheManager.getCache("ehcachebasedacltests");
cache.removeAll();
return cache;
}
@Test
public void cacheOperationSucceeds() throws Exception {
EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
cache.setCache(getCache());
cache.afterPropertiesSet();
cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_100_SCOTT, OBJECT_100_ROD});
cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_200_PETER});
// Check we can get them from cache again
assertEquals(OBJECT_100_SCOTT, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"))[0]);
assertEquals(OBJECT_100_ROD, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"))[1]);
assertEquals(OBJECT_200_PETER, cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "200"))[0]);
assertNull(cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE")));
// Check after eviction we cannot get them from cache
cache.removeEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100"));
assertNull(cache.getEntriesFromCache(new NamedEntityObjectIdentity("OBJECT", "100")));
}
@Test
public void startupDetectsMissingCache() throws Exception {
EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
try {
cache.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
Ehcache myCache = getCache();
cache.setCache(myCache);
assertEquals(myCache, cache.getCache());
}
}

View File

@ -1,58 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.cache;
import junit.framework.TestCase;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
/**
* Tests {@link NullAclEntryCache}.
*
* @author Ben Alex
* @version $Id$
*/
public class NullAclEntryCacheTests extends TestCase {
//~ Constructors ===================================================================================================
public NullAclEntryCacheTests() {
super();
}
public NullAclEntryCacheTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(NullAclEntryCacheTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testCacheOperation() throws Exception {
NullAclEntryCache cache = new NullAclEntryCache();
cache.putEntriesInCache(new BasicAclEntry[] {new SimpleAclEntry()});
cache.getEntriesFromCache(new NamedEntityObjectIdentity("not_used", "not_used"));
cache.removeEntriesFromCache(new NamedEntityObjectIdentity("not_used", "not_used"));
}
}

View File

@ -1,145 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.jdbc;
import junit.framework.TestCase;
import org.springframework.security.PopulatedDatabase;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.springframework.jdbc.object.MappingSqlQuery;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Tests {@link JdbcDaoImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class JdbcDaoImplTests extends TestCase {
//~ Static fields/initializers =====================================================================================
public static final String OBJECT_IDENTITY = "org.springframework.security.acl.DomainObject";
//~ Constructors ===================================================================================================
public JdbcDaoImplTests() {
super();
}
public JdbcDaoImplTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(JdbcDaoImplTests.class);
}
private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {
JdbcDaoImpl dao = new JdbcDaoImpl();
dao.setDataSource(PopulatedDatabase.getDataSource());
dao.afterPropertiesSet();
return dao;
}
public final void setUp() throws Exception {
super.setUp();
}
public void testExceptionThrownIfBasicAclEntryClassNotFound()
throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "7");
try {
dao.getAcls(identity);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGetsEntriesWhichExistInDatabaseAndHaveAcls()
throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "2");
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(2, acls.length);
}
public void testGetsEntriesWhichExistInDatabaseButHaveNoAcls()
throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "5");
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(1, acls.length);
assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER, acls[0].getRecipient());
}
public void testGetsEntriesWhichHaveNoParent() throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(1, acls.length);
assertNull(acls[0].getAclObjectParentIdentity());
}
public void testGettersSetters() throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
dao.setAclsByObjectIdentity(new MockMappingSqlQuery());
assertNotNull(dao.getAclsByObjectIdentity());
dao.setAclsByObjectIdentityQuery("foo");
assertEquals("foo", dao.getAclsByObjectIdentityQuery());
dao.setObjectPropertiesQuery("foobar");
assertEquals("foobar", dao.getObjectPropertiesQuery());
}
public void testNullReturnedIfEntityNotFound() throws Exception {
JdbcDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "NOT_VALID_ID");
BasicAclEntry[] result = dao.getAcls(identity);
assertNull(result);
}
public void testReturnsNullForUnNamedEntityObjectIdentity()
throws Exception {
JdbcDaoImpl dao = new JdbcDaoImpl();
AclObjectIdentity identity = new AclObjectIdentity() {}
;
assertNull(dao.getAcls(identity));
}
//~ Inner Classes ==================================================================================================
private class MockMappingSqlQuery extends MappingSqlQuery {
protected Object mapRow(ResultSet arg0, int arg1)
throws SQLException {
return null;
}
}
}

View File

@ -1,312 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acl.basic.jdbc;
import junit.framework.TestCase;
import org.springframework.security.PopulatedDatabase;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.acl.basic.NamedEntityObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.object.MappingSqlQuery;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Tests {@link JdbcExtendedDaoImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class JdbcExtendedDaoImplTests extends TestCase {
//~ Static fields/initializers =====================================================================================
public static final String OBJECT_IDENTITY = "org.springframework.security.acl.DomainObject";
//~ Constructors ===================================================================================================
public JdbcExtendedDaoImplTests() {
super();
}
public JdbcExtendedDaoImplTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(JdbcExtendedDaoImplTests.class);
}
private JdbcExtendedDaoImpl makePopulatedJdbcDao()
throws Exception {
JdbcExtendedDaoImpl dao = new JdbcExtendedDaoImpl();
dao.setDataSource(PopulatedDatabase.getDataSource());
dao.afterPropertiesSet();
return dao;
}
public final void setUp() throws Exception {
super.setUp();
}
public void testChangeMask() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "204");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
// Create a BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl1 = new SimpleAclEntry("rod", identity, parentIdentity, SimpleAclEntry.CREATE);
dao.create(simpleAcl1);
// Create another BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ);
dao.create(simpleAcl2);
// Check creation was successful
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(2, acls.length);
assertEquals(SimpleAclEntry.CREATE, acls[0].getMask());
assertEquals(SimpleAclEntry.READ, acls[1].getMask());
// Attempt to change mask
dao.changeMask(identity, "rod", new Integer(SimpleAclEntry.ADMINISTRATION));
dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.NOTHING));
acls = dao.getAcls(identity);
assertEquals(2, acls.length);
assertEquals("rod", acls[0].getRecipient());
assertEquals(SimpleAclEntry.ADMINISTRATION, acls[0].getMask());
assertEquals("scott", acls[1].getRecipient());
assertEquals(SimpleAclEntry.NOTHING, acls[1].getMask());
}
public void testChangeMaskThrowsExceptionWhenExistingRecordNotFound()
throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "205");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
// Create at least one record for this AclObjectIdentity
SimpleAclEntry simpleAcl1 = new SimpleAclEntry("rod", identity, parentIdentity, SimpleAclEntry.CREATE);
dao.create(simpleAcl1);
// Attempt to change mask, but for a recipient we don't have
try {
dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.ADMINISTRATION));
fail("Should have thrown DataRetrievalFailureException");
} catch (DataRetrievalFailureException expected) {
assertTrue(true);
}
}
public void testConvertAclObjectIdentity() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
try {
dao.convertAclObjectIdentityToString(new AclObjectIdentity() {
// not a NamedEntityObjectIdentity
});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testCreationOfIdentityThenAclInSeparateInvocations()
throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "206");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
// Create just the object identity (NB: recipient and mask is null)
SimpleAclEntry simpleAcl1 = new SimpleAclEntry();
simpleAcl1.setAclObjectIdentity(identity);
simpleAcl1.setAclObjectParentIdentity(parentIdentity);
dao.create(simpleAcl1);
// Delete it
dao.delete(identity);
}
public void testDeletionOfAllRecipients() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "203");
// Create a BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl1 = new SimpleAclEntry("rod", identity, null, SimpleAclEntry.CREATE);
dao.create(simpleAcl1);
// Create another BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, null, SimpleAclEntry.READ);
dao.create(simpleAcl2);
// Check creation was successful
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(2, acls.length);
// Attempt deletion and check delete successful
dao.delete(identity);
assertNull(dao.getAcls(identity));
}
public void testDeletionOfSpecificRecipient() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "202");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
// Create a BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl1 = new SimpleAclEntry("rod", identity, parentIdentity, SimpleAclEntry.CREATE);
dao.create(simpleAcl1);
// Create another BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ);
dao.create(simpleAcl2);
// Check creation was successful
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(2, acls.length);
// Attempt deletion and check delete successful
dao.delete(identity, "scott");
acls = dao.getAcls(identity);
assertEquals(1, acls.length);
assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient());
}
public void testGettersSetters() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
assertNotNull(dao.getAclObjectIdentityDelete());
dao.setAclObjectIdentityDelete(null);
assertNull(dao.getAclObjectIdentityDelete());
assertNotNull(dao.getAclObjectIdentityInsert());
dao.setAclObjectIdentityInsert(null);
assertNull(dao.getAclObjectIdentityInsert());
assertNotNull(dao.getAclPermissionDelete());
dao.setAclPermissionDelete(null);
assertNull(dao.getAclPermissionDelete());
assertNotNull(dao.getAclPermissionInsert());
dao.setAclPermissionInsert(null);
assertNull(dao.getAclPermissionInsert());
assertNotNull(dao.getAclPermissionUpdate());
dao.setAclPermissionUpdate(null);
assertNull(dao.getAclPermissionUpdate());
assertNotNull(dao.getAclsByObjectIdentity());
dao.setAclsByObjectIdentity(null);
assertNull(dao.getAclsByObjectIdentity());
assertNotNull(dao.getLookupPermissionIdMapping());
dao.setLookupPermissionIdMapping(null);
assertNull(dao.getLookupPermissionIdMapping());
assertNotNull(dao.getAclObjectIdentityDeleteStatement());
dao.setAclObjectIdentityDeleteStatement("SELECT ...");
assertEquals("SELECT ...", dao.getAclObjectIdentityDeleteStatement());
assertNotNull(dao.getAclObjectIdentityInsertStatement());
dao.setAclObjectIdentityInsertStatement("SELECT ...");
assertEquals("SELECT ...", dao.getAclObjectIdentityInsertStatement());
assertNotNull(dao.getAclPermissionDeleteStatement());
dao.setAclPermissionDeleteStatement("SELECT ...");
assertEquals("SELECT ...", dao.getAclPermissionDeleteStatement());
assertNotNull(dao.getAclPermissionInsertStatement());
dao.setAclPermissionInsertStatement("SELECT ...");
assertEquals("SELECT ...", dao.getAclPermissionInsertStatement());
assertNotNull(dao.getAclPermissionUpdateStatement());
dao.setAclPermissionUpdateStatement("SELECT ...");
assertEquals("SELECT ...", dao.getAclPermissionUpdateStatement());
assertNotNull(dao.getAclsByObjectIdentityQuery());
dao.setAclsByObjectIdentityQuery("SELECT ...");
assertEquals("SELECT ...", dao.getAclsByObjectIdentityQuery());
assertNotNull(dao.getLookupPermissionIdQuery());
dao.setLookupPermissionIdQuery("SELECT ...");
assertEquals("SELECT ...", dao.getLookupPermissionIdQuery());
}
public void testNormalCreationAndDuplicateDetection()
throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "200");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "1");
// Create a BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl1 = new SimpleAclEntry("rod", identity, parentIdentity, SimpleAclEntry.CREATE);
dao.create(simpleAcl1);
// Create another BasicAclEntry for this AclObjectIdentity
SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, parentIdentity, SimpleAclEntry.READ);
dao.create(simpleAcl2);
// Check creation was successful
BasicAclEntry[] acls = dao.getAcls(identity);
assertEquals(2, acls.length);
assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient());
assertEquals(simpleAcl1.getMask(), acls[0].getMask());
assertEquals(simpleAcl2.getRecipient(), acls[1].getRecipient());
assertEquals(simpleAcl2.getMask(), acls[1].getMask());
// Check it rejects an attempt to create another identical entry
try {
dao.create(simpleAcl1);
fail("Should have thrown DataIntegrityViolationException");
} catch (DataIntegrityViolationException expected) {
assertTrue(true);
}
}
public void testRejectsInvalidParent() throws Exception {
JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "201");
AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, "987987987987986");
SimpleAclEntry simpleAcl = new SimpleAclEntry("rod", identity, parentIdentity, SimpleAclEntry.CREATE);
try {
dao.create(simpleAcl);
fail("Should have thrown DataRetrievalFailureException");
} catch (DataRetrievalFailureException expected) {
assertTrue(true);
}
}
//~ Inner Classes ==================================================================================================
private class MockMappingSqlQuery extends MappingSqlQuery {
protected Object mapRow(ResultSet arg0, int arg1)
throws SQLException {
return null;
}
}
}

View File

@ -1,373 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.afterinvocation;
import java.util.List;
import java.util.Vector;
import junit.framework.TestCase;
import org.springframework.security.AuthorizationServiceException;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.MockAclManager;
import org.springframework.security.SecurityConfig;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.MockAclObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.SimpleMethodInvocation;
/**
* Tests {@link BasicAclEntryAfterInvocationCollectionFilteringProvider}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests extends TestCase {
//~ Constructors ===================================================================================================
public BasicAclEntryAfterInvocationCollectionFilteringProviderTests() {
super();
}
public BasicAclEntryAfterInvocationCollectionFilteringProviderTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject()
throws Exception {
// Create an AclManager, granting scott only ADMINISTRATION rights
AclManager aclManager = new MockAclManager("belmont", "scott",
new AclEntry[] {
new SimpleAclEntry("scott", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION)
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create a Collection containing many items
List list = new Vector();
list.add("sydney");
list.add("melbourne");
list.add("belmont");
list.add("brisbane");
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED");
// Filter
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(),
SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), list);
assertEquals(0, filteredList.size());
}
public void testCorrectOperationWhenPrincipalHasNoPermissionToDomainObject()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create a Collection containing many items, which only "belmont"
// should remain in after filtering by provider
List list = new Vector();
list.add("sydney");
list.add("melbourne");
list.add("belmont");
list.add("brisbane");
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list);
assertEquals(0, filteredList.size());
}
public void testCorrectOperationWhenPrincipalIsAuthorised()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
assertEquals(aclManager, provider.getAclManager());
provider.afterPropertiesSet();
// Create a Collection containing many items, which only "belmont"
// should remain in after filtering by provider
List list = new Vector();
list.add("sydney");
list.add("melbourne");
list.add("belmont");
list.add("brisbane");
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list);
assertEquals(1, filteredList.size());
assertEquals("belmont", filteredList.get(0));
}
public void testCorrectOperationWhenReturnedObjectIsArray()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
assertEquals(aclManager, provider.getAclManager());
provider.afterPropertiesSet();
// Create a Collection containing many items, which only "belmont"
// should remain in after filtering by provider
String[] list = new String[4];
list[0] = "sydney";
list[1] = "melbourne";
list[2] = "belmont";
list[3] = "brisbane";
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
String[] filteredList = (String[]) provider.decide(auth, new SimpleMethodInvocation(), attr, list);
assertEquals(1, filteredList.length);
assertEquals("belmont", filteredList[0]);
}
public void testDetectsIfReturnedObjectIsNotACollection()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE),
new MockAclEntry()
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
try {
provider.decide(auth, new SimpleMethodInvocation(), attr, new String("RETURN_OBJECT_NOT_COLLECTION"));
fail("Should have thrown AuthorizationServiceException");
} catch (AuthorizationServiceException expected) {
assertTrue(true);
}
}
public void testGrantsAccessIfReturnedObjectIsNull()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE),
new MockAclEntry()
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, null);
assertNull(filteredList);
}
public void testRespectsModificationsToProcessConfigAttribute() throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new MockAclEntry()
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
assertEquals("AFTER_ACL_COLLECTION_READ", provider.getProcessConfigAttribute());
provider.setProcessConfigAttribute("AFTER_ACL_COLLECTION_ADMIN");
assertEquals("AFTER_ACL_COLLECTION_ADMIN", provider.getProcessConfigAttribute());
provider.afterPropertiesSet();
// Create a Collection containing many items, which only "sydney"
// should remain in after filtering by provider
List list = new Vector();
list.add("sydney");
list.add("melbourne");
list.add("belmont");
list.add("brisbane");
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// As no matching config attrib, ensure provider doesn't change list
assertEquals(4, ((List) provider.decide(auth, new SimpleMethodInvocation(), attr, list)).size());
// Filter, this time with the conf attrib provider setup to answer
attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_ADMIN");
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list);
assertEquals(1, filteredList.size());
assertEquals("sydney", filteredList.get(0));
}
public void testRespectsModificationsToRequirePermissions()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
provider.setAclManager(aclManager);
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
assertEquals(SimpleAclEntry.ADMINISTRATION, provider.getRequirePermission()[0]);
provider.afterPropertiesSet();
// Create a Collection containing many items, which only "sydney"
// should remain in after filtering by provider
List list = new Vector();
list.add("sydney");
list.add("melbourne");
list.add("belmont");
list.add("brisbane");
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_COLLECTION_READ");
// Filter
List filteredList = (List) provider.decide(auth, new SimpleMethodInvocation(), attr, list);
assertEquals(1, filteredList.size());
assertEquals("sydney", filteredList.get(0));
}
public void testStartupDetectsMissingAclManager() throws Exception {
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An aclManager is mandatory", expected.getMessage());
}
}
public void testStartupDetectsMissingProcessConfigAttribute()
throws Exception {
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
provider.setAclManager(aclManager);
provider.setProcessConfigAttribute(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A processConfigAttribute is mandatory", expected.getMessage());
}
}
public void testStartupDetectsMissingRequirePermission()
throws Exception {
BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider();
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
provider.setAclManager(aclManager);
provider.setRequirePermission(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("One or more requirePermission entries is mandatory", expected.getMessage());
}
}
public void testSupportsAnything() {
assertTrue(new BasicAclEntryAfterInvocationCollectionFilteringProvider().supports(String.class));
}
//~ Inner Classes ==================================================================================================
private class MockAclEntry implements AclEntry {
// just so AclTag iterates some different types of AclEntrys
}
}

View File

@ -1,257 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.afterinvocation;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.security.AccessDeniedException;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.MockAclManager;
import org.springframework.security.SecurityConfig;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.MockAclObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.SimpleMethodInvocation;
/**
* Tests {@link BasicAclEntryAfterInvocationProvider}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
//~ Methods ========================================================================================================
public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject()
throws Exception {
// Create an AclManager, granting scott only ADMINISTRATION rights
AclManager aclManager = new MockAclManager("belmont", "scott",
new AclEntry[]{
new SimpleAclEntry("scott", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION)
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
try {
provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont");
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
public void testCorrectOperationWhenPrincipalHasNoPermissionToDomainObject()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
try {
provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont");
fail("Should have thrown AccessDeniedException");
} catch (AccessDeniedException expected) {
assertTrue(true);
}
}
public void testCorrectOperationWhenPrincipalIsAuthorised()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
assertEquals(aclManager, provider.getAclManager());
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
// Filter
assertEquals("belmont", provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont"));
}
public void testGrantsAccessIfReturnedObjectIsNull()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("belmont", "rod",
new AclEntry[]{
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE),
new MockAclEntry()
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
// Filter
assertNull(provider.decide(auth, new SimpleMethodInvocation(), attr, null));
}
public void testRespectsModificationsToProcessConfigAttribute()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[]{
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new MockAclEntry()
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
assertEquals("AFTER_ACL_ADMIN", provider.getProcessConfigAttribute());
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
// As no matching config attrib, ensure provider returns original obj
assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
// Filter, this time with the conf attrib provider setup to answer
attr = SecurityConfig.createList("AFTER_ACL_ADMIN");
assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
}
public void testRespectsModificationsToRequirePermissions()
throws Exception {
// Create an AclManager
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[]{
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setAclManager(aclManager);
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
provider.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION});
assertEquals(SimpleAclEntry.ADMINISTRATION, provider.getRequirePermission()[0]);
provider.afterPropertiesSet();
// Create the Authentication and Config Attribs we'll be presenting
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("rod", "NOT_USED");
List<ConfigAttribute> attr = SecurityConfig.createList("AFTER_ACL_READ");
// Filter
assertEquals("sydney", provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
}
public void testStartupDetectsMissingAclManager() throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An aclManager is mandatory", expected.getMessage());
}
}
public void testStartupDetectsMissingProcessConfigAttribute()
throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
provider.setAclManager(aclManager);
provider.setProcessConfigAttribute(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A processConfigAttribute is mandatory", expected.getMessage());
}
}
public void testStartupDetectsMissingRequirePermission()
throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
AclManager aclManager = new MockAclManager("sydney", "rod",
new AclEntry[] {
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new MockAclEntry()
});
provider.setAclManager(aclManager);
provider.setRequirePermission(null);
try {
provider.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("One or more requirePermission entries is mandatory", expected.getMessage());
}
}
public void testSupportsAnything() {
assertTrue(new BasicAclEntryAfterInvocationProvider().supports(String.class));
}
//~ Inner Classes ==================================================================================================
private class MockAclEntry implements AclEntry {
// just so AclTag iterates some different types of AclEntrys
}
}

View File

@ -1,472 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.vote;
import java.lang.reflect.Method;
import java.util.List;
import junit.framework.TestCase;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.springframework.security.AuthorizationServiceException;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.MockAclManager;
import org.springframework.security.SecurityConfig;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.MockAclObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.SimpleMethodInvocation;
/**
* Tests {@link BasicAclEntryVoter}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicAclEntryVoterTests extends TestCase {
//~ Constructors ===================================================================================================
public BasicAclEntryVoterTests() {
super();
}
public BasicAclEntryVoterTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
private MethodInvocation getMethodInvocation(SomeDomainObject domainObject)
throws Exception {
Class clazz = SomeDomainObjectManager.class;
Method method = clazz.getMethod("someServiceMethod", new Class[] {SomeDomainObject.class});
return new SimpleMethodInvocation(new SomeDomainObjectManager(), method, new Object[] {domainObject});
}
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicAclEntryVoterTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testNormalOperation() throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject, "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
assertEquals(aclManager, voter.getAclManager());
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
assertEquals("FOO_ADMIN_OR_WRITE_ACCESS", voter.getProcessConfigAttribute());
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
assertEquals(2, voter.getRequirePermission().length);
voter.setProcessDomainObjectClass(SomeDomainObject.class);
assertEquals(SomeDomainObject.class, voter.getProcessDomainObjectClass());
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
MethodInvocation mi = getMethodInvocation(domainObject);
assertEquals(AccessDecisionVoter.ACCESS_GRANTED,
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr));
}
public void testOnlySupportsMethodInvocationAndJoinPoint() {
BasicAclEntryVoter voter = new BasicAclEntryVoter();
assertTrue(voter.supports(MethodInvocation.class));
assertTrue(voter.supports(JoinPoint.class));
assertFalse(voter.supports(String.class));
}
public void testStartupRejectsMissingAclManager() throws Exception {
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
try {
voter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupRejectsMissingProcessConfigAttribute()
throws Exception {
AclManager aclManager = new MockAclManager("domain1", "rod",
new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
try {
voter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupRejectsMissingProcessDomainObjectClass()
throws Exception {
BasicAclEntryVoter voter = new BasicAclEntryVoter();
try {
voter.setProcessDomainObjectClass(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupRejectsMissingRequirePermission()
throws Exception {
AclManager aclManager = new MockAclManager("domain1", "rod",
new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setProcessDomainObjectClass(SomeDomainObject.class);
try {
voter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testSupportsConfigAttribute() {
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setProcessConfigAttribute("foobar");
assertTrue(voter.supports(new SecurityConfig("foobar")));
}
public void testVoterAbstainsIfDomainObjectIsNull()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject, "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("A_DIFFERENT_ATTRIBUTE");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
MethodInvocation mi = getMethodInvocation(domainObject);
assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN,
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr));
}
public void testVoterAbstainsIfNotMatchingConfigAttribute()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = null;
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject, "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
MethodInvocation mi = getMethodInvocation(domainObject);
assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN,
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr));
}
public void testVoterCanDenyAccessBasedOnInternalMethodOfDomainObject()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject.getParent(), "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.setInternalMethod("getParent");
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
MethodInvocation mi = getMethodInvocation(domainObject);
assertEquals(AccessDecisionVoter.ACCESS_DENIED,
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr));
}
public void testVoterCanDenyAccessIfPrincipalHasNoPermissionsAtAllToDomainObject()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject, "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.setInternalMethod("getParent");
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
MethodInvocation mi = getMethodInvocation(domainObject);
// NB: scott is the principal, not rod
assertEquals(AccessDecisionVoter.ACCESS_DENIED,
voter.vote(new UsernamePasswordAuthenticationToken("scott", null), mi, attr));
}
public void testVoterCanGrantAccessBasedOnInternalMethodOfDomainObject()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject.getParent(), "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.setInternalMethod("getParent");
assertEquals("getParent", voter.getInternalMethod());
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
// (well actually it will access domainObject.getParent())
MethodInvocation mi = getMethodInvocation(domainObject);
assertEquals(AccessDecisionVoter.ACCESS_GRANTED,
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr));
}
public void testVoterThrowsExceptionIfInvalidInternalMethodOfDomainObject()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject.getParent(), "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.setInternalMethod("getNonExistentParentName");
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation, so voter can retrieve domainObject
// (well actually it will access domainObject.getParent())
MethodInvocation mi = getMethodInvocation(domainObject);
try {
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr);
fail("Should have thrown AuthorizationServiceException");
} catch (AuthorizationServiceException expected) {
assertTrue(true);
}
}
public void testVoterThrowsExceptionIfProcessDomainObjectNotFound()
throws Exception {
// Setup a domain object subject of this test
SomeDomainObject domainObject = new SomeDomainObject("foo");
// Setup an AclManager
AclManager aclManager = new MockAclManager(domainObject.getParent(), "rod",
new AclEntry[]{
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)
});
// Wire up a voter
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setAclManager(aclManager);
voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS");
voter.setRequirePermission(new int[]{SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE});
voter.setProcessDomainObjectClass(SomeDomainObject.class);
voter.afterPropertiesSet();
// Wire up an invocation to be voted on
List<ConfigAttribute> attr = SecurityConfig.createList("FOO_ADMIN_OR_WRITE_ACCESS");
// Setup a MockMethodInvocation that doesn't provide SomeDomainObject arg
Class clazz = String.class;
Method method = clazz.getMethod("toString", new Class[]{});
MethodInvocation mi = new SimpleMethodInvocation(new String(), method, new Object[]{domainObject});
try {
voter.vote(new UsernamePasswordAuthenticationToken("rod", null), mi, attr);
fail("Should have thrown AuthorizationServiceException");
} catch (AuthorizationServiceException expected) {
assertTrue(true);
}
}
public void testSetRequirePermissionFromString() {
assertPermission("NOTHING", SimpleAclEntry.NOTHING);
assertPermission("ADMINISTRATION", SimpleAclEntry.ADMINISTRATION);
assertPermission("READ", SimpleAclEntry.READ);
assertPermission("WRITE", SimpleAclEntry.WRITE);
assertPermission("CREATE", SimpleAclEntry.CREATE);
assertPermission("DELETE", SimpleAclEntry.DELETE);
assertPermission(new String[] { "WRITE", "CREATE" }, new int[] { SimpleAclEntry.WRITE, SimpleAclEntry.CREATE });
}
public void testSetRequirePermissionFromStringWrongValues() {
BasicAclEntryVoter voter = new BasicAclEntryVoter();
try {
voter.setRequirePermissionFromString(new String[] { "X" });
fail(IllegalArgumentException.class.getName() + " must have been thrown.");
} catch (IllegalArgumentException e) {
// expected
}
}
private void assertPermission(String text, int value) {
assertPermission(new String[] { text }, new int[] { value });
}
private void assertPermission(String[] text, int[] value) {
BasicAclEntryVoter voter = new BasicAclEntryVoter();
voter.setRequirePermissionFromString(text);
assertEquals("Test incorreclty coded", value.length, text.length);
assertEquals(value.length, voter.getRequirePermission().length);
for (int i = 0; i < value.length; i++) {
assertEquals(value[i], voter.getRequirePermission()[i]);
}
}
//~ Inner Classes ==================================================================================================
private class MockAclEntry implements AclEntry {
// just so AclTag iterates some different types of AclEntrys
}
}

View File

@ -1,214 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.taglibs.authz;
import org.springframework.security.Authentication;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.BasicAclEntry;
import org.springframework.security.context.SecurityContextHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.util.ExpressionEvaluationUtils;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.servlet.ServletContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
/**
* An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows its body through if some authorizations
* are granted to the request's principal.
* <p>
* Only works with permissions that are subclasses of {@link org.springframework.security.acl.basic.BasicAclEntry}.
* <p>
* One or more comma separate integer permissions are specified via the <code>hasPermission</code> attribute.
* The tag will include its body if <b>any</b> of the integer permissions have been granted to the current
* <code>Authentication</code> (obtained from the <code>SecurityContextHolder</code>).
* <p>
* For this class to operate it must be able to access the application context via the
* <code>WebApplicationContextUtils</code> and locate an {@link AclManager}. Application contexts have no need to have
* more than one <code>AclManager</code> (as a provider-based implementation can be used so that it locates a provider
* that is authoritative for the given domain object instance), so the first <code>AclManager</code> located will be
* used.
*
* @author Ben Alex
* @version $Id$
*/
public class AclTag extends TagSupport {
//~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(AclTag.class);
//~ Instance fields ================================================================================================
private Object domainObject;
private String hasPermission = "";
//~ Methods ========================================================================================================
public int doStartTag() throws JspException {
if ((null == hasPermission) || "".equals(hasPermission)) {
return Tag.SKIP_BODY;
}
final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission,
pageContext);
Integer[] requiredIntegers = null;
try {
requiredIntegers = parseIntegersString(evaledPermissionsString);
} catch (NumberFormatException nfe) {
throw new JspException(nfe);
}
Object resolvedDomainObject = null;
if (domainObject instanceof String) {
resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", (String) domainObject,
Object.class, pageContext);
} else {
resolvedDomainObject = domainObject;
}
if (resolvedDomainObject == null) {
if (logger.isDebugEnabled()) {
logger.debug("domainObject resolved to null, so including tag body");
}
// Of course they have access to a null object!
return Tag.EVAL_BODY_INCLUDE;
}
if (SecurityContextHolder.getContext().getAuthentication() == null) {
if (logger.isDebugEnabled()) {
logger.debug(
"SecurityContextHolder did not return a non-null Authentication object, so skipping tag body");
}
return Tag.SKIP_BODY;
}
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
ApplicationContext context = getContext(pageContext);
String[] beans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, AclManager.class, false, false);
if (beans.length == 0) {
throw new JspException("No AclManager would found the application context: " + context.toString());
}
AclManager aclManager = (AclManager) context.getBean(beans[0]);
// Obtain aclEntrys applying to the current Authentication object
AclEntry[] acls = aclManager.getAcls(resolvedDomainObject, auth);
if (logger.isDebugEnabled()) {
logger.debug("Authentication: '" + auth + "' has: " + ((acls == null) ? 0 : acls.length)
+ " AclEntrys for domain object: '" + resolvedDomainObject + "' from AclManager: '"
+ aclManager.toString() + "'");
}
if ((acls == null) || (acls.length == 0)) {
return Tag.SKIP_BODY;
}
for (int i = 0; i < acls.length; i++) {
// Locate processable AclEntrys
if (acls[i] instanceof BasicAclEntry) {
BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
// See if principal has any of the required permissions
for (int y = 0; y < requiredIntegers.length; y++) {
if (processableAcl.isPermitted(requiredIntegers[y].intValue())) {
if (logger.isDebugEnabled()) {
logger.debug("Including tag body as found permission: " + requiredIntegers[y]
+ " due to AclEntry: '" + processableAcl + "'");
}
return Tag.EVAL_BODY_INCLUDE;
}
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("No permission, so skipping tag body");
}
return Tag.SKIP_BODY;
}
/**
* Allows test cases to override where application context obtained from.
*
* @param pageContext so the <code>ServletContext</code> can be accessed as required by Spring's
* <code>WebApplicationContextUtils</code>
*
* @return the Spring application context (never <code>null</code>)
*/
protected ApplicationContext getContext(PageContext pageContext) {
ServletContext servletContext = pageContext.getServletContext();
return WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
}
public Object getDomainObject() {
return domainObject;
}
public String getHasPermission() {
return hasPermission;
}
private Integer[] parseIntegersString(String integersString)
throws NumberFormatException {
final Set integers = new HashSet();
final StringTokenizer tokenizer;
tokenizer = new StringTokenizer(integersString, ",", false);
while (tokenizer.hasMoreTokens()) {
String integer = tokenizer.nextToken();
integers.add(new Integer(integer));
}
return (Integer[]) integers.toArray(new Integer[] {});
}
public void setDomainObject(Object domainObject) {
this.domainObject = domainObject;
}
public void setHasPermission(String hasPermission) {
this.hasPermission = hasPermission;
}
}

View File

@ -17,7 +17,6 @@ package org.springframework.security.taglibs.velocity;
import org.springframework.security.Authentication;
import org.springframework.security.taglibs.authz.AclTag;
import org.springframework.security.taglibs.authz.AuthenticationTag;
import org.springframework.security.taglibs.authz.AuthorizeTag;

View File

@ -3,53 +3,53 @@
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>security</short-name>
<uri>http://www.springframework.org/security/tags</uri>
<description>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>security</short-name>
<uri>http://www.springframework.org/security/tags</uri>
<description>
Spring Security Authorization Tag Library
$Id$
</description>
$Id$
</description>
<tag>
<name>authorize</name>
<tag-class>org.springframework.security.taglibs.authz.AuthorizeTag</tag-class>
<description>
<tag>
<name>authorize</name>
<tag-class>org.springframework.security.taglibs.authz.AuthorizeTag</tag-class>
<description>
A simple tag to output or not the body of the tag if the principal
has or doesn't have certain authorities.
</description>
</description>
<attribute>
<name>ifNotGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
<attribute>
<name>ifNotGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
A comma separated list of roles which the user must not have
for the body to be output.
</description>
</attribute>
</description>
</attribute>
<attribute>
<name>ifAllGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
<attribute>
<name>ifAllGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
A comma separated list of roles which the user must all
possess for the body to be output.
</description>
</attribute>
</description>
</attribute>
<attribute>
<name>ifAnyGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
<attribute>
<name>ifAnyGranted</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
A comma separated list of roles, one of which the user must
possess for the body to be output.
</description>
</attribute>
</tag>
</description>
</attribute>
</tag>
<tag>
<name>authentication</name>
@ -88,66 +88,34 @@
</attribute>
</tag>
<tag>
<name>acl</name>
<tag-class>org.springframework.security.taglibs.authz.AclTag</tag-class>
<description>
<tag>
<name>accesscontrollist</name>
<tag-class>org.springframework.security.taglibs.authz.AccessControlListTag</tag-class>
<description>
Allows inclusion of a tag body if the current Authentication
has one of the specified permissions to the presented
domain object instance. This tag uses the first AclManager
it locates via
WebApplicationContextUtils.getRequiredWebApplicationContext(HttpServletContext).
</description>
has one of the specified permissions to the presented
domain object instance.
</description>
<attribute>
<name>hasPermission</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
<attribute>
<name>hasPermission</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
A comma separated list of integers, each representing a
required bit mask permission from a subclass of
required bit mask permission from a subclass of
org.springframework.security.acl.basic.AbstractBasicAclEntry.
</description>
</attribute>
<attribute>
<name>domainObject</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
</attribute>
<attribute>
<name>domainObject</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
The actual domain object instance for which permissions
are being evaluated.
</description>
</attribute>
</tag>
<tag>
<name>accesscontrollist</name>
<tag-class>org.springframework.security.taglibs.authz.AccessControlListTag</tag-class>
<description>
Allows inclusion of a tag body if the current Authentication
has one of the specified permissions to the presented
domain object instance.
</description>
<attribute>
<name>hasPermission</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
A comma separated list of integers, each representing a
required bit mask permission from a subclass of
org.springframework.security.acl.basic.AbstractBasicAclEntry.
are being evaluated.
</description>
</attribute>
<attribute>
<name>domainObject</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
The actual domain object instance for which permissions
are being evaluated.
</description>
</attribute>
</tag>
</attribute>
</tag>
</taglib>

View File

@ -1,179 +0,0 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.taglibs.authz;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.security.Authentication;
import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
/**
* Tests {@link AclTag}.
*
* @author Ben Alex
* @version $Id$
*/
public class AclTagTests extends TestCase {
//~ Instance fields ================================================================================================
private final MyAclTag aclTag = new MyAclTag();
//~ Methods ========================================================================================================
protected void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
public void testInclusionDeniedWhenAclManagerUnawareOfObject() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString());
aclTag.setDomainObject(new Integer(54));
assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
}
public void testInclusionDeniedWhenNoListOfPermissionsGiven() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(null);
aclTag.setDomainObject("object1");
assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
}
public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() throws JspException {
Authentication auth = new TestingAuthenticationToken("john", "crow", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
assertEquals(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ),
aclTag.getHasPermission());
aclTag.setDomainObject("object1");
assertEquals("object1", aclTag.getDomainObject());
assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
}
public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString());
aclTag.setDomainObject("object1");
assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
}
public void testInclusionDeniedWhenSecurityContextEmpty() throws JspException {
SecurityContextHolder.getContext().setAuthentication(null);
aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString());
aclTag.setDomainObject("object1");
assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
}
public void testInclusionPermittedWhenDomainObjectIsNull() throws JspException {
aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString());
aclTag.setDomainObject(null);
assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
}
public void testJspExceptionThrownIfHasPermissionNotValidFormat() throws JspException {
Authentication auth = new TestingAuthenticationToken("john", "crow", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission("0,5, 6"); // shouldn't be any space
try {
aclTag.doStartTag();
fail("Should have thrown JspException");
} catch (JspException expected) {
assertTrue(true);
}
}
public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
aclTag.setDomainObject("object1");
assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
}
public void testOperationWhenPrincipalHoldsPermissionOfSingleList() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString());
aclTag.setDomainObject("object1");
assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
}
//~ Inner Classes ==================================================================================================
private class MockAclEntry implements AclEntry {
// just so AclTag iterates some different types of AclEntrys
}
private class MyAclTag extends AclTag {
protected ApplicationContext getContext(PageContext pageContext) {
StaticApplicationContext context = new StaticApplicationContext();
final AclEntry[] acls = new AclEntry[] {
new MockAclEntry(),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
new SimpleAclEntry("rod", new MockAclObjectIdentity(), null, SimpleAclEntry.READ)
};
// Create an AclManager
AclManager aclManager = new AclManager() {
String object = "object1";
String principal = "rod";
public AclEntry[] getAcls(Object domainInstance) {
return domainInstance.equals(object) ? acls : null;
}
public AclEntry[] getAcls(Object domainInstance, Authentication authentication) {
return domainInstance.equals(object) && authentication.getPrincipal().equals(principal) ? acls : null;
}
};
// Register the AclManager into our ApplicationContext
context.getBeanFactory().registerSingleton("aclManager", aclManager);
return context;
}
}
private static class MockAclObjectIdentity implements AclObjectIdentity {
}
}