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:
parent
ffafc5f3e0
commit
4ddfff7018
5 changed files with 132 additions and 150 deletions
|
@ -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 + "']";
|
||||
}
|
||||
|
||||
}
|
|
@ -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<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
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
|
||||
@prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
|
||||
@prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> .
|
||||
@prefix editByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.EditByRolePermission#> .
|
||||
|
||||
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 ;
|
||||
.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue