9 changed files with 325 additions and 178 deletions
@ -0,0 +1,59 @@ |
|||||||
|
package org.springframework.security.acls.domain; |
||||||
|
|
||||||
|
import org.springframework.security.acls.AclFormattingUtils; |
||||||
|
import org.springframework.security.acls.Permission; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides an abstract superclass for {@link Permission} implementations. |
||||||
|
* |
||||||
|
* @author Ben Alex |
||||||
|
* @since 2.0.3 |
||||||
|
* @see AbstractRegisteredPermission |
||||||
|
* |
||||||
|
*/ |
||||||
|
public abstract class AbstractPermission implements Permission { |
||||||
|
|
||||||
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
|
protected char code; |
||||||
|
protected int mask; |
||||||
|
|
||||||
|
//~ Constructors ===================================================================================================
|
||||||
|
|
||||||
|
protected AbstractPermission(int mask, char code) { |
||||||
|
this.mask = mask; |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
|
public final boolean equals(Object arg0) { |
||||||
|
if (arg0 == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(arg0 instanceof Permission)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Permission rhs = (Permission) arg0; |
||||||
|
|
||||||
|
return (this.mask == rhs.getMask()); |
||||||
|
} |
||||||
|
|
||||||
|
public final int getMask() { |
||||||
|
return mask; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPattern() { |
||||||
|
return AclFormattingUtils.printBinary(mask, code); |
||||||
|
} |
||||||
|
|
||||||
|
public final String toString() { |
||||||
|
return this.getClass().getSimpleName() + "[" + getPattern() + "=" + mask + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.mask; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
package org.springframework.security.acls.domain; |
||||||
|
|
||||||
|
import org.springframework.security.acls.Permission; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides an abstract base for standard {@link Permission} instances that wish to offer static convenience |
||||||
|
* methods to callers via delegation to {@link DefaultPermissionFactory}. |
||||||
|
* |
||||||
|
* @author Ben Alex |
||||||
|
* @since 2.0.3 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public abstract class AbstractRegisteredPermission extends AbstractPermission { |
||||||
|
protected static DefaultPermissionFactory defaultPermissionFactory = new DefaultPermissionFactory(); |
||||||
|
|
||||||
|
protected AbstractRegisteredPermission(int mask, char code) { |
||||||
|
super(mask, code); |
||||||
|
} |
||||||
|
|
||||||
|
protected final static void registerPermissionsFor(Class subClass) { |
||||||
|
defaultPermissionFactory.registerPublicPermissions(subClass); |
||||||
|
} |
||||||
|
|
||||||
|
public final static Permission buildFromMask(int mask) { |
||||||
|
return defaultPermissionFactory.buildFromMask(mask); |
||||||
|
} |
||||||
|
|
||||||
|
public final static Permission[] buildFromMask(int[] masks) { |
||||||
|
return defaultPermissionFactory.buildFromMask(masks); |
||||||
|
} |
||||||
|
|
||||||
|
public final static Permission buildFromName(String name) { |
||||||
|
return defaultPermissionFactory.buildFromName(name); |
||||||
|
} |
||||||
|
|
||||||
|
public final static Permission[] buildFromName(String[] names) { |
||||||
|
return defaultPermissionFactory.buildFromName(names); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,127 @@ |
|||||||
|
package org.springframework.security.acls.domain; |
||||||
|
|
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.springframework.security.acls.Permission; |
||||||
|
import org.springframework.security.acls.jdbc.LookupStrategy; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default implementation of {@link PermissionFactory}. |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* Generally this class will be used by a {@link Permission} instance, as opposed to being dependency |
||||||
|
* injected into a {@link LookupStrategy} or similar. Nevertheless, the latter mode of operation is |
||||||
|
* fully supported (in which case your {@link Permission} implementations probably should extend |
||||||
|
* {@link AbstractPermission} instead of {@link AbstractRegisteredPermission}). |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* @author Ben Alex |
||||||
|
* @since 2.0.3 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public class DefaultPermissionFactory implements PermissionFactory { |
||||||
|
private Map registeredPermissionsByInteger = new HashMap(); |
||||||
|
private Map registeredPermissionsByName = new HashMap(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Permit registration of a {@link DefaultPermissionFactory} class. The class must provide |
||||||
|
* public static fields of type {@link Permission} to represent the possible permissions. |
||||||
|
* |
||||||
|
* @param clazz a {@link Permission} class with public static fields to register |
||||||
|
*/ |
||||||
|
public void registerPublicPermissions(Class clazz) { |
||||||
|
Assert.notNull(clazz, "Class required"); |
||||||
|
Assert.isAssignable(Permission.class, clazz); |
||||||
|
|
||||||
|
Field[] fields = clazz.getFields(); |
||||||
|
|
||||||
|
for (int i = 0; i < fields.length; i++) { |
||||||
|
try { |
||||||
|
Object fieldValue = fields[i].get(null); |
||||||
|
|
||||||
|
if (Permission.class.isAssignableFrom(fieldValue.getClass())) { |
||||||
|
// Found a Permission static field
|
||||||
|
Permission perm = (Permission) fieldValue; |
||||||
|
String permissionName = fields[i].getName(); |
||||||
|
|
||||||
|
registerPermission(perm, permissionName); |
||||||
|
} |
||||||
|
} catch (Exception ignore) {} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void registerPermission(Permission perm, String permissionName) { |
||||||
|
Assert.notNull(perm, "Permission required"); |
||||||
|
Assert.hasText(permissionName, "Permission name required"); |
||||||
|
|
||||||
|
Integer mask = new Integer(perm.getMask()); |
||||||
|
|
||||||
|
// Ensure no existing Permission uses this integer or code
|
||||||
|
Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask), "An existing Permission already provides mask " + mask); |
||||||
|
Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName), "An existing Permission already provides name '" + permissionName + "'"); |
||||||
|
|
||||||
|
// Register the new Permission
|
||||||
|
registeredPermissionsByInteger.put(mask, perm); |
||||||
|
registeredPermissionsByName.put(permissionName, perm); |
||||||
|
} |
||||||
|
|
||||||
|
public Permission buildFromMask(int mask) { |
||||||
|
if (registeredPermissionsByInteger.containsKey(new Integer(mask))) { |
||||||
|
// The requested mask has an exactly match against a statically-defined Permission, so return it
|
||||||
|
return (Permission) registeredPermissionsByInteger.get(new Integer(mask)); |
||||||
|
} |
||||||
|
|
||||||
|
// To get this far, we have to use a CumulativePermission
|
||||||
|
CumulativePermission permission = new CumulativePermission(); |
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++) { |
||||||
|
int permissionToCheck = 1 << i; |
||||||
|
|
||||||
|
if ((mask & permissionToCheck) == permissionToCheck) { |
||||||
|
Permission p = (Permission) registeredPermissionsByInteger.get(new Integer(permissionToCheck)); |
||||||
|
Assert.state(p != null, "Mask " + permissionToCheck + " does not have a corresponding static Permission"); |
||||||
|
permission.set(p); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return permission; |
||||||
|
} |
||||||
|
|
||||||
|
public Permission[] buildFromMask(int[] masks) { |
||||||
|
if ((masks == null) || (masks.length == 0)) { |
||||||
|
return new Permission[0]; |
||||||
|
} |
||||||
|
|
||||||
|
Permission[] permissions = new Permission[masks.length]; |
||||||
|
|
||||||
|
for (int i = 0; i < masks.length; i++) { |
||||||
|
permissions[i] = buildFromMask(masks[i]); |
||||||
|
} |
||||||
|
|
||||||
|
return permissions; |
||||||
|
} |
||||||
|
|
||||||
|
public Permission buildFromName(String name) { |
||||||
|
Assert.isTrue(registeredPermissionsByName.containsKey(name), "Unknown permission '" + name + "'"); |
||||||
|
|
||||||
|
return (Permission) registeredPermissionsByName.get(name); |
||||||
|
} |
||||||
|
|
||||||
|
public Permission[] buildFromName(String[] names) { |
||||||
|
if ((names == null) || (names.length == 0)) { |
||||||
|
return new Permission[0]; |
||||||
|
} |
||||||
|
|
||||||
|
Permission[] permissions = new Permission[names.length]; |
||||||
|
|
||||||
|
for (int i = 0; i < names.length; i++) { |
||||||
|
permissions[i] = buildFromName(names[i]); |
||||||
|
} |
||||||
|
|
||||||
|
return permissions; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
package org.springframework.security.acls.domain; |
||||||
|
|
||||||
|
import org.springframework.security.acls.Permission; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides a simple mechanism to retrieve {@link Permission} instances from integer masks. |
||||||
|
* |
||||||
|
* @author Ben Alex |
||||||
|
* @since 2.0.3 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public interface PermissionFactory { |
||||||
|
|
||||||
|
/** |
||||||
|
* Dynamically creates a <code>CumulativePermission</code> or <code>BasePermission</code> representing the |
||||||
|
* active bits in the passed mask. |
||||||
|
* |
||||||
|
* @param mask to build |
||||||
|
* |
||||||
|
* @return a Permission representing the requested object |
||||||
|
*/ |
||||||
|
public abstract Permission buildFromMask(int mask); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
/* 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.acls.domain; |
||||||
|
|
||||||
|
import org.springframework.security.acls.Permission; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* A test permission. |
||||||
|
* |
||||||
|
* @author Ben Alex |
||||||
|
* @version $Id$ |
||||||
|
*/ |
||||||
|
public class SpecialPermission extends BasePermission { |
||||||
|
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
|
||||||
|
|
||||||
|
/** |
||||||
|
* Registers the public static permissions defined on this class. This is mandatory so |
||||||
|
* that the static methods will operate correctly. |
||||||
|
*/ |
||||||
|
static { |
||||||
|
registerPermissionsFor(SpecialPermission.class); |
||||||
|
} |
||||||
|
|
||||||
|
protected SpecialPermission(int mask, char code) { |
||||||
|
super(mask, code); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue