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 index dd96aedac..a3df82419 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java @@ -2,12 +2,10 @@ 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.policy.bean.PropertyRestrictionBean; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; @@ -30,10 +28,8 @@ public class DisplayByRolePermission extends Permission { private final String roleName; private final RoleLevel roleLevel; - private final ServletContext ctx; - public DisplayByRolePermission(String roleName, RoleLevel roleLevel, - ServletContext ctx) { + public DisplayByRolePermission(String roleName, RoleLevel roleLevel) { super(NAMESPACE + roleName); if (roleName == null) { @@ -42,13 +38,9 @@ public class DisplayByRolePermission extends Permission { 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 @@ -110,22 +102,21 @@ public class DisplayByRolePermission extends Permission { * subject, its predicate, and its object. */ private boolean isAuthorized(DisplayObjectPropertyStatement action) { - String subjectUri = action.getSubjectUri(); + String subjectUri = action.getSubjectUri(); String objectUri = action.getObjectUri(); Property op = action.getProperty(); - return canDisplayResource(subjectUri) - && canDisplayPredicate(op) + return canDisplayResource(subjectUri) && canDisplayPredicate(op) && canDisplayResource(objectUri); } private boolean canDisplayResource(String resourceUri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( + return PropertyRestrictionBean.getBean().canDisplayResource( resourceUri, this.roleLevel); } private boolean canDisplayPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(predicate, this.roleLevel); + return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate, + this.roleLevel); } @Override 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 index 6c4bb7a24..263815bd2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java @@ -2,12 +2,10 @@ 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.policy.bean.PropertyRestrictionBean; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; @@ -27,10 +25,8 @@ public class EditByRolePermission extends Permission { private final String roleName; private final RoleLevel roleLevel; - private final ServletContext ctx; - public EditByRolePermission(String roleName, RoleLevel roleLevel, - ServletContext ctx) { + public EditByRolePermission(String roleName, RoleLevel roleLevel) { super(NAMESPACE + roleName); if (roleName == null) { @@ -39,13 +35,9 @@ public class EditByRolePermission extends Permission { 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; } /** @@ -80,8 +72,7 @@ public class EditByRolePermission extends Permission { private boolean isAuthorized(AbstractDataPropertyStatementAction action) { String subjectUri = action.getSubjectUri(); Property predicate = action.getPredicate(); - return canModifyResource(subjectUri) - && canModifyPredicate(predicate); + return canModifyResource(subjectUri) && canModifyPredicate(predicate); } /** @@ -92,19 +83,18 @@ public class EditByRolePermission extends Permission { String subjectUri = action.getSubjectUri(); Property predicate = action.getPredicate(); String objectUri = action.getObjectUri(); - return canModifyResource(subjectUri) - && canModifyPredicate(predicate) + return canModifyResource(subjectUri) && canModifyPredicate(predicate) && canModifyResource(objectUri); } private boolean canModifyResource(String resourceUri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( - resourceUri, roleLevel); + return PropertyRestrictionBean.getBean().canModifyResource(resourceUri, + roleLevel); } private boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - predicate, roleLevel); + return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, + roleLevel); } @Override 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 1a050608f..be496700a 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 @@ -150,9 +150,9 @@ public class PermissionRegistry { List permissions = new ArrayList(); permissions.addAll(SimplePermission.getAllInstances()); - permissions.addAll(createDisplayByRolePermissions(ctx)); - permissions.addAll(createEditByRolePermissions(ctx)); - permissions.addAll(createPublishByRolePermissions(ctx)); + permissions.addAll(createDisplayByRolePermissions()); + permissions.addAll(createEditByRolePermissions()); + permissions.addAll(createPublishByRolePermissions()); PermissionRegistry.createRegistry(ctx, permissions); @@ -169,17 +169,12 @@ public class PermissionRegistry { * same rights as PUBLIC. Other permissions give them their self-editing * privileges. */ - private Collection createDisplayByRolePermissions( - ServletContext ctx) { + private Collection createDisplayByRolePermissions() { 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)); + list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN)); + list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR)); + list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR)); + list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC)); return list; } @@ -191,12 +186,11 @@ public class PermissionRegistry { * * Other permissions give self-editors their editing privileges. */ - private Collection createEditByRolePermissions( - ServletContext ctx) { + private Collection createEditByRolePermissions() { 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("Admin", RoleLevel.DB_ADMIN)); + list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR)); + list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR)); return list; } @@ -210,17 +204,12 @@ public class PermissionRegistry { * same rights as PUBLIC. Other permissions give them their self-editing * privileges. */ - private Collection createPublishByRolePermissions( - ServletContext ctx) { + private Collection createPublishByRolePermissions() { List list = new ArrayList(); - list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN, - ctx)); - list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR, - ctx)); - list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR, - ctx)); - list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC, - ctx)); + list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN)); + list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR)); + list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR)); + list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC)); return list; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java index e587742a7..9942cfa88 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java @@ -2,12 +2,10 @@ 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.policy.bean.PropertyRestrictionBean; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement; @@ -29,10 +27,8 @@ public class PublishByRolePermission extends Permission { private final String roleName; private final RoleLevel roleLevel; - private final ServletContext ctx; - public PublishByRolePermission(String roleName, RoleLevel roleLevel, - ServletContext ctx) { + public PublishByRolePermission(String roleName, RoleLevel roleLevel) { super(NAMESPACE + roleName); if (roleName == null) { @@ -41,13 +37,9 @@ public class PublishByRolePermission extends Permission { 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 @@ -116,13 +108,13 @@ public class PublishByRolePermission extends Permission { } private boolean canPublishResource(String resourceUri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canPublishResource( + return PropertyRestrictionBean.getBean().canPublishResource( resourceUri, this.roleLevel); } private boolean canPublishPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx) - .canPublishPredicate(predicate, this.roleLevel); + return PropertyRestrictionBean.getBean().canPublishPredicate(predicate, + this.roleLevel); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java index 326ee93ef..e072f183a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java @@ -4,7 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy; import javax.servlet.ServletContext; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; 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.beans.BaseResourceBean.RoleLevel; @@ -23,13 +23,13 @@ public abstract class BaseSelfEditingPolicy { } protected boolean canModifyResource(String uri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( - uri, roleLevel); + return PropertyRestrictionBean.getBean().canModifyResource(uri, + roleLevel); } protected boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - predicate, roleLevel); + return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, + roleLevel); } protected PolicyDecision cantModifyResource(String uri) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java index d0e411be0..57cfa0aa6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java @@ -11,7 +11,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; 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; @@ -114,14 +114,18 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { String subjectUri = action.getSubjectUri(); Property predicate = action.getProperty(); String objectUri = action.getObjectUri(); - if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate) + if (canDisplayResource(subjectUri) + && canDisplayPredicate(predicate) && canDisplayResource(objectUri) - && isAboutAssociatedIndividual(individuals, subjectUri, objectUri)) { + && isAboutAssociatedIndividual(individuals, subjectUri, + objectUri)) { return authorized("user may view ObjectPropertyStatement " - + subjectUri + " ==> " + predicate.getURI() + " ==> " + objectUri); + + subjectUri + " ==> " + predicate.getURI() + " ==> " + + objectUri); } else { return defaultDecision("user may not view ObjectPropertyStatement " - + subjectUri + " ==> " + predicate.getURI() + " ==> " + objectUri); + + subjectUri + " ==> " + predicate.getURI() + " ==> " + + objectUri); } } @@ -138,13 +142,13 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { } private boolean canDisplayResource(String uri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( - uri, RoleLevel.SELF); + return PropertyRestrictionBean.getBean().canDisplayResource(uri, + RoleLevel.SELF); } private boolean canDisplayPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(predicate, RoleLevel.SELF); + return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate, + RoleLevel.SELF); } private boolean isAboutAssociatedIndividual(Collection selves, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java new file mode 100644 index 000000000..517fb84fd --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java @@ -0,0 +1,207 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import java.util.Arrays; +import java.util.Collection; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +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.beans.Property; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + +/** + * Assists the role-based policies in determining whether a property or resource + * may be displayed, modified, or published in linked open data. + * + * There is a singleton bean that holds the current threshold role levels for + * displaying, modifying, or publishing restricted properties. + * + * Create this bean after the context models are in place. + * + * Add PropertyRestrictionListener to your EditProcessObject if you are editing + * a property, to ensure that the bean stays current. + */ +public abstract class PropertyRestrictionBean { + private static final Log log = LogFactory + .getLog(PropertyRestrictionBean.class); + + private static final PropertyRestrictionBean NULL = new PropertyRestrictionBeanNull(); + + protected static volatile PropertyRestrictionBean instance = NULL; + + protected static final Collection PROHIBITED_NAMESPACES = Arrays + .asList(new String[] { VitroVocabulary.vitroURI, "" }); + + protected static final Collection PERMITTED_EXCEPTIONS = Arrays + .asList(new String[] { VitroVocabulary.MONIKER, + VitroVocabulary.MODTIME, VitroVocabulary.IND_MAIN_IMAGE, + VitroVocabulary.LINK, VitroVocabulary.PRIMARY_LINK, + VitroVocabulary.ADDITIONAL_LINK, + VitroVocabulary.LINK_ANCHOR, VitroVocabulary.LINK_URL }); + + // ---------------------------------------------------------------------- + // static methods + // ---------------------------------------------------------------------- + + public static PropertyRestrictionBean getBean() { + return instance; + } + + // ---------------------------------------------------------------------- + // instance methods + // ---------------------------------------------------------------------- + + /** + * Any resource can be displayed. + * + * (Someday we may want to implement display restrictions based on VClass.) + */ + public abstract boolean canDisplayResource(String resourceUri, + RoleLevel userRole); + + /** + * A resource cannot be modified if its namespace is in the prohibited list + * (but some exceptions are allowed). + * + * (Someday we may want to implement modify restrictions based on VClass.) + */ + public abstract boolean canModifyResource(String resourceUri, + RoleLevel userRole); + + /** + * Any resource can be published. + * + * (Someday we may want to implement publish restrictions based on VClass.) + */ + public abstract boolean canPublishResource(String resourceUri, + RoleLevel userRole); + + /** + * If display of a predicate is restricted, the user's role must be at least + * as high as the restriction level. + */ + public abstract boolean canDisplayPredicate(Property predicate, + RoleLevel userRole); + + /** + * A predicate cannot be modified if its namespace is in the prohibited list + * (some exceptions are allowed). + * + * If modification of a predicate is restricted, the user's role must be at + * least as high as the restriction level. + */ + public abstract boolean canModifyPredicate(Property predicate, + RoleLevel userRole); + + /** + * If publishing of a predicate is restricted, the user's role must be at + * least as high as the restriction level. + */ + public abstract boolean canPublishPredicate(Property predicate, + RoleLevel userRole); + + /** + * The threshold values for this property may have changed. + */ + public abstract void updateProperty(PropertyRestrictionLevels levels); + + // ---------------------------------------------------------------------- + // The null implementation + // ---------------------------------------------------------------------- + + /** + * A placeholder for when the bean instance is not set. + */ + private static class PropertyRestrictionBeanNull extends + PropertyRestrictionBean { + @Override + public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { + warn(); + return false; + } + + @Override + public boolean canModifyResource(String resourceUri, RoleLevel userRole) { + warn(); + return false; + } + + @Override + public boolean canPublishResource(String resourceUri, RoleLevel userRole) { + warn(); + return false; + } + + @Override + public boolean canDisplayPredicate(Property predicate, + RoleLevel userRole) { + warn(); + return false; + } + + @Override + public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { + warn(); + return false; + } + + @Override + public boolean canPublishPredicate(Property predicate, + RoleLevel userRole) { + warn(); + return false; + } + + @Override + public void updateProperty(PropertyRestrictionLevels levels) { + warn(); + } + + private void warn() { + try { + throw new IllegalStateException(); + } catch (IllegalStateException e) { + log.warn("No PropertyRestrictionBean in place.", e); + } + } + } + + // ---------------------------------------------------------------------- + // Setup class + // ---------------------------------------------------------------------- + + /** + * Create the bean at startup and remove it at shutdown. + */ + public static class Setup implements ServletContextListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + + try { + instance = new PropertyRestrictionBeanImpl( + PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, + ModelAccess.on(ctx)); + } catch (Exception e) { + ss.fatal(this, + "could not set up PropertyRestrictionBean", e); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + instance = NULL; + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java new file mode 100644 index 000000000..4681de664 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java @@ -0,0 +1,252 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.MODIFY; +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.PUBLISH; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.rdf.model.impl.Util; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; + +/** + * On creation, populate a map of PropertyRestrictionLevels. + * + * When a change is detected, update the map accordingly. + * + * ------------------------------ + * + * How is authorization determined? + * + * Resources are easy. If they aren't in a prohibited namespace, or are an + * exception to the prohibition, they are accessible. + * + * Properties are harder. The prohibited namespace and exceptions still apply, + * but if we pass that test, then we check the threshold map. + * + * When a test is made, we look for thresholds in the map. First we look for the + * full key of domain-base-range, in case we are testing a faux property. Faux + * properties are recorded in the map with the full key. + * + * If we don't find the full key, then perhaps we are testing a faux property + * that has no settings, or perhaps we are testing an object property. We look + * for the partial key of null-base-null, which covers both of these cases, + * since object properties (and data properties) are recorded the map with a + * partial key. + * + * Similarly, if we find a null threshold value in the full key, we look back to + * the partial key for a threshold. + * + * If we find no non-null threshold value then the property is unrestricted for + * that feature. + * + * ----------------------------- + * + * It would perhaps be a silly optimization, but if we find a key with 3 null + * thresholds, we could remove it from the map without changing the behavior. + */ +public class PropertyRestrictionBeanImpl extends PropertyRestrictionBean { + private static final Log log = LogFactory + .getLog(PropertyRestrictionBeanImpl.class); + + private final Set prohibitedNamespaces; + private final Set permittedExceptions; + + private final Map thresholdMap = new ConcurrentHashMap<>(); + + public PropertyRestrictionBeanImpl(Collection prohibitedNamespaces, + Collection permittedExceptions, ContextModelAccess models) { + Objects.requireNonNull(prohibitedNamespaces, + "prohibitedNamespaces may not be null."); + this.prohibitedNamespaces = Collections.unmodifiableSet(new TreeSet<>( + prohibitedNamespaces)); + + Objects.requireNonNull(permittedExceptions, + "permittedExceptions may not be null."); + this.permittedExceptions = Collections.unmodifiableSet(new TreeSet<>( + permittedExceptions)); + + Objects.requireNonNull(models, "models may not be null."); + populateThresholdMap(models.getWebappDaoFactory()); + } + + private void populateThresholdMap(WebappDaoFactory wadf) { + for (ObjectProperty oProp : wadf.getObjectPropertyDao() + .getAllObjectProperties()) { + addObjectPropertyToMap(oProp); + for (FauxProperty fProp : wadf.getFauxPropertyDao() + .getFauxPropertiesForBaseUri(oProp.getURI())) { + addFauxPropertyToMap(fProp); + } + } + for (DataProperty dProp : wadf.getDataPropertyDao() + .getAllDataProperties()) { + addDataPropertyToMap(dProp); + } + } + + private void addObjectPropertyToMap(ObjectProperty oProp) { + FullPropertyKey key = new FullPropertyKey(oProp.getURI()); + PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, + oProp.getHiddenFromDisplayBelowRoleLevel(), + oProp.getProhibitedFromUpdateBelowRoleLevel(), + oProp.getHiddenFromPublishBelowRoleLevel()); + thresholdMap.put(key, levels); + } + + private void addFauxPropertyToMap(FauxProperty fProp) { + FullPropertyKey key = new FullPropertyKey(fProp.getDomainURI(), + fProp.getBaseURI(), fProp.getRangeURI()); + PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, + fProp.getHiddenFromDisplayBelowRoleLevel(), + fProp.getProhibitedFromUpdateBelowRoleLevel(), + fProp.getHiddenFromPublishBelowRoleLevel()); + thresholdMap.put(key, levels); + } + + private void addDataPropertyToMap(DataProperty dProp) { + FullPropertyKey key = new FullPropertyKey(dProp.getURI()); + PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, + dProp.getHiddenFromDisplayBelowRoleLevel(), + dProp.getProhibitedFromUpdateBelowRoleLevel(), + dProp.getHiddenFromPublishBelowRoleLevel()); + thresholdMap.put(key, levels); + } + + @Override + public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { + return (resourceUri != null) && (userRole != null); + } + + @Override + public boolean canModifyResource(String resourceUri, RoleLevel userRole) { + if (resourceUri == null || userRole == null) { + return false; + } + if (prohibitedNamespaces.contains(namespace(resourceUri)) + && !permittedExceptions.contains(resourceUri)) { + return false; + } + return true; + } + + @Override + public boolean canPublishResource(String resourceUri, RoleLevel userRole) { + return (resourceUri != null) && (userRole != null); + } + + @Override + public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { + if (predicate == null || predicate.getURI() == null) { + return false; + } + return isAuthorized(userRole, getThreshold(predicate, DISPLAY)); + } + + @Override + public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { + if (predicate == null || predicate.getURI() == null) { + return false; + } + return isAuthorized(userRole, getPropertyModifyThreshold(predicate)); + } + + @Override + public boolean canPublishPredicate(Property predicate, RoleLevel userRole) { + if (predicate == null || predicate.getURI() == null) { + return false; + } + return isAuthorized(userRole, getThreshold(predicate, PUBLISH)); + } + + @Override + public void updateProperty(PropertyRestrictionLevels levels) { + thresholdMap.put(levels.getKey(), levels); + } + + private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) { + if (userRole == null) { + return false; + } + if (thresholdRole == null) { + return true; + } + return userRole.compareTo(thresholdRole) >= 0; + } + + private RoleLevel getPropertyModifyThreshold(Property p) { + if (prohibitedNamespaces.contains(namespace(p.getURI())) + && !permittedExceptions.contains(p.getURI())) { + return RoleLevel.NOBODY; + } + return getThreshold(p, MODIFY); + } + + private RoleLevel getThreshold(Property p, Which which) { + RoleLevel qualifiedLevel = getThreshold(new FullPropertyKey(p), which); + if (qualifiedLevel != null) { + return qualifiedLevel; + } + + RoleLevel bareLevel = getThreshold(new FullPropertyKey(p.getURI()), + which); + return bareLevel; + } + + private RoleLevel getThreshold(FullPropertyKey key, Which which) { + PropertyRestrictionLevels levels = thresholdMap.get(key); + if (levels == null) { + return null; + } else { + return levels.getLevel(which); + } + } + + private String namespace(String uri) { + return uri.substring(0, Util.splitNamespace(uri)); + } + + @Override + public String toString() { + SortedSet keys = new TreeSet<>( + new Comparator() { + @Override + public int compare(FullPropertyKey o1, FullPropertyKey o2) { + return o1.toString().compareTo(o2.toString()); + } + }); + keys.addAll(thresholdMap.keySet()); + + StringBuilder buffer = new StringBuilder(); + for (FullPropertyKey key : keys) { + buffer.append(key + " " + thresholdMap.get(key).getLevel(DISPLAY) + + " " + thresholdMap.get(key).getLevel(MODIFY) + " " + + thresholdMap.get(key).getLevel(PUBLISH) + "\n"); + } + return buffer.toString(); + + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java new file mode 100644 index 000000000..a5f4711a8 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java @@ -0,0 +1,68 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; + +/** + * The threshold levels for operations on a given property. + * + * This is based on the assumption that the FullPropertyKey is sufficient to + * distinguish all properties. An object property and a data property may not + * share the same key. A faux property must have a different key from any object + * property. + */ +public class PropertyRestrictionLevels { + private final FullPropertyKey key; + private final RoleLevel displayThreshold; + private final RoleLevel modifyThreshold; + private final RoleLevel publishThreshold; + + public enum Which { + DISPLAY, MODIFY, PUBLISH + } + + public PropertyRestrictionLevels(FullPropertyKey key, + RoleRestrictedProperty p) { + this(key, p.getHiddenFromDisplayBelowRoleLevel(), p + .getProhibitedFromUpdateBelowRoleLevel(), p + .getHiddenFromPublishBelowRoleLevel()); + } + + public PropertyRestrictionLevels(FullPropertyKey key, + RoleLevel displayThreshold, RoleLevel modifyThreshold, + RoleLevel publishThreshold) { + this.key = key; + this.displayThreshold = displayThreshold; + this.modifyThreshold = modifyThreshold; + this.publishThreshold = publishThreshold; + } + + public FullPropertyKey getKey() { + return key; + } + + public RoleLevel getLevel(Which which) { + if (which == null) { + return null; + } else { + switch (which) { + case DISPLAY: + return displayThreshold; + case MODIFY: + return modifyThreshold; + default: + return publishThreshold; + } + } + } + + @Override + public String toString() { + return "PropertyRestrictionLevels[key=" + key + ", display=" + + displayThreshold + ", modify=" + modifyThreshold + + ", publish=" + publishThreshold + "]"; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java index 97b1f359a..f6997825a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java @@ -2,20 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; - -import javax.servlet.ServletContext; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.Model; - import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.listener.ChangeListener; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; /** * Add this ChangeListener to your EditProcessObject when modifying the @@ -26,12 +18,6 @@ public class PropertyRestrictionListener implements ChangeListener { private static final Log log = LogFactory .getLog(PropertyRestrictionListener.class); - private final ServletContext ctx; - - public PropertyRestrictionListener(ServletContext ctx) { - this.ctx = ctx; - } - /** * If the deleted property had a non-null restriction, rebuild the bean. */ @@ -39,84 +25,43 @@ public class PropertyRestrictionListener implements ChangeListener { public void doDeleted(Object oldObj, EditProcessObject epo) { if (oldObj instanceof RoleRestrictedProperty) { RoleRestrictedProperty p = (RoleRestrictedProperty) oldObj; - if (anyRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(), - p.getProhibitedFromUpdateBelowRoleLevel(), - p.getHiddenFromPublishBelowRoleLevel(), null, null, null)) { - log.debug("rebuilding the PropertyRestrictionPolicyHelper after deletion"); - createAndSetBean(); - } + FullPropertyKey key = new FullPropertyKey(p); + updateLevels(new PropertyRestrictionLevels(key, p)); } else { log.warn("Not an instance of RoleRestrictedProperty: " + oldObj); } } /** - * If the inserted property has a non-null restriction, rebuild the bean. + * Update the inserted property. */ @Override public void doInserted(Object newObj, EditProcessObject epo) { if (newObj instanceof RoleRestrictedProperty) { RoleRestrictedProperty p = (RoleRestrictedProperty) newObj; - if (anyRoleChanged(null, null, null, - p.getHiddenFromDisplayBelowRoleLevel(), - p.getProhibitedFromUpdateBelowRoleLevel(), - p.getHiddenFromPublishBelowRoleLevel())) { - log.debug("rebuilding the PropertyRestrictionPolicyHelper after insertion"); - createAndSetBean(); - } + FullPropertyKey key = new FullPropertyKey(p); + updateLevels(new PropertyRestrictionLevels(key, p)); } else { log.warn("Not an instance of RoleRestrictedProperty: " + newObj); } } /** - * If the updated property has changed its restrictions, rebuild the bean. + * Update the changed property. */ @Override public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { - if (oldObj instanceof RoleRestrictedProperty - && newObj instanceof RoleRestrictedProperty) { - RoleRestrictedProperty oldP = (RoleRestrictedProperty) oldObj; + if (newObj instanceof RoleRestrictedProperty) { RoleRestrictedProperty newP = (RoleRestrictedProperty) newObj; - if (anyRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(), - oldP.getProhibitedFromUpdateBelowRoleLevel(), - oldP.getHiddenFromPublishBelowRoleLevel(), - newP.getHiddenFromDisplayBelowRoleLevel(), - newP.getProhibitedFromUpdateBelowRoleLevel(), - newP.getHiddenFromPublishBelowRoleLevel())) { - log.debug("rebuilding the PropertyRestrictionPolicyHelper after update"); - createAndSetBean(); - } + FullPropertyKey key = new FullPropertyKey(newP); + updateLevels(new PropertyRestrictionLevels(key, newP)); } else { log.warn("Not instances of RoleRestrictedProperty: " + oldObj + ", " + newObj); } } - private boolean anyRoleChanged(RoleLevel oldDisplayRole, - RoleLevel oldUpdateRole, RoleLevel oldPublishRole, - RoleLevel newDisplayRole, RoleLevel newUpdateRole, - RoleLevel newPublishRole) { - return (!isTheSame(oldDisplayRole, newDisplayRole)) - || (!isTheSame(oldUpdateRole, newUpdateRole)) - || (!isTheSame(oldPublishRole, newPublishRole)); - } - - private boolean isTheSame(RoleLevel oldRole, RoleLevel newRole) { - if ((oldRole == null) && (newRole == null)) { - return true; - } else if ((oldRole == null) || (newRole == null)) { - return false; - } else { - return oldRole.compareTo(newRole) == 0; - } - } - - private void createAndSetBean() { - OntModel model = ModelAccess.on(ctx).getOntModel(); - Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY); - PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper - .createBean(model, displayModel); - PropertyRestrictionPolicyHelper.setBean(ctx, bean); + private void updateLevels(PropertyRestrictionLevels levels) { + PropertyRestrictionBean.getBean().updateProperty(levels); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java deleted file mode 100644 index 6e8d5637a..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ /dev/null @@ -1,498 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.rdf.model.impl.Util; -import com.hp.hpl.jena.shared.Lock; - -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; -import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; -import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils; - -/** - * Assists the role-based policies in determining whether a property or resource - * may be displayed, modified, or published in linked open data. - * - * There is a bean in the context that holds the current threshold role levels - * for displaying, modifying, or publishing restricted properties. - * - * Create this bean after the Jena model is in place in the context. - * - * Add PropertyRestrictionListener to your EditProcessObject if you are editing - * a property, to ensure that the bean stays current. - */ -public class PropertyRestrictionPolicyHelper { - private static final Log log = LogFactory - .getLog(PropertyRestrictionPolicyHelper.class); - - private static final Collection PROHIBITED_NAMESPACES = Arrays - .asList(new String[] { VitroVocabulary.vitroURI, "" }); - - private static final Collection PERMITTED_EXCEPTIONS = Arrays - .asList(new String[] { - VitroVocabulary.MONIKER, - VitroVocabulary.MODTIME, - - VitroVocabulary.IND_MAIN_IMAGE, - - VitroVocabulary.LINK, - VitroVocabulary.PRIMARY_LINK, - VitroVocabulary.ADDITIONAL_LINK, - VitroVocabulary.LINK_ANCHOR, - VitroVocabulary.LINK_URL }); - - /** - * The bean is attached to the ServletContext using this attribute name. - */ - private static final String ATTRIBUTE_NAME = PropertyRestrictionPolicyHelper.class - .getName(); - - // ---------------------------------------------------------------------- - // static methods - // ---------------------------------------------------------------------- - - public static PropertyRestrictionPolicyHelper getBean(ServletContext ctx) { - Object attribute = ctx.getAttribute(ATTRIBUTE_NAME); - if (!(attribute instanceof PropertyRestrictionPolicyHelper)) { - throw new IllegalStateException( - "PropertyRestrictionPolicyHelper has not been initialized."); - } - return (PropertyRestrictionPolicyHelper) attribute; - } - - private static void removeBean(ServletContext ctx) { - ctx.removeAttribute(ATTRIBUTE_NAME); - } - - public static void setBean(ServletContext ctx, - PropertyRestrictionPolicyHelper bean) { - if (bean == null) { - throw new NullPointerException("bean may not be null."); - } - ctx.setAttribute(ATTRIBUTE_NAME, bean); - } - - /** - * Initialize the bean with the standard prohibitions and exceptions, and - * with the thresholds obtained from the model. - */ - public static PropertyRestrictionPolicyHelper createBean(OntModel model, - Model displayModel) { - - - Map displayThresholdMap = - new HashMap(); - Map modifyThresholdMap = - new HashMap(); - Map publishThresholdMap = - new HashMap(); - - OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, - ModelFactory.createUnion(displayModel, model)); - - - populateThresholdMap(union, displayThresholdMap, - VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); - populateThresholdMap(union, modifyThresholdMap, - VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); - populateThresholdMap(union, publishThresholdMap, - VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT); - - PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper( - PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, - displayThresholdMap, modifyThresholdMap, publishThresholdMap); - - return bean; - } - - private RoleLevel getModifyThreshold(Property property) { - return getThreshold(property, modifyThresholdMap); - } - - private RoleLevel getThreshold(Property property, - Map thresholdMap) { - if (property.getURI() == null) { - return RoleLevel.NOBODY; - } - RoleLevel roleLevel = thresholdMap.get(new FullPropertyKey(property)); - if (roleLevel == null) { - roleLevel = thresholdMap - .get(new FullPropertyKey(property.getURI())); - } - return roleLevel; - } - - /** - * Find all the resources that possess this property, and map the resource - * URI to the required RoleLevel. - */ - private static void populateThresholdMap(OntModel model, - Map map, String propertyUri) { - model.enterCriticalSection(Lock.READ); - try { - com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri); - StmtIterator stmts = model.listStatements((Resource) null, - property, (Resource) null); - try { - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - Resource subject = stmt.getSubject(); - RDFNode objectNode = stmt.getObject(); - if ((subject == null) || (!(objectNode instanceof Resource))) { - continue; - } - Resource object = (Resource) objectNode; - RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); - map.put(new FullPropertyKey(subject.getURI()), role); - } - } finally { - stmts.close(); - } - List fauxOps = ApplicationConfigurationOntologyUtils - .getAdditionalFauxSubproperties(null, null, model, model); - for (ObjectProperty faux : fauxOps) { - RoleLevel role = null; - if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT - .equals(propertyUri)) { - role = faux.getProhibitedFromUpdateBelowRoleLevel(); - } else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT - .equals(propertyUri)) { - role = faux.getHiddenFromDisplayBelowRoleLevel(); - } else if (VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT - .equals(propertyUri)) { - role = faux.getHiddenFromPublishBelowRoleLevel(); - } - if (role != null) { - FullPropertyKey key = new FullPropertyKey(faux); - map.put(key, role); - log.debug("Putting key: " + key + " ==> L:" + role); - } - } - - } finally { - model.leaveCriticalSection(); - } - } - - // ---------------------------------------------------------------------- - // the bean - // ---------------------------------------------------------------------- - - /** - * URIs in these namespaces can't be modified, unless they are listed in the - * exceptions. - */ - private final Collection modifyProhibitedNamespaces; - - /** - * These URIs can be modified, even if they are in the prohibited - * namespaces. - */ - private final Collection modifyExceptionsAllowedUris; - - /** - * These URIs can be displayed only if the user's role is at least as high - * as the threshold role. - */ - private final Map displayThresholdMap; - - /** - * These URIs can be modified only if the user's role is at least as high as - * the threshold role. - */ - private final Map modifyThresholdMap; - - /** - * These URIs can be published only if the user's role is at least as high as - * the threshold role. - */ - private final Map publishThresholdMap; - - - /** - * Store unmodifiable versions of the inputs. - * - * Protected access: the bean should only be created by the static methods, - * or by unit tests. - */ - protected PropertyRestrictionPolicyHelper( - Collection modifyProhibitedNamespaces, - Collection modifyExceptionsAllowedUris, - Map displayThresholdMap, - Map modifyThresholdMap, - Map publishThresholdMap) { - this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces); - this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris); - this.displayThresholdMap = displayThresholdMap; - this.modifyThresholdMap = modifyThresholdMap; - this.publishThresholdMap = publishThresholdMap; - // TODO: why are these no longer unmodifiable? Brian changed during the - // TODO: ISF integration. - // this.displayThresholdMap = unmodifiable(displayThresholdMap); - // this.modifyThresholdMap = unmodifiable(modifyThresholdMap); - - if (log.isDebugEnabled()) { - log.debug("prohibited: " + this.modifyProhibitedNamespaces); - log.debug("exceptions: " + this.modifyExceptionsAllowedUris); - log.debug("display thresholds: " + this.displayThresholdMap); - log.debug("modify thresholds: " + this.modifyThresholdMap); - log.debug("publish thresholds: " + this.publishThresholdMap); - } - } - - private Collection unmodifiable(Collection raw) { - if (raw == null) { - return Collections.emptyList(); - } else { - return Collections.unmodifiableCollection(new HashSet(raw)); - } - } - - @SuppressWarnings("unused") - private Map unmodifiable(Map raw) { - if (raw == null) { - return Collections.emptyMap(); - } else { - return Collections.unmodifiableMap(new HashMap( - raw)); - } - } - - /** - * Any resource can be displayed. - * - * (Someday we may want to implement display restrictions based on VClass.) - */ - @SuppressWarnings("unused") - public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { - if (resourceUri == null) { - log.debug("can't display resource: resourceUri was null"); - return false; - } - - log.debug("can display resource '" + resourceUri + "'"); - return true; - } - - /** - * A resource cannot be modified if its namespace is in the prohibited list - * (but some exceptions are allowed). - * - * (Someday we may want to implement modify restrictions based on VClass.) - */ - @SuppressWarnings("unused") - public boolean canModifyResource(String resourceUri, RoleLevel userRole) { - if (resourceUri == null) { - log.debug("can't modify resource: resourceUri was null"); - return false; - } - - if (modifyProhibitedNamespaces.contains(namespace(resourceUri))) { - if (modifyExceptionsAllowedUris.contains(resourceUri)) { - log.debug("'" + resourceUri + "' is a permitted exception"); - } else { - log.debug("can't modify resource '" + resourceUri - + "': prohibited namespace: '" + namespace(resourceUri) - + "'"); - return false; - } - } - - log.debug("can modify resource '" + resourceUri + "'"); - return true; - } - - /** - * Any resource can be published. - * - * (Someday we may want to implement publish restrictions based on VClass.) - */ - @SuppressWarnings("unused") - public boolean canPublishResource(String resourceUri, RoleLevel userRole) { - if (resourceUri == null) { - log.debug("can't publish resource: resourceUri was null"); - return false; - } - - log.debug("can publish resource '" + resourceUri + "'"); - return true; - } - - /** - * If display of a predicate is restricted, the user's role must be at least - * as high as the restriction level. - */ - public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null) { - log.debug("can't display predicate: predicate was null"); - return false; - } - - RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap); - - if (isAuthorized(userRole, displayThreshold)) { - log.debug("can display predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + displayThreshold); - return true; - } - - log.debug("can't display predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + displayThreshold); - return false; - } - - /** - * A predicate cannot be modified if its namespace is in the prohibited list - * (some exceptions are allowed). - * - * If modification of a predicate is restricted, the user's role must be at - * least as high as the restriction level. - */ - public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null || predicate.getURI() == null) { - log.debug("can't modify predicate: predicate was null"); - return false; - } - - if (modifyProhibitedNamespaces.contains(namespace(predicate.getURI()))) { - if (modifyExceptionsAllowedUris.contains(predicate.getURI())) { - log.debug("'" + predicate.getURI() + "' is a permitted exception"); - } else { - log.debug("can't modify resource '" + predicate.getURI() - + "': prohibited namespace: '" - + namespace(predicate.getURI()) + "'"); - return false; - } - } - - RoleLevel modifyThreshold = getModifyThreshold(predicate); - if (isAuthorized(userRole, modifyThreshold)) { - log.debug("can modify predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + modifyThreshold); - return true; - } - - log.debug("can't modify predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + modifyThreshold); - return false; - } - - /** - * If publishing of a predicate is restricted, the user's role must be at least - * as high as the restriction level. - */ - public boolean canPublishPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null) { - log.debug("can't publish predicate: predicate was null"); - return false; - } - - RoleLevel publishThreshold = getThreshold(predicate, publishThresholdMap); - - if (isAuthorized(userRole, publishThreshold)) { - log.debug("can publish predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + publishThreshold); - return true; - } - - log.debug("can't publish predicate: '" + predicate.getURI() + "', domain=" - + predicate.getDomainVClassURI() + ", range=" - + predicate.getRangeVClassURI() + ", userRole=" - + userRole + ", thresholdRole=" + publishThreshold); - return false; - } - - private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) { - if (userRole == null) { - return false; - } - if (thresholdRole == null) { - return true; - } - return userRole.compareTo(thresholdRole) >= 0; - } - - private String namespace(String uri) { - return uri.substring(0, Util.splitNamespace(uri)); - } - - // ---------------------------------------------------------------------- - // Setup class - // ---------------------------------------------------------------------- - - /** - * Create the bean at startup and remove it at shutdown. - */ - public static class Setup implements ServletContextListener { - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - - try { - OntModel model = ModelAccess.on(ctx).getOntModel(); - if (model == null) { - throw new NullPointerException( - "jenaOntModel has not been initialized."); - } - Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY); - if (displayModel == null) { - throw new NullPointerException( - "display model has not been initialized."); - } - - PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper - .createBean(model, displayModel); - PropertyRestrictionPolicyHelper.setBean(ctx, bean); - } catch (Exception e) { - ss.fatal(this, "could not set up PropertyRestrictionPolicyHelper", e); - } - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - removeBean(sce.getServletContext()); - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java index fb93bce16..040141c2b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java @@ -9,6 +9,12 @@ import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; * user's role level. */ public interface RoleRestrictedProperty { + String getDomainVClassURI(); + + String getRangeVClassURI(); + + String getURI(); + RoleLevel getHiddenFromDisplayBelowRoleLevel(); RoleLevel getProhibitedFromUpdateBelowRoleLevel(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java index 359c646b2..e388c65ad 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java @@ -8,7 +8,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; 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; @@ -31,13 +31,13 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface { } protected boolean canModifyResource(String uri) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource( - uri, RoleLevel.SELF); + return PropertyRestrictionBean.getBean().canModifyResource(uri, + RoleLevel.SELF); } protected boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( - predicate, RoleLevel.SELF); + return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, + RoleLevel.SELF); } protected PolicyDecision cantModifyResource(String uri) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java index f5f9c9b3e..2d868520a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java @@ -233,4 +233,18 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean, + ", customEntryForm=" + customEntryForm + ", customListView=" + customListView + "]"; } + + // ---------------------------------------------------------------------- + // Satisfy the RoleRestrictedProperty interface. + // ---------------------------------------------------------------------- + + @Override + public String getDomainVClassURI() { + return getDomainURI(); + } + + @Override + public String getRangeVClassURI() { + return getRangeURI(); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java index ec3759041..115f84f74 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java @@ -34,9 +34,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class DatapropRetryController extends BaseEditController { @@ -124,7 +124,7 @@ public class DatapropRetryController extends BaseEditController { //set up any listeners List changeListenerList = new ArrayList(); - changeListenerList.add(new PropertyRestrictionListener(getServletContext())); + changeListenerList.add(new PropertyRestrictionListener()); epo.setChangeListenerList(changeListenerList); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java index 9c6cdfd3a..7516ac914 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/FauxPropertyRetryController.java @@ -211,7 +211,7 @@ public class FauxPropertyRetryController extends BaseEditController { private void setListeners() { epo.setChangeListenerList(Collections - .singletonList(new PropertyRestrictionListener(ctx))); + .singletonList(new PropertyRestrictionListener())); } private void setForwarders() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java index 2b2ed1a77..63c2a2e15 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/PropertyRetryController.java @@ -33,9 +33,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; public class PropertyRetryController extends BaseEditController { @@ -115,7 +115,7 @@ public class PropertyRetryController extends BaseEditController { //set up any listeners List changeListenerList = new ArrayList<>(); - changeListenerList.add(new PropertyRestrictionListener(getServletContext())); + changeListenerList.add(new PropertyRestrictionListener()); epo.setChangeListenerList(changeListenerList); //make a postinsert pageforwarder that will send us to a new class's fetch screen diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PropertyDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PropertyDao.java index 378aac5dd..1e325cac9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PropertyDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/PropertyDao.java @@ -7,6 +7,7 @@ import java.util.Objects; import com.hp.hpl.jena.vocabulary.OWL; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.VClass; @@ -72,9 +73,12 @@ public interface PropertyDao { this(OWL_THING, uri, OWL_THING); } - public FullPropertyKey(Property prop) { - this(prop.getDomainVClassURI(), prop.getURI(), prop - .getRangeVClassURI()); + public FullPropertyKey(Property p) { + this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI()); + } + + public FullPropertyKey(RoleRestrictedProperty p) { + this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI()); } public FullPropertyKey(String domainUri, String propertyUri, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index be1198c4d..e2ccdfb81 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -42,6 +42,7 @@ import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; @@ -1137,7 +1138,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } qexec.close(); } - FullPropertyKey key = new FullPropertyKey(op); + FullPropertyKey key = new FullPropertyKey((RoleRestrictedProperty)op); String customListViewConfigFileName = customListViewConfigFileMap.get(key); if (customListViewConfigFileName == null) { log.debug("no list view found for " + key); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 013f6afcc..fa81a6705 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -274,7 +274,7 @@ public class GroupedPropertyList extends BaseTemplateModel { } private boolean redundant(ObjectProperty op, ObjectProperty op2) { - return new FullPropertyKey(op).equals(new FullPropertyKey(op2)); + return new FullPropertyKey((Property)op).equals(new FullPropertyKey((Property)op2)); } private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri, diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java index 95cc96aff..cfaff087f 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java @@ -12,7 +12,7 @@ import static org.junit.Assert.assertNull; import org.junit.Before; import org.junit.Test; -import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelperStub; +import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBeanStub; import stubs.javax.servlet.ServletContextStub; import com.hp.hpl.jena.ontology.OntModel; @@ -23,7 +23,6 @@ import edu.cornell.mannlib.vitro.testing.AbstractTestClass; 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.HasProfile; -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.requestedAction.RequestedAction; @@ -71,9 +70,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass { public void setUp() throws Exception { ctx = new ServletContextStub(); - PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub + PropertyRestrictionBeanStub .getInstance(new String[] { UNSAFE_NS }); - PropertyRestrictionPolicyHelper.setBean(ctx, prph); policy = new SelfEditingPolicy(ctx); @@ -87,14 +85,13 @@ public class SelfEditingPolicyTest extends AbstractTestClass { @Test public void testProhibitedProperties() { - PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub + PropertyRestrictionBeanStub .getInstance(new String[] { UNSAFE_NS }, new String[] { "http://mannlib.cornell.edu/bad#prp234", "http://mannlib.cornell.edu/bad#prp999", "http://mannlib.cornell.edu/bad#prp333", "http://mannlib.cornell.edu/bad#prp777", "http://mannlib.cornell.edu/bad#prp0020" }); - PropertyRestrictionPolicyHelper.setBean(ctx, prph); whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java index d448a3ac6..34267371a 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java @@ -10,7 +10,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelperStub; +import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBeanStub; import stubs.javax.servlet.ServletContextStub; import com.hp.hpl.jena.ontology.OntModel; @@ -22,7 +22,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; 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.identifier.common.HasProfile; -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.requestedAction.propstmt.AddObjectPropertyStatement; @@ -78,9 +77,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass { @Before public void setUp() throws Exception { ServletContextStub ctx = new ServletContextStub(); - PropertyRestrictionPolicyHelper.setBean(ctx, - PropertyRestrictionPolicyHelperStub - .getInstance(new String[] { ADMIN_NS })); + PropertyRestrictionBeanStub.getInstance(new String[] { ADMIN_NS }); policy = new SelfEditingPolicy(ctx); Assert.assertNotNull(policy); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImplTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImplTest.java new file mode 100644 index 000000000..fc3fe813a --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImplTest.java @@ -0,0 +1,511 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.DISPLAY; +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.MODIFY; +import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.PUBLISH; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.CURATOR; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.DB_ADMIN; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.EDITOR; +import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.NOBODY; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccessStub; +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; + +/** + * If we believe that authorization will succeed regardless of user role, check + * that it succeeds with the lowest role. + * + * If we believe that authorization will fail regardless of user role, check + * that it fails with the highest role. + * + * If we believe that authorization depends on the user role, it should pass if + * the user role is higher than or equal to the threshold, and fail if the user + * role is less than the threshold. + * + * Note that we can't set a threshold to be tested to either the lowest or + * highest role, or the attempt to test with higher or lower role will throw an + * exception. + */ +public class PropertyRestrictionBeanImplTest extends AbstractTestClass { + private static final String NS_PROHIBITED = "http://prbi.prohibited/"; + private static final String URI_RESOURCE_EXCEPTIONAL = NS_PROHIBITED + + "exceptionalResource"; + private static final String URI_PREDICATE_EXCEPTIONAL = NS_PROHIBITED + + "exceptionalPredicate"; + + private static final List PROHIBITED_NAMESPACES = Arrays + .asList(new String[] { NS_PROHIBITED }); + private static final List PERMITTED_EXCEPTIONS = Arrays + .asList(new String[] { URI_RESOURCE_EXCEPTIONAL, + URI_PREDICATE_EXCEPTIONAL }); + + private static final String URI_RESOURCE_ANY = "http://prbi.test/anyResource"; + private static final String URI_RESOURCE_PROHIBITED = NS_PROHIBITED + + "resource"; + + private static final String URI_PREDICATE_BARE = "http://prbi.test/barePredicate"; + private static final String URI_PREDICATE_PROHIBITED = NS_PROHIBITED + + "predicate"; + private static final String URI_PREDICATE_UNKNOWN = "http://prbi.test/unknownPredicate"; + + private static final String URI_DOMAIN_1 = "http://prbi.test/domain1"; + private static final String URI_RANGE_1 = "http://prbi.test/range1"; + private static final String URI_DOMAIN_2 = "http://prbi.test/domain2"; + private static final String URI_RANGE_2 = "http://prbi.test/range2"; + + private PropertyRestrictionBeanImpl bean; + + private ObjectProperty barePredicate; + private ObjectProperty prohibitedPredicate; + private ObjectProperty exceptionalPredicate; + private ObjectProperty unknownPredicate; + + private FauxProperty emptyFaux; + private FauxProperty restrictedFaux; + private FauxProperty unknownFaux; + + @Before + public void setup() { + barePredicate = createObjectProperty(null, URI_PREDICATE_BARE, null, + EDITOR, CURATOR, DB_ADMIN); + unknownPredicate = createObjectProperty(null, URI_PREDICATE_UNKNOWN, + null, null, null, null); + prohibitedPredicate = createObjectProperty(null, + URI_PREDICATE_PROHIBITED, null, null, null, null); + exceptionalPredicate = createObjectProperty(null, + URI_PREDICATE_EXCEPTIONAL, null, CURATOR, EDITOR, EDITOR); + + emptyFaux = createFauxProperty(URI_DOMAIN_1, URI_PREDICATE_BARE, + URI_RANGE_1, null, null, null); + restrictedFaux = createFauxProperty(URI_DOMAIN_2, URI_PREDICATE_BARE, + URI_RANGE_2, EDITOR, DB_ADMIN, CURATOR); + unknownFaux = createFauxProperty(URI_DOMAIN_1, URI_PREDICATE_UNKNOWN, + URI_RANGE_1, NOBODY, NOBODY, NOBODY); + + ObjectPropertyDaoStub opDao = new ObjectPropertyDaoStub(); + opDao.addObjectProperty(barePredicate); + opDao.addObjectProperty(prohibitedPredicate); + opDao.addObjectProperty(exceptionalPredicate); + + DataPropertyDaoStub dpDao = new DataPropertyDaoStub(); + + FauxPropertyDaoStub fpDao = new FauxPropertyDaoStub(); + fpDao.insertFauxProperty(emptyFaux); + fpDao.insertFauxProperty(restrictedFaux); + + WebappDaoFactoryStub wadf = new WebappDaoFactoryStub(); + wadf.setObjectPropertyDao(opDao); + wadf.setDataPropertyDao(dpDao); + wadf.setFauxPropertyDao(fpDao); + + ContextModelAccessStub models = new ContextModelAccessStub(); + models.setWebappDaoFactory(wadf); + + bean = new PropertyRestrictionBeanImpl(PROHIBITED_NAMESPACES, + PERMITTED_EXCEPTIONS, models); + } + + private ObjectProperty createObjectProperty(String domainUri, String uri, + String rangeUri, RoleLevel displayThreshold, + RoleLevel modifyThreshold, RoleLevel publishThreshold) { + ObjectProperty op = new ObjectProperty(); + op.setURI(uri); + op.setDomainVClassURI(domainUri); + op.setRangeVClassURI(rangeUri); + op.setHiddenFromDisplayBelowRoleLevel(displayThreshold); + op.setProhibitedFromUpdateBelowRoleLevel(modifyThreshold); + op.setHiddenFromPublishBelowRoleLevel(publishThreshold); + return op; + } + + private FauxProperty createFauxProperty(String domainUri, String uri, + String rangeUri, RoleLevel displayThreshold, + RoleLevel modifyThreshold, RoleLevel publishThreshold) { + FauxProperty fp = new FauxProperty(domainUri, uri, rangeUri); + fp.setHiddenFromDisplayBelowRoleLevel(displayThreshold); + fp.setProhibitedFromUpdateBelowRoleLevel(modifyThreshold); + fp.setHiddenFromPublishBelowRoleLevel(publishThreshold); + return fp; + } + + // ---------------------------------------------------------------------- + // Resources + // ---------------------------------------------------------------------- + + @Test + public void nullResource_display_false() { + assertFalse(bean.canDisplayResource(null, highestRole())); + } + + @Test + public void anyResource_display_true() { + assertTrue(bean.canDisplayResource(URI_RESOURCE_ANY, lowestRole())); + } + + @Test + public void anyResource_nullUserRole_display_false() { + assertFalse(bean.canDisplayResource(URI_RESOURCE_ANY, null)); + } + + @Test + public void nullResource_modify_false() { + assertFalse(bean.canModifyResource(null, highestRole())); + } + + @Test + public void prohibitedResource_modify_false() { + assertFalse(bean.canModifyResource(URI_RESOURCE_PROHIBITED, + highestRole())); + } + + @Test + public void exceptionalResource_modify_true() { + assertTrue(bean.canModifyResource(URI_RESOURCE_EXCEPTIONAL, + lowestRole())); + } + + @Test + public void unremarkableResource_modify_true() { + assertTrue(bean.canModifyResource(URI_RESOURCE_ANY, lowestRole())); + } + + @Test + public void unremarkableResource_nullUserRole_modify_false() { + assertFalse(bean.canModifyResource(URI_RESOURCE_ANY, null)); + } + + @Test + public void nullResource_publish_false() { + assertFalse(bean.canPublishResource(null, highestRole())); + } + + @Test + public void anyResource_publish_true() { + assertTrue(bean.canPublishResource(URI_RESOURCE_ANY, lowestRole())); + } + + @Test + public void anyResource_nullUserRole_publish_false() { + assertFalse(bean.canPublishResource(URI_RESOURCE_ANY, null)); + } + + // ---------------------------------------------------------------------- + // Predicates + // ---------------------------------------------------------------------- + + // ----- display + + @Test + public void nullPredicate_display_false() { + assertFalse(bean.canDisplayPredicate(null, highestRole())); + } + + @Test + public void barePredicate_display_byRole() { + assertTrue(bean.canDisplayPredicate(barePredicate, + higherRole(barePredicate, DISPLAY))); + assertTrue(bean.canDisplayPredicate(barePredicate, + sameRole(barePredicate, DISPLAY))); + assertFalse(bean.canDisplayPredicate(barePredicate, + lowerRole(barePredicate, DISPLAY))); + } + + @Test + public void unknownBarePredicate_display_true() { + assertTrue(bean.canDisplayPredicate(unknownPredicate, lowestRole())); + } + + @Test + public void emptyQualifiedPredicate_display_byBareRole() { + assertTrue(bean.canDisplayPredicate(asProperty(emptyFaux), + higherRole(barePredicate, DISPLAY))); + assertTrue(bean.canDisplayPredicate(asProperty(emptyFaux), + sameRole(barePredicate, DISPLAY))); + assertFalse(bean.canDisplayPredicate(asProperty(emptyFaux), + lowerRole(barePredicate, DISPLAY))); + } + + @Test + public void restrictedQualifiedPredicate_display_byRole() { + assertTrue(bean.canDisplayPredicate(asProperty(restrictedFaux), + higherRole(restrictedFaux, DISPLAY))); + assertTrue(bean.canDisplayPredicate(asProperty(restrictedFaux), + sameRole(restrictedFaux, DISPLAY))); + assertFalse(bean.canDisplayPredicate(asProperty(restrictedFaux), + lowerRole(restrictedFaux, DISPLAY))); + } + + @Test + public void unknownQualifiedPredicate_display_true() { + assertTrue(bean.canDisplayPredicate(asProperty(unknownFaux), + lowestRole())); + } + + // ----- modify + + @Test + public void nullPredicate_modify_false() { + assertFalse(bean.canModifyPredicate(null, highestRole())); + } + + @Test + public void prohibitedPredicate_modify_false() { + assertFalse(bean.canModifyPredicate(prohibitedPredicate, lowestRole())); + } + + @Test + public void exceptionalPredicate_modify_byRole() { + assertTrue(bean.canModifyPredicate(exceptionalPredicate, + higherRole(exceptionalPredicate, MODIFY))); + assertTrue(bean.canModifyPredicate(exceptionalPredicate, + sameRole(exceptionalPredicate, MODIFY))); + assertFalse(bean.canModifyPredicate(exceptionalPredicate, + lowerRole(exceptionalPredicate, MODIFY))); + } + + @Test + public void barePredicate_modify_byRole() { + assertTrue(bean.canModifyPredicate(barePredicate, + higherRole(barePredicate, MODIFY))); + assertTrue(bean.canModifyPredicate(barePredicate, + sameRole(barePredicate, MODIFY))); + assertFalse(bean.canModifyPredicate(barePredicate, + lowerRole(barePredicate, MODIFY))); + } + + @Test + public void unknownBarePredicate_modify_true() { + assertTrue(bean.canModifyPredicate(unknownPredicate, lowestRole())); + } + + @Test + public void emptyQualifiedPredicate_modify_byBareRole() { + assertTrue(bean.canModifyPredicate(asProperty(emptyFaux), + higherRole(barePredicate, MODIFY))); + assertTrue(bean.canModifyPredicate(asProperty(emptyFaux), + sameRole(barePredicate, MODIFY))); + assertFalse(bean.canModifyPredicate(asProperty(emptyFaux), + lowerRole(barePredicate, MODIFY))); + } + + @Test + public void restrictedQualifiedPredicate_modify_byRole() { + assertTrue(bean.canModifyPredicate(asProperty(restrictedFaux), + higherRole(restrictedFaux, MODIFY))); + assertTrue(bean.canModifyPredicate(asProperty(restrictedFaux), + sameRole(restrictedFaux, MODIFY))); + assertFalse(bean.canModifyPredicate(asProperty(restrictedFaux), + lowerRole(restrictedFaux, MODIFY))); + } + + @Test + public void unknownQualifiedPredicate_modify_true() { + assertTrue(bean.canModifyPredicate(asProperty(unknownFaux), + lowestRole())); + } + + // ----- publish + + @Test + public void nullPredicate_publish_false() { + assertFalse(bean.canPublishPredicate(null, highestRole())); + } + + @Test + public void barePredicate_publish_byRole() { + assertTrue(bean.canPublishPredicate(barePredicate, + higherRole(barePredicate, PUBLISH))); + assertTrue(bean.canPublishPredicate(barePredicate, + sameRole(barePredicate, PUBLISH))); + assertFalse(bean.canPublishPredicate(barePredicate, + lowerRole(barePredicate, PUBLISH))); + } + + @Test + public void unknownBarePredicate_publish_true() { + assertTrue(bean.canPublishPredicate(unknownPredicate, lowestRole())); + } + + @Test + public void emptyQualifiedPredicate_publish_byBareRole() { + assertTrue(bean.canPublishPredicate(asProperty(emptyFaux), + higherRole(barePredicate, PUBLISH))); + assertTrue(bean.canPublishPredicate(asProperty(emptyFaux), + sameRole(barePredicate, PUBLISH))); + assertFalse(bean.canPublishPredicate(asProperty(emptyFaux), + lowerRole(barePredicate, PUBLISH))); + } + + @Test + public void restrictedQualifiedPredicate_publish_byRole() { + assertTrue(bean.canPublishPredicate(asProperty(restrictedFaux), + higherRole(restrictedFaux, PUBLISH))); + assertTrue(bean.canPublishPredicate(asProperty(restrictedFaux), + sameRole(restrictedFaux, PUBLISH))); + assertFalse(bean.canPublishPredicate(asProperty(restrictedFaux), + lowerRole(restrictedFaux, PUBLISH))); + } + + @Test + public void unknownQualifiedPredicate_publish_true() { + assertTrue(bean.canPublishPredicate(asProperty(unknownFaux), + lowestRole())); + } + + // ---------------------------------------------------------------------- + // update permissions + // ---------------------------------------------------------------------- + + @Test + public void updateToAllowDisplay() { + RoleLevel desiredDisplayLevel = lowerRole(barePredicate, DISPLAY); + + assertFalse(bean + .canDisplayPredicate(barePredicate, desiredDisplayLevel)); + + bean.updateProperty(updatedLevels(barePredicate, desiredDisplayLevel, + sameRole(barePredicate, MODIFY), + sameRole(barePredicate, PUBLISH))); + + assertTrue(bean.canDisplayPredicate(barePredicate, desiredDisplayLevel)); + } + + @Test + public void updateToAllowModify() { + RoleLevel desiredModifyLevel = lowerRole(barePredicate, MODIFY); + + assertFalse(bean.canModifyPredicate(barePredicate, desiredModifyLevel)); + + bean.updateProperty(updatedLevels(barePredicate, + sameRole(barePredicate, DISPLAY), desiredModifyLevel, + sameRole(barePredicate, PUBLISH))); + + assertTrue(bean.canModifyPredicate(barePredicate, desiredModifyLevel)); + } + + @Test + public void updateToAllowPublish() { + RoleLevel desiredPublishLevel = lowerRole(barePredicate, PUBLISH); + + assertFalse(bean + .canPublishPredicate(barePredicate, desiredPublishLevel)); + + bean.updateProperty(updatedLevels(barePredicate, + sameRole(barePredicate, DISPLAY), + sameRole(barePredicate, MODIFY), desiredPublishLevel)); + + assertTrue(bean.canPublishPredicate(barePredicate, desiredPublishLevel)); + } + + @Test + public void updateToDisallowDisplay() { + RoleLevel desiredDisplayLevel = sameRole(barePredicate, DISPLAY); + + assertTrue(bean.canDisplayPredicate(barePredicate, desiredDisplayLevel)); + + bean.updateProperty(updatedLevels(barePredicate, + higherRole(barePredicate, DISPLAY), + sameRole(barePredicate, MODIFY), + sameRole(barePredicate, PUBLISH))); + + assertFalse(bean + .canDisplayPredicate(barePredicate, desiredDisplayLevel)); + } + + @Test + public void updateToDisallowModify() { + RoleLevel desiredModifyLevel = sameRole(barePredicate, MODIFY); + + assertTrue(bean.canModifyPredicate(barePredicate, desiredModifyLevel)); + + bean.updateProperty(updatedLevels(barePredicate, + sameRole(barePredicate, DISPLAY), + higherRole(barePredicate, MODIFY), + sameRole(barePredicate, PUBLISH))); + + assertFalse(bean.canModifyPredicate(barePredicate, desiredModifyLevel)); + } + + @Test + public void updateToDisallowPublish() { + RoleLevel desiredPublishLevel = sameRole(barePredicate, PUBLISH); + + assertTrue(bean.canPublishPredicate(barePredicate, desiredPublishLevel)); + + bean.updateProperty(updatedLevels(barePredicate, + sameRole(barePredicate, DISPLAY), + sameRole(barePredicate, MODIFY), + higherRole(barePredicate, PUBLISH))); + + assertFalse(bean + .canPublishPredicate(barePredicate, desiredPublishLevel)); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private RoleLevel lowestRole() { + return RoleLevel.values()[0]; + } + + private RoleLevel highestRole() { + RoleLevel[] values = RoleLevel.values(); + return values[values.length - 1]; + } + + private RoleLevel sameRole(RoleRestrictedProperty p, Which which) { + switch (which) { + case DISPLAY: + return p.getHiddenFromDisplayBelowRoleLevel(); + case MODIFY: + return p.getProhibitedFromUpdateBelowRoleLevel(); + default: // PUBLISH + return p.getHiddenFromPublishBelowRoleLevel(); + } + } + + private RoleLevel lowerRole(RoleRestrictedProperty p, Which which) { + return RoleLevel.values()[sameRole(p, which).ordinal() - 1]; + } + + private RoleLevel higherRole(RoleRestrictedProperty p, Which which) { + return RoleLevel.values()[sameRole(p, which).ordinal() + 1]; + } + + private Property asProperty(FauxProperty fp) { + Property p = new Property(); + p.setURI(fp.getBaseURI()); + p.setDomainVClassURI(fp.getDomainURI()); + p.setRangeVClassURI(fp.getRangeURI()); + return p; + } + + private PropertyRestrictionLevels updatedLevels(RoleRestrictedProperty p, + RoleLevel displayLevel, RoleLevel modifyLevel, + RoleLevel publishLevel) { + return new PropertyRestrictionLevels(new FullPropertyKey(p), + displayLevel, modifyLevel, publishLevel); + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java deleted file mode 100644 index 0ad53df91..000000000 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java +++ /dev/null @@ -1,331 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.CURATOR; -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.DB_ADMIN; -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.EDITOR; -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.NOBODY; -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.PUBLIC; -import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.SELF; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.Resource; - -import edu.cornell.mannlib.vitro.testing.AbstractTestClass; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; - -/** - * Check that the bean gets built properly, and check that the bean works - * properly. - */ -public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { - private static final Log log = LogFactory - .getLog(PropertyRestrictionPolicyHelperTest.class); - - private static final String PROPERTY_DISPLAY_THRESHOLD = VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT; - private static final String PROPERTY_MODIFY_THRESHOLD = VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT; - private static final String PROPERTY_PUBLISH_THRESHOLD = VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT; - - private static final String[] PROHIBITED_NAMESPACES = new String[] { - VitroVocabulary.vitroURI, "" }; - - private static final String[] PERMITTED_EXCEPTIONS = new String[] { VitroVocabulary.MONIKER }; - - private OntModel ontModel; - private ModelWrapper wrapper; - private PropertyRestrictionPolicyHelper bean; - - @Before - public void setLoggingLevel() { - // setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG); - } - - private FullPropertyKey key(String predicateURI) { - return new FullPropertyKey(predicateURI); - } - - @Before - public void createTheBean() { - Map displayLevels = new HashMap<>(); - displayLevels.put(key("http://predicates#display_curator"), CURATOR); - displayLevels.put(key("http://predicates#display_hidden"), NOBODY); - - Map modifyLevels = new HashMap<>(); - modifyLevels.put(key("http://predicates#modify_self"), SELF); - modifyLevels.put(key("http://predicates#modify_curator"), CURATOR); - modifyLevels.put(key("http://predicates#modify_hidden"), NOBODY); - - Map publishLevels = new HashMap<>(); - publishLevels.put(key("http://predicates#publish_curator"), CURATOR); - publishLevels.put(key("http://predicates#publish_hidden"), NOBODY); - - bean = new PropertyRestrictionPolicyHelper( - Arrays.asList(PROHIBITED_NAMESPACES), - Arrays.asList(PERMITTED_EXCEPTIONS), displayLevels, - modifyLevels, publishLevels); - } - - @Before - public void createTheModel() { - ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); - - wrapper = new ModelWrapper(ontModel); - - wrapper.add("http://thresholds#display_public", - PROPERTY_DISPLAY_THRESHOLD, PUBLIC.getURI()); - wrapper.add("http://thresholds#display_hidden", - PROPERTY_DISPLAY_THRESHOLD, NOBODY.getURI()); - - wrapper.add("http://thresholds#modify_editor", - PROPERTY_MODIFY_THRESHOLD, EDITOR.getURI()); - wrapper.add("http://thresholds#modify_curator", - PROPERTY_MODIFY_THRESHOLD, CURATOR.getURI()); - - wrapper.add("http://thresholds#publish_public", - PROPERTY_PUBLISH_THRESHOLD, PUBLIC.getURI()); - wrapper.add("http://thresholds#publish_hidden", - PROPERTY_PUBLISH_THRESHOLD, NOBODY.getURI()); - } - - // ---------------------------------------------------------------------- - // test the bean - // ---------------------------------------------------------------------- - - @Test - public void displayResource() { - assertEquals("display a random resource", true, - bean.canDisplayResource("http://someRandom#string", null)); - } - - @Test - public void modifyResourceNoRestriction() { - assertEquals("modify a random resource", true, - bean.canModifyResource("http://someRandom#string", null)); - } - - @Test - public void modifyResourceProhibitedNamespace() { - assertEquals("modify a prohibited resource", false, - bean.canModifyResource(PROHIBITED_NAMESPACES[0] + "random", - null)); - } - - @Test - public void publishResource() { - assertEquals("publish a random resource", true, - bean.canPublishResource("http://someRandom#string", null)); - } - - @Test - public void modifyResourcePermittedException() { - assertEquals("modify a exception resource", true, - bean.canModifyResource(PERMITTED_EXCEPTIONS[0], null)); - } - - @Test - public void displayPredicateNoRestriction() { - assertEquals("displayPredicate: open", true, bean.canDisplayPredicate( - createVitroProperty("http://predicates#open"), PUBLIC)); - } - - @Test - public void displayPredicateRestrictionLower() { - assertEquals("displayPredicate: lower restriction", true, - bean.canDisplayPredicate( - createVitroProperty("http://predicates#display_self"), - CURATOR)); - } - - @Test - public void displayPredicateRestrictionEqual() { - assertEquals( - "displayPredicate: equal restriction", - true, - bean.canDisplayPredicate( - createVitroProperty("http://predicates#display_curator"), - CURATOR)); - } - - @Test - public void displayPredicateRestrictionHigher() { - assertEquals( - "displayPredicate: higher restriction", - false, - bean.canDisplayPredicate( - createVitroProperty("http://predicates#display_hidden"), - CURATOR)); - } - - @Test - public void modifyPredicateNoRestriction() { - assertEquals("modifyPredicate: open", true, bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - "http://predicates#open"), PUBLIC)); - } - - @Test - public void modifyPredicateRestrictionLower() { - assertEquals("modifyPredicate: lower restriction", true, - bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - "http://predicates#modify_self"), CURATOR)); - } - - @Test - public void modifyPredicateRestrictionEqual() { - assertEquals("modifyPredicate: equal restriction", true, - bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - "http://predicates#modify_curator"), CURATOR)); - } - - @Test - public void modifyPredicateRestrictionHigher() { - assertEquals("modifyPredicate: higher restriction", false, - bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - "http://predicates#modify_hidden"), CURATOR)); - } - - @Test - public void modifyPredicateProhibitedNamespace() { - assertEquals( - "modifyPredicate: prohibited namespace", - false, - bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - PROHIBITED_NAMESPACES[0] + "randoom"), DB_ADMIN)); - } - - @Test - public void modifyPredicatePermittedException() { - assertEquals("modifyPredicate: permitted exception", true, - bean.canModifyPredicate( - new edu.cornell.mannlib.vitro.webapp.beans.Property( - PERMITTED_EXCEPTIONS[0]), DB_ADMIN)); - } - - @Test - public void publishPredicateNoRestriction() { - assertEquals("publishPredicate: open", true, bean.canPublishPredicate( - createVitroProperty("http://predicates#open"), PUBLIC)); - } - - @Test - public void publishPredicateRestrictionLower() { - assertEquals("publishPredicate: lower restriction", true, - bean.canPublishPredicate( - createVitroProperty("http://predicates#publish_self"), - CURATOR)); - } - - @Test - public void publishPredicateRestrictionEqual() { - assertEquals( - "publishPredicate: equal restriction", - true, - bean.canPublishPredicate( - createVitroProperty("http://predicates#publish_curator"), - CURATOR)); - } - - @Test - public void publishPredicateRestrictionHigher() { - assertEquals( - "publishPredicate: higher restriction", - false, - bean.canPublishPredicate( - createVitroProperty("http://predicates#publish_hidden"), - CURATOR)); - } - - // ---------------------------------------------------------------------- - // test the bean builder - // ---------------------------------------------------------------------- - - @Test - public void buildDisplayThresholds() { - Map expectedMap = new HashMap<>(); - expectedMap.put(key("http://thresholds#display_public"), PUBLIC); - expectedMap.put(key("http://thresholds#display_hidden"), NOBODY); - - Map actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD); - assertEquals("display thresholds", expectedMap, actualMap); - } - - @Test - public void buildModifyThresholds() { - Map expectedMap = new HashMap<>(); - expectedMap.put(key("http://thresholds#modify_editor"), EDITOR); - expectedMap.put(key("http://thresholds#modify_curator"), CURATOR); - - Map actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD); - assertEquals("modify thresholds", expectedMap, actualMap); - } - - @Test - public void buildPublishThresholds() { - Map expectedMap = new HashMap<>(); - expectedMap.put(key("http://thresholds#publish_public"), PUBLIC); - expectedMap.put(key("http://thresholds#publish_hidden"), NOBODY); - - Map actualMap = populateThresholdMap(PROPERTY_PUBLISH_THRESHOLD); - assertEquals("publish thresholds", expectedMap, actualMap); - } - - /** Invoke the private static method "populateThresholdMap" */ - private Map populateThresholdMap(String propertyUri) { - Map map = new HashMap(); - try { - Class clazz = PropertyRestrictionPolicyHelper.class; - Method method = clazz.getDeclaredMethod("populateThresholdMap", - OntModel.class, Map.class, String.class); - method.setAccessible(true); - method.invoke(null, ontModel, map, propertyUri); - return map; - } catch (Exception e) { - fail("failed to populate the map: propertyUri='" + propertyUri - + "', " + e); - return null; - } - } - - private static class ModelWrapper { - private final OntModel model; - - public ModelWrapper(OntModel model) { - this.model = model; - } - - public void add(String subjectUri, String propertyUri, String objectUri) { - Resource subject = model.getResource(subjectUri); - Property property = model.getProperty(propertyUri); - Resource object = model.getResource(objectUri); - model.add(subject, property, object); - } - } - - private edu.cornell.mannlib.vitro.webapp.beans.Property createVitroProperty( - String propertyURI) { - return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI); - } -} diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanStub.java new file mode 100644 index 000000000..033056cd5 --- /dev/null +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanStub.java @@ -0,0 +1,122 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.hp.hpl.jena.rdf.model.impl.Util; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; +import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +/** + * Allow the unit test to specify a variety of restrictions + */ +public class PropertyRestrictionBeanStub extends PropertyRestrictionBean { + + // ---------------------------------------------------------------------- + // Stub infrastructure + // ---------------------------------------------------------------------- + + /** Don't prohibit or restrict anything. */ + public static PropertyRestrictionBean getInstance() { + return getInstance(null, null); + } + + /** Prohibit some namespaces. */ + public static PropertyRestrictionBeanStub getInstance( + String[] restrictedNamespaces) { + return getInstance(restrictedNamespaces, null); + } + + /** + * Prohibit some namespaces and restrict some properties from modification + * by anybody. They may still be displayed or published. + * + * We can implement more granular control if we need it. + */ + public static PropertyRestrictionBeanStub getInstance( + String[] restrictedNamespaces, String[] restrictedProperties) { + PropertyRestrictionBeanStub stub = new PropertyRestrictionBeanStub( + restrictedNamespaces, restrictedProperties); + PropertyRestrictionBean.instance = stub; + return stub; + } + + private final Set restrictedNamespaces; + private final Set restrictedProperties; + + private PropertyRestrictionBeanStub(String[] restrictedNamespaces, + String[] restrictedProperties) { + this.restrictedNamespaces = (restrictedNamespaces == null) ? Collections + . emptySet() : new HashSet<>( + Arrays.asList(restrictedNamespaces)); + this.restrictedProperties = (restrictedProperties == null) ? Collections + . emptySet() : new HashSet<>( + Arrays.asList(restrictedProperties)); + } + + private boolean isPermittedNamespace(String uri) { + return !restrictedNamespaces.contains(namespace(uri)); + } + + private String namespace(String uri) { + return uri.substring(0, Util.splitNamespace(uri)); + } + + private boolean isPermittedProperty(String uri) { + return !restrictedProperties.contains(uri); + } + + // ---------------------------------------------------------------------- + // Stub methods + // ---------------------------------------------------------------------- + + @Override + public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { + return isPermittedNamespace(resourceUri); + } + + @Override + public boolean canModifyResource(String resourceUri, RoleLevel userRole) { + return isPermittedNamespace(resourceUri) + && isPermittedProperty(resourceUri); + } + + @Override + public boolean canPublishResource(String resourceUri, RoleLevel userRole) { + return isPermittedNamespace(resourceUri); + } + + @Override + public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { + return isPermittedNamespace(predicate.getURI()); + } + + @Override + public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { + return isPermittedNamespace(predicate.getURI()) + && isPermittedProperty(predicate.getURI()); + } + + @Override + public boolean canPublishPredicate(Property predicate, RoleLevel userRole) { + return isPermittedNamespace(predicate.getURI()); + } + + // ---------------------------------------------------------------------- + // Un-implemented methods + // ---------------------------------------------------------------------- + + @Override + public void updateProperty(PropertyRestrictionLevels levels) { + throw new RuntimeException( + "PropertyRestrictionBeanStub.updateProperty() not implemented."); + } + +} diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java deleted file mode 100644 index 5c98a2909..000000000 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java +++ /dev/null @@ -1,63 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; - -/** - * Allow the unit test to specify a variety of restrictions - */ -public class PropertyRestrictionPolicyHelperStub extends - PropertyRestrictionPolicyHelper { - - /** Don't prohibit or restrict anything. */ - public static PropertyRestrictionPolicyHelper getInstance() { - return getInstance(null, null); - } - - /** Prohibit some namespaces. */ - public static PropertyRestrictionPolicyHelperStub getInstance( - String[] restrictedNamespaces) { - return getInstance(restrictedNamespaces, null); - } - - /** - * Prohibit some namespaces and restrict some properties from modification - * by anybody. - */ - public static PropertyRestrictionPolicyHelperStub getInstance( - String[] restrictedNamespaces, String[] restrictedProperties) { - Set namespaceSet = new HashSet(); - if (restrictedNamespaces != null) { - namespaceSet.addAll(Arrays.asList(restrictedNamespaces)); - } - - Map thresholdMap = new HashMap<>(); - if (restrictedProperties != null) { - for (String prop : restrictedProperties) { - thresholdMap.put(new FullPropertyKey(prop), RoleLevel.NOBODY); - } - } - - return new PropertyRestrictionPolicyHelperStub(namespaceSet, null, - null, thresholdMap, null); - } - - private PropertyRestrictionPolicyHelperStub( - Set modifyRestrictedNamespaces, - Set modifyPermittedExceptions, - Map displayThresholds, - Map modifyThresholds, - Map publishThresholds) { - super(modifyRestrictedNamespaces, modifyPermittedExceptions, - displayThresholds, modifyThresholds, publishThresholds); - } -} diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java index 5ad473575..e599d67c7 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/DataPropertyDaoStub.java @@ -2,6 +2,7 @@ package stubs.edu.cornell.mannlib.vitro.webapp.dao; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -57,6 +58,11 @@ public class DataPropertyDaoStub implements DataPropertyDao { // Stub methods // ---------------------------------------------------------------------- + @Override + public List getAllDataProperties() { + return new ArrayList<>(dpMap.values()); + } + @Override public DataProperty getDataPropertyByURI(String dataPropertyURI) { return dpMap.get(dataPropertyURI); @@ -189,12 +195,6 @@ public class DataPropertyDaoStub implements DataPropertyDao { "PropertyDao.getClassesWithRestrictionOnProperty() not implemented."); } - @Override - public List getAllDataProperties() { - throw new RuntimeException( - "DataPropertyDao.getAllDataProperties() not implemented."); - } - @Override public List getAllExternalIdDataProperties() { throw new RuntimeException( diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/FauxPropertyDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/FauxPropertyDaoStub.java index 4c0321b0b..8be971cde 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/FauxPropertyDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/FauxPropertyDaoStub.java @@ -2,9 +2,11 @@ package stubs.edu.cornell.mannlib.vitro.webapp.dao; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao; @@ -19,7 +21,7 @@ public class FauxPropertyDaoStub implements FauxPropertyDao { // ---------------------------------------------------------------------- private final Map props = new HashMap<>(); - + // ---------------------------------------------------------------------- // Stub methods // ---------------------------------------------------------------------- @@ -30,28 +32,32 @@ public class FauxPropertyDaoStub implements FauxPropertyDao { return props.get(new FullPropertyKey(domainUri, baseUri, rangeUri)); } + @Override + public List getFauxPropertiesForBaseUri(String uri) { + List list = new ArrayList<>(); + for (FauxProperty fp : props.values()) { + if (Objects.equals(fp.getBaseURI(), uri)) { + list.add(fp); + } + } + return list; + } + + @Override + public void insertFauxProperty(FauxProperty fp) { + props.put(new FullPropertyKey(fp), fp); + } + // ---------------------------------------------------------------------- // Un-implemented methods // ---------------------------------------------------------------------- - @Override - public List getFauxPropertiesForBaseUri(String uri) { - throw new RuntimeException( - "FauxPropertyDaoStub.getFauxPropertiesForBaseUri() not implemented."); - } - @Override public FauxProperty getFauxPropertyFromContextUri(String contextUri) { throw new RuntimeException( "FauxPropertyDaoStub.getFauxPropertyFromContextUri() not implemented."); } - @Override - public void insertFauxProperty(FauxProperty fp) { - throw new RuntimeException( - "FauxPropertyDaoStub.insertFauxProperty() not implemented."); - } - @Override public void updateFauxProperty(FauxProperty fp) { throw new RuntimeException( diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java index dacbdbc88..33c802dc5 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java @@ -2,6 +2,7 @@ package stubs.edu.cornell.mannlib.vitro.webapp.dao; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,17 +41,18 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { opMap.put(uri, property); } - - public void setCustomListViewConfigFileName(ObjectProperty property, String filename) { + + public void setCustomListViewConfigFileName(ObjectProperty property, + String filename) { if (property == null) { throw new NullPointerException("property may not be null."); } - + String uri = property.getURI(); if (uri == null) { throw new NullPointerException("uri may not be null."); } - + configFilesMap.put(uri, filename); } @@ -58,6 +60,11 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { // Stub methods // ---------------------------------------------------------------------- + @Override + public List getAllObjectProperties() { + return new ArrayList<>(opMap.values()); + } + @Override public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) { if (objectPropertyURI == null) { @@ -65,18 +72,18 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { } return opMap.get(objectPropertyURI); } - - @Override - public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, - String domainURI, String rangeURI) { - return getObjectPropertyByURI(objectPropertyURI); - } - - @Override - public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, - String domainURI, String rangeURI, ObjectProperty base) { - return getObjectPropertyByURI(objectPropertyURI); - } + + @Override + public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, + String domainURI, String rangeURI) { + return getObjectPropertyByURI(objectPropertyURI); + } + + @Override + public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, + String domainURI, String rangeURI, ObjectProperty base) { + return getObjectPropertyByURI(objectPropertyURI); + } @Override public String getCustomListViewConfigFileName(ObjectProperty objectProperty) { @@ -194,12 +201,6 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { "ObjectPropertyDaoStub.getClassesWithRestrictionOnProperty() not implemented."); } - @Override - public List getAllObjectProperties() { - throw new RuntimeException( - "ObjectPropertyDaoStub.getAllObjectProperties() not implemented."); - } - @Override public List getObjectPropertiesForObjectPropertyStatements( List objectPropertyStatements) { diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index 9c3fc7a42..ffbeff7a8 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -46,7 +46,7 @@ edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry$Setup edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsSmokeTest -edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup +edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean$Setup edu.cornell.mannlib.vitro.webapp.auth.policy.setup.CommonPolicyFamilySetup