NIHVIVO-2720 Restructure PrimitiveRdfEdit to check whether the changes are authorized before attempting them.
This commit is contained in:
parent
1aef7ddcb7
commit
89340d3f86
2 changed files with 67 additions and 66 deletions
|
@ -20,8 +20,8 @@ import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
|
|
||||||
|
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.Actions;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseBasicAjaxControllers;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
|
||||||
|
@ -32,10 +32,14 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected Actions requiredActions(VitroRequest vreq) {
|
* No need to restrict authorization here. doRequest() will return an error
|
||||||
return new Actions(new UseBasicAjaxControllers());
|
* if the user is not authorized.
|
||||||
}
|
*/
|
||||||
|
@Override
|
||||||
|
protected Actions requiredActions(VitroRequest vreq) {
|
||||||
|
return Actions.AUTHORIZED;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doRequest(VitroRequest vreq,
|
protected void doRequest(VitroRequest vreq,
|
||||||
|
@ -79,63 +83,60 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
|
||||||
|
|
||||||
String editorUri = EditN3Utils.getEditorUri(vreq);
|
String editorUri = EditN3Utils.getEditorUri(vreq);
|
||||||
try {
|
try {
|
||||||
processChanges( additions, retractions, getWriteModel(vreq),getQueryModel(vreq), editorUri);
|
Model a = mergeModels(additions);
|
||||||
|
Model r = mergeModels(retractions);
|
||||||
|
|
||||||
|
Model toBeAdded = a.difference(r);
|
||||||
|
Model toBeRetracted = r.difference(a);
|
||||||
|
|
||||||
|
Model depResRetractions = DependentResourceDeleteJena
|
||||||
|
.getDependentResourceDeleteForChange(toBeAdded,
|
||||||
|
toBeRetracted, getWriteModel(vreq));
|
||||||
|
toBeRetracted.add(depResRetractions);
|
||||||
|
|
||||||
|
if (!isAuthorized(vreq, toBeAdded, toBeRetracted)) {
|
||||||
|
doError(response, "Not authorized for these RDF edits", HttpStatus.SC_UNAUTHORIZED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processChanges(editorUri, getWriteModel(vreq), toBeAdded, toBeRetracted);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
doError(response,e.getMessage(),HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
doError(response,e.getMessage(),HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processChanges(Set<Model> additions, Set<Model> retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
|
|
||||||
Model a = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
|
|
||||||
for(Model m : additions)
|
|
||||||
a.add(m);
|
|
||||||
|
|
||||||
Model r = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
|
|
||||||
for(Model m : retractions)
|
|
||||||
r.add(m);
|
|
||||||
|
|
||||||
processChanges(a,r,writeModel,queryModel,editorURI);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void processChanges(Model additions, Model retractions, OntModel writeModel, OntModel queryModel, String editorURI ) throws Exception{
|
|
||||||
/*
|
|
||||||
* Do a diff on the additions and retractions and then only add the delta to the jenaOntModel.
|
|
||||||
*/
|
|
||||||
Model assertionsAdded = additions.difference( retractions );
|
|
||||||
Model assertionsRetracted = retractions.difference( additions );
|
|
||||||
|
|
||||||
Model depResRetractions =
|
|
||||||
DependentResourceDeleteJena
|
|
||||||
.getDependentResourceDeleteForChange(assertionsAdded, assertionsRetracted, queryModel);
|
|
||||||
assertionsRetracted.add( depResRetractions );
|
|
||||||
|
|
||||||
Lock lock = null;
|
|
||||||
try{
|
|
||||||
lock = writeModel.getLock();
|
|
||||||
lock.enterCriticalSection(Lock.WRITE);
|
|
||||||
writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,true));
|
|
||||||
writeModel.add( assertionsAdded );
|
|
||||||
writeModel.remove( assertionsRetracted );
|
|
||||||
}catch(Throwable t){
|
|
||||||
throw new Exception("Error while modifying model \n" + t.getMessage());
|
|
||||||
}finally{
|
|
||||||
writeModel.getBaseModel().notifyEvent(new EditEvent(editorURI,false));
|
|
||||||
lock.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isAuthorized(VitroRequest vreq, Model toBeAdded, Model toBeRetracted) {
|
||||||
|
return PolicyHelper.isAuthorizedToAdd(vreq, toBeAdded)
|
||||||
|
&& PolicyHelper.isAuthorizedToDrop(vreq, toBeRetracted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Package access to allow for unit testing. */
|
||||||
|
void processChanges(String editorUri, OntModel writeModel,
|
||||||
|
Model toBeAdded, Model toBeRetracted) throws Exception {
|
||||||
|
Lock lock = writeModel.getLock();
|
||||||
|
try {
|
||||||
|
lock.enterCriticalSection(Lock.WRITE);
|
||||||
|
writeModel.getBaseModel().notifyEvent(new EditEvent(editorUri, true));
|
||||||
|
writeModel.add(toBeAdded);
|
||||||
|
writeModel.remove(toBeRetracted);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new Exception("Error while modifying model \n" + t.getMessage());
|
||||||
|
} finally {
|
||||||
|
writeModel.getBaseModel().notifyEvent(new EditEvent(editorUri, false));
|
||||||
|
lock.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the values from a parameters into RDF models.
|
* Convert the values from a parameters into RDF models.
|
||||||
|
*
|
||||||
|
* Package access to allow for unit testing.
|
||||||
|
*
|
||||||
* @param parameters - the result of request.getParameters(String)
|
* @param parameters - the result of request.getParameters(String)
|
||||||
* @param format - a valid format string for Jena's Model.read()
|
* @param format - a valid format string for Jena's Model.read()
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
protected Set<Model> parseRdfParam(String[] parameters, String format) throws Exception{
|
Set<Model> parseRdfParam(String[] parameters, String format) throws Exception{
|
||||||
Set<Model> models = new HashSet<Model>();
|
Set<Model> models = new HashSet<Model>();
|
||||||
for( String param : parameters){
|
for( String param : parameters){
|
||||||
try{
|
try{
|
||||||
|
@ -150,19 +151,23 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
|
||||||
}
|
}
|
||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OntModel getWriteModel(HttpServletRequest request){
|
private OntModel getWriteModel(HttpServletRequest request){
|
||||||
HttpSession session = request.getSession(false);
|
HttpSession session = request.getSession(false);
|
||||||
if( session == null || session.getAttribute("jenaOntModel") == null )
|
if( session == null || session.getAttribute("jenaOntModel") == null )
|
||||||
return (OntModel)getServletContext().getAttribute("jenaOntModel");
|
return (OntModel)getServletContext().getAttribute("jenaOntModel");
|
||||||
else
|
else
|
||||||
return (OntModel)session.getAttribute("jenaOntModel");
|
return (OntModel)session.getAttribute("jenaOntModel");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OntModel getQueryModel(HttpServletRequest request){
|
|
||||||
return getWriteModel(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log log = LogFactory.getLog(PrimitiveRdfEdit.class.getName());
|
|
||||||
|
|
||||||
|
/** Package access to allow for unit testing. */
|
||||||
|
Model mergeModels(Set<Model> additions) {
|
||||||
|
Model a = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel();
|
||||||
|
for (Model m : additions) {
|
||||||
|
a.add(m);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log log = LogFactory.getLog(PrimitiveRdfEdit.class.getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
@ -11,12 +10,10 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
|
||||||
|
|
||||||
public class PrimitiveRdfEditTest {
|
public class PrimitiveRdfEditTest {
|
||||||
|
|
||||||
|
@ -48,16 +45,17 @@ public class PrimitiveRdfEditTest {
|
||||||
|
|
||||||
Assert.assertNotNull( writeModel );
|
Assert.assertNotNull( writeModel );
|
||||||
long size = writeModel.size();
|
long size = writeModel.size();
|
||||||
pre.processChanges( models, Collections.EMPTY_SET, writeModel, writeModel, "uri:fakeEditorUri");
|
pre.processChanges("uri:fakeEditorUri", writeModel,
|
||||||
|
pre.mergeModels(models), ModelFactory.createDefaultModel());
|
||||||
Assert.assertEquals(size+totalStmts, writeModel.size());
|
Assert.assertEquals(size+totalStmts, writeModel.size());
|
||||||
|
|
||||||
String params3[] = { testN3b };
|
String params3[] = { testN3b };
|
||||||
Set<Model> retracts = pre.parseRdfParam( params3, "N3");
|
Set<Model> retracts = pre.parseRdfParam( params3, "N3");
|
||||||
pre.processChanges(Collections.EMPTY_SET, retracts, writeModel, writeModel, "uri:fakeEditorUri");
|
pre.processChanges("uri:fakeEditorUri", writeModel,
|
||||||
|
ModelFactory.createDefaultModel(), pre.mergeModels(retracts));
|
||||||
Assert.assertEquals(size+totalStmts-1, writeModel.size());
|
Assert.assertEquals(size+totalStmts-1, writeModel.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseRdfParam() throws Exception {
|
public void testParseRdfParam() throws Exception {
|
||||||
PrimitiveRdfEdit pre = new PrimitiveRdfEdit();
|
PrimitiveRdfEdit pre = new PrimitiveRdfEdit();
|
||||||
|
@ -65,7 +63,5 @@ public class PrimitiveRdfEditTest {
|
||||||
Set<Model> models = pre.parseRdfParam(params, "N3");
|
Set<Model> models = pre.parseRdfParam(params, "N3");
|
||||||
Assert.assertNotNull(models);
|
Assert.assertNotNull(models);
|
||||||
Assert.assertTrue( models.size() == 2);
|
Assert.assertTrue( models.size() == 2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue