Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Reject access to jcr:content from REST-API for NOT_FOUND (status 404).
  • Loading branch information
lsitu authored and Andrew Woods committed May 28, 2014
1 parent 1fcf260 commit 015bc64
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 3 deletions.
32 changes: 32 additions & 0 deletions fcrepo-http-api/src/main/java/org/fcrepo/http/api/FedoraNodes.java
Expand Up @@ -91,6 +91,7 @@
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import com.google.common.annotations.VisibleForTesting;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.sun.jersey.core.header.ContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
Expand Down Expand Up @@ -155,6 +156,8 @@ public Response head(@PathParam("path") final List<PathSegment> pathList,
@Context final Request request,
@Context final HttpServletResponse servletResponse,
@Context final UriInfo uriInfo) throws RepositoryException {
throwIfPathIncludesJcr(pathList, "HEAD");

final String path = toPath(pathList);
LOGGER.trace("Getting head for: {}", path);

Expand Down Expand Up @@ -193,6 +196,8 @@ public RdfStream describe(@PathParam("path") final List<PathSegment> pathList,
@Context final Request request,
@Context final HttpServletResponse servletResponse,
@Context final UriInfo uriInfo) throws RepositoryException {
throwIfPathIncludesJcr(pathList, "MOVE");

final String path = toPath(pathList);
LOGGER.trace("Getting profile for: {}", path);

Expand Down Expand Up @@ -350,6 +355,7 @@ public Response updateSparql(@PathParam("path")
@ContentLocation final InputStream requestBodyStream,
@Context final Request request, @Context final HttpServletResponse servletResponse)
throws RepositoryException, IOException {
throwIfPathIncludesJcr(pathList, "PATCH");

final String path = toPath(pathList);
LOGGER.debug("Attempting to update path: {}", path);
Expand Down Expand Up @@ -414,6 +420,8 @@ public Response createOrReplaceObjectRdf(
@Context final Request request,
@Context final HttpServletResponse servletResponse) throws RepositoryException, ParseException,
IOException, InvalidChecksumException, URISyntaxException {
throwIfPathIncludesJcr(pathList, "PUT");

final String path = toPath(pathList);
LOGGER.debug("Attempting to replace path: {}", path);
try {
Expand Down Expand Up @@ -497,6 +505,7 @@ public Response createObject(@PathParam("path")
@ContentLocation final InputStream requestBodyStream)
throws RepositoryException, ParseException, IOException,
InvalidChecksumException, URISyntaxException {
throwIfPathIncludesJcr(pathList, "POST");

String pid;
final String newObjectPath;
Expand Down Expand Up @@ -696,6 +705,7 @@ public Response createObjectFromFormPost(
@Context final UriInfo uriInfo,
@FormDataParam("file") final InputStream file
) throws RepositoryException, URISyntaxException, InvalidChecksumException, ParseException, IOException {
throwIfPathIncludesJcr(pathList, "POST with multipart attachment");

final MediaType effectiveContentType = file == null ? null : MediaType.APPLICATION_OCTET_STREAM_TYPE;
return createObject(pathList, mixin, null, null, effectiveContentType, slug, servletResponse, uriInfo, file);
Expand All @@ -714,6 +724,7 @@ public Response createObjectFromFormPost(
public Response deleteObject(@PathParam("path")
final List<PathSegment> pathList,
@Context final Request request) throws RepositoryException {
throwIfPathIncludesJcr(pathList, "DELETE");

try {

Expand Down Expand Up @@ -757,6 +768,7 @@ public Response deleteObject(@PathParam("path")
public Response copyObject(@PathParam("path") final List<PathSegment> path,
@HeaderParam("Destination") final String destinationUri)
throws RepositoryException, URISyntaxException {
throwIfPathIncludesJcr(path, "COPY");

try {

Expand Down Expand Up @@ -803,6 +815,7 @@ public Response moveObject(@PathParam("path") final List<PathSegment> pathList,
@HeaderParam("Destination") final String destinationUri,
@Context final Request request)
throws RepositoryException, URISyntaxException {
throwIfPathIncludesJcr(pathList, "MOVE");

try {

Expand Down Expand Up @@ -856,8 +869,27 @@ public Response moveObject(@PathParam("path") final List<PathSegment> pathList,
public Response options(@PathParam("path") final List<PathSegment> pathList,
@Context final HttpServletResponse servletResponse)
throws RepositoryException {
throwIfPathIncludesJcr(pathList, "OPTIONS");

addOptionsHttpHeaders(servletResponse);
return status(OK).build();
}

/**
* Method to check for any jcr namespace element in the path
*/
@VisibleForTesting
protected void throwIfPathIncludesJcr(final List<PathSegment> pathList, final String msg) {
if (pathList == null || pathList.size() == 0) {
return;
}
final PathSegment pathSegment = pathList.get(pathList.size() - 1);
final String[] tokens = pathSegment.getPath().split(":");
if (tokens.length == 2 && tokens[0].equalsIgnoreCase("jcr")) {
final String requestPath = uriInfo.getPath();
LOGGER.trace("{} request with jcr namespace is not allowed: {} ", msg, requestPath);
throw new WebApplicationException(notFound().build());
}
}

}
Expand Up @@ -50,6 +50,7 @@
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jcr.ItemExistsException;
import javax.jcr.Node;
Expand All @@ -63,6 +64,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
Expand Down Expand Up @@ -588,4 +590,12 @@ public void testHead() throws RepositoryException {
final Response response = testObj.head( createPathList(pid), mockRequest, mockResponse, mockUriInfo);
assertEquals(SC_OK, response.getStatus());
}

@Test(expected = WebApplicationException.class)
public void testCheckJcrNamespace() {
final List<PathSegment> pathList = createPathList("anypath");
pathList.add(createPathList("jcr:path").get(0));
testObj.throwIfPathIncludesJcr(pathList, "TEST");
}

}
Expand Up @@ -300,6 +300,45 @@ public String apply(final Header h) {

}

@Test
public void testGetDatastreamContentWithJCRBadBath() throws Exception {
final String pid = getRandomUniquePid();

createObject(pid);
createDatastream(pid, "ds1", "foo");

final HttpResponse response =
execute(new HttpGet(serverAddress + pid + "/ds1/jcr:content"));
assertEquals(NOT_FOUND.getStatusCode(), response
.getStatusLine().getStatusCode());
}

@Test
public void testRangeRequestWithJCRContentBadPath() throws Exception {
final String pid = getRandomUniquePid();
createObject(pid);

final HttpPost createDSMethod = postDSMethod(pid, "ds1", "marbles for everyone");
assertEquals(201, getStatus(createDSMethod));

final HttpGet method_test_get = new HttpGet(serverAddress + pid + "/ds1/jcr:content");
method_test_get.setHeader("Range", "bytes=1-3");
assertEquals(NOT_FOUND.getStatusCode(), getStatus(method_test_get));
}

@Test
public void testPutDatastreamContentWithJCRContentBadPath() throws Exception {
final String pid = getRandomUniquePid();
createObject(pid);

final HttpPost createDSMethod = postDSMethod(pid, "ds1", "marbles for everyone");
assertEquals(201, getStatus(createDSMethod));

final HttpPut method_test_put = new HttpPut(serverAddress + pid + "/ds1/jcr:content");
assertEquals(NOT_FOUND.getStatusCode(), getStatus(method_test_put));

}

@Test
public void testDeleteDatastream() throws Exception {
final String pid = getRandomUniquePid();
Expand All @@ -316,6 +355,18 @@ public void testDeleteDatastream() throws Exception {
assertEquals(404, getStatus(method_test_get));
}

@Test
public void testDeleteDatastreamContentWithJCRBadPath() throws Exception {
final String pid = getRandomUniquePid();

createObject(pid);
createDatastream(pid, "ds1", "foo");

final HttpDelete dmethod =
new HttpDelete(serverAddress + pid + "/ds1/jcr:content");
assertEquals(NOT_FOUND.getStatusCode(), getStatus(dmethod));
}


@Test
public void testHeadRepositoryGraph() throws Exception {
Expand Down Expand Up @@ -919,6 +970,22 @@ public void testRoundTripReplaceGraphForDatastream() throws Exception {
final HttpResponse response = client.execute(replaceMethod);
assertEquals(204, response.getStatusLine().getStatusCode());

}
@Test
public void testGetGraphForDatastreamWithJCRBadPath() throws Exception {

final String pid = getRandomUniquePid();
final String subjectURI = serverAddress + pid + "/ds1/jcr:content";

createDatastream(pid, "ds1", "some-content");

final HttpGet getObjMethod = new HttpGet(subjectURI);
getObjMethod.addHeader("Accept", "text/turtle");
getObjMethod.addHeader("Prefer", "return=minimal");
final HttpResponse response = client.execute(getObjMethod);

assertEquals(NOT_FOUND.getStatusCode(), response.getStatusLine().getStatusCode());

}
@Test
public void testDescribeSize() throws Exception {
Expand Down Expand Up @@ -1063,6 +1130,14 @@ public void testValidHTMLForDS() throws Exception {
validateHTML(pid + "/ds");
}

@Test
public void testGetHTMLForDSWithJCRBadPath() throws Exception {
final String pid = getRandomUniquePid();
final HttpResponse response = client.execute(new HttpPut(serverAddress
+ pid + "/ds/jcr:content"));
assertEquals(NOT_FOUND.getStatusCode(), response.getStatusLine().getStatusCode());
}

@Test
public void testCopy() throws Exception {
final HttpResponse response = createObject("");
Expand Down Expand Up @@ -1183,8 +1258,8 @@ private void testOptionsHeaders(final HttpResponse httpResponse) {

private static List<String> headerValues( final HttpResponse response, final String headerName ) {
final List<String> values = new ArrayList<String>();
for ( Header header : response.getHeaders(headerName) ) {
for ( String elem : header.getValue().split(",") ) {
for ( final Header header : response.getHeaders(headerName) ) {
for ( final String elem : header.getValue().split(",") ) {
values.add( elem.trim() );
}
}
Expand Down Expand Up @@ -1486,7 +1561,7 @@ public String apply(final Header h) {
createResource(serverAddress + pid + "?limit=2&amp;offset=0").asNode()));

// it should not have a next page link
for ( String link : nextLinks ) {
for ( final String link : nextLinks ) {
assertFalse("Should not have next page header!", link.contains("rel=\"next\""));
}
assertFalse("Should not have next pagiple!", nextGraph.contains(ANY, ANY, NEXT_PAGE.asNode(), ANY));
Expand Down

0 comments on commit 015bc64

Please sign in to comment.