Index: dna-graph/src/test/java/org/jboss/dna/graph/MockSecurityContext.java =================================================================== --- dna-graph/src/test/java/org/jboss/dna/graph/MockSecurityContext.java (revision 983) +++ dna-graph/src/test/java/org/jboss/dna/graph/MockSecurityContext.java (working copy) @@ -20,17 +20,14 @@ this.entitlements = entitlements != null ? entitlements : Collections.emptySet(); } - @Override public String getUserName() { return userName; } - @Override public boolean hasRole( String roleName ) { return entitlements.contains(roleName); } - @Override public void logout() { } Index: extensions/dna-web-jcr-rest-war/pom.xml =================================================================== --- extensions/dna-web-jcr-rest-war/pom.xml (revision 982) +++ extensions/dna-web-jcr-rest-war/pom.xml (working copy) @@ -42,16 +42,11 @@ resources - - - - - - org.codehaus.cargo cargo-maven2-plugin + start-container @@ -71,14 +66,10 @@ - high + low + dnauser:password:connect,readwrite|unauthorized:password:bogus - - - ${project.build.directory}/test-classes/jetty-dna.policy - - false @@ -106,6 +97,7 @@ + Index: extensions/dna-web-jcr-rest-war/src/main/resources/log4j.properties =================================================================== --- extensions/dna-web-jcr-rest-war/src/main/resources/log4j.properties (revision 0) +++ extensions/dna-web-jcr-rest-war/src/main/resources/log4j.properties (revision 0) @@ -0,0 +1,13 @@ +log4j.rootLogger = INFO, stdout + +log4j.category.org.apache=DEBUG +log4j.category.org.jboss.resteasy=DEBUG +log4j.category.org.mortbay.jetty.security=ERROR +log4j.category.org.slf4j.impl.JCLLoggerAdapter=DEBUG +log4j.category.org.springframework=INFO + +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Threshold = INFO +log4j.appender.stdout.Target = System.out +log4j.appender.stdout.layout = org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern = [%-5p] [%C] : %m%n [%F:%L] Index: extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml =================================================================== --- extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml (revision 982) +++ extensions/dna-web-jcr-rest-war/src/main/webapp/WEB-INF/web.xml (working copy) @@ -21,39 +21,47 @@ --> JBoss DNA JCR RESTful Interface + org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider + org.jboss.dna.web.jcr.rest.CONFIG_FILE /configRepository.xml + resteasy.providers org.jboss.dna.web.jcr.rest.JcrResources$NotFoundExceptionMapper, org.jboss.dna.web.jcr.rest.JcrResources$JSONExceptionMapper, org.jboss.dna.web.jcr.rest.JcrResources$RepositoryExceptionMapper + javax.ws.rs.Application org.jboss.dna.web.jcr.rest.JcrApplication + org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap + org.jboss.dna.web.jcr.rest.DnaJcrDeployer + Resteasy org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher + Resteasy /* - Index: extensions/dna-web-jcr-rest-war/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java =================================================================== --- extensions/dna-web-jcr-rest-war/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java (revision 982) +++ extensions/dna-web-jcr-rest-war/src/test/java/org/jboss/dna/web/jcr/rest/JcrResourcesTest.java (working copy) @@ -24,13 +24,15 @@ package org.jboss.dna.web.jcr.rest; import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.hamcrest.core.IsNull.notNullValue; -import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; +import java.net.Authenticator; import java.net.HttpURLConnection; +import java.net.PasswordAuthentication; import java.net.URL; import java.util.HashSet; import java.util.Set; @@ -48,14 +50,15 @@ @Before public void beforeEach() { -// final String login ="dnauser"; -// final String password ="password"; -// -// Authenticator.setDefault(new Authenticator() { -// protected PasswordAuthentication getPasswordAuthentication() { -// return new PasswordAuthentication (login, password.toCharArray()); -// } -// }); + // Configured in pom + final String login ="dnauser"; + final String password ="password"; + + Authenticator.setDefault(new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication (login, password.toCharArray()); + } + }); } private String getResponseFor( HttpURLConnection connection ) throws IOException { @@ -72,6 +75,55 @@ } @Test + public void shouldNotServeContentToUnauthorizedUser() throws Exception { + + final String login ="dnauser"; + final String password ="invalidpassword"; + + Authenticator.setDefault(new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication (login, password.toCharArray()); + } + }); + + URL postUrl = new URL(SERVER_URL + "/"); + HttpURLConnection connection = (HttpURLConnection)postUrl.openConnection(); + + connection.setDoOutput(true); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", MediaType.APPLICATION_JSON); + + assertThat(connection.getResponseCode(), is(HttpURLConnection.HTTP_UNAUTHORIZED)); + connection.disconnect(); + + } + + @Test + public void shouldNotServeContentToUserWithoutConnectRole() throws Exception { + + // Configured in pom + final String login ="unauthorizeduser"; + final String password ="password"; + + Authenticator.setDefault(new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication (login, password.toCharArray()); + } + }); + + URL postUrl = new URL(SERVER_URL + "/"); + HttpURLConnection connection = (HttpURLConnection)postUrl.openConnection(); + + connection.setDoOutput(true); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", MediaType.APPLICATION_JSON); + + assertThat(connection.getResponseCode(), is(HttpURLConnection.HTTP_UNAUTHORIZED)); + connection.disconnect(); + + } + + @Test public void shouldServeContentAtRoot() throws Exception { URL postUrl = new URL(SERVER_URL + "/"); HttpURLConnection connection = (HttpURLConnection)postUrl.openConnection(); Index: extensions/dna-web-jcr-rest-war/src/test/resources/dna-test-users.props =================================================================== --- extensions/dna-web-jcr-rest-war/src/test/resources/dna-test-users.props (revision 982) +++ extensions/dna-web-jcr-rest-war/src/test/resources/dna-test-users.props (working copy) @@ -1 +0,0 @@ -dnauser=password,readwrite Index: extensions/dna-web-jcr-rest-war/src/test/resources/jetty-dna.policy =================================================================== --- extensions/dna-web-jcr-rest-war/src/test/resources/jetty-dna.policy (revision 982) +++ extensions/dna-web-jcr-rest-war/src/test/resources/jetty-dna.policy (working copy) @@ -1,5 +0,0 @@ -dna-jcr { - org.mortbay.jetty.plus.jaas.spi.PropertyFileLoginModule optional - debug="true" - file="target/test-classes/dna-test-users.props"; -}; Index: extensions/dna-web-jcr-rest-war/src/test/resources/jetty-jaas.xml =================================================================== --- extensions/dna-web-jcr-rest-war/src/test/resources/jetty-jaas.xml (revision 982) +++ extensions/dna-web-jcr-rest-war/src/test/resources/jetty-jaas.xml (working copy) @@ -1,9 +0,0 @@ - - - - xyzrealm - dna-jcr - - - - Index: extensions/dna-web-jcr-rest-war/src/test/resources/log4j.properties =================================================================== --- extensions/dna-web-jcr-rest-war/src/test/resources/log4j.properties (revision 982) +++ extensions/dna-web-jcr-rest-war/src/test/resources/log4j.properties (working copy) @@ -1,9 +1,9 @@ log4j.rootLogger = DEBUG, stdout -log4j.category.org.apache=INFO -log4j.category.org.jboss.resteasy=INFO -log4j.category.org.mortbay=DEBUG -log4j.category.org.slf4j.impl.JCLLoggerAdapter=INFO +log4j.category.org.apache=DEBUG +log4j.category.org.jboss.resteasy=DEBUG +log4j.category.org.mortbay.jetty.security=ERROR +log4j.category.org.slf4j.impl.JCLLoggerAdapter=DEBUG log4j.category.org.springframework=INFO log4j.appender.stdout = org.apache.log4j.ConsoleAppender Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java =================================================================== --- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java (revision 982) +++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/JcrResources.java (working copy) @@ -35,7 +35,6 @@ import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.PropertyIterator; -import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; @@ -126,36 +125,26 @@ public static final String EMPTY_WORKSPACE_NAME = ""; /** - * Returns a reference to the named repository, if it exists. - * - * @param repositoryName the name of the repository to load - * @return the repository - * @throws RepositoryException if any other error occurs - */ - private Repository getRepository( String repositoryName ) throws RepositoryException { - return RepositoryFactory.getRepository(repositoryName); - } - - /** * Returns an active session for the given workspace name in the named repository. * + * @param request the servlet request; may not be null or unauthenticated * @param rawRepositoryName the URL-encoded name of the repository in which the session is created - * @param rawWorkspaceName the URL-endecoded name of the workspace to which the session should be connected + * @param rawWorkspaceName the URL-encoded name of the workspace to which the session should be connected * @return an active session with the given workspace in the named repository * @throws RepositoryException if any other error occurs */ - private Session getSession( String rawRepositoryName, + private Session getSession( HttpServletRequest request, + String rawRepositoryName, String rawWorkspaceName ) throws NotFoundException, RepositoryException { + assert request != null; + assert request.getUserPrincipal() != null: "Request must be authorized"; - Repository repository; - try { - repository = getRepository(repositoryNameFor(rawRepositoryName)); - - } catch (RepositoryException re) { - throw new NotFoundException(re.getMessage(), re); + // Sanity check + if (request.getUserPrincipal() == null) { + throw new UnauthorizedException("Client is not authorized"); } - return repository.login(null, workspaceNameFor(rawWorkspaceName)); + return RepositoryFactory.getSession(request, repositoryNameFor(rawRepositoryName), workspaceNameFor(rawWorkspaceName)); } /** @@ -205,7 +194,7 @@ Map workspaces = new HashMap(); - Session session = getSession(rawRepositoryName, null); + Session session = getSession(request, rawRepositoryName, null); rawRepositoryName = URL_ENCODER.encode(rawRepositoryName); for (String name : session.getWorkspace().getAccessibleWorkspaceNames()) { @@ -222,6 +211,7 @@ /** * Handles GET requests for an item in a workspace. * + * @param request the servlet request; may not be null or unauthenticated * @param rawRepositoryName the URL-encoded repository name * @param rawWorkspaceName the URL-encoded workspace name * @param path the path to the item @@ -242,7 +232,8 @@ @GET @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" ) @Produces( "application/json" ) - public String getItem( @PathParam( "repositoryName" ) String rawRepositoryName, + public String getItem( @Context HttpServletRequest request, + @PathParam( "repositoryName" ) String rawRepositoryName, @PathParam( "workspaceName" ) String rawWorkspaceName, @PathParam( "path" ) String path, @QueryParam( "dna:depth" ) @DefaultValue( "0" ) int depth ) @@ -251,7 +242,7 @@ assert rawRepositoryName != null; assert rawWorkspaceName != null; - Session session = getSession(rawRepositoryName, rawWorkspaceName); + Session session = getSession(request, rawRepositoryName, rawWorkspaceName); Item item; if ("/".equals(path) || "".equals(path)) { @@ -365,6 +356,7 @@ * jcr:mixinTypes} properties. *

* + * @param request the servlet request; may not be null or unauthenticated * @param rawRepositoryName the URL-encoded repository name * @param rawWorkspaceName the URL-encoded workspace name * @param path the path to the item @@ -379,7 +371,8 @@ @POST @Path( "/{repositoryName}/{workspaceName}/items/{path:.*}" ) @Consumes( "application/json" ) - public Response postItem( @PathParam( "repositoryName" ) String rawRepositoryName, + public Response postItem( @Context HttpServletRequest request, + @PathParam( "repositoryName" ) String rawRepositoryName, @PathParam( "workspaceName" ) String rawWorkspaceName, @PathParam( "path" ) String path, String requestContent ) @@ -394,7 +387,7 @@ String parentPath = lastSlashInd == -1 ? "/" : "/" + path.substring(0, lastSlashInd); String newNodeName = lastSlashInd == -1 ? path : path.substring(lastSlashInd + 1); - Session session = getSession(rawRepositoryName, rawWorkspaceName); + Session session = getSession(request, rawRepositoryName, rawWorkspaceName); Node parentNode = (Node)session.getItem(parentPath); @@ -499,6 +492,7 @@ /** * Deletes the item at {@code path}. * + * @param request the servlet request; may not be null or unauthenticated * @param rawRepositoryName the URL-encoded repository name * @param rawWorkspaceName the URL-encoded workspace name * @param path the path to the item @@ -509,7 +503,8 @@ @DELETE @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" ) @Consumes( "application/json" ) - public void deleteItem( @PathParam( "repositoryName" ) String rawRepositoryName, + public void deleteItem( @Context HttpServletRequest request, + @PathParam( "repositoryName" ) String rawRepositoryName, @PathParam( "workspaceName" ) String rawWorkspaceName, @PathParam( "path" ) String path ) throws NotFoundException, UnauthorizedException, RepositoryException { @@ -518,7 +513,7 @@ assert rawWorkspaceName != null; assert path != null; - Session session = getSession(rawRepositoryName, rawWorkspaceName); + Session session = getSession(request, rawRepositoryName, rawWorkspaceName); Item item; try { @@ -539,6 +534,7 @@ * keys correspond to the values that will be set on the properties. *

* + * @param request the servlet request; may not be null or unauthenticated * @param rawRepositoryName the URL-encoded repository name * @param rawWorkspaceName the URL-encoded workspace name * @param path the path to the item @@ -552,7 +548,8 @@ @PUT @Path( "/{repositoryName}/{workspaceName}/items{path:.*}" ) @Consumes( "application/json" ) - public String putItem( @PathParam( "repositoryName" ) String rawRepositoryName, + public String putItem( @Context HttpServletRequest request, + @PathParam( "repositoryName" ) String rawRepositoryName, @PathParam( "workspaceName" ) String rawWorkspaceName, @PathParam( "path" ) String path, String requestContent ) throws UnauthorizedException, JSONException, RepositoryException { @@ -561,7 +558,7 @@ assert rawRepositoryName != null; assert rawWorkspaceName != null; - Session session = getSession(rawRepositoryName, rawWorkspaceName); + Session session = getSession(request, rawRepositoryName, rawWorkspaceName); Node node; Item item; if ("".equals(path) || "/".equals(path)) { Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java =================================================================== --- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java (revision 982) +++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/RepositoryFactory.java (working copy) @@ -1,9 +1,10 @@ package org.jboss.dna.web.jcr.rest; import java.util.Collection; -import javax.jcr.Repository; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.jboss.dna.web.jcr.rest.spi.RepositoryProvider; public class RepositoryFactory { @@ -30,8 +31,8 @@ provider.startup(context); } - public static Repository getRepository( String repositoryName ) throws RepositoryException { - return provider.getRepository(repositoryName); + public static Session getSession( HttpServletRequest request, String repositoryName, String workspaceName) throws RepositoryException { + return provider.getSession(request, repositoryName, workspaceName); } public static Collection getJcrRepositoryNames() { Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/ServletSecurityContext.java =================================================================== --- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/ServletSecurityContext.java (revision 0) +++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/ServletSecurityContext.java (revision 0) @@ -0,0 +1,53 @@ +package org.jboss.dna.web.jcr.rest; + +import javax.servlet.http.HttpServletRequest; +import org.jboss.dna.common.util.CheckArg; +import org.jboss.dna.graph.SecurityContext; + +/** + * Servlet-based {@link SecurityContext security context} that assumes servlet-based authentication and provides authorization + * through the {@link HttpServletRequest#isUserInRole(String) servlet role-checking mechanism}. + */ +public class ServletSecurityContext implements SecurityContext { + + private final String userName; + private final HttpServletRequest request; + + /** + * Create a {@link ServletSecurityContext} with the supplied {@link HttpServletRequest servlet information}. + * + * @param request the servlet request; may not be null + */ + public ServletSecurityContext( HttpServletRequest request ) { + CheckArg.isNotNull(request, "request"); + this.request = request; + this.userName = request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null; + } + + /** + * {@inheritDoc SecurityContext#getUserName()} + * + * @see SecurityContext#getUserName() + */ + public final String getUserName() { + return userName; + } + + /** + * {@inheritDoc SecurityContext#hasRole(String)} + * + * @see SecurityContext#hasRole(String) + */ + public final boolean hasRole( String roleName ) { + return request.isUserInRole(roleName); + } + + /** + * {@inheritDoc SecurityContext#logout()} + * + * @see SecurityContext#logout() + */ + public void logout() { + } + +} Property changes on: extensions\dna-web-jcr-rest\src\main\java\org\jboss\dna\web\jcr\rest\ServletSecurityContext.java ___________________________________________________________________ Added: svn:keywords + Id Revision Added: svn:eol-style + LF Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java =================================================================== --- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java (revision 982) +++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/DnaJcrRepositoryProvider.java (working copy) @@ -6,9 +6,15 @@ import java.util.Set; import javax.jcr.Repository; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.jboss.dna.jcr.JcrConfiguration; import org.jboss.dna.jcr.JcrEngine; +import org.jboss.dna.jcr.SecurityContextCredentials; +import org.jboss.dna.web.jcr.rest.ServletSecurityContext; +import org.jboss.resteasy.spi.NotFoundException; +import org.jboss.resteasy.spi.UnauthorizedException; import org.xml.sax.SAXException; public class DnaJcrRepositoryProvider implements RepositoryProvider { @@ -24,7 +30,7 @@ return new HashSet(jcrEngine.getRepositoryNames()); } - public Repository getRepository( String repositoryName ) throws RepositoryException { + private Repository getRepository( String repositoryName ) throws RepositoryException { return jcrEngine.getRepository(repositoryName); } @@ -46,4 +52,37 @@ public void shutdown() { jcrEngine.shutdown(); } + + /** + * Returns an active session for the given workspace name in the named repository. + * + * @param request the servlet request; may not be null or unauthenticated + * @param repositoryName the name of the repository in which the session is created + * @param workspaceName the name of the workspace to which the session should be connected + * @return an active session with the given workspace in the named repository + * @throws RepositoryException if any other error occurs + */ + public Session getSession( HttpServletRequest request, + String repositoryName, + String workspaceName ) throws RepositoryException { + assert request != null; + assert request.getUserPrincipal() != null: "Request must be authorized"; + + // Sanity check in case assertions are disabled + if (request.getUserPrincipal() == null) { + throw new UnauthorizedException("Client is not authorized"); + } + + Repository repository; + + try { + repository = getRepository(repositoryName); + + } catch (RepositoryException re) { + throw new NotFoundException(re.getMessage(), re); + } + + return repository.login(new SecurityContextCredentials(new ServletSecurityContext(request)), workspaceName); + + } } Index: extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java =================================================================== --- extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java (revision 982) +++ extensions/dna-web-jcr-rest/src/main/java/org/jboss/dna/web/jcr/rest/spi/RepositoryProvider.java (working copy) @@ -1,9 +1,10 @@ package org.jboss.dna.web.jcr.rest.spi; import java.util.Set; -import javax.jcr.Repository; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; /** * Interface for any class that provides access to one or more local JCR repositories. Repository providers must provide a public, @@ -12,15 +13,18 @@ public interface RepositoryProvider { /** - * Returns a reference to the named repository + * Returns an active session for the given workspace name in the named repository. * - * @param repositoryName the name of the repository to retrieve; may be null - * @return the repository with the given name; may not be null - * @throws RepositoryException if no repository with the given name exists or there is an error obtaining a reference to the - * named repository + * @param request the servlet request; may not be null or unauthenticated + * @param repositoryName the name of the repository in which the session is created + * @param workspaceName the name of the workspace to which the session should be connected + * @return an active session with the given workspace in the named repository + * @throws RepositoryException if any other error occurs */ - Repository getRepository( String repositoryName ) throws RepositoryException; - + public Session getSession( HttpServletRequest request, + String repositoryName, + String workspaceName ) throws RepositoryException; + /** * Returns the available repository names * @@ -40,4 +44,5 @@ * any external resource held. */ void shutdown(); + } Index: extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml =================================================================== --- extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml (revision 982) +++ extensions/dna-web-jcr-rest/src/main/webapp/WEB-INF/web.xml (working copy) @@ -1,65 +0,0 @@ - - - - - JBoss DNA JCR RESTful Interface - - - org.jboss.dna.web.jcr.rest.REPOSITORY_PROVIDER - org.jboss.dna.web.jcr.rest.spi.DnaJcrRepositoryProvider - - - - resteasy.providers - org.jboss.dna.web.jcr.rest.JcrResources$NotFoundExceptionMapper, - org.jboss.dna.web.jcr.rest.JcrResources$JSONExceptionMapper, - org.jboss.dna.web.jcr.rest.JcrResources$RepositoryExceptionMapper - - - - - javax.ws.rs.core.Application - org.jboss.dna.web.jcr.rest.JcrApplication - - - - - org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap - - - - - org.jboss.dna.web.jcr.rest.DnaJcrDeployer - - - - Resteasy - - org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher - - - - - Resteasy - /* - - - \ No newline at end of file Index: pom.xml =================================================================== --- pom.xml (revision 982) +++ pom.xml (working copy) @@ -143,8 +143,8 @@ extensions/dna-mimetype-detector-aperture extensions/dna-common-jdbc extensions/dna-connector-jdbc-metadata - - + extensions/dna-web-jcr-rest + extensions/dna-web-jcr-rest-war dna-integration-tests