NIHVIVO-3523 Merge the DisplayByRolePermission and EditByRolePermission code from branches/dev-permissions-NIHVIVO-3523

This commit is contained in:
j2blake 2012-01-09 16:21:03 +00:00
commit 597ed286bd
17 changed files with 593 additions and 454 deletions

View file

@ -0,0 +1,74 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier.common;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
/**
* The current user has this Permission, through one or more PermissionSets.
*/
public class HasPermissionSet extends AbstractCommonIdentifier implements
Identifier, Comparable<HasPermissionSet> {
public static Collection<HasPermission> getIdentifiers(IdentifierBundle ids) {
return getIdentifiersForClass(ids, HasPermission.class);
}
public static Collection<Permission> getPermissions(IdentifierBundle ids) {
Set<Permission> set = new HashSet<Permission>();
for (HasPermission id : getIdentifiers(ids)) {
set.add(id.getPermission());
}
return set;
}
private final PermissionSet permissionSet; // never null
public HasPermissionSet(PermissionSet permissionSet) {
if (permissionSet == null) {
throw new NullPointerException("permissionSet may not be null.");
}
this.permissionSet = permissionSet;
}
public PermissionSet getPermissionSet() {
return permissionSet;
}
@Override
public String toString() {
return "HasPermissionSet[" + permissionSet.getLabel() + "]";
}
@Override
public int hashCode() {
return permissionSet.getUri().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof HasPermissionSet)) {
return false;
}
HasPermissionSet that = (HasPermissionSet) obj;
return this.permissionSet.getUri().equals(that.permissionSet.getUri());
}
@Override
public int compareTo(HasPermissionSet that) {
return this.permissionSet.getUri().compareTo(
that.permissionSet.getUri());
}
}

View file

@ -1,52 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier.common;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* The current user has this RoleLevel.
*/
public class HasRoleLevel extends AbstractCommonIdentifier implements Identifier {
public static Collection<HasRoleLevel> getIdentifiers(IdentifierBundle ids) {
return getIdentifiersForClass(ids, HasRoleLevel.class);
}
public static Collection<String> getRoleLevelUris(IdentifierBundle ids) {
Set<String> set = new HashSet<String>();
for (HasRoleLevel id : getIdentifiers(ids)) {
set.add(id.getRoleLevel().getURI());
}
return set;
}
public static RoleLevel getUsersRoleLevel(IdentifierBundle whoToAuth) {
Collection<HasRoleLevel> roleIds = getIdentifiers(whoToAuth);
if (roleIds.isEmpty()) {
return RoleLevel.PUBLIC;
} else {
return roleIds.iterator().next().getRoleLevel();
}
}
private final RoleLevel roleLevel;
public HasRoleLevel(RoleLevel roleLevel) {
this.roleLevel = roleLevel;
}
public RoleLevel getRoleLevel() {
return roleLevel;
}
@Override
public String toString() {
return "HasRoleLevel[" + roleLevel + "]";
}
}

View file

@ -0,0 +1,45 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
/**
* Figure out what PermissionSets the user is entitled to have.
*/
public class HasPermissionSetFactory extends BaseIdentifierBundleFactory {
private static final Log log = LogFactory
.getLog(HasPermissionFactory.class);
public HasPermissionSetFactory(ServletContext ctx) {
super(ctx);
}
@Override
public IdentifierBundle getIdentifierBundle(HttpServletRequest req) {
IdentifierBundle ids = new ArrayIdentifierBundle();
UserAccount user = LoginStatusBean.getCurrentUser(req);
if (user != null) {
for (String psUri: user.getPermissionSetUris()) {
PermissionSet ps = uaDao.getPermissionSetByUri(psUri);
if (ps != null) {
ids.add(new HasPermissionSet(ps));
}
}
}
return ids;
}
}

View file

@ -1,29 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Create an identifier that shows the role level of the current user, or
* PUBLIC if the user is not logged in.
*/
public class HasRoleLevelFactory extends BaseIdentifierBundleFactory {
public HasRoleLevelFactory(ServletContext ctx) {
super(ctx);
}
@Override
public IdentifierBundle getIdentifierBundle(HttpServletRequest req) {
RoleLevel roleLevel = RoleLevel.getRoleFromLoginStatus(req);
return new ArrayIdentifierBundle(new HasRoleLevel(roleLevel));
}
}

View file

@ -0,0 +1,138 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Is the user authorized to display properties that are marked as restricted to
* a certain "Role Level"?
*/
public class DisplayByRolePermission extends Permission {
private static final Log log = LogFactory
.getLog(DisplayByRolePermission.class);
public static final String NAMESPACE = "java:"
+ DisplayByRolePermission.class.getName() + "#";
private final String roleName;
private final RoleLevel roleLevel;
private final ServletContext ctx;
public DisplayByRolePermission(String roleName, RoleLevel roleLevel,
ServletContext ctx) {
super(NAMESPACE + roleName);
if (roleName == null) {
throw new NullPointerException("role may not be null.");
}
if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null.");
}
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName;
this.roleLevel = roleLevel;
this.ctx = ctx;
}
@Override
public boolean isAuthorized(RequestedAction whatToAuth) {
boolean result;
if (whatToAuth instanceof DisplayDataProperty) {
result = isAuthorized((DisplayDataProperty) whatToAuth);
} else if (whatToAuth instanceof DisplayObjectProperty) {
result = isAuthorized((DisplayObjectProperty) whatToAuth);
} else if (whatToAuth instanceof DisplayDataPropertyStatement) {
result = isAuthorized((DisplayDataPropertyStatement) whatToAuth);
} else if (whatToAuth instanceof DisplayObjectPropertyStatement) {
result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth);
} else {
result = false;
}
if (result) {
log.debug(this + " authorizes " + whatToAuth);
} else {
log.debug(this + " does not authorize " + whatToAuth);
}
return result;
}
/**
* The user may see this data property if they are allowed to see its
* predicate.
*/
private boolean isAuthorized(DisplayDataProperty action) {
String predicateUri = action.getDataProperty().getURI();
return canDisplayPredicate(predicateUri);
}
/**
* The user may see this object property if they are allowed to see its
* predicate.
*/
private boolean isAuthorized(DisplayObjectProperty action) {
String predicateUri = action.getObjectProperty().getURI();
return canDisplayPredicate(predicateUri);
}
/**
* The user may see this data property if they are allowed to see its
* subject and its predicate.
*/
private boolean isAuthorized(DisplayDataPropertyStatement action) {
DataPropertyStatement stmt = action.getDataPropertyStatement();
String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI();
return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri);
}
/**
* The user may see this data property if they are allowed to see its
* subject, its predicate, and its object.
*/
private boolean isAuthorized(DisplayObjectPropertyStatement action) {
ObjectPropertyStatement stmt = action.getObjectPropertyStatement();
String subjectUri = stmt.getSubjectURI();
String predicateUri = stmt.getPropertyURI();
String objectUri = stmt.getObjectURI();
return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri)
&& canDisplayResource(objectUri);
}
private boolean canDisplayResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
resourceUri, this.roleLevel);
}
private boolean canDisplayPredicate(String predicateUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(predicateUri, this.roleLevel);
}
@Override
public String toString() {
return "DisplayByRolePermission['" + roleName + "']";
}
}

View file

@ -0,0 +1,114 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Is the user authorized to edit properties that are marked as restricted to a
* certain "Role Level"?
*/
public class EditByRolePermission extends Permission {
private static final Log log = LogFactory
.getLog(EditByRolePermission.class);
public static final String NAMESPACE = "java:"
+ EditByRolePermission.class.getName() + "#";
private final String roleName;
private final RoleLevel roleLevel;
private final ServletContext ctx;
public EditByRolePermission(String roleName, RoleLevel roleLevel,
ServletContext ctx) {
super(NAMESPACE + roleName);
if (roleName == null) {
throw new NullPointerException("role may not be null.");
}
if (roleLevel == null) {
throw new NullPointerException("roleLevel may not be null.");
}
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
this.roleName = roleName;
this.roleLevel = roleLevel;
this.ctx = ctx;
}
/**
* If the requested action is to edit a property statement, we might
* authorize it based on their role level.
*/
@Override
public boolean isAuthorized(RequestedAction whatToAuth) {
boolean result;
if (whatToAuth instanceof AbstractDataPropertyAction) {
result = isAuthorized((AbstractDataPropertyAction) whatToAuth);
} else if (whatToAuth instanceof AbstractObjectPropertyAction) {
result = isAuthorized((AbstractObjectPropertyAction) whatToAuth);
} else {
result = false;
}
if (result) {
log.debug(this + " authorizes " + whatToAuth);
} else {
log.debug(this + " does not authorize " + whatToAuth);
}
return result;
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject and its predicate.
*/
private boolean isAuthorized(AbstractDataPropertyAction action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri);
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject, its predicate, and its object.
*/
private boolean isAuthorized(AbstractObjectPropertyAction action) {
String subjectUri = action.getUriOfSubject();
String predicateUri = action.getUriOfPredicate();
String objectUri = action.getUriOfObject();
return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri)
&& canModifyResource(objectUri);
}
private boolean canModifyResource(String resourceUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
resourceUri, roleLevel);
}
private boolean canModifyPredicate(String predicateUri) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
predicateUri, roleLevel);
}
@Override
public String toString() {
return "EditByRolePermission['" + roleName + "']";
}
}

View file

@ -16,6 +16,7 @@ import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
@ -31,7 +32,7 @@ public class PermissionRegistry {
private static final String ATTRIBUTE_NAME = PermissionRegistry.class
.getName();
/**
/**
* Has the registry been created yet?
*/
public static boolean isRegistryCreated(ServletContext ctx) {
@ -59,7 +60,8 @@ public class PermissionRegistry {
}
/**
* Get the registry from the context. If there isn't one, throw an exception.
* Get the registry from the context. If there isn't one, throw an
* exception.
*/
public static PermissionRegistry getRegistry(ServletContext ctx) {
if (ctx == null) {
@ -128,7 +130,10 @@ public class PermissionRegistry {
StartupStatus ss = StartupStatus.getBean(ctx);
try {
List<Permission> permissions = new ArrayList<Permission>();
permissions.addAll(SimplePermission.getAllInstances());
permissions.addAll(createDisplayByRolePermissions(ctx));
permissions.addAll(createEditByRolePermissions(ctx));
PermissionRegistry.createRegistry(ctx, permissions);
@ -140,6 +145,30 @@ public class PermissionRegistry {
}
}
private Collection<Permission> createDisplayByRolePermissions(
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>();
list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN,
ctx));
list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR,
ctx));
list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR,
ctx));
list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC,
ctx));
return list;
}
private Collection<Permission> createEditByRolePermissions(
ServletContext ctx) {
List<Permission> list = new ArrayList<Permission>();
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN, ctx));
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR, ctx));
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR, ctx));
list.add(new EditByRolePermission("Public", RoleLevel.PUBLIC, ctx));
return list;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);

View file

@ -1,179 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Permit display of various data based on the user's Role level and the
* restrictions in the onotology.
*/
public class DisplayRestrictedDataByRoleLevelPolicy implements PolicyIface {
private static final Log log = LogFactory
.getLog(DisplayRestrictedDataByRoleLevelPolicy.class);
private final ServletContext ctx;
public DisplayRestrictedDataByRoleLevelPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* If the requested action is to display a property or a property statement,
* we might authorize it based on their role level.
*/
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whoToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth);
/*
* This policy treats a self-editor as no better than public. If you
* want self-editors to see their own properties, some other policy must
* grant that.
*/
if (userRole == RoleLevel.SELF) {
userRole = RoleLevel.PUBLIC;
}
PolicyDecision result;
if (whatToAuth instanceof DisplayDataProperty) {
result = isAuthorized((DisplayDataProperty) whatToAuth, userRole);
} else if (whatToAuth instanceof DisplayObjectProperty) {
result = isAuthorized((DisplayObjectProperty) whatToAuth, userRole);
} else if (whatToAuth instanceof DisplayDataPropertyStatement) {
result = isAuthorized((DisplayDataPropertyStatement) whatToAuth,
userRole);
} else if (whatToAuth instanceof DisplayObjectPropertyStatement) {
result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth,
userRole);
} else {
result = defaultDecision("Unrecognized action");
}
log.debug("decision for '" + whatToAuth + "' is " + result);
return result;
}
/**
* The user may see this data property if they are allowed to see its
* predicate.
*/
private PolicyDecision isAuthorized(DisplayDataProperty action,
RoleLevel userRole) {
String predicateUri = action.getDataProperty().getURI();
if (canDisplayPredicate(predicateUri, userRole)) {
return authorized("user may view DataProperty " + predicateUri);
} else {
return defaultDecision("user may not view DataProperty "
+ predicateUri);
}
}
/**
* The user may see this object property if they are allowed to see its
* predicate.
*/
private PolicyDecision isAuthorized(DisplayObjectProperty action,
RoleLevel userRole) {
String predicateUri = action.getObjectProperty().getURI();
if (canDisplayPredicate(predicateUri, userRole)) {
return authorized("user may view ObjectProperty " + predicateUri);
} else {
return defaultDecision("user may not view ObjectProperty "
+ predicateUri);
}
}
/**
* The user may see this data property if they are allowed to see its
* subject and its predicate.
*/
private PolicyDecision isAuthorized(DisplayDataPropertyStatement action,
RoleLevel userRole) {
DataPropertyStatement stmt = action.getDataPropertyStatement();
String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI();
if (canDisplayResource(subjectUri, userRole)
&& canDisplayPredicate(predicateUri, userRole)) {
return authorized("user may view DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
} else {
return defaultDecision("user may not view DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
}
}
/**
* The user may see this data property if they are allowed to see its
* subject, its predicate, and its object.
*/
private PolicyDecision isAuthorized(DisplayObjectPropertyStatement action,
RoleLevel userRole) {
ObjectPropertyStatement stmt = action.getObjectPropertyStatement();
String subjectUri = stmt.getSubjectURI();
String predicateUri = stmt.getPropertyURI();
String objectUri = stmt.getObjectURI();
if (canDisplayResource(subjectUri, userRole)
&& canDisplayPredicate(predicateUri, userRole)
&& canDisplayResource(objectUri, userRole)) {
return authorized("user may view ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
} else {
return defaultDecision("user may not view ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
}
}
/** If the user is explicitly authorized, return this. */
private PolicyDecision authorized(String message) {
String className = this.getClass().getSimpleName();
return new BasicPolicyDecision(Authorization.AUTHORIZED, className
+ ": " + message);
}
/** If the user isn't explicitly authorized, return this. */
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
private boolean canDisplayResource(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
uri, userRole);
}
private boolean canDisplayPredicate(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(uri, userRole);
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
}

View file

@ -1,147 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
/**
* Permit adding, editing, or deleting of various data based on the user's Role
* level and the restrictions in the ontology.
*
* This policy only authorizes users who are Editors, Curators or DBAs.
* Self-editors and users who are not logged in must look elsewhere for
* authorization.
*/
public class EditRestrictedDataByRoleLevelPolicy implements PolicyIface {
private static final Log log = LogFactory
.getLog(EditRestrictedDataByRoleLevelPolicy.class);
private final ServletContext ctx;
public EditRestrictedDataByRoleLevelPolicy(ServletContext ctx) {
this.ctx = ctx;
}
/**
* If the requested action is to edit a property statement, we might
* authorize it based on their role level.
*/
@Override
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
RequestedAction whatToAuth) {
if (whoToAuth == null) {
return defaultDecision("whomToAuth was null");
}
if (whatToAuth == null) {
return defaultDecision("whatToAuth was null");
}
RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth);
if (!userRoleIsHighEnough(userRole)) {
return defaultDecision("insufficient role level: " + userRole);
}
PolicyDecision result;
if (whatToAuth instanceof AbstractDataPropertyAction) {
result = isAuthorized((AbstractDataPropertyAction) whatToAuth,
userRole);
} else if (whatToAuth instanceof AbstractObjectPropertyAction) {
result = isAuthorized((AbstractObjectPropertyAction) whatToAuth,
userRole);
} else {
result = defaultDecision("Unrecognized action");
}
log.debug("whoToAuth: " + whoToAuth);
log.debug("decision for '" + whatToAuth + "' is " + result);
return result;
}
/**
* We only consider Editors, Curators and DBAs.
*/
private boolean userRoleIsHighEnough(RoleLevel userRole) {
return (userRole == RoleLevel.EDITOR)
|| (userRole == RoleLevel.CURATOR)
|| (userRole == RoleLevel.DB_ADMIN);
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject and its predicate.
*/
private PolicyDecision isAuthorized(AbstractDataPropertyAction action,
RoleLevel userRole) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
if (canModifyResource(subjectUri, userRole)
&& canModifyPredicate(predicateUri, userRole)) {
return authorized("user may modify DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
} else {
return defaultDecision("user may not modify DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
}
}
/**
* The user may add, edit, or delete this data property if they are allowed
* to modify its subject, its predicate, and its object.
*/
private PolicyDecision isAuthorized(AbstractObjectPropertyAction action,
RoleLevel userRole) {
String subjectUri = action.getUriOfSubject();
String predicateUri = action.getUriOfPredicate();
String objectUri = action.getUriOfObject();
if (canModifyResource(subjectUri, userRole)
&& canModifyPredicate(predicateUri, userRole)
&& canModifyResource(objectUri, userRole)) {
return authorized("user may modify ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
} else {
return defaultDecision("user may not modify ObjectPropertyStatement "
+ subjectUri + " ==> " + predicateUri + " ==> " + objectUri);
}
}
/** If the user is explicitly authorized, return this. */
private PolicyDecision authorized(String message) {
String className = this.getClass().getSimpleName();
return new BasicPolicyDecision(Authorization.AUTHORIZED, className
+ ": " + message);
}
/** If the user isn't explicitly authorized, return this. */
private PolicyDecision defaultDecision(String message) {
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message);
}
private boolean canModifyResource(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
uri, userRole);
}
private boolean canModifyPredicate(String uri, RoleLevel userRole) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, userRole);
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " - " + hashCode();
}
}

View file

@ -9,14 +9,12 @@ import javax.servlet.ServletContextListener;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionSetFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProfileOrIsBlacklistedFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingRightsFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EditRestrictedDataByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
@ -35,15 +33,13 @@ public class CommonPolicyFamilySetup implements ServletContextListener {
try {
policy(ctx, new PermissionsPolicy());
policy(ctx, new DisplayRestrictedDataByRoleLevelPolicy(ctx));
policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx));
policy(ctx, new EditRestrictedDataByRoleLevelPolicy(ctx));
policy(ctx, new SelfEditingPolicy(ctx));
factory(ctx, new IsUserFactory(ctx));
factory(ctx, new IsRootUserFactory(ctx));
factory(ctx, new HasRoleLevelFactory(ctx));
factory(ctx, new HasProfileOrIsBlacklistedFactory(ctx));
factory(ctx, new HasPermissionSetFactory(ctx));
factory(ctx, new HasPermissionFactory(ctx));
factory(ctx, new HasProxyEditingRightsFactory(ctx));
} catch (Exception e) {

View file

@ -16,11 +16,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
@ -71,20 +68,22 @@ public class LoginRedirector {
if (isSelfEditorWithIndividual()) {
log.debug("Going to Individual home page.");
return getAssociatedIndividualHomePage();
} else if (isMerelySelfEditor()) {
}
if (!canSeeSiteAdminPage()) {
log.debug("User not recognized. Going to application home.");
return getApplicationHomePageUrl();
}
if (isLoginPage(afterLoginPage)) {
log.debug("Coming from /login. Going to site admin page.");
return getSiteAdminPageUrl();
} else if (null != afterLoginPage) {
log.debug("Returning to requested page: " + afterLoginPage);
return afterLoginPage;
} else {
if (isLoginPage(afterLoginPage)) {
log.debug("Coming from /login. Going to site admin page.");
return getSiteAdminPageUrl();
} else if (null != afterLoginPage) {
log.debug("Returning to requested page: " + afterLoginPage);
return afterLoginPage;
} else {
log.debug("Don't know what to do. Go home.");
return getApplicationHomePageUrl();
}
log.debug("Don't know what to do. Go home.");
return getApplicationHomePageUrl();
}
}
@ -113,7 +112,7 @@ public class LoginRedirector {
}
public String assembleWelcomeMessage() {
if (isMerelySelfEditor() && !isSelfEditorWithIndividual()) {
if (!canSeeSiteAdminPage() && !isSelfEditorWithIndividual()) {
// A special message for unrecognized self-editors:
return "You have logged in, "
+ "but the system contains no profile for you.";
@ -147,14 +146,9 @@ public class LoginRedirector {
}
}
private boolean isMerelySelfEditor() {
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(request);
if (IsRootUser.isRootUser(ids)) {
return false;
}
RoleLevel role = HasRoleLevel.getUsersRoleLevel(ids);
return role == RoleLevel.PUBLIC || role == RoleLevel.SELF;
private boolean canSeeSiteAdminPage() {
return PolicyHelper.isAuthorizedForActions(request,
SimplePermission.SEE_SITE_ADMIN_PAGE.ACTIONS);
}
private boolean isLoginPage(String page) {

View file

@ -0,0 +1,124 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.dao.filtering.filters;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import net.sf.jga.fn.UnaryFunctor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* Filter the properties depending on what DisplayByRolePermission is on the
* request. If no request, or no permission, use the Public permission.
*/
public class FilterByRoleLevelPermission extends VitroFiltersImpl {
private static final Log log = LogFactory
.getLog(FilterByRoleLevelPermission.class);
private final Permission permission;
private static Permission getDefaultPermission(ServletContext ctx) {
if (ctx == null) {
throw new NullPointerException("context may not be null.");
}
return PermissionRegistry.getRegistry(ctx).getPermission(
DisplayByRolePermission.NAMESPACE + "Public");
}
private static Permission getPermissionFromRequest(HttpServletRequest req) {
if (req == null) {
throw new NullPointerException("request may not be null.");
}
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req);
for (Permission p : HasPermission.getPermissions(ids)) {
if (p instanceof DisplayByRolePermission) {
return p;
}
}
return getDefaultPermission(req.getSession().getServletContext());
}
/** Get the DisplayByRolePermission from the request, or use Public. */
public FilterByRoleLevelPermission(HttpServletRequest req) {
this(getPermissionFromRequest(req));
}
/** Use the Public permission. */
public FilterByRoleLevelPermission(ServletContext ctx) {
this(getDefaultPermission(ctx));
}
/** Use the specified permission. */
public FilterByRoleLevelPermission(Permission permission) {
if (permission == null) {
throw new NullPointerException("permission may not be null.");
}
this.permission = permission;
setDataPropertyFilter(new DataPropertyFilterByPolicy());
setObjectPropertyFilter(new ObjectPropertyFilterByPolicy());
setDataPropertyStatementFilter(new DataPropertyStatementFilterByPolicy());
setObjectPropertyStatementFilter(new ObjectPropertyStatementFilterByPolicy());
}
boolean checkAuthorization(RequestedAction whatToAuth) {
boolean decision = permission.isAuthorized(whatToAuth);
log.debug("decision is " + decision);
return decision;
}
private class DataPropertyFilterByPolicy extends
UnaryFunctor<DataProperty, Boolean> {
@Override
public Boolean fn(DataProperty dp) {
return checkAuthorization(new DisplayDataProperty(dp));
}
}
private class ObjectPropertyFilterByPolicy extends
UnaryFunctor<ObjectProperty, Boolean> {
@Override
public Boolean fn(ObjectProperty op) {
return checkAuthorization(new DisplayObjectProperty(op));
}
}
private class DataPropertyStatementFilterByPolicy extends
UnaryFunctor<DataPropertyStatement, Boolean> {
@Override
public Boolean fn(DataPropertyStatement dps) {
return checkAuthorization(new DisplayDataPropertyStatement(dps));
}
}
private class ObjectPropertyStatementFilterByPolicy extends
UnaryFunctor<ObjectPropertyStatement, Boolean> {
@Override
public Boolean fn(ObjectPropertyStatement ops) {
return checkAuthorization(new DisplayObjectPropertyStatement(ops));
}
}
}

View file

@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.filtering.filters;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletContext;
@ -14,8 +13,6 @@ import net.sf.jga.fn.UnaryFunctor;
import net.sf.jga.fn.adaptor.ChainUnary;
import net.sf.jga.fn.property.GetProperty;
import net.sf.jga.fn.string.Match;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
/**
* Static methods to help create commonly used filters.
@ -26,9 +23,7 @@ public class VitroFilterUtils {
* public view.
*/
public static VitroFilters getPublicFilter(ServletContext ctx) {
return new HideFromDisplayByPolicyFilter(
new ArrayIdentifierBundle(),
new DisplayRestrictedDataByRoleLevelPolicy(ctx));
return new FilterByRoleLevelPermission(ctx);
}
/** Gets a VitroFilters that permits all objects */

View file

@ -12,7 +12,6 @@ import org.apache.xerces.util.XMLChar;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProfile;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser;
public class EditN3Utils {
@ -23,7 +22,6 @@ public class EditN3Utils {
List<String> uris = new ArrayList<String>();
uris.addAll(IsUser.getUserUris(ids));
uris.addAll(HasProfile.getProfileUris(ids));
uris.addAll(HasRoleLevel.getRoleLevelUris(ids));
uris.add("Unknown N3 Editor");
return uris.get(0);
}

View file

@ -36,9 +36,13 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
@ -125,7 +129,13 @@ public class AuthenticateTest extends AbstractTestClass {
authenticator.setAssociatedUri(OLD_SELF.username,
"old_self_associated_uri");
PermissionSet adminPermissionSet = new PermissionSet();
adminPermissionSet.setUri(URI_DBA);
adminPermissionSet.setPermissionUris(Collections
.singleton(SimplePermission.SEE_SITE_ADMIN_PAGE.getUri()));
userAccountsDao = new UserAccountsDaoStub();
userAccountsDao.addPermissionSet(adminPermissionSet);
userAccountsDao.addUser(createUserFromUserInfo(NEW_DBA));
userAccountsDao.addUser(createUserFromUserInfo(OLD_DBA));
userAccountsDao.addUser(createUserFromUserInfo(OLD_SELF));
@ -140,6 +150,11 @@ public class AuthenticateTest extends AbstractTestClass {
servletContext = new ServletContextStub();
servletContext.setAttribute("webappDaoFactory", webappDaoFactory);
setLoggerLevel(ServletPolicyList.class, Level.WARN);
ServletPolicyList.addPolicy(servletContext, new PermissionsPolicy());
PermissionRegistry.createRegistry(servletContext,
Collections.singleton(SimplePermission.SEE_SITE_ADMIN_PAGE));
servletConfig = new ServletConfigStub();
servletConfig.setServletContext(servletContext);
@ -153,9 +168,6 @@ public class AuthenticateTest extends AbstractTestClass {
response = new HttpServletResponseStub();
PermissionRegistry.createRegistry(servletContext,
Collections.<Permission> emptySet());
auth = new Authenticate();
auth.init(servletConfig);
@ -163,7 +175,7 @@ public class AuthenticateTest extends AbstractTestClass {
new ConfigurationPropertiesStub().setBean(servletContext);
ActiveIdentifierBundleFactories.addFactory(servletContext,
new HasRoleLevelFactory(servletContext));
new HasPermissionFactory(servletContext));
}
private UserAccount createUserFromUserInfo(UserInfo userInfo) {

View file

@ -3,6 +3,8 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
@prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
@prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> .
@prefix editByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.EditByRolePermission#> .
auth:ADMIN
a auth:PermissionSet ;
@ -45,6 +47,10 @@ auth:ADMIN
# permissions for ANY user, even if they are not logged in.
auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for ADMIN
auth:hasPermission displayByRole:Admin ;
auth:hasPermission editByRole:Admin ;
.
auth:CURATOR
@ -76,6 +82,10 @@ auth:CURATOR
# permissions for ANY user, even if they are not logged in.
auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for CURATOR
auth:hasPermission displayByRole:Curator ;
auth:hasPermission editByRole:Curator ;
.
auth:EDITOR
@ -99,6 +109,10 @@ auth:EDITOR
# permissions for ANY user, even if they are not logged in.
auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for EDITOR
auth:hasPermission displayByRole:Editor ;
auth:hasPermission editByRole:Editor ;
.
auth:SELF_EDITOR
@ -116,6 +130,12 @@ auth:SELF_EDITOR
# permissions for ANY user, even if they are not logged in.
auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for SELF_EDITOR
# For role-based display and editing, SelfEditor is like Public.
# SelfEditor uses its special permissions to edit/display its own values.
auth:hasPermission displayByRole:Public ;
auth:hasPermission editByRole:Public ;
.
auth:PUBLIC
@ -125,4 +145,8 @@ auth:PUBLIC
# permissions for ANY user, even if they are not logged in.
auth:hasPermission simplePermission:QueryFullModel ;
# role-based permissions for PUBLIC
auth:hasPermission displayByRole:Public ;
auth:hasPermission editByRole:Public ;
.

View file

@ -46,7 +46,8 @@ edu.cornell.mannlib.vitro.webapp.auth.policy.RootUserPolicy$Setup
edu.cornell.mannlib.vitro.webapp.auth.policy.RestrictHomeMenuItemEditingPolicy$Setup
# The Solr index uses a "public" filter, so the PropertyRestrictionPolicyHelper must already be set up.
# The Solr index uses a "public" permission, so the PropertyRestrictionPolicyHelper
# and the PermissionRegistry must already be set up.
edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup
edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
@ -54,6 +55,8 @@ edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
# On shutdown, this will kill the background thread started by Apache Commons File Upload
org.apache.commons.fileupload.servlet.FileCleanerCleanup
# The VClassGroupCache index uses a "public" permission, so the PropertyRestrictionPolicyHelper
# and the PermissionRegistry must already be set up.
edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache$Setup
# This should be near the end, because it will issue a warning if the connection to Solr times out.