NIHVIVO-2720 Restructure PrimitiveRdfEdit to check whether the changes are authorized before attempting them.

This commit is contained in:
j2blake 2011-06-23 16:20:31 +00:00
parent 1aef7ddcb7
commit 89340d3f86
2 changed files with 67 additions and 66 deletions

View file

@ -20,8 +20,8 @@ import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;
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.usepages.UseBasicAjaxControllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
@ -32,10 +32,14 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
private static final long serialVersionUID = 1L;
@Override
protected Actions requiredActions(VitroRequest vreq) {
return new Actions(new UseBasicAjaxControllers());
}
/**
* No need to restrict authorization here. doRequest() will return an error
* if the user is not authorized.
*/
@Override
protected Actions requiredActions(VitroRequest vreq) {
return Actions.AUTHORIZED;
}
@Override
protected void doRequest(VitroRequest vreq,
@ -79,63 +83,60 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
String editorUri = EditN3Utils.getEditorUri(vreq);
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) {
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.
*
* Package access to allow for unit testing.
*
* @param parameters - the result of request.getParameters(String)
* @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>();
for( String param : parameters){
try{
@ -151,7 +152,7 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
return models;
}
protected OntModel getWriteModel(HttpServletRequest request){
private OntModel getWriteModel(HttpServletRequest request){
HttpSession session = request.getSession(false);
if( session == null || session.getAttribute("jenaOntModel") == null )
return (OntModel)getServletContext().getAttribute("jenaOntModel");
@ -159,10 +160,14 @@ public class PrimitiveRdfEdit extends VitroAjaxController {
return (OntModel)session.getAttribute("jenaOntModel");
}
protected OntModel getQueryModel(HttpServletRequest request){
return getWriteModel(request);
}
/** 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());
}

View file

@ -2,7 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.edit;
import java.util.Collections;
import java.util.Set;
import junit.framework.Assert;
@ -11,12 +10,10 @@ import org.junit.Before;
import org.junit.Test;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
public class PrimitiveRdfEditTest {
@ -48,16 +45,17 @@ public class PrimitiveRdfEditTest {
Assert.assertNotNull( writeModel );
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());
String params3[] = { testN3b };
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());
}
@Test
public void testParseRdfParam() throws Exception {
PrimitiveRdfEdit pre = new PrimitiveRdfEdit();
@ -65,7 +63,5 @@ public class PrimitiveRdfEditTest {
Set<Model> models = pre.parseRdfParam(params, "N3");
Assert.assertNotNull(models);
Assert.assertTrue( models.size() == 2);
}
}