diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/Actions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/Actions.java index ad668aa6d..03e3a4573 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/Actions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/Actions.java @@ -39,15 +39,39 @@ public class Actions { return (actions == null) ? AUTHORIZED : actions; } - private final List> clauseList; - + /** + * This is a list of clauses that get ORed together. + * If all of the RequestedAction objects from any of the + * Sets are authorized, then the Actions object should + * be considered authorized. + */ + private List> clauseList; + + public Actions(){ + clauseList= new ArrayList>(); + } + public Actions(RequestedAction... actions) { this(Arrays.asList(actions)); } + public Actions(Actions... actions){ + Set accumActs = new HashSet(); + for( Actions actionToAnd : actions){ + if( actionToAnd != null ){ + for( Set ras : actionToAnd.clauseList){ + accumActs.addAll( ras ); + } + } + } + clauseList= new ArrayList>(); + clauseList.add( accumActs ); + } + public Actions(Collection actions) { this(Collections.> emptyList(), actions); } + private Actions(List> oldList, Collection newActions) { @@ -61,7 +85,19 @@ public class Actions { } this.clauseList = Collections.unmodifiableList(newList); } - + + public Actions and(RequestedAction... newActions){ + return and(Arrays.asList( newActions)); + } + + public Actions and(Collection newActions){ + return new Actions( this.clauseList, newActions); + } + + public void and( Actions otherAct ) throws Exception{ + andWithAction(otherAct); + } + public Actions or(RequestedAction... newActions) { return or(Arrays.asList(newActions)); } @@ -143,6 +179,42 @@ public class Actions { return sb.toString(); } + /** + * AND for Actions. + * ANDing with an Action with multiple disjoint clauses is not supported. + * + * To do the AND, we take each ORed clause, and add all of the RequestedActions + * so now in each of the alternative clauses, all of the singleClauseToAnd + * RequestedActions are required. + * + * @throws Exception when multiple disjoint clauses are present on both Actions. + */ + private void andWithAction( Actions otherAct ) throws Exception{ + Set singleClauseToAnd; + List> clauses; + + if( otherAct.singleAndClause() ){ + clauses = this.clauseList; + singleClauseToAnd = otherAct.clauseList.get(0); + }else if( this.singleAndClause() ){ + clauses = new ArrayList>( otherAct.clauseList ); + singleClauseToAnd = this.clauseList.get(0); + }else{ + //both have multiple ORed clauses, give up + throw new Exception("ANDing with an Action with multiple disjoint clauses is not supported."); + } + + // + for( Set clause : clauses){ + clause.addAll( singleClauseToAnd ); + } + this.clauseList = clauses; + } + + private boolean singleAndClause(){ + return clauseList.size() == 1; + } + /** * Nobody knows about this action class, so only the root user should be * authorized for it. diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java index 10ff18f7c..70ebed8c8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/PageController.java @@ -3,6 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,6 +18,8 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequiresActions; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; @@ -41,6 +44,42 @@ public class PageController extends FreemarkerHttpServlet{ protected static final String DATA_GETTER_MAP = "pageTypeToDataGetterMap"; + /** + * Get the required actions for all the data getters then + * AND them together. + */ + @Override + protected Actions requiredActions(VitroRequest vreq) { + try { + Actions actAcc = null; + List dgList = + DataGetterUtils.getDataGettersForPage(vreq, vreq.getDisplayModel(), getPageUri(vreq)); + for( DataGetter dg : dgList){ + if( dg instanceof RequiresActions ){ + RequiresActions ra = (RequiresActions) dg; + Actions acts = ra.requiredActions(vreq); + if( acts != null ){ + if( actAcc != null ){ + actAcc.and( acts ); + }else{ + actAcc = acts; + } + } + } + } + + if( actAcc == null ) + return Actions.AUTHORIZED; + else + return actAcc; + + } catch (Exception e) { + // TODO Auto-generated catch block + log.debug(e); + return Actions.UNAUTHORIZED; + } + } + @Override protected ResponseValues processRequest(VitroRequest vreq) throws Exception { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java index 46a8f3b68..008a3870f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java @@ -55,7 +55,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; public class DataGetterUtils { final static Log log = LogFactory.getLog(DataGetterUtils.class); - + + /** + * Attribute name in request for DataGetters + */ + public final static String DATA_GETTERS_FOR_PAGE = "data_getters_for_page"; + /** * Get a list of DataGetter objects that are associated with a page. * This should not return PageDataGetters and should not throw an @@ -63,10 +68,16 @@ public class DataGetterUtils { */ public static List getDataGettersForPage(VitroRequest vreq, Model displayModel, String pageURI) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException { - List dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI); - List dgList = dataGettersForURIs(vreq, displayModel, dgUris); - log.debug("getDataGettersForPage: " + dgList); - return dgList; + + if( vreq.getAttribute(DATA_GETTERS_FOR_PAGE) != null){ + return (List) vreq.getAttribute(DATA_GETTERS_FOR_PAGE); + }else{ + List dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI); + List dgList = dataGettersForURIs(vreq, displayModel, dgUris); + log.debug("getDataGettersForPage: " + dgList); + vreq.setAttribute( DATA_GETTERS_FOR_PAGE , dgList ); + return dgList; + } } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdateTestDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdate.java similarity index 57% rename from webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdateTestDataGetter.java rename to webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdate.java index 0d0ac41aa..7bb33194b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdateTestDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/SparqlUpdate.java @@ -11,28 +11,35 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.update.GraphStore; import com.hp.hpl.jena.update.GraphStoreFactory; import com.hp.hpl.jena.update.UpdateAction; -import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder; - +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequiresActions; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.search.indexing.IndexBuilder; /** - * Test to experiment with Jena ARQ SPARQL update and the RDFServiceDataset. + * Handle a SPARQL Update request. This uses Jena ARQ and the RDFServiceDataset to + * evaluate a SPARQL Update with the RDFService. + * + * The reason to make this a DataGettere was to allow configuration in RDF of this + * service. */ -public class SparqlUpdateTestDataGetter implements DataGetter{ - private static final Log log = LogFactory.getLog(SparqlUpdateTestDataGetter.class); +public class SparqlUpdate implements DataGetter, RequiresActions{ + + private static final Log log = LogFactory.getLog(SparqlUpdate.class); VitroRequest vreq; ServletContext context; - /** - * Constructor with display model and data getter URI that will be called by reflection. - */ - public SparqlUpdateTestDataGetter(VitroRequest vreq ){ + public SparqlUpdate( + VitroRequest vreq, Model displayModel, String dataGetterURI ) { if( vreq == null ) throw new IllegalArgumentException("VitroRequest may not be null."); this.vreq = vreq; @@ -40,6 +47,10 @@ public class SparqlUpdateTestDataGetter implements DataGetter{ } + /** + * Gets the update from the request and then executes it on + * the RDFService. + */ @Override public Map getData( Map valueMap ) { HashMap data = new HashMap(); @@ -61,6 +72,25 @@ public class SparqlUpdateTestDataGetter implements DataGetter{ data.put("bodyTemplate", "page-sparqlUpdateTest.ftl"); return data; + } + + + /** + * Check if this request is authorized by the email/password. + * If not do normal authorization. + */ + @Override + public Actions requiredActions(VitroRequest vreq) { + String email = vreq.getParameter("email"); + String password = vreq.getParameter("password"); + + boolean isAuth = PolicyHelper.isAuthorizedForActions(vreq, + email, password, SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS); + + if( isAuth ) + return Actions.AUTHORIZED; + else + return SimplePermission.MANAGE_SEARCH_INDEX.ACTIONS; } } diff --git a/webapp/web/WEB-INF/ontologies/app/sparqlTestMenu.n3 b/webapp/web/WEB-INF/ontologies/app/sparqlTestMenu.n3 index 028595010..6dcb46376 100644 --- a/webapp/web/WEB-INF/ontologies/app/sparqlTestMenu.n3 +++ b/webapp/web/WEB-INF/ontologies/app/sparqlTestMenu.n3 @@ -5,18 +5,17 @@ @prefix rdf: . @prefix rdfs: . -### Test page for SPARQL UPDATE ### -### Not For Production ### -display:SparqlTestMenuItem +### page for SPARQL UPDATE ### +display:SparqlUpdateMenuItem a display:NavigationElement ; - display:linkText "SPARQL Update Test"; - display:toPage display:SparqlUpdateTestPage . + display:linkText "SPARQL Update"; + display:toPage display:SparqlUpdatePage . -display:SparqlUpdateTestPage +display:SparqlUpdatePage a display:Page ; - display:title "SPARQL Update Test" ; - display:urlMapping "/sparqlUpdateTest" ; + display:title "SPARQL Update" ; + display:urlMapping "/sparql" ; display:hasDataGetter display:sparqlUpdateDataGetter . display:sparqlUpdateDataGetter - a . + a .