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.Authentication;
import org.springframework.security.taglibs.authz.AclTag;
import org.springframework.security.taglibs.authz.AuthenticationTag; import org.springframework.security.taglibs.authz.AuthenticationTag;
import org.springframework.security.taglibs.authz.AuthorizeTag; import org.springframework.security.taglibs.authz.AuthorizeTag;

View File

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