diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java new file mode 100644 index 000000000..f03d6c344 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java @@ -0,0 +1,55 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.permissions; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; + +/** + * This is what the PermissionRegistry hands out if you ask for a Permission + * that it doesn't know about. Nothing is authorized by this Permission. + */ +public class BrokenPermission implements Permission { + private final String uri; + private final String localName; + private final String namespace; + + public BrokenPermission(String uri) { + this.uri = uri; + + int namespaceBreak = uri.lastIndexOf("#"); + if (namespaceBreak == -1) { + namespaceBreak = uri.lastIndexOf("/"); + } + + int localNameStart = namespaceBreak + 1; + + this.namespace = uri.substring(0, localNameStart); + this.localName = uri.substring(localNameStart); + } + + @Override + public String getUri() { + return uri; + } + + @Override + public String getLocalName() { + return localName; + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + return false; + } + + @Override + public String toString() { + return "BrokenPermission[" + uri + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java index b335f1616..8089db2ec 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java @@ -37,7 +37,7 @@ public interface Permission { @Override public String getUri() { - return "java://" + Permission.class.getName() + "#NOT_AUTHORIZED"; + return "java:" + Permission.class.getName() + "#NOT_AUTHORIZED"; } @Override @@ -47,7 +47,7 @@ public interface Permission { @Override public String getNamespace() { - return "java://" + Permission.class.getName(); + return "java:" + Permission.class.getName(); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java index d402a207f..dd169f190 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java @@ -2,16 +2,24 @@ package edu.cornell.mannlib.vitro.webapp.auth.permissions; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + /** - * Holds a map of known Permission objects by URI. Resides in the + * An immutable collection of Permission objects, keyed by URI. Resides in the * ServletContext. * * This is not thread-safe, so all Permissions should be added during context @@ -23,9 +31,35 @@ public class PermissionRegistry { private static final String ATTRIBUTE_NAME = PermissionRegistry.class .getName(); + /** + * Has the registry been created yet? + */ + public static boolean isRegistryCreated(ServletContext ctx) { + return ctx.getAttribute(ATTRIBUTE_NAME) instanceof PermissionRegistry; + } + /** - * Get the registry from the context. If the context doesn't contain a - * registry yet, create one. + * Create the registry and store it in the context. + */ + public static void createRegistry(ServletContext ctx, + Collection permissions) { + if (ctx == null) { + throw new NullPointerException("ctx may not be null."); + } + if (permissions == null) { + throw new NullPointerException("permissions may not be null."); + } + if (ctx.getAttribute(ATTRIBUTE_NAME) != null) { + throw new IllegalStateException( + "PermissionRegistry has already been set."); + } + + PermissionRegistry registry = new PermissionRegistry(permissions); + ctx.setAttribute(ATTRIBUTE_NAME, registry); + } + + /** + * Get the registry from the context. If there isn't one, throw an exception. */ public static PermissionRegistry getRegistry(ServletContext ctx) { if (ctx == null) { @@ -33,46 +67,34 @@ public class PermissionRegistry { } Object o = ctx.getAttribute(ATTRIBUTE_NAME); - if (o instanceof PermissionRegistry) { - return (PermissionRegistry) o; - } - if (o != null) { - log.error("Error: PermissionRegistry was set to an " + if (o == null) { + throw new IllegalStateException( + "PermissionRegistry has not been set."); + } else if (!(o instanceof PermissionRegistry)) { + throw new IllegalStateException("PermissionRegistry was set to an " + "invalid object: " + o); } - PermissionRegistry registry = new PermissionRegistry(); - ctx.setAttribute(ATTRIBUTE_NAME, registry); - return registry; + return (PermissionRegistry) o; } - private final Map permissionsMap = new HashMap(); + private final Map permissionsMap; - private PermissionRegistry() { - // nothing to initialize; + public PermissionRegistry(Collection permissions) { + Map map = new HashMap(); + for (Permission p : permissions) { + String uri = p.getUri(); + if (map.containsKey(uri)) { + throw new IllegalStateException("A Permission is already " + + "registered with this URI: '" + uri + "'."); + } + map.put(uri, p); + } + this.permissionsMap = Collections.unmodifiableMap(map); } /** - * Add a Permission to the registry. If a Permission with the same URI is - * already present, throw an IllegalStateException. - */ - public void addPermission(Permission p) { - if (p == null) { - throw new NullPointerException("p may not be null."); - } - - String uri = p.getUri(); - if (isPermission(uri)) { - throw new IllegalStateException( - "A Permission is already registered with this URI: '" + uri - + "'."); - } - - permissionsMap.put(uri, p); - } - - /** - * Is there already a Permission registered with this URI? + * Is there a Permission registered with this URI? */ public boolean isPermission(String uri) { return permissionsMap.containsKey(uri); @@ -80,14 +102,47 @@ public class PermissionRegistry { /** * Get the permission that is registered with this URI. If there is no such - * Permission, return a dummy Permission that always denies authorization. + * Permission, return a BrokenPermission that always denies authorization. * * If you want to know whether an actual Permission has been registered at * this URI, call isPermission() instead. */ public Permission getPermission(String uri) { Permission p = permissionsMap.get(uri); - return (p == null) ? Permission.NOT_AUTHORIZED : p; + if (p == null) { + log.warn("No Permission is registered for '" + uri + "'"); + return new BrokenPermission(uri); + } + + return p; } + // ---------------------------------------------------------------------- + // Setup class + // ---------------------------------------------------------------------- + + public static class Setup implements ServletContextListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + try { + List permissions = new ArrayList(); + permissions.addAll(SimplePermission.getAllInstances()); + + PermissionRegistry.createRegistry(ctx, permissions); + + ss.info(this, "Created the PermissionRegistry with " + + permissions.size() + " permissions."); + } catch (Exception e) { + ss.fatal(this, "Failed to initialize the PermissionRegistry.", + e); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + sce.getServletContext().removeAttribute(ATTRIBUTE_NAME); + } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java index 73b7f6b8a..276f82885 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -22,7 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct public class SimplePermission implements Permission { private static final Log log = LogFactory.getLog(SimplePermission.class); - private static final String NAMESPACE = "java://" + private static final String NAMESPACE = "java:" + SimplePermission.class.getName() + "#"; private static final Map allInstances = new HashMap(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java index 050cc4081..89beacf13 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java @@ -20,7 +20,7 @@ public class SimpleRequestedAction extends RequestedAction { @Override public String getURI() { - return "java://" + this.getClass().getName() + "#" + localName; + return "java:" + this.getClass().getName() + "#" + localName; } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java index 79fdc2426..738814cbb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequestActionConstants.java @@ -3,7 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; public class RequestActionConstants { - public static String actionNamespace = "java://"; + public static String actionNamespace = "java:"; public static String SOME_URI = "?SOME_URI"; public static String SOME_LITERAL = "?SOME_LITERAL"; diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index b74d6f4c3..5a62388c4 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -34,6 +34,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup # Must run after JenaDataSourceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup +edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry$Setup + edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup