From 863718241ded51cc711d2d67ceca70baa24b9ed8 Mon Sep 17 00:00:00 2001 From: j2blake Date: Mon, 11 Apr 2011 19:39:36 +0000 Subject: [PATCH] NIHVIVO-2254 Create RequestedActions to display properties and statements. Create policies for authorizing those actions. Create Identifiers for those policies to recognize. Create a filter that is based on policy authorizations. Use that filter instead of the one that is based only on role level. --- webapp/config/web.xml | 5 + .../CommonIdentifierBundleFactory.java | 117 ++++++++++ .../identifier/HasAssociatedIndividual.java | 195 ++++++++++++++++ .../webapp/auth/identifier/HasRoleLevel.java | 20 ++ ...isplayRestrictedDataByRoleLevelPolicy.java | 180 +++++++++++++++ .../DisplayRestrictedDataToSelfPolicy.java | 211 ++++++++++++++++++ .../policy/setup/CommonPolicyFamilySetup.java | 56 +++++ .../display/DisplayDataProperty.java | 19 ++ .../display/DisplayDataPropertyStatement.java | 20 ++ .../display/DisplayObjectProperty.java | 19 ++ .../DisplayObjectPropertyStatement.java | 20 ++ .../vitro/webapp/beans/BaseResourceBean.java | 2 +- .../HideFromDisplayByPolicyFilter.java | 94 ++++++++ .../filtering/filters/VitroFilterUtils.java | 95 ++++---- .../webapp/dao/jena/VClassGroupCache.java | 18 +- .../webapp/filters/VitroRequestPrep.java | 54 ++--- .../webapp/search/lucene/LuceneSetup.java | 3 +- .../webapp/search/lucene/LuceneSetupCJK.java | 4 +- 18 files changed, 1035 insertions(+), 97 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/CommonIdentifierBundleFactory.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasAssociatedIndividual.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasRoleLevel.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/HideFromDisplayByPolicyFilter.java diff --git a/webapp/config/web.xml b/webapp/config/web.xml index 3ac845523..adb00a220 100644 --- a/webapp/config/web.xml +++ b/webapp/config/web.xml @@ -164,6 +164,11 @@ + + edu.cornell.mannlib.vitro.webapp.auth.policy.setup.CommonPolicyFamilySetup + + + edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/CommonIdentifierBundleFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/CommonIdentifierBundleFactory.java new file mode 100644 index 000000000..7652e6f13 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/CommonIdentifierBundleFactory.java @@ -0,0 +1,117 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +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.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; + +/** + * Create Identifiers that are recognized by the common policy family. + */ +public class CommonIdentifierBundleFactory implements IdentifierBundleFactory { + private static final Log log = LogFactory + .getLog(CommonIdentifierBundleFactory.class); + + @Override + public IdentifierBundle getIdentifierBundle(ServletRequest request, + HttpSession session, ServletContext context) { + + // If this is not an HttpServletRequest, we might as well fail now. + HttpServletRequest req = (HttpServletRequest) request; + + ArrayIdentifierBundle bundle = new ArrayIdentifierBundle(); + + bundle.addAll(determineRoleLevelIdentifiers(req)); + bundle.addAll(determineAssociatedIndividualIdentifiers(req)); + + return bundle; + } + + /** + * Create an identifier that shows the role level of the current user, or + * PUBLIC if the user is not logged in. + */ + private Collection determineRoleLevelIdentifiers( + HttpServletRequest req) { + RoleLevel roleLevel = RoleLevel.getRoleFromLoginStatus(req); + return Collections.singleton(new HasRoleLevel(roleLevel)); + } + + /** + * Find all of the individuals that are associated with the current user, + * and create an Identifier for each one. + */ + private Collection determineAssociatedIndividualIdentifiers( + HttpServletRequest req) { + Collection ids = new ArrayList(); + + LoginStatusBean bean = LoginStatusBean.getBean(req); + String username = bean.getUsername(); + + if (!bean.isLoggedIn()) { + log.debug("No SelfEditing: not logged in."); + return ids; + } + + if (StringUtils.isEmpty(username)) { + log.debug("No SelfEditing: username is empty."); + return ids; + } + + HttpSession session = req.getSession(false); + if (session == null) { + log.debug("No SelfEditing: session is null."); + return ids; + } + + ServletContext context = session.getServletContext(); + WebappDaoFactory wdf = (WebappDaoFactory) context + .getAttribute("webappDaoFactory"); + if (wdf == null) { + log.error("Could not get a WebappDaoFactory from the ServletContext"); + return ids; + } + + IndividualDao indDao = wdf.getIndividualDao(); + + SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req); + String uri = sec.getIndividualUriFromUsername(indDao, username); + if (uri == null) { + log.debug("Could not find an Individual with a netId of " + + username); + return ids; + } + + Individual ind = indDao.getIndividualByURI(uri); + if (ind == null) { + log.warn("Found a URI for the netId " + username + + " but could not build Individual"); + return ids; + } + + log.debug("Found an Individual for netId " + username + " URI: " + uri); + + // Use the factory method to fill in the Blacklisting reason, if there + // is one. + ids.add(HasAssociatedIndividual.getInstance(ind, context)); + + return ids; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasAssociatedIndividual.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasAssociatedIndividual.java new file mode 100644 index 000000000..57fd06eec --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasAssociatedIndividual.java @@ -0,0 +1,195 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; + +import javax.servlet.ServletContext; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.RDFNode; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; + +/** + * The current user is associated with this Individual. + * + * This includes a thick factory method that will look through a directory of + * files to determine whether the associated individual is blacklisted. + */ +public class HasAssociatedIndividual implements Identifier { + private static final Log log = LogFactory + .getLog(HasAssociatedIndividual.class); + + private final static String BLACKLIST_SPARQL_DIR = "/admin/selfEditBlacklist"; + private static final String NOT_BLACKLISTED = null; + + // ---------------------------------------------------------------------- + // static methods + // ---------------------------------------------------------------------- + + public static HasAssociatedIndividual getInstance(Individual individual, + ServletContext context) { + if (individual == null) { + throw new NullPointerException("individual may not be null."); + } + if (context == null) { + throw new NullPointerException("context may not be null."); + } + + String reasonForBlacklisting = checkForBlacklisted(individual, context); + return new HasAssociatedIndividual(individual.getURI(), + reasonForBlacklisting); + } + + /** + * Runs through .sparql files in the BLACKLIST_SPARQL_DIR. + * + * The first that returns one or more rows will be cause the user to be + * blacklisted. + * + * The first variable from the first solution set will be returned. + */ + private static String checkForBlacklisted(Individual ind, + ServletContext context) { + String realPath = context.getRealPath(BLACKLIST_SPARQL_DIR); + File blacklistDir = new File(realPath); + if (!blacklistDir.isDirectory() || !blacklistDir.canRead()) { + log.debug("cannot read blacklist directory " + realPath); + return NOT_BLACKLISTED; + } + + log.debug("checking directlry " + realPath + + " for blacklisting sparql query files"); + File[] files = blacklistDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getName().endsWith(".sparql"); + } + }); + + String reasonForBlacklist = NOT_BLACKLISTED; + for (File file : files) { + try { + reasonForBlacklist = runSparqlFileForBlacklist(file, ind, + context); + if (reasonForBlacklist != NOT_BLACKLISTED) + break; + } catch (RuntimeException ex) { + log.error( + "Could not run blacklist check query for file " + + file.getAbsolutePath() + File.separatorChar + + file.getName(), ex); + } + } + return reasonForBlacklist; + } + + /** + * Runs the SPARQL query in the file with the uri of the individual + * substituted in. + * + * The URI of ind will be substituted into the query where ever the token + * "?individualURI" is found. + * + * If there are any solution sets, then the URI of the variable named + * "cause" will be returned. Make sure that it is a resource with a URI. + * Otherwise null will be returned. + */ + private static String runSparqlFileForBlacklist(File file, Individual ind, + ServletContext context) { + if (!file.canRead()) { + log.debug("cannot read blacklisting SPARQL file " + file.getName()); + return NOT_BLACKLISTED; + } + + String queryString = null; + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + byte b[] = new byte[fis.available()]; + fis.read(b); + queryString = new String(b); + } catch (IOException ioe) { + log.debug(ioe); + return NOT_BLACKLISTED; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + log.warn("could not close file", e); + } + } + } + + if (StringUtils.isEmpty(queryString)) { + log.debug(file.getName() + " is empty"); + return NOT_BLACKLISTED; + } + + Model model = (Model) context.getAttribute("jenaOntModel"); + + queryString = queryString.replaceAll("\\?individualURI", + "<" + ind.getURI() + ">"); + log.debug(queryString); + + Query query = QueryFactory.create(queryString); + QueryExecution qexec = QueryExecutionFactory.create(query, model); + try { + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution solution = results.nextSolution(); + if (solution.contains("cause")) { + RDFNode node = solution.get("cause"); + if (node.isResource()) { + return node.asResource().getURI(); + } else if (node.isLiteral()) { + return node.asLiteral().getString(); + } + } else { + log.error("Query solution must contain a variable " + + "\"cause\" of type Resource or Literal."); + return NOT_BLACKLISTED; + } + } + } finally { + qexec.close(); + } + return NOT_BLACKLISTED; + } + + // ---------------------------------------------------------------------- + // the Identifier + // ---------------------------------------------------------------------- + + private final String associatedIndividualUri; + private final String reasonForBlacklisting; + + public HasAssociatedIndividual(String associatedIndividualUri, + String reasonForBlacklisting) { + this.associatedIndividualUri = associatedIndividualUri; + this.reasonForBlacklisting = reasonForBlacklisting; + } + + public String getAssociatedIndividualUri() { + return associatedIndividualUri; + } + + public boolean isBlacklisted() { + return reasonForBlacklisting != NOT_BLACKLISTED; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasRoleLevel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasRoleLevel.java new file mode 100644 index 000000000..2b0d2019b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/HasRoleLevel.java @@ -0,0 +1,20 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier; + +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; + +/** + * The current user has this RoleLevel. + */ +public class HasRoleLevel implements Identifier { + private final RoleLevel roleLevel; + + public HasRoleLevel(RoleLevel roleLevel) { + this.roleLevel = roleLevel; + } + + public RoleLevel getRoleLevel() { + return roleLevel; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java new file mode 100644 index 000000000..383fecaba --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataByRoleLevelPolicy.java @@ -0,0 +1,180 @@ +/* $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.HasRoleLevel; +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.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 = getUsersRoleLevel(whoToAuth); + + 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); + } + + /** + * The user is nobody unless they have a HasRoleLevel identifier. + */ + private RoleLevel getUsersRoleLevel(IdentifierBundle whoToAuth) { + RoleLevel userRole = RoleLevel.PUBLIC; + for (Identifier id : whoToAuth) { + if (id instanceof HasRoleLevel) { + userRole = ((HasRoleLevel) id).getRoleLevel(); + } + } + return userRole; + } + +} 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 new file mode 100644 index 000000000..8911a2fa8 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java @@ -0,0 +1,211 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.HasAssociatedIndividual; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.HasRoleLevel; +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.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.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; + +/** + * Permit display of various data if it relates to the user's associated + * individual. + * + * This policy is only to handle the case where a user would not be able to see + * data except for their self-editing status. If the data would be visible + * without that status, we assume that some other policy will grant access. + */ +public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { + private static final Log log = LogFactory + .getLog(DisplayRestrictedDataToSelfPolicy.class); + + private final ServletContext ctx; + + public DisplayRestrictedDataToSelfPolicy(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 = getUsersRoleLevel(whoToAuth); + if (userRole != RoleLevel.SELF) { + return defaultDecision("not a self-editor"); + } + + Collection associated = getAssociatedIndividualUris(whoToAuth); + if (associated.isEmpty()) { + return defaultDecision("not self-editing for anyone"); + } + + if (whatToAuth instanceof DisplayDataProperty) { + return defaultDecision("DataProperties have no associated 'self'"); + } else if (whatToAuth instanceof DisplayObjectProperty) { + return defaultDecision("ObjectProperties have no associated 'self'"); + } + + PolicyDecision result; + if (whatToAuth instanceof DisplayDataPropertyStatement) { + result = isAuthorized((DisplayDataPropertyStatement) whatToAuth, + associated); + } else if (whatToAuth instanceof DisplayObjectPropertyStatement) { + result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth, + associated); + } else { + result = defaultDecision("Unrecognized action"); + } + + log.debug("decision for '" + whatToAuth + "' is " + result); + return result; + } + + /** + * The user may see this data property statement if the subject and the + * predicate are both viewable by self-editors, and the subject is one of + * the associated individuals (the "selves"). + */ + private PolicyDecision isAuthorized(DisplayDataPropertyStatement action, + Collection individuals) { + DataPropertyStatement stmt = action.getDataPropertyStatement(); + String subjectUri = stmt.getIndividualURI(); + String predicateUri = stmt.getDatapropURI(); + if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) + && isAboutAssociatedIndividual(individuals, stmt)) { + 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 statement if the subject, the + * predicate, and the object are all viewable by self-editors, and either + * the subject or the object is one of the associated individuals (the + * "selves"). + */ + private PolicyDecision isAuthorized(DisplayObjectPropertyStatement action, + Collection individuals) { + ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); + String subjectUri = stmt.getSubjectURI(); + String predicateUri = stmt.getPropertyURI(); + String objectUri = stmt.getObjectURI(); + if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) + && canDisplayResource(objectUri) + && isAboutAssociatedIndividual(individuals, stmt)) { + 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) { + return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( + uri, RoleLevel.SELF); + } + + private boolean canDisplayPredicate(String uri) { + return PropertyRestrictionPolicyHelper.getBean(ctx) + .canDisplayPredicate(uri, RoleLevel.SELF); + } + + private boolean isAboutAssociatedIndividual(Collection selves, + DataPropertyStatement stmt) { + for (String self : selves) { + if (self.equals(stmt.getIndividualURI())) { + return true; + } + } + return false; + } + + private boolean isAboutAssociatedIndividual(Collection selves, + ObjectPropertyStatement stmt) { + for (String self : selves) { + if (self.equals(stmt.getSubjectURI()) + || self.equals(stmt.getObjectURI())) { + return true; + } + } + return false; + } + + /** + * The user is nobody unless they have a HasRoleLevel identifier. + */ + private RoleLevel getUsersRoleLevel(IdentifierBundle whoToAuth) { + RoleLevel userRole = RoleLevel.PUBLIC; + for (Identifier id : whoToAuth) { + if (id instanceof HasRoleLevel) { + userRole = ((HasRoleLevel) id).getRoleLevel(); + } + } + return userRole; + } + + /** + * Find out who the user has self-editing rights for. We only include the + * ones that are not blacklisted. + */ + private Collection getAssociatedIndividualUris( + IdentifierBundle whoToAuth) { + List list = new ArrayList(); + for (Identifier id : whoToAuth) { + if (id instanceof HasAssociatedIndividual) { + HasAssociatedIndividual haiId = (HasAssociatedIndividual) id; + if (!haiId.isBlacklisted()) { + list.add(haiId.getAssociatedIndividualUri()); + } + } + } + return list; + } + +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java new file mode 100644 index 000000000..ff6eee6e4 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -0,0 +1,56 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy.setup; + +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.auth.identifier.ActiveIdentifierBundleFactories; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.CommonIdentifierBundleFactory; +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.ServletPolicyList; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup; + +/** + * Set up the common policy family, with Identifier factory. + */ +public class CommonPolicyFamilySetup implements ServletContextListener { + private static final Log log = LogFactory + .getLog(CommonPolicyFamilySetup.class); + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + + if (AbortStartup.isStartupAborted(ctx)) { + return; + } + + try { + ServletPolicyList.addPolicy(ctx, + new DisplayRestrictedDataByRoleLevelPolicy(ctx)); + ServletPolicyList.addPolicy(ctx, + new DisplayRestrictedDataToSelfPolicy(ctx)); + + // This factory creates Identifiers for all of the above policies. + CommonIdentifierBundleFactory factory = new CommonIdentifierBundleFactory(); + + ActiveIdentifierBundleFactories.addFactory(sce, factory); + } catch (Exception e) { + log.error("could not run " + this.getClass().getSimpleName() + ": " + + e); + AbortStartup.abortStartup(ctx); + throw new RuntimeException(e); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { /* nothing */ + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java new file mode 100644 index 000000000..9341cdd20 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java @@ -0,0 +1,19 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; + +/** Should we allow the user to see this DataProperty? */ +public class DisplayDataProperty extends RequestedAction { + private final DataProperty dataProperty; + + public DisplayDataProperty(DataProperty dataProperty) { + this.dataProperty = dataProperty; + } + + public DataProperty getDataProperty() { + return dataProperty; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java new file mode 100644 index 000000000..75601a27e --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java @@ -0,0 +1,20 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; + +/** Should we let the user see this DataPropertyStatement? */ +public class DisplayDataPropertyStatement extends RequestedAction { + private final DataPropertyStatement dataPropertyStatement; + + public DisplayDataPropertyStatement( + DataPropertyStatement dataPropertyStatement) { + this.dataPropertyStatement = dataPropertyStatement; + } + + public DataPropertyStatement getDataPropertyStatement() { + return dataPropertyStatement; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java new file mode 100644 index 000000000..49161abe1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java @@ -0,0 +1,19 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; + +/** Should we allow the user to see this ObjectProperty? */ +public class DisplayObjectProperty extends RequestedAction { + private final ObjectProperty objectProperty; + + public DisplayObjectProperty(ObjectProperty objectProperty) { + this.objectProperty = objectProperty; + } + + public ObjectProperty getObjectProperty() { + return objectProperty; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java new file mode 100644 index 000000000..b78ec967b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java @@ -0,0 +1,20 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; + +/** Should we let the user see this ObjectPropertyStatement? */ +public class DisplayObjectPropertyStatement extends RequestedAction { + private final ObjectPropertyStatement objectPropertyStatement; + + public DisplayObjectPropertyStatement( + ObjectPropertyStatement objectPropertyStatement) { + this.objectPropertyStatement = objectPropertyStatement; + } + + public ObjectPropertyStatement getObjectPropertyStatement() { + return objectPropertyStatement; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java index 9e2fadf87..e661e9dcd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java @@ -73,7 +73,7 @@ public class BaseResourceBean implements ResourceBean { if( level == LoginStatusBean.ANYBODY) // 0 return PUBLIC; if( level == LoginStatusBean.NON_EDITOR) // 1 - return PUBLIC; // no correspondence with self-editing, which does not authorize through the LoginStatusBean + return SELF; if( level == LoginStatusBean.EDITOR ) // 4 return EDITOR; if( level == LoginStatusBean.CURATOR ) // 5 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/HideFromDisplayByPolicyFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/HideFromDisplayByPolicyFilter.java new file mode 100644 index 000000000..164a00061 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/HideFromDisplayByPolicyFilter.java @@ -0,0 +1,94 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.filtering.filters; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import net.sf.jga.fn.UnaryFunctor; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +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.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; + +/** + * Ask the current policies whether we can show these things to the user. + */ +public class HideFromDisplayByPolicyFilter extends VitroFiltersImpl { + private static final Log log = LogFactory + .getLog(HideFromDisplayByPolicyFilter.class); + + private final IdentifierBundle idBundle; + private final PolicyIface policy; + + public HideFromDisplayByPolicyFilter(IdentifierBundle idBundle, + PolicyIface policy) { + if (idBundle == null) { + throw new NullPointerException("idBundle may not be null."); + } + if (policy == null) { + throw new NullPointerException("policy may not be null."); + } + + this.idBundle = idBundle; + this.policy = policy; + + setDataPropertyFilter(new DataPropertyFilterByPolicy()); + setObjectPropertyFilter(new ObjectPropertyFilterByPolicy()); + setDataPropertyStatementFilter(new DataPropertyStatementFilterByPolicy()); + setObjectPropertyStatementFilter(new ObjectPropertyStatementFilterByPolicy()); + } + + boolean checkAuthorization(RequestedAction whatToAuth) { + PolicyDecision decision = policy.isAuthorized(idBundle, whatToAuth); + log.debug("decision is " + decision); + + if (decision != null) { + if (decision.getAuthorized() == Authorization.AUTHORIZED) { + return true; + } + } + return false; + } + + private class DataPropertyFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(DataProperty dp) { + return checkAuthorization(new DisplayDataProperty(dp)); + } + } + + private class ObjectPropertyFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(ObjectProperty op) { + return checkAuthorization(new DisplayObjectProperty(op)); + } + } + + private class DataPropertyStatementFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(DataPropertyStatement dps) { + return checkAuthorization(new DisplayDataPropertyStatement(dps)); + } + } + + private class ObjectPropertyStatementFilterByPolicy extends + UnaryFunctor { + @Override + public Boolean fn(ObjectPropertyStatement ops) { + return checkAuthorization(new DisplayObjectPropertyStatement(ops)); + } + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java index 6a89d74f7..5c4ceaf33 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/VitroFilterUtils.java @@ -8,36 +8,28 @@ import java.util.Comparator; import java.util.Date; import java.util.List; +import javax.servlet.ServletContext; + import net.sf.jga.fn.UnaryFunctor; -import net.sf.jga.fn.adaptor.AdaptorFunctors; import net.sf.jga.fn.adaptor.ChainUnary; import net.sf.jga.fn.property.GetProperty; import net.sf.jga.fn.string.Match; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +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; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; /** * Static methods to help create commonly used filters. - * - * @author bdc34 - * */ public class VitroFilterUtils { - protected static UnaryFunctor t = AdaptorFunctors.constantUnary(Boolean.TRUE); - - private static final Log log = LogFactory.getLog(VitroFilterUtils.class.getName()); - - /** - * Gets a filter that filters out any resource - * that has a annotation of hiddenFromDisplayBelowRoleLevel higher than current user's role level - */ - public static VitroFilters getDisplayFilterByRoleLevel(RoleLevel role, WebappDaoFactory wdf){ - return new HiddenFromDisplayBelowRoleLevelFilter(role, wdf); - } + /** + * Gets a filter that hides any property or resource that is restricted from + * public view. + */ + public static VitroFilters getPublicFilter(ServletContext ctx) { + return new HideFromDisplayByPolicyFilter( + new ArrayIdentifierBundle(), + new DisplayRestrictedDataByRoleLevelPolicy(ctx)); + } /** Gets a VitroFilters that permits all objects */ protected static VitroFiltersImpl getNoOpFilter(){ @@ -55,21 +47,19 @@ public class VitroFilterUtils { public static UnaryFunctor FirstLetterOfIndividuals(){ return new UnaryFunctor(){ - public String fn(Individual arg){ + @Override + public String fn(Individual arg){ return arg.getName().substring(0,1); } - public String toString(){ return "filter: FirstLetterOfIndividuals"; } + @Override + public String toString(){ return "filter: FirstLetterOfIndividuals"; } }; } public static class EntitySortTransform extends UnaryFunctor,List>{ - private final String fieldName; - private final boolean ascending; private final Comparator comparator; public EntitySortTransform( String fieldName, boolean ascending){ - this.fieldName = fieldName; - this.ascending = ascending; if ( "timekey".equalsIgnoreCase( fieldName )){ if( ascending ) comparator = timekeyComp; @@ -95,14 +85,16 @@ public class VitroFilterUtils { } } - public List fn(List individuals) { + @Override + public List fn(List individuals) { Collections.sort(individuals,comparator); return individuals; } private static Comparator timekeyComp = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getTimekey(); Date time2 = o2.getTimekey(); if( time1 == null && time2 == null ) @@ -113,11 +105,13 @@ public class VitroFilterUtils { return -1; return time1.compareTo(time2); } - public String toString(){ return "timekeyComp"; } + @Override + public String toString(){ return "timekeyComp"; } }; private static Comparator sunsetComp = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getSunset(); Date time2 = o2.getSunset(); if( time1 == null && time2 == null ) @@ -128,11 +122,13 @@ public class VitroFilterUtils { return -1; return time1.compareTo(time2); } - public String toString(){ return "sunsetComp"; } + @Override + public String toString(){ return "sunsetComp"; } }; private static Comparator sunriseComp = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getSunrise(); Date time2 = o2.getSunrise(); if( time1 == null && time2 == null ) @@ -143,13 +139,15 @@ public class VitroFilterUtils { return -1; return time1.compareTo(time2); } - public String toString(){ return "sunriseComp"; } + @Override + public String toString(){ return "sunriseComp"; } }; private static Comparator nameComp = new Comparator(){ // return ((Individual)o1).getName().compareTo(((Individual)o2).getName()); - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { String name1 = o1.getName(); String name2 = o2.getName(); if( name1 == null && name2 == null ) @@ -162,12 +160,14 @@ public class VitroFilterUtils { return collator.compare(name1,name2); //return name1.compareTo(name2); } - public String toString(){ return "nameComp"; } + @Override + public String toString(){ return "nameComp"; } }; private static Comparator timekeyCompDesc = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getTimekey(); Date time2 = o2.getTimekey(); if( time1 == null && time2 == null ) @@ -178,11 +178,13 @@ public class VitroFilterUtils { return 1; return time2.compareTo(time1); } - public String toString(){ return "timkeyCompDesc"; } + @Override + public String toString(){ return "timkeyCompDesc"; } }; private static Comparator sunsetCompDesc = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getSunset(); Date time2 = o2.getSunset(); if( time1 == null && time2 == null ) @@ -193,11 +195,13 @@ public class VitroFilterUtils { return 1; return time2.compareTo(time1); } - public String toString(){ return "sunsetCompDesc"; } + @Override + public String toString(){ return "sunsetCompDesc"; } }; private static Comparator sunriseCompDesc = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { Date time1 = o1.getSunrise(); Date time2 = o2.getSunrise(); if( time1 == null && time2 == null ) @@ -208,11 +212,13 @@ public class VitroFilterUtils { return 1; return time2.compareTo(time1); } - public String toString(){ return "sunriseCompDesc"; } + @Override + public String toString(){ return "sunriseCompDesc"; } }; private static Comparator nameCompDesc = new Comparator(){ - public int compare(Individual o1, Individual o2) { + @Override + public int compare(Individual o1, Individual o2) { String name1 = o1.getName(); String name2 = o2.getName(); if( name1 == null && name2 == null ) @@ -225,7 +231,8 @@ public class VitroFilterUtils { return collator.compare(name1,name2); //return name2.compareTo(name1); } - public String toString(){ return "nameCompDesc"; } + @Override + public String toString(){ return "nameCompDesc"; } }; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java index 6ba26f2d1..3389714ac 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java @@ -2,14 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletContext; @@ -23,17 +19,14 @@ import com.hp.hpl.jena.rdf.listeners.StatementListener; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; -import edu.cornell.mannlib.vitro.webapp.flags.PortalFlag; import edu.cornell.mannlib.vitro.webapp.servlet.setup.AbortStartup; public class VClassGroupCache{ @@ -153,15 +146,8 @@ public class VClassGroupCache{ return Collections.emptyList(); } - VitroFilters vFilters = null; - vFilters = VitroFilterUtils.getDisplayFilterByRoleLevel(RoleLevel.PUBLIC, wdFactory); - - WebappDaoFactory filteringDaoFactory ; - if( vFilters !=null ){ - filteringDaoFactory = new WebappDaoFactoryFiltering(wdFactory,vFilters); - }else{ - filteringDaoFactory = wdFactory; - } + VitroFilters vFilters = VitroFilterUtils.getPublicFilter(context); + WebappDaoFactory filteringDaoFactory = new WebappDaoFactoryFiltering(wdFactory,vFilters); // BJL23: You may be wondering, why this extra method? // Can't we just use the filtering DAO? diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index ea28872cd..171f6e7fa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -26,6 +26,7 @@ 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.SelfEditingIdentifierFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.SelfEditingIdentifierFactory.SelfEditing; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.Portal; @@ -34,7 +35,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PortalDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.FilterFactory; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HiddenFromDisplayBelowRoleLevelFilter; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.flags.FlagException; @@ -76,7 +77,8 @@ public class VitroRequestPrep implements Filter { private static final Log log = LogFactory.getLog(VitroRequestPrep.class.getName()); - public void doFilter(ServletRequest request, + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -166,32 +168,21 @@ public class VitroRequestPrep implements Filter { filters = getFiltersFromContextFilterFactory(req, wdf); - /* bdc34:to be removed in vivo 1.3 - if( wdf.getApplicationDao().isFlag1Active() && (portalFlag != null) ){ - VitroFilters portalFilter = - VitroFilterUtils.getFilterFromPortalFlag(portalFlag); - if( filters != null ) - filters = filters.and(portalFilter); - else - filters = portalFilter; - } - */ - if( filters != null ){ log.debug("Wrapping WebappDaoFactory in portal filters"); wdf = new WebappDaoFactoryFiltering(wdf, filters); } } - /* display filtering happens now at any level, all the time; editing pages get their WebappDaoFactories differently */ - // TODO -- We can put a HidenFromDisplayByPolicyFilter here, since ID bundles are available from ActiveIdenfierBundleFactor and Policy is available from ServletPolicyList - WebappDaoFactory roleFilteredFact = - new WebappDaoFactoryFiltering(wdf, new HiddenFromDisplayBelowRoleLevelFilter( role, wdf )); - wdf = roleFilteredFact; - if( log.isDebugEnabled() ) log.debug("setting role-based WebappDaoFactory filter for role " + role.toString()); - - vreq.setWebappDaoFactory(wdf); - + /* + * display filtering happens now at any level, all the time; editing + * pages get their WebappDaoFactories differently + */ + HideFromDisplayByPolicyFilter filter = new HideFromDisplayByPolicyFilter( + RequestIdentifiers.getIdBundleForRequest(req), + ServletPolicyList.getPolicies(_context)); + vreq.setWebappDaoFactory(new WebappDaoFactoryFiltering(wdf, filter)); + // support for Dataset interface if using Jena in-memory model if (vreq.getDataset() == null) { Dataset dataset = WebappDaoFactoryJena.makeInMemoryDataset( @@ -209,14 +200,13 @@ public class VitroRequestPrep implements Filter { (WebappDaoFactory) _context.getAttribute("webappDaoFactory"); } - public void init(FilterConfig filterConfig) throws ServletException { + @Override + public void init(FilterConfig filterConfig) throws ServletException { _context = filterConfig.getServletContext(); - ApplicationBean a = null; - try { - a = (ApplicationBean) _context.getAttribute("applicationBean"); - } catch (Exception e) {} - if ( a != null ) { - _appbean = (ApplicationBean) a; + + Object o = _context.getAttribute("applicationBean"); + if (o instanceof ApplicationBean) { + _appbean = (ApplicationBean) o; } else { _appbean = new ApplicationBean(); } @@ -359,7 +349,7 @@ public class VitroRequestPrep implements Filter { if( request.getAttribute("home") != null) idStr = (String)request.getAttribute("home"); else if( request.getParameter("home") != null) - idStr = (String)request.getParameter("home"); + idStr = request.getParameter("home"); else if( request.getAttribute("home") != null) idStr = (String)request.getAttribute("home"); else @@ -428,7 +418,9 @@ public class VitroRequestPrep implements Filter { return true; } - public void destroy() { + @Override + public void destroy() { + // Nothing to do. } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetup.java index db1f462aa..9a5376c93 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetup.java @@ -30,7 +30,6 @@ import org.apache.lucene.util.Version; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -133,7 +132,7 @@ public class LuceneSetup implements javax.servlet.ServletContextListener { // get objects to index. It is filtered so that non-public text // does not get into the search index. WebappDaoFactory wadf = (WebappDaoFactory) context.getAttribute("webappDaoFactory"); - VitroFilters vf = VitroFilterUtils.getDisplayFilterByRoleLevel(RoleLevel.PUBLIC, wadf); + VitroFilters vf = VitroFilterUtils.getPublicFilter(context); wadf = new WebappDaoFactoryFiltering(wadf, vf); List sources = new ArrayList(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetupCJK.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetupCJK.java index c71c9c0ed..3e3949ed6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetupCJK.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/lucene/LuceneSetupCJK.java @@ -19,7 +19,6 @@ import org.apache.lucene.search.BooleanQuery; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -103,8 +102,7 @@ public class LuceneSetupCJK implements javax.servlet.ServletContextListener { //does not get into the search index. WebappDaoFactory wadf = (WebappDaoFactory) context.getAttribute("webappDaoFactory"); - VitroFilters vf = - VitroFilterUtils.getDisplayFilterByRoleLevel(RoleLevel.PUBLIC, wadf); + VitroFilters vf = VitroFilterUtils.getPublicFilter(context); wadf = new WebappDaoFactoryFiltering(wadf,vf); List sources = new ArrayList();