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 ; .