From ffafc5f3e0ee8dfb097d8c51f48dac4e9fbd2c27 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 6 Jan 2012 21:58:16 +0000 Subject: [PATCH 1/4] NIHVIVO-3523 Create the DisplayByRolePermission, so we can use the PermissionsPolicy instead of DisplayRestrictedDataByRoleLevelPolicy, and these display restrictions can be assigned to arbitrary PermissionSets. --- .../permissions/DisplayByRolePermission.java | 138 ++++++++++++++ .../auth/permissions/PermissionRegistry.java | 22 ++- ...isplayRestrictedDataByRoleLevelPolicy.java | 179 ------------------ .../policy/setup/CommonPolicyFamilySetup.java | 2 - .../filters/FilterByRoleLevelPermission.java | 124 ++++++++++++ .../filtering/filters/VitroFilterUtils.java | 7 +- .../WEB-INF/resources/permission_config.n3 | 18 ++ .../WEB-INF/resources/startup_listeners.txt | 5 +- 8 files changed, 305 insertions(+), 190 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByRoleLevelPermission.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java new file mode 100644 index 000000000..c98120dec --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java @@ -0,0 +1,138 @@ +/* $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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; + +/** + * Is the user authorized to display properties that are marked as restricted to + * a certain "Role Level"? + */ +public class DisplayByRolePermission extends Permission { + private static final Log log = LogFactory + .getLog(DisplayByRolePermission.class); + + public static final String NAMESPACE = "java:" + + DisplayByRolePermission.class.getName() + "#"; + + private final String roleName; + private final RoleLevel roleLevel; + private final ServletContext ctx; + + public DisplayByRolePermission(String roleName, RoleLevel roleLevel, + ServletContext ctx) { + super(NAMESPACE + roleName); + + if (roleName == null) { + throw new NullPointerException("role may not be null."); + } + if (roleLevel == null) { + throw new NullPointerException("roleLevel may not be null."); + } + if (ctx == null) { + throw new NullPointerException("context may not be null."); + } + + this.roleName = roleName; + this.roleLevel = roleLevel; + this.ctx = ctx; + } + + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + boolean result; + + if (whatToAuth instanceof DisplayDataProperty) { + result = isAuthorized((DisplayDataProperty) whatToAuth); + } else if (whatToAuth instanceof DisplayObjectProperty) { + result = isAuthorized((DisplayObjectProperty) whatToAuth); + } else if (whatToAuth instanceof DisplayDataPropertyStatement) { + result = isAuthorized((DisplayDataPropertyStatement) whatToAuth); + } else if (whatToAuth instanceof DisplayObjectPropertyStatement) { + result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth); + } else { + result = false; + } + + if (result) { + log.debug(this + " authorizes " + whatToAuth); + } else { + log.debug(this + " does not authorize " + whatToAuth); + } + + return result; + } + + /** + * The user may see this data property if they are allowed to see its + * predicate. + */ + private boolean isAuthorized(DisplayDataProperty action) { + String predicateUri = action.getDataProperty().getURI(); + return canDisplayPredicate(predicateUri); + } + + /** + * The user may see this object property if they are allowed to see its + * predicate. + */ + private boolean isAuthorized(DisplayObjectProperty action) { + String predicateUri = action.getObjectProperty().getURI(); + return canDisplayPredicate(predicateUri); + } + + /** + * The user may see this data property if they are allowed to see its + * subject and its predicate. + */ + private boolean isAuthorized(DisplayDataPropertyStatement action) { + DataPropertyStatement stmt = action.getDataPropertyStatement(); + String subjectUri = stmt.getIndividualURI(); + String predicateUri = stmt.getDatapropURI(); + return canDisplayResource(subjectUri) + && canDisplayPredicate(predicateUri); + } + + /** + * The user may see this data property if they are allowed to see its + * subject, its predicate, and its object. + */ + private boolean isAuthorized(DisplayObjectPropertyStatement action) { + ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); + String subjectUri = stmt.getSubjectURI(); + String predicateUri = stmt.getPropertyURI(); + String objectUri = stmt.getObjectURI(); + return canDisplayResource(subjectUri) + && canDisplayPredicate(predicateUri) + && canDisplayResource(objectUri); + } + + private boolean canDisplayResource(String resourceUri) { + return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( + resourceUri, this.roleLevel); + } + + private boolean canDisplayPredicate(String predicateUri) { + return PropertyRestrictionPolicyHelper.getBean(ctx) + .canDisplayPredicate(predicateUri, this.roleLevel); + } + + @Override + public String toString() { + return "DisplayByRolePermission['" + roleName + "']"; + } + +} 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 dd169f190..d539fcfbe 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 @@ -16,6 +16,7 @@ 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; /** @@ -31,7 +32,7 @@ public class PermissionRegistry { private static final String ATTRIBUTE_NAME = PermissionRegistry.class .getName(); - /** + /** * Has the registry been created yet? */ public static boolean isRegistryCreated(ServletContext ctx) { @@ -59,7 +60,8 @@ public class PermissionRegistry { } /** - * Get the registry from the context. If there isn't one, throw an exception. + * Get the registry from the context. If there isn't one, throw an + * exception. */ public static PermissionRegistry getRegistry(ServletContext ctx) { if (ctx == null) { @@ -128,7 +130,9 @@ public class PermissionRegistry { StartupStatus ss = StartupStatus.getBean(ctx); try { List permissions = new ArrayList(); + permissions.addAll(SimplePermission.getAllInstances()); + permissions.addAll(createDisplayByRolePermissions(ctx)); PermissionRegistry.createRegistry(ctx, permissions); @@ -140,6 +144,20 @@ public class PermissionRegistry { } } + private Collection createDisplayByRolePermissions( + ServletContext ctx) { + List list = new ArrayList(); + list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN, + ctx)); + list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR, + ctx)); + list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR, + ctx)); + list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC, + ctx)); + return list; + } + @Override public void contextDestroyed(ServletContextEvent sce) { sce.getServletContext().removeAttribute(ATTRIBUTE_NAME); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java deleted file mode 100644 index eaea0a599..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java +++ /dev/null @@ -1,179 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; - -/** - * Permit display of various data based on the user's Role level and the - * restrictions in the onotology. - */ -public class DisplayRestrictedDataByRoleLevelPolicy implements PolicyIface { - private static final Log log = LogFactory - .getLog(DisplayRestrictedDataByRoleLevelPolicy.class); - - private final ServletContext ctx; - - public DisplayRestrictedDataByRoleLevelPolicy(ServletContext ctx) { - this.ctx = ctx; - } - - /** - * If the requested action is to display a property or a property statement, - * we might authorize it based on their role level. - */ - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return defaultDecision("whomToAuth was null"); - } - if (whatToAuth == null) { - return defaultDecision("whatToAuth was null"); - } - - RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth); - /* - * This policy treats a self-editor as no better than public. If you - * want self-editors to see their own properties, some other policy must - * grant that. - */ - if (userRole == RoleLevel.SELF) { - userRole = RoleLevel.PUBLIC; - } - - PolicyDecision result; - if (whatToAuth instanceof DisplayDataProperty) { - result = isAuthorized((DisplayDataProperty) whatToAuth, userRole); - } else if (whatToAuth instanceof DisplayObjectProperty) { - result = isAuthorized((DisplayObjectProperty) whatToAuth, userRole); - } else if (whatToAuth instanceof DisplayDataPropertyStatement) { - result = isAuthorized((DisplayDataPropertyStatement) whatToAuth, - userRole); - } else if (whatToAuth instanceof DisplayObjectPropertyStatement) { - result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth, - userRole); - } else { - result = defaultDecision("Unrecognized action"); - } - - log.debug("decision for '" + whatToAuth + "' is " + result); - return result; - } - - /** - * The user may see this data property if they are allowed to see its - * predicate. - */ - private PolicyDecision isAuthorized(DisplayDataProperty action, - RoleLevel userRole) { - String predicateUri = action.getDataProperty().getURI(); - if (canDisplayPredicate(predicateUri, userRole)) { - return authorized("user may view DataProperty " + predicateUri); - } else { - return defaultDecision("user may not view DataProperty " - + predicateUri); - } - } - - /** - * The user may see this object property if they are allowed to see its - * predicate. - */ - private PolicyDecision isAuthorized(DisplayObjectProperty action, - RoleLevel userRole) { - String predicateUri = action.getObjectProperty().getURI(); - if (canDisplayPredicate(predicateUri, userRole)) { - return authorized("user may view ObjectProperty " + predicateUri); - } else { - return defaultDecision("user may not view ObjectProperty " - + predicateUri); - } - } - - /** - * The user may see this data property if they are allowed to see its - * subject and its predicate. - */ - private PolicyDecision isAuthorized(DisplayDataPropertyStatement action, - RoleLevel userRole) { - DataPropertyStatement stmt = action.getDataPropertyStatement(); - String subjectUri = stmt.getIndividualURI(); - String predicateUri = stmt.getDatapropURI(); - if (canDisplayResource(subjectUri, userRole) - && canDisplayPredicate(predicateUri, userRole)) { - return authorized("user may view DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); - } else { - return defaultDecision("user may not view DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); - } - } - - /** - * The user may see this data property if they are allowed to see its - * subject, its predicate, and its object. - */ - private PolicyDecision isAuthorized(DisplayObjectPropertyStatement action, - RoleLevel userRole) { - ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); - String subjectUri = stmt.getSubjectURI(); - String predicateUri = stmt.getPropertyURI(); - String objectUri = stmt.getObjectURI(); - if (canDisplayResource(subjectUri, userRole) - && canDisplayPredicate(predicateUri, userRole) - && canDisplayResource(objectUri, userRole)) { - return authorized("user may view ObjectPropertyStatement " - + subjectUri + " ==> " + predicateUri + " ==> " + objectUri); - } else { - return defaultDecision("user may not view ObjectPropertyStatement " - + subjectUri + " ==> " + predicateUri + " ==> " + objectUri); - } - } - - /** If the user is explicitly authorized, return this. */ - private PolicyDecision authorized(String message) { - String className = this.getClass().getSimpleName(); - return new BasicPolicyDecision(Authorization.AUTHORIZED, className - + ": " + message); - } - - /** If the user isn't explicitly authorized, return this. */ - private PolicyDecision defaultDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); - } - - private boolean canDisplayResource(String uri, RoleLevel userRole) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( - uri, userRole); - } - - private boolean canDisplayPredicate(String uri, RoleLevel userRole) { - return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(uri, userRole); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " - " + hashCode(); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index 850f6e586..5662e7ab6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -14,7 +14,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingR import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; -import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.EditRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy; @@ -35,7 +34,6 @@ public class CommonPolicyFamilySetup implements ServletContextListener { try { policy(ctx, new PermissionsPolicy()); - policy(ctx, new DisplayRestrictedDataByRoleLevelPolicy(ctx)); policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx)); policy(ctx, new EditRestrictedDataByRoleLevelPolicy(ctx)); policy(ctx, new SelfEditingPolicy(ctx)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByRoleLevelPermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByRoleLevelPermission.java new file mode 100644 index 000000000..f5ad90293 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByRoleLevelPermission.java @@ -0,0 +1,124 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.filtering.filters; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import net.sf.jga.fn.UnaryFunctor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; + +/** + * Filter the properties depending on what DisplayByRolePermission is on the + * request. If no request, or no permission, use the Public permission. + */ +public class FilterByRoleLevelPermission extends VitroFiltersImpl { + private static final Log log = LogFactory + .getLog(FilterByRoleLevelPermission.class); + + private final Permission permission; + + private static Permission getDefaultPermission(ServletContext ctx) { + if (ctx == null) { + throw new NullPointerException("context may not be null."); + } + + return PermissionRegistry.getRegistry(ctx).getPermission( + DisplayByRolePermission.NAMESPACE + "Public"); + } + + private static Permission getPermissionFromRequest(HttpServletRequest req) { + if (req == null) { + throw new NullPointerException("request may not be null."); + } + + IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req); + for (Permission p : HasPermission.getPermissions(ids)) { + if (p instanceof DisplayByRolePermission) { + return p; + } + } + return getDefaultPermission(req.getSession().getServletContext()); + } + + /** Get the DisplayByRolePermission from the request, or use Public. */ + public FilterByRoleLevelPermission(HttpServletRequest req) { + this(getPermissionFromRequest(req)); + } + + /** Use the Public permission. */ + public FilterByRoleLevelPermission(ServletContext ctx) { + this(getDefaultPermission(ctx)); + } + + /** Use the specified permission. */ + public FilterByRoleLevelPermission(Permission permission) { + if (permission == null) { + throw new NullPointerException("permission may not be null."); + } + + this.permission = permission; + + setDataPropertyFilter(new DataPropertyFilterByPolicy()); + setObjectPropertyFilter(new ObjectPropertyFilterByPolicy()); + setDataPropertyStatementFilter(new DataPropertyStatementFilterByPolicy()); + setObjectPropertyStatementFilter(new ObjectPropertyStatementFilterByPolicy()); + } + + boolean checkAuthorization(RequestedAction whatToAuth) { + boolean decision = permission.isAuthorized(whatToAuth); + log.debug("decision is " + decision); + return decision; + } + + private class DataPropertyFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(DataProperty dp) { + return checkAuthorization(new DisplayDataProperty(dp)); + } + } + + private class ObjectPropertyFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(ObjectProperty op) { + return checkAuthorization(new DisplayObjectProperty(op)); + } + } + + private class DataPropertyStatementFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(DataPropertyStatement dps) { + return checkAuthorization(new DisplayDataPropertyStatement(dps)); + } + } + + private class ObjectPropertyStatementFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(ObjectPropertyStatement ops) { + return checkAuthorization(new DisplayObjectPropertyStatement(ops)); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java index f4f628e03..7a8a15301 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java @@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.filtering.filters; import java.text.Collator; import java.util.Collections; import java.util.Comparator; -import java.util.Date; import java.util.List; import javax.servlet.ServletContext; @@ -14,8 +13,6 @@ import net.sf.jga.fn.UnaryFunctor; import net.sf.jga.fn.adaptor.ChainUnary; import net.sf.jga.fn.property.GetProperty; import net.sf.jga.fn.string.Match; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.beans.Individual; /** * Static methods to help create commonly used filters. @@ -26,9 +23,7 @@ public class VitroFilterUtils { * public view. */ public static VitroFilters getPublicFilter(ServletContext ctx) { - return new HideFromDisplayByPolicyFilter( - new ArrayIdentifierBundle(), - new DisplayRestrictedDataByRoleLevelPolicy(ctx)); + return new FilterByRoleLevelPermission(ctx); } /** Gets a VitroFilters that permits all objects */ diff --git a/webapp/web/WEB-INF/resources/permission_config.n3 b/webapp/web/WEB-INF/resources/permission_config.n3 index 67ecf59c7..bb18ec92f 100644 --- a/webapp/web/WEB-INF/resources/permission_config.n3 +++ b/webapp/web/WEB-INF/resources/permission_config.n3 @@ -3,6 +3,7 @@ @prefix rdfs: . @prefix auth: . @prefix simplePermission: . +@prefix displayByRole: . auth:ADMIN a auth:PermissionSet ; @@ -45,6 +46,9 @@ auth:ADMIN # permissions for ANY user, even if they are not logged in. auth:hasPermission simplePermission:QueryFullModel ; + + # role-based permissions for ADMIN + auth:hasPermission displayByRole:Admin ; . auth:CURATOR @@ -76,6 +80,9 @@ auth:CURATOR # permissions for ANY user, even if they are not logged in. auth:hasPermission simplePermission:QueryFullModel ; + + # role-based permissions for CURATOR + auth:hasPermission displayByRole:Curator ; . auth:EDITOR @@ -99,6 +106,9 @@ auth:EDITOR # permissions for ANY user, even if they are not logged in. auth:hasPermission simplePermission:QueryFullModel ; + + # role-based permissions for EDITOR + auth:hasPermission displayByRole:Editor ; . auth:SELF_EDITOR @@ -116,6 +126,11 @@ auth:SELF_EDITOR # permissions for ANY user, even if they are not logged in. auth:hasPermission simplePermission:QueryFullModel ; + + # role-based permissions for SELF_EDITOR + # For role-based display, SelfEditor is like Public. + # SelfEditor uses its special permissions to edit/display its own values. + auth:hasPermission displayByRole:Public ; . auth:PUBLIC @@ -125,4 +140,7 @@ auth:PUBLIC # permissions for ANY user, even if they are not logged in. auth:hasPermission simplePermission:QueryFullModel ; + + # role-based permissions for PUBLIC + auth:hasPermission displayByRole:Public ; . diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index 5a62388c4..034242f09 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -46,7 +46,8 @@ edu.cornell.mannlib.vitro.webapp.auth.policy.RootUserPolicy$Setup edu.cornell.mannlib.vitro.webapp.auth.policy.RestrictHomeMenuItemEditingPolicy$Setup -# The Solr index uses a "public" filter, so the PropertyRestrictionPolicyHelper must already be set up. +# The Solr index uses a "public" permission, so the PropertyRestrictionPolicyHelper +# and the PermissionRegistry must already be set up. edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup @@ -54,6 +55,8 @@ edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup # On shutdown, this will kill the background thread started by Apache Commons File Upload org.apache.commons.fileupload.servlet.FileCleanerCleanup +# The VClassGroupCache index uses a "public" permission, so the PropertyRestrictionPolicyHelper +# and the PermissionRegistry must already be set up. edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache$Setup # This should be near the end, because it will issue a warning if the connection to Solr times out. From 4ddfff7018ea7d31224df242b78dcd188b9e7387 Mon Sep 17 00:00:00 2001 From: j2blake Date: Fri, 6 Jan 2012 22:39:41 +0000 Subject: [PATCH 2/4] NIHVIVO-3523 Create the EditByRolePermission, so we can use the PermissionsPolicy instead of EditRestrictedDataByRoleLevelPolicy, and these edit restrictions can be assigned to arbitrary PermissionSets. --- .../permissions/EditByRolePermission.java | 114 ++++++++++++++ .../auth/permissions/PermissionRegistry.java | 11 ++ .../EditRestrictedDataByRoleLevelPolicy.java | 147 ------------------ .../policy/setup/CommonPolicyFamilySetup.java | 2 - .../WEB-INF/resources/permission_config.n3 | 8 +- 5 files changed, 132 insertions(+), 150 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/EditRestrictedDataByRoleLevelPolicy.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java new file mode 100644 index 000000000..ece94bfae --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java @@ -0,0 +1,114 @@ +/* $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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; + +/** + * Is the user authorized to edit properties that are marked as restricted to a + * certain "Role Level"? + */ +public class EditByRolePermission extends Permission { + private static final Log log = LogFactory + .getLog(EditByRolePermission.class); + + public static final String NAMESPACE = "java:" + + EditByRolePermission.class.getName() + "#"; + + private final String roleName; + private final RoleLevel roleLevel; + private final ServletContext ctx; + + public EditByRolePermission(String roleName, RoleLevel roleLevel, + ServletContext ctx) { + super(NAMESPACE + roleName); + + if (roleName == null) { + throw new NullPointerException("role may not be null."); + } + if (roleLevel == null) { + throw new NullPointerException("roleLevel may not be null."); + } + if (ctx == null) { + throw new NullPointerException("context may not be null."); + } + + this.roleName = roleName; + this.roleLevel = roleLevel; + this.ctx = ctx; + } + + /** + * If the requested action is to edit a property statement, we might + * authorize it based on their role level. + */ + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + boolean result; + + if (whatToAuth instanceof AbstractDataPropertyAction) { + result = isAuthorized((AbstractDataPropertyAction) whatToAuth); + } else if (whatToAuth instanceof AbstractObjectPropertyAction) { + result = isAuthorized((AbstractObjectPropertyAction) whatToAuth); + } else { + result = false; + } + + if (result) { + log.debug(this + " authorizes " + whatToAuth); + } else { + log.debug(this + " does not authorize " + whatToAuth); + } + + return result; + } + + /** + * The user may add, edit, or delete this data property if they are allowed + * to modify its subject and its predicate. + */ + private boolean isAuthorized(AbstractDataPropertyAction action) { + String subjectUri = action.getSubjectUri(); + String predicateUri = action.getPredicateUri(); + return canModifyResource(subjectUri) + && canModifyPredicate(predicateUri); + } + + /** + * The user may add, edit, or delete this data property if they are allowed + * to modify its subject, its predicate, and its object. + */ + private boolean isAuthorized(AbstractObjectPropertyAction action) { + String subjectUri = action.getUriOfSubject(); + String predicateUri = action.getUriOfPredicate(); + String objectUri = action.getUriOfObject(); + return canModifyResource(subjectUri) + && canModifyPredicate(predicateUri) + && canModifyResource(objectUri); + } + + private boolean canModifyResource(String resourceUri) { + return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( + resourceUri, roleLevel); + } + + private boolean canModifyPredicate(String predicateUri) { + return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( + predicateUri, roleLevel); + } + + @Override + public String toString() { + return "EditByRolePermission['" + roleName + "']"; + } + +} 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 d539fcfbe..44461249a 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 @@ -133,6 +133,7 @@ public class PermissionRegistry { permissions.addAll(SimplePermission.getAllInstances()); permissions.addAll(createDisplayByRolePermissions(ctx)); + permissions.addAll(createEditByRolePermissions(ctx)); PermissionRegistry.createRegistry(ctx, permissions); @@ -158,6 +159,16 @@ public class PermissionRegistry { return list; } + private Collection createEditByRolePermissions( + ServletContext ctx) { + List list = new ArrayList(); + list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN, ctx)); + list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR, ctx)); + list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR, ctx)); + list.add(new EditByRolePermission("Public", RoleLevel.PUBLIC, ctx)); + return list; + } + @Override public void contextDestroyed(ServletContextEvent sce) { sce.getServletContext().removeAttribute(ATTRIBUTE_NAME); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/EditRestrictedDataByRoleLevelPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/EditRestrictedDataByRoleLevelPolicy.java deleted file mode 100644 index c8c5acb41..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/EditRestrictedDataByRoleLevelPolicy.java +++ /dev/null @@ -1,147 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - -/** - * Permit adding, editing, or deleting of various data based on the user's Role - * level and the restrictions in the ontology. - * - * This policy only authorizes users who are Editors, Curators or DBAs. - * Self-editors and users who are not logged in must look elsewhere for - * authorization. - */ -public class EditRestrictedDataByRoleLevelPolicy implements PolicyIface { - private static final Log log = LogFactory - .getLog(EditRestrictedDataByRoleLevelPolicy.class); - - private final ServletContext ctx; - - public EditRestrictedDataByRoleLevelPolicy(ServletContext ctx) { - this.ctx = ctx; - } - - /** - * If the requested action is to edit a property statement, we might - * authorize it based on their role level. - */ - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return defaultDecision("whomToAuth was null"); - } - if (whatToAuth == null) { - return defaultDecision("whatToAuth was null"); - } - - RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth); - if (!userRoleIsHighEnough(userRole)) { - return defaultDecision("insufficient role level: " + userRole); - } - - PolicyDecision result; - if (whatToAuth instanceof AbstractDataPropertyAction) { - result = isAuthorized((AbstractDataPropertyAction) whatToAuth, - userRole); - } else if (whatToAuth instanceof AbstractObjectPropertyAction) { - result = isAuthorized((AbstractObjectPropertyAction) whatToAuth, - userRole); - } else { - result = defaultDecision("Unrecognized action"); - } - - log.debug("whoToAuth: " + whoToAuth); - log.debug("decision for '" + whatToAuth + "' is " + result); - return result; - } - - /** - * We only consider Editors, Curators and DBAs. - */ - private boolean userRoleIsHighEnough(RoleLevel userRole) { - return (userRole == RoleLevel.EDITOR) - || (userRole == RoleLevel.CURATOR) - || (userRole == RoleLevel.DB_ADMIN); - } - - /** - * The user may add, edit, or delete this data property if they are allowed - * to modify its subject and its predicate. - */ - private PolicyDecision isAuthorized(AbstractDataPropertyAction action, - RoleLevel userRole) { - String subjectUri = action.getSubjectUri(); - String predicateUri = action.getPredicateUri(); - if (canModifyResource(subjectUri, userRole) - && canModifyPredicate(predicateUri, userRole)) { - return authorized("user may modify DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); - } else { - return defaultDecision("user may not modify DataPropertyStatement " - + subjectUri + " ==> " + predicateUri); - } - } - - /** - * The user may add, edit, or delete this data property if they are allowed - * to modify its subject, its predicate, and its object. - */ - private PolicyDecision isAuthorized(AbstractObjectPropertyAction action, - RoleLevel userRole) { - String subjectUri = action.getUriOfSubject(); - String predicateUri = action.getUriOfPredicate(); - String objectUri = action.getUriOfObject(); - if (canModifyResource(subjectUri, userRole) - && canModifyPredicate(predicateUri, userRole) - && canModifyResource(objectUri, userRole)) { - return authorized("user may modify ObjectPropertyStatement " - + subjectUri + " ==> " + predicateUri + " ==> " + objectUri); - } else { - return defaultDecision("user may not modify ObjectPropertyStatement " - + subjectUri + " ==> " + predicateUri + " ==> " + objectUri); - } - } - - /** If the user is explicitly authorized, return this. */ - private PolicyDecision authorized(String message) { - String className = this.getClass().getSimpleName(); - return new BasicPolicyDecision(Authorization.AUTHORIZED, className - + ": " + message); - } - - /** If the user isn't explicitly authorized, return this. */ - private PolicyDecision defaultDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); - } - - private boolean canModifyResource(String uri, RoleLevel userRole) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( - uri, userRole); - } - - private boolean canModifyPredicate(String uri, RoleLevel userRole) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - uri, userRole); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " - " + hashCode(); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index 5662e7ab6..a3df32f5e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -15,7 +15,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFact import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; -import edu.cornell.mannlib.vitro.webapp.auth.policy.EditRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; @@ -35,7 +34,6 @@ public class CommonPolicyFamilySetup implements ServletContextListener { try { policy(ctx, new PermissionsPolicy()); policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx)); - policy(ctx, new EditRestrictedDataByRoleLevelPolicy(ctx)); policy(ctx, new SelfEditingPolicy(ctx)); factory(ctx, new IsUserFactory(ctx)); diff --git a/webapp/web/WEB-INF/resources/permission_config.n3 b/webapp/web/WEB-INF/resources/permission_config.n3 index bb18ec92f..5f83f0ad6 100644 --- a/webapp/web/WEB-INF/resources/permission_config.n3 +++ b/webapp/web/WEB-INF/resources/permission_config.n3 @@ -4,6 +4,7 @@ @prefix auth: . @prefix simplePermission: . @prefix displayByRole: . +@prefix editByRole: . auth:ADMIN a auth:PermissionSet ; @@ -49,6 +50,7 @@ auth:ADMIN # role-based permissions for ADMIN auth:hasPermission displayByRole:Admin ; + auth:hasPermission editByRole:Admin ; . auth:CURATOR @@ -83,6 +85,7 @@ auth:CURATOR # role-based permissions for CURATOR auth:hasPermission displayByRole:Curator ; + auth:hasPermission editByRole:Curator ; . auth:EDITOR @@ -109,6 +112,7 @@ auth:EDITOR # role-based permissions for EDITOR auth:hasPermission displayByRole:Editor ; + auth:hasPermission editByRole:Editor ; . auth:SELF_EDITOR @@ -128,9 +132,10 @@ auth:SELF_EDITOR auth:hasPermission simplePermission:QueryFullModel ; # role-based permissions for SELF_EDITOR - # For role-based display, SelfEditor is like Public. + # For role-based display and editing, SelfEditor is like Public. # SelfEditor uses its special permissions to edit/display its own values. auth:hasPermission displayByRole:Public ; + auth:hasPermission editByRole:Public ; . auth:PUBLIC @@ -143,4 +148,5 @@ auth:PUBLIC # role-based permissions for PUBLIC auth:hasPermission displayByRole:Public ; + auth:hasPermission editByRole:Public ; . From 97a878d3c9ab5737fc685665f7b6440d7ad09307 Mon Sep 17 00:00:00 2001 From: j2blake Date: Sun, 8 Jan 2012 23:06:17 +0000 Subject: [PATCH 3/4] NIHVIVO-3523 Clean up HasRoleLevel identifier - no longer used. --- .../auth/identifier/common/HasRoleLevel.java | 52 ------------------- .../factory/HasRoleLevelFactory.java | 29 ----------- .../policy/setup/CommonPolicyFamilySetup.java | 2 - .../authenticate/LoginRedirector.java | 44 +++++++--------- .../n3editing/processEdit/EditN3Utils.java | 2 - .../controller/edit/AuthenticateTest.java | 22 ++++++-- 6 files changed, 36 insertions(+), 115 deletions(-) delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasRoleLevel.java delete mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasRoleLevel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasRoleLevel.java deleted file mode 100644 index 535ef5815..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasRoleLevel.java +++ /dev/null @@ -1,52 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.identifier.common; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - -/** - * The current user has this RoleLevel. - */ -public class HasRoleLevel extends AbstractCommonIdentifier implements Identifier { - public static Collection getIdentifiers(IdentifierBundle ids) { - return getIdentifiersForClass(ids, HasRoleLevel.class); - } - - public static Collection getRoleLevelUris(IdentifierBundle ids) { - Set set = new HashSet(); - for (HasRoleLevel id : getIdentifiers(ids)) { - set.add(id.getRoleLevel().getURI()); - } - return set; - } - - public static RoleLevel getUsersRoleLevel(IdentifierBundle whoToAuth) { - Collection roleIds = getIdentifiers(whoToAuth); - if (roleIds.isEmpty()) { - return RoleLevel.PUBLIC; - } else { - return roleIds.iterator().next().getRoleLevel(); - } - } - - private final RoleLevel roleLevel; - - public HasRoleLevel(RoleLevel roleLevel) { - this.roleLevel = roleLevel; - } - - public RoleLevel getRoleLevel() { - return roleLevel; - } - - @Override - public String toString() { - return "HasRoleLevel[" + roleLevel + "]"; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java deleted file mode 100644 index bf118184d..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - -/** - * Create an identifier that shows the role level of the current user, or - * PUBLIC if the user is not logged in. - */ -public class HasRoleLevelFactory extends BaseIdentifierBundleFactory { - - public HasRoleLevelFactory(ServletContext ctx) { - super(ctx); - } - - @Override - public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { - RoleLevel roleLevel = RoleLevel.getRoleFromLoginStatus(req); - return new ArrayIdentifierBundle(new HasRoleLevel(roleLevel)); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index a3df32f5e..b3e2d1d9f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -11,7 +11,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProfileOrIsBlacklistedFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingRightsFactory; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; @@ -38,7 +37,6 @@ public class CommonPolicyFamilySetup implements ServletContextListener { factory(ctx, new IsUserFactory(ctx)); factory(ctx, new IsRootUserFactory(ctx)); - factory(ctx, new HasRoleLevelFactory(ctx)); factory(ctx, new HasProfileOrIsBlacklistedFactory(ctx)); factory(ctx, new HasPermissionFactory(ctx)); factory(ctx, new HasProxyEditingRightsFactory(ctx)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java index db523865e..92c8cda72 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java @@ -16,11 +16,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; @@ -71,20 +68,22 @@ public class LoginRedirector { if (isSelfEditorWithIndividual()) { log.debug("Going to Individual home page."); return getAssociatedIndividualHomePage(); - } else if (isMerelySelfEditor()) { + } + + if (!canSeeSiteAdminPage()) { log.debug("User not recognized. Going to application home."); return getApplicationHomePageUrl(); + } + + if (isLoginPage(afterLoginPage)) { + log.debug("Coming from /login. Going to site admin page."); + return getSiteAdminPageUrl(); + } else if (null != afterLoginPage) { + log.debug("Returning to requested page: " + afterLoginPage); + return afterLoginPage; } else { - if (isLoginPage(afterLoginPage)) { - log.debug("Coming from /login. Going to site admin page."); - return getSiteAdminPageUrl(); - } else if (null != afterLoginPage) { - log.debug("Returning to requested page: " + afterLoginPage); - return afterLoginPage; - } else { - log.debug("Don't know what to do. Go home."); - return getApplicationHomePageUrl(); - } + log.debug("Don't know what to do. Go home."); + return getApplicationHomePageUrl(); } } @@ -113,7 +112,7 @@ public class LoginRedirector { } public String assembleWelcomeMessage() { - if (isMerelySelfEditor() && !isSelfEditorWithIndividual()) { + if (!canSeeSiteAdminPage() && !isSelfEditorWithIndividual()) { // A special message for unrecognized self-editors: return "You have logged in, " + "but the system contains no profile for you."; @@ -147,14 +146,9 @@ public class LoginRedirector { } } - private boolean isMerelySelfEditor() { - IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(request); - if (IsRootUser.isRootUser(ids)) { - return false; - } - - RoleLevel role = HasRoleLevel.getUsersRoleLevel(ids); - return role == RoleLevel.PUBLIC || role == RoleLevel.SELF; + private boolean canSeeSiteAdminPage() { + return PolicyHelper.isAuthorizedForActions(request, + SimplePermission.SEE_SITE_ADMIN_PAGE.ACTIONS); } private boolean isLoginPage(String page) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Utils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Utils.java index e8a8256b4..2f1b1bb62 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Utils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/processEdit/EditN3Utils.java @@ -12,7 +12,6 @@ import org.apache.xerces.util.XMLChar; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProfile; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; public class EditN3Utils { @@ -23,7 +22,6 @@ public class EditN3Utils { List uris = new ArrayList(); uris.addAll(IsUser.getUserUris(ids)); uris.addAll(HasProfile.getProfileUris(ids)); - uris.addAll(HasRoleLevel.getRoleLevelUris(ids)); uris.add("Unknown N3 Editor"); return uris.get(0); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java index d62993f30..0389b65ee 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java @@ -36,9 +36,13 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory; import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; @@ -125,7 +129,13 @@ public class AuthenticateTest extends AbstractTestClass { authenticator.setAssociatedUri(OLD_SELF.username, "old_self_associated_uri"); + PermissionSet adminPermissionSet = new PermissionSet(); + adminPermissionSet.setUri(URI_DBA); + adminPermissionSet.setPermissionUris(Collections + .singleton(SimplePermission.SEE_SITE_ADMIN_PAGE.getUri())); + userAccountsDao = new UserAccountsDaoStub(); + userAccountsDao.addPermissionSet(adminPermissionSet); userAccountsDao.addUser(createUserFromUserInfo(NEW_DBA)); userAccountsDao.addUser(createUserFromUserInfo(OLD_DBA)); userAccountsDao.addUser(createUserFromUserInfo(OLD_SELF)); @@ -140,6 +150,11 @@ public class AuthenticateTest extends AbstractTestClass { servletContext = new ServletContextStub(); servletContext.setAttribute("webappDaoFactory", webappDaoFactory); + setLoggerLevel(ServletPolicyList.class, Level.WARN); + ServletPolicyList.addPolicy(servletContext, new PermissionsPolicy()); + PermissionRegistry.createRegistry(servletContext, + Collections.singleton(SimplePermission.SEE_SITE_ADMIN_PAGE)); + servletConfig = new ServletConfigStub(); servletConfig.setServletContext(servletContext); @@ -153,9 +168,6 @@ public class AuthenticateTest extends AbstractTestClass { response = new HttpServletResponseStub(); - PermissionRegistry.createRegistry(servletContext, - Collections. emptySet()); - auth = new Authenticate(); auth.init(servletConfig); @@ -163,7 +175,7 @@ public class AuthenticateTest extends AbstractTestClass { new ConfigurationPropertiesStub().setBean(servletContext); ActiveIdentifierBundleFactories.addFactory(servletContext, - new HasRoleLevelFactory(servletContext)); + new HasPermissionFactory(servletContext)); } private UserAccount createUserFromUserInfo(UserInfo userInfo) { From c2f869cc453a8dcaf7735abf190893d8e0d1665e Mon Sep 17 00:00:00 2001 From: j2blake Date: Sun, 8 Jan 2012 23:20:02 +0000 Subject: [PATCH 4/4] NIHVIVO-3523 Create HasPermissionSet identifier -- not needed, but helps in diagnostics. --- .../identifier/common/HasPermissionSet.java | 74 +++++++++++++++++++ .../factory/HasPermissionSetFactory.java | 45 +++++++++++ .../policy/setup/CommonPolicyFamilySetup.java | 2 + 3 files changed, 121 insertions(+) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java new file mode 100644 index 000000000..e39273ed9 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java @@ -0,0 +1,74 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.common; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; + +/** + * The current user has this Permission, through one or more PermissionSets. + */ +public class HasPermissionSet extends AbstractCommonIdentifier implements + Identifier, Comparable { + public static Collection getIdentifiers(IdentifierBundle ids) { + return getIdentifiersForClass(ids, HasPermission.class); + } + + public static Collection getPermissions(IdentifierBundle ids) { + Set set = new HashSet(); + for (HasPermission id : getIdentifiers(ids)) { + set.add(id.getPermission()); + } + return set; + } + + private final PermissionSet permissionSet; // never null + + public HasPermissionSet(PermissionSet permissionSet) { + if (permissionSet == null) { + throw new NullPointerException("permissionSet may not be null."); + } + this.permissionSet = permissionSet; + } + + public PermissionSet getPermissionSet() { + return permissionSet; + } + + @Override + public String toString() { + return "HasPermissionSet[" + permissionSet.getLabel() + "]"; + } + + @Override + public int hashCode() { + return permissionSet.getUri().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof HasPermissionSet)) { + return false; + } + HasPermissionSet that = (HasPermissionSet) obj; + return this.permissionSet.getUri().equals(that.permissionSet.getUri()); + } + + @Override + public int compareTo(HasPermissionSet that) { + return this.permissionSet.getUri().compareTo( + that.permissionSet.getUri()); + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java new file mode 100644 index 000000000..4d4b397d0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java @@ -0,0 +1,45 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Figure out what PermissionSets the user is entitled to have. + */ +public class HasPermissionSetFactory extends BaseIdentifierBundleFactory { + private static final Log log = LogFactory + .getLog(HasPermissionFactory.class); + + public HasPermissionSetFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + IdentifierBundle ids = new ArrayIdentifierBundle(); + UserAccount user = LoginStatusBean.getCurrentUser(req); + if (user != null) { + + for (String psUri: user.getPermissionSetUris()) { + PermissionSet ps = uaDao.getPermissionSetByUri(psUri); + if (ps != null) { + ids.add(new HasPermissionSet(ps)); + } + } + } + return ids; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index b3e2d1d9f..729ee4ad0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -9,6 +9,7 @@ import javax.servlet.ServletContextListener; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionSetFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProfileOrIsBlacklistedFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingRightsFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; @@ -38,6 +39,7 @@ public class CommonPolicyFamilySetup implements ServletContextListener { factory(ctx, new IsUserFactory(ctx)); factory(ctx, new IsRootUserFactory(ctx)); factory(ctx, new HasProfileOrIsBlacklistedFactory(ctx)); + factory(ctx, new HasPermissionSetFactory(ctx)); factory(ctx, new HasPermissionFactory(ctx)); factory(ctx, new HasProxyEditingRightsFactory(ctx)); } catch (Exception e) {