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 33a5b5261..b335f1616 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 @@ -2,10 +2,58 @@ package edu.cornell.mannlib.vitro.webapp.auth.permissions; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; + /** - * Base class that describes a unit of authorization, or permission to perform + * Interface that describes a unit of authorization, or permission to perform * requested actions. */ -public abstract class Permission { - // no members +public interface Permission { + /** + * Get the URI that identifies this Permission object. + */ + String getUri(); + + /** + * Convenience method to get the localName portion of the URI. + */ + String getLocalName(); + + /** + * Convenience method to get the namespace portion of the URI. + */ + String getNamespace(); + + /** + * Is a user with this Permission authorized to perform this + * RequestedAction? + */ + boolean isAuthorized(RequestedAction whatToAuth); + + /** + * An implementation of Permission that authorizes nothing. + */ + static Permission NOT_AUTHORIZED = new Permission() { + + @Override + public String getUri() { + return "java://" + Permission.class.getName() + "#NOT_AUTHORIZED"; + } + + @Override + public String getLocalName() { + return "NOT_AUTHORIZED"; + } + + @Override + public String getNamespace() { + return "java://" + Permission.class.getName(); + } + + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + return false; + } + + }; } 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 new file mode 100644 index 000000000..f45a13dd0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java @@ -0,0 +1,57 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.permissions; + +import javax.servlet.ServletContext; + +/** + * Holds a map of known Permission objects by URI. Resides in the + * ServletContext. + */ +public class PermissionRegistry { + /** + * Get the registry from the context. If the context doesn't contain a + * registry yet, write a warning and return an immutable registry with no + * permissions. + */ + public static PermissionRegistry getRegistry(ServletContext ctx) { + throw new RuntimeException( + "PermissionRegistry.getBean not implemented."); + } + + /** + * Create an empty registry and set it into the context. This should only be + * called from PermissionSetsLoader. + */ + protected static void setRegistry(ServletContext ctx, + PermissionRegistry registry) { + throw new RuntimeException( + "PermissionRegistry.setRegistry not implemented."); + } + + /** + * Add a Permission to the registry. If a Permission with the same URI is + * already present, throw an IllegalStateException. + */ + public void addPermission(Permission p) { + throw new RuntimeException( + "PermissionRegistry.addPermission not implemented."); + } + + /** + * Is there already a Permission registered with this URI? + */ + public boolean isPermission(String uri) { + throw new RuntimeException( + "PermissionRegistry.isPermission not implemented."); + } + + /** + * Get the permission that is registered with this URI. If there is no such + * Permission, return a dummy Permission that always denies authorization. + */ + public Permission getPermission(String uri) { + throw new RuntimeException( + "PermissionRegistry.getPermission not implemented."); + } +} 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 new file mode 100644 index 000000000..a9acce512 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -0,0 +1,83 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.permissions; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleRequestedAction; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; + +/** + * A class of simple permissions. Each instance holds a RequestedAction, and + * will only authorize that RequestedAction (or one with the same URI). + */ +public class SimplePermission implements Permission { + private static final Log log = LogFactory.getLog(SimplePermission.class); + + private static final String NAMESPACE = "java://" + + SimplePermission.class.getName() + "#"; + + private static final List allInstances = new ArrayList(); + + public static final SimplePermission MANAGE_MENUS = new SimplePermission( + "ManageMenus"); + + public static List getAllInstances() { + return new ArrayList(allInstances); + } + + private final String localName; + public final RequestedAction ACTION; + public final Actions ACTIONS; + + public SimplePermission(String localName) { + if (localName == null) { + throw new NullPointerException("name may not be null."); + } + + this.localName = localName; + this.ACTION = new SimpleRequestedAction(localName); + this.ACTIONS = new Actions(this.ACTION); + + // TODO -- we need to throw an exception if another Permission already has this localname. + allInstances.add(this); + } + + @Override + public String getLocalName() { + return this.localName; + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public String getUri() { + return NAMESPACE + this.localName; + } + + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + if (whatToAuth != null) { + if (ACTION.getURI().equals(whatToAuth.getURI())) { + log.debug(this + " authorizes " + whatToAuth); + return true; + } + } + log.debug(this + " does not authorize " + whatToAuth); + return false; + } + + @Override + public String toString() { + return "SimplePermission['" + localName + "']"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java index 3c9b2b591..09f374d83 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java @@ -15,12 +15,11 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.querymodel.QueryFullModel; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.querymodel.QueryUserAccountsModel; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.AccessSpecialDataModels; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.DoFrontEndEditing; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.DoBackEndEditing; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.DoFrontEndEditing; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageOwnProxies; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManagePortals; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageProxies; @@ -68,9 +67,6 @@ public class UseRestrictedPagesByRoleLevelPolicy implements PolicyIface { } else if (whatToAuth instanceof ManageUserAccounts) { result = isAuthorized(whatToAuth, RoleLevel.DB_ADMIN, userRole); - } else if (whatToAuth instanceof ManageMenus) { - result = isAuthorized(whatToAuth, RoleLevel.DB_ADMIN, userRole); - } else if (whatToAuth instanceof ManageSearchIndex) { result = isAuthorized(whatToAuth, RoleLevel.DB_ADMIN, userRole); 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 new file mode 100644 index 000000000..050cc4081 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java @@ -0,0 +1,49 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; + +/** + * A RequestedAction that can be recognized by a SimplePermission. + */ +public class SimpleRequestedAction extends RequestedAction { + private final String localName; + + public SimpleRequestedAction(String localName) { + if (localName == null) { + throw new NullPointerException("localName may not be null."); + } + + this.localName = localName; + } + + @Override + public String getURI() { + return "java://" + this.getClass().getName() + "#" + localName; + } + + @Override + public int hashCode() { + return (localName == null) ? 0 : localName.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof SimpleRequestedAction) { + SimpleRequestedAction that = (SimpleRequestedAction) o; + return equivalent(this.localName, that.localName); + } + return false; + } + + private boolean equivalent(Object o1, Object o2) { + return (o1 == null) ? (o2 == null) : o1.equals(o2); + } + + @Override + public String toString() { + return "SimpleRequestedAction['" + localName + "']"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageMenus.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageMenus.java deleted file mode 100644 index d6419e39d..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageMenus.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; - -/** Should we allow the user to use the pages for editing menus? */ -public class ManageMenus extends RequestedAction implements - UsePagesRequestedAction { - // no fields -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java index 29c584157..70d740de4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java @@ -15,12 +15,12 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.Option; import edu.cornell.mannlib.vedit.util.FormUtils; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.DoBackEndEditing; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageProxies; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeSiteAdminPage; @@ -140,7 +140,7 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet { data.put("siteInfo", UrlBuilder.getUrl("/editForm", "controller", "ApplicationBean")); } - if (PolicyHelper.isAuthorizedForActions(vreq, new ManageMenus())) { + if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.MANAGE_MENUS.ACTION)) { data.put("menuManagement", UrlBuilder.getUrl("/individual", "uri", "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#DefaultMenu", "switchToDisplayModel", "true")); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuManagementController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuManagementController.java index 43b5e7fda..626e99587 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuManagementController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuManagementController.java @@ -2,29 +2,15 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import java.util.List; -import java.util.ArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.MenuManagementDataUtils; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; -import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; - -import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.Individual; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; @@ -32,8 +18,15 @@ import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetter; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; +import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; +import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.DataGetterUtils; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.MenuManagementDataUtils; +import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetter; import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.SelectDataGetterUtils; /* @@ -54,7 +47,7 @@ public class MenuManagementController extends FreemarkerHttpServlet { protected final static String ITEM_PARAM = "objectUri"; - public final static Actions REQUIRED_ACTIONS = new Actions(new ManageMenus()); + public final static Actions REQUIRED_ACTIONS = SimplePermission.MANAGE_MENUS.ACTIONS; @Override protected Actions requiredActions(VitroRequest vreq) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuN3EditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuN3EditController.java index f98a40ec7..9254eaf38 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuN3EditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/MenuN3EditController.java @@ -5,8 +5,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; import java.util.HashMap; import java.util.Map; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; @@ -19,7 +19,7 @@ public class MenuN3EditController extends FreemarkerHttpServlet { protected final static String N3_PARAM = "navigationN3"; - public final static Actions REQUIRED_ACTIONS = new Actions(new ManageMenus()); + public final static Actions REQUIRED_ACTIONS = SimplePermission.MANAGE_MENUS.ACTIONS; @Override protected Actions requiredActions(VitroRequest vreq) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index 3d36b28c2..d02e87bdf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -34,10 +34,10 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.AccessSpecialDataModels; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; @@ -196,7 +196,7 @@ public class VitroRequestPrep implements Filter { private boolean authorizedForSpecialModel(HttpServletRequest req) { if (isParameterPresent(req, SWITCH_TO_DISPLAY_MODEL)) { - return PolicyHelper.isAuthorizedForActions(req, new ManageMenus()); + return PolicyHelper.isAuthorizedForActions(req, SimplePermission.MANAGE_MENUS.ACTION); } else if (anyOtherSpecialProperties(req)){ return PolicyHelper.isAuthorizedForActions(req, new AccessSpecialDataModels()); } else { diff --git a/webapp/web/WEB-INF/resources/permission_config.n3 b/webapp/web/WEB-INF/resources/permission_config.n3 new file mode 100644 index 000000000..485474eab --- /dev/null +++ b/webapp/web/WEB-INF/resources/permission_config.n3 @@ -0,0 +1,10 @@ +# $This file is distributed under the terms of the license in /doc/license.txt$ + +@prefix auth: . +@prefix simplePermission: . + +auth:ADMIN + a auth:PermissionSet ; + auth:hasPermission simplePermission:ManageMenus ; + . +