Skip to content

Commit

Permalink
Change http error code for unauthorized PATCH request
Browse files Browse the repository at this point in the history
  • Loading branch information
osmandin authored and Andrew Woods committed Feb 27, 2015
1 parent ed44bea commit 5eb9636
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 13 deletions.
Expand Up @@ -50,6 +50,7 @@
import java.util.Iterator;

import javax.inject.Inject;
import javax.jcr.AccessDeniedException;
import javax.jcr.Binary;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand Down Expand Up @@ -599,7 +600,8 @@ protected void replaceResourceWithStream(final FedoraResource resource,

protected void patchResourcewithSparql(final FedoraResource resource,
final String requestBody,
final RdfStream resourceTriples) throws MalformedRdfException {
final RdfStream resourceTriples)
throws MalformedRdfException, AccessDeniedException {
resource.updateProperties(translator(), requestBody, resourceTriples);
}

Expand Down
10 changes: 8 additions & 2 deletions fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraLdp.java
Expand Up @@ -48,6 +48,7 @@

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.jcr.AccessDeniedException;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand Down Expand Up @@ -315,13 +316,14 @@ public Response createOrReplaceObjectRdf(
* @param requestBodyStream the request body stream
* @return 201
* @throws MalformedRdfException if malformed rdf exception occurred
* @throws AccessDeniedException if exception updating property occurred
* @throws IOException if IO exception occurred
*/
@PATCH
@Consumes({contentTypeSPARQLUpdate})
@Timed
public Response updateSparql(@ContentLocation final InputStream requestBodyStream)
throws IOException, MalformedRdfException {
throws IOException, MalformedRdfException, AccessDeniedException {

if (null == requestBodyStream) {
throw new BadRequestException("SPARQL-UPDATE requests must have content!");
Expand Down Expand Up @@ -363,6 +365,9 @@ public Response updateSparql(@ContentLocation final InputStream requestBodyStrea
}
throw ex;
} catch (final RepositoryException e) {
if (e instanceof AccessDeniedException) {
throw new AccessDeniedException(e.getMessage());
}
throw new RepositoryRuntimeException(e);
}
}
Expand All @@ -382,6 +387,7 @@ public Response updateSparql(@ContentLocation final InputStream requestBodyStrea
* @throws InvalidChecksumException if invalid checksum exception occurred
* @throws IOException if IO exception occurred
* @throws MalformedRdfException if malformed rdf exception occurred
* @throws AccessDeniedException if access denied in creating resource
*/
@POST
@Consumes({MediaType.APPLICATION_OCTET_STREAM + ";qs=1001", MediaType.WILDCARD})
Expand All @@ -391,7 +397,7 @@ public Response createObject(@QueryParam("checksum") final String checksum,
@HeaderParam("Content-Type") final MediaType requestContentType,
@HeaderParam("Slug") final String slug,
@ContentLocation final InputStream requestBodyStream)
throws InvalidChecksumException, IOException, MalformedRdfException {
throws InvalidChecksumException, IOException, MalformedRdfException, AccessDeniedException {

if (!(resource() instanceof Container)) {
throw new ClientErrorException("Object cannot have child nodes", CONFLICT);
Expand Down
Expand Up @@ -41,6 +41,7 @@
import java.util.Iterator;
import java.util.List;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
Expand Down Expand Up @@ -352,7 +353,7 @@ public boolean hasType(final String type) {
@Override
public void updateProperties(final IdentifierConverter<Resource, FedoraResource> idTranslator,
final String sparqlUpdateStatement, final RdfStream originalTriples)
throws MalformedRdfException {
throws MalformedRdfException, AccessDeniedException {

final Model model = originalTriples.asModel();

Expand Down
Expand Up @@ -17,10 +17,10 @@

import static org.slf4j.LoggerFactory.getLogger;

import javax.jcr.AccessDeniedException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import com.google.common.base.Joiner;
import org.fcrepo.kernel.models.FedoraResource;
import org.fcrepo.kernel.exception.MalformedRdfException;
import org.fcrepo.kernel.exception.RepositoryRuntimeException;
Expand Down Expand Up @@ -52,7 +52,7 @@ public class JcrPropertyStatementListener extends StatementListener {

private final IdentifierConverter<Resource, FedoraResource> idTranslator;

private final List<String> exceptions;
private final List<Exception> exceptions;

/**
* Construct a statement listener within the given session
Expand Down Expand Up @@ -113,7 +113,7 @@ public void addedStatement(final Statement input) {

jcrRdfTools.addProperty(resource, property, objectNode, input.getModel().getNsPrefixMap());
} catch (final RepositoryException | RepositoryRuntimeException e) {
exceptions.add(e.getMessage());
exceptions.add(e);
}

}
Expand Down Expand Up @@ -152,18 +152,27 @@ public void removedStatement(final Statement s) {
jcrRdfTools.removeProperty(resource, property, objectNode, s.getModel().getNsPrefixMap());

} catch (final RepositoryException | RepositoryRuntimeException e) {
exceptions.add(e.getMessage());
exceptions.add(e);
}

}

/**
* Assert that no exceptions were thrown while this listener was processing change
* @throws MalformedRdfException if malformed rdf exception occurred
* @throws javax.jcr.AccessDeniedException if access denied exception occurred
*/
public void assertNoExceptions() throws MalformedRdfException {
public void assertNoExceptions() throws MalformedRdfException, AccessDeniedException {
final StringBuilder sb = new StringBuilder();
for (Exception e : exceptions) {
sb.append(e.getMessage());
sb.append("\n");
if (e instanceof AccessDeniedException) {
throw new AccessDeniedException(sb.toString());
}
}
if (!exceptions.isEmpty()) {
throw new MalformedRdfException(Joiner.on("\n").join(exceptions));
throw new MalformedRdfException(sb.toString());
}
}
}
Expand Up @@ -25,6 +25,7 @@
import static org.junit.Assert.assertTrue;

import javax.inject.Inject;
import javax.jcr.AccessDeniedException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand Down Expand Up @@ -195,7 +196,7 @@ public void testObjectGraphWithUriProperty() throws RepositoryException {
}

@Test
public void testUpdatingObjectGraphWithErrors() {
public void testUpdatingObjectGraphWithErrors() throws AccessDeniedException {
final String pid = getRandomPid();
final Container object = containerService.findOrCreate(session, pid);

Expand Down
Expand Up @@ -35,20 +35,25 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import javax.inject.Inject;
import javax.jcr.AccessDeniedException;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import javax.jcr.version.Version;

import com.google.common.base.Predicate;
Expand Down Expand Up @@ -79,6 +84,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.jcr.security.SimplePrincipal;
import org.springframework.test.context.ContextConfiguration;

import com.hp.hpl.jena.graph.Node;
Expand Down Expand Up @@ -339,7 +345,7 @@ public void testDatastreamGraph() throws RepositoryException, InvalidChecksumExc
}

@Test
public void testUpdatingObjectGraph() throws MalformedRdfException {
public void testUpdatingObjectGraph() throws MalformedRdfException, AccessDeniedException {

final FedoraResource object =
containerService.findOrCreate(session, "/testObjectGraphUpdates");
Expand Down Expand Up @@ -419,6 +425,31 @@ public void testAddMissingReference() throws RepositoryException, MalformedRdfEx
+ "WHERE { }", new RdfStream());
}

@Test(expected = AccessDeniedException.class)
public void testUpdateDenied() throws RepositoryException {
final FedoraResource object =
containerService.findOrCreate(session, "/testRefObject");
try {
object.updateProperties(
subjects,
"INSERT { <> <http://purl.org/dc/elements/1.1/title> \"test-original\". }"
+ " WHERE { }", new RdfStream());
} catch (AccessDeniedException e) {
fail("Should fail at update, not create property");
}
final AccessControlManager acm = session.getAccessControlManager();
final Privilege[] permissions = new Privilege[] {acm.privilegeFromName(Privilege.JCR_READ)};
final AccessControlList acl = (AccessControlList) acm.getApplicablePolicies("/testRefObject").next();
acl.addAccessControlEntry(SimplePrincipal.newInstance("anonymous"), permissions);
acm.setPolicy("/testRefObject", acl);
session.save();

object.updateProperties(
subjects,
"INSERT { <> <http://purl.org/dc/elements/1.1/title> \"test-update\". }"
+ " WHERE { }", new RdfStream());
}

@Test
public void testUpdatingRdfType() throws RepositoryException {
final FedoraResource object =
Expand Down
Expand Up @@ -18,6 +18,7 @@
import java.util.Date;
import java.util.Iterator;

import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.version.Version;
Expand Down Expand Up @@ -116,10 +117,11 @@ public interface FedoraResource {
* @param sparqlUpdateStatement sparql update statement
* @param originalTriples original triples
* @throws MalformedRdfException if malformed rdf exception occurred
* @throws AccessDeniedException if access denied in updating properties
*/
void updateProperties(final IdentifierConverter<Resource, FedoraResource> idTranslator,
final String sparqlUpdateStatement,
final RdfStream originalTriples) throws MalformedRdfException;
final RdfStream originalTriples) throws MalformedRdfException, AccessDeniedException;

/**
* Return the RDF properties of this object using the provided context
Expand Down

0 comments on commit 5eb9636

Please sign in to comment.