edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry Maven / Gradle / Ivy
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import java.util.ArrayList;
import java.util.Collection;
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.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* A collection of Permission objects, keyed by URI. Resides in the
* ServletContext.
*
* This is not thread-safe, so Permissions should be added only during context
* initialization.
*/
public class PermissionRegistry {
private static final Log log = LogFactory.getLog(PermissionRegistry.class);
// ----------------------------------------------------------------------
// The factory
// ----------------------------------------------------------------------
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;
}
/**
* 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();
registry.addPermissions(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) {
throw new NullPointerException("ctx may not be null.");
}
Object o = ctx.getAttribute(ATTRIBUTE_NAME);
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);
}
return (PermissionRegistry) o;
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
private final Map map = new HashMap<>();
/**
* This class is not thread-safe, so permissions should be added only during
* context initialization.
*/
public void addPermissions(Collection permissions) {
for (Permission p : permissions) {
addPermission(p);
}
}
/**
* This class is not thread-safe, so permissions should be added only during
* context initialization.
*/
public void addPermission(Permission p) {
String uri = p.getUri();
if (map.containsKey(uri)) {
throw new IllegalStateException("A Permission is already "
+ "registered with this URI: '" + uri + "'.");
}
map.put(uri, p);
}
/**
* Is there a Permission registered with this URI?
*/
public boolean isPermission(String uri) {
return map.containsKey(uri);
}
/**
* Get the permission that is registered with this URI. If there is no such
* 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 = map.get(uri);
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());
permissions.addAll(createDisplayByRolePermissions());
permissions.addAll(createEditByRolePermissions());
permissions.addAll(createPublishByRolePermissions());
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);
}
}
/**
* There is no DisplayByRolePermission for self-editors. They get the
* same rights as PUBLIC. Other permissions give them their self-editing
* privileges.
*/
private Collection createDisplayByRolePermissions() {
List list = new ArrayList();
list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN));
list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR));
list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC));
return list;
}
/**
* There is no EditByRolePermission for PUBLIC or for self-editors. A
* property may be given an edit-level of "PUBLIC", but that may also
* simply be the default assigned to it when editing, and we don't want
* to recognize that.
*
* Other permissions give self-editors their editing privileges.
*/
private Collection createEditByRolePermissions() {
List list = new ArrayList();
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN));
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR));
return list;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
}
/**
* There is no PublishByRolePermission for self-editors. They get the
* same rights as PUBLIC. Other permissions give them their self-editing
* privileges.
*/
private Collection createPublishByRolePermissions() {
List list = new ArrayList();
list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN));
list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR));
list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR));
list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC));
return list;
}
}
}