NIHVIVO-3523 Create the EditByRolePermission, so we can use the PermissionsPolicy instead of EditRestrictedDataByRoleLevelPolicy, and these edit restrictions can be assigned to arbitrary PermissionSets.

This commit is contained in:
j2blake 2012-01-06 22:39:41 +00:00
parent ffafc5f3e0
commit 4ddfff7018
5 changed files with 132 additions and 150 deletions

View file

@ -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 + "']";
}
}

View file

@ -133,6 +133,7 @@ public class PermissionRegistry {
permissions.addAll(SimplePermission.getAllInstances()); permissions.addAll(SimplePermission.getAllInstances());
permissions.addAll(createDisplayByRolePermissions(ctx)); permissions.addAll(createDisplayByRolePermissions(ctx));
permissions.addAll(createEditByRolePermissions(ctx));
PermissionRegistry.createRegistry(ctx, permissions); PermissionRegistry.createRegistry(ctx, permissions);
@ -158,6 +159,16 @@ public class PermissionRegistry {
return list; return list;
} }
private Collection<Permission> createEditByRolePermissions(
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>();
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 @Override
public void contextDestroyed(ServletContextEvent sce) { public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME); sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);

View file

@ -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();
}
}

View file

@ -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.IsRootUserFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; 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.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.PermissionsPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
@ -35,7 +34,6 @@ public class CommonPolicyFamilySetup implements ServletContextListener {
try { try {
policy(ctx, new PermissionsPolicy()); policy(ctx, new PermissionsPolicy());
policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx)); policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx));
policy(ctx, new EditRestrictedDataByRoleLevelPolicy(ctx));
policy(ctx, new SelfEditingPolicy(ctx)); policy(ctx, new SelfEditingPolicy(ctx));
factory(ctx, new IsUserFactory(ctx)); factory(ctx, new IsUserFactory(ctx));

View file

@ -4,6 +4,7 @@
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> . @prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
@prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> . @prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
@prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> . @prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> .
@prefix editByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.EditByRolePermission#> .
auth:ADMIN auth:ADMIN
a auth:PermissionSet ; a auth:PermissionSet ;
@ -49,6 +50,7 @@ auth:ADMIN
# role-based permissions for ADMIN # role-based permissions for ADMIN
auth:hasPermission displayByRole:Admin ; auth:hasPermission displayByRole:Admin ;
auth:hasPermission editByRole:Admin ;
. .
auth:CURATOR auth:CURATOR
@ -83,6 +85,7 @@ auth:CURATOR
# role-based permissions for CURATOR # role-based permissions for CURATOR
auth:hasPermission displayByRole:Curator ; auth:hasPermission displayByRole:Curator ;
auth:hasPermission editByRole:Curator ;
. .
auth:EDITOR auth:EDITOR
@ -109,6 +112,7 @@ auth:EDITOR
# role-based permissions for EDITOR # role-based permissions for EDITOR
auth:hasPermission displayByRole:Editor ; auth:hasPermission displayByRole:Editor ;
auth:hasPermission editByRole:Editor ;
. .
auth:SELF_EDITOR auth:SELF_EDITOR
@ -128,9 +132,10 @@ auth:SELF_EDITOR
auth:hasPermission simplePermission:QueryFullModel ; auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for SELF_EDITOR # 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. # SelfEditor uses its special permissions to edit/display its own values.
auth:hasPermission displayByRole:Public ; auth:hasPermission displayByRole:Public ;
auth:hasPermission editByRole:Public ;
. .
auth:PUBLIC auth:PUBLIC
@ -143,4 +148,5 @@ auth:PUBLIC
# role-based permissions for PUBLIC # role-based permissions for PUBLIC
auth:hasPermission displayByRole:Public ; auth:hasPermission displayByRole:Public ;
auth:hasPermission editByRole:Public ;
. .