SLING-2300 Set the j_workspace request attribute to the workspace extracted from the request URL (this will later be handled by the AuthenticationInfoPostProcessor to set the required workspace property in the AuthenticationInfo)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1205779 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
index 95e1fb2..b40c98a 100644
--- a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
+++ b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
@@ -28,17 +28,28 @@
class AuthHttpContext implements HttpContext {
/**
+ * The root path at which the DavEx servlet is registered. This is used to
+ * extract the workspace name from the request URL where the workspace name
+ * is the first segment in the path after the this path.
+ */
+ private final String davRoot;
+
+ /**
* Handles security
*
* @see #handleSecurity(HttpServletRequest, HttpServletResponse)
*/
private AuthenticationSupport authenticator;
+ AuthHttpContext(final String davRoot) {
+ this.davRoot = davRoot;
+ }
+
public void setAuthenticationSupport(final AuthenticationSupport auth) {
this.authenticator = auth;
}
- // ---------- HttpContext interface ----------------------------------------
+ // ---------- HttpContext
/**
* Returns the MIME type as resolved by the <code>MimeTypeService</code> or
@@ -62,11 +73,15 @@
* is missing this method returns <code>false</code> and sends a 503/SERVICE
* UNAVAILABLE status back to the client.
*/
- public boolean handleSecurity(final HttpServletRequest request,
- final HttpServletResponse response)
- throws IOException {
+ public boolean handleSecurity(final HttpServletRequest request, final HttpServletResponse response)
+ throws IOException {
final AuthenticationSupport localAuthenticator = this.authenticator;
- if ( localAuthenticator != null ) {
+ if (localAuthenticator != null) {
+
+ final String wsp = getWorkspace(request.getPathInfo());
+ if (wsp != null) {
+ request.setAttribute("j_workspace", wsp);
+ }
return localAuthenticator.handleSecurity(request, response);
}
// send 503/SERVICE UNAVAILABLE, flush to ensure delivery
@@ -76,4 +91,46 @@
// terminate this request now
return false;
}
+
+ private final String getWorkspace(final String uriPath) {
+
+ // Paths to consider
+ // /davRoot
+ // /davRoot/
+ // /davRoot/wsp
+ // /davRoot/wsp/
+ // /davRoot/wsp/...
+
+ if (uriPath != null && uriPath.startsWith(this.davRoot)) {
+
+ // cut off root
+ int start = this.davRoot.length();
+
+ // just the root
+ if (start >= uriPath.length()) {
+ return null;
+ }
+
+ if (uriPath.charAt(start) == '/') {
+ start++;
+ } else {
+ // expected slash, actually (don't care)
+ return null;
+ }
+
+ // just the root with trailing slash
+ if (start >= uriPath.length()) {
+ return null;
+ }
+
+ int end = uriPath.indexOf('/', start);
+ if (end > start) {
+ return uriPath.substring(start, end);
+ } else if (end < 0) {
+ return uriPath.substring(start);
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
index 332ff93..aed68c4 100644
--- a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
+++ b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
@@ -106,11 +106,11 @@
@Activate
protected void activate(final BundleContext bundleContext, final Map<String, ?> config) {
- final AuthHttpContext context = new AuthHttpContext();
- context.setAuthenticationSupport(authSupport);
-
final String davRoot = OsgiUtil.toString(config.get(PROP_DAV_ROOT), DEFAULT_DAV_ROOT);
+ final AuthHttpContext context = new AuthHttpContext(davRoot);
+ context.setAuthenticationSupport(authSupport);
+
// prepare DavEx servlet config
final Dictionary<String, String> initProps = new Hashtable<String, String>();
diff --git a/src/test/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContextTest.java b/src/test/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContextTest.java
new file mode 100644
index 0000000..50f4b9d
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContextTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.davex.impl.servlets;
+
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class AuthHttpContextTest {
+
+ private static Method getWorkspace;
+
+ @BeforeClass
+ public static void getGetWorkspaceMethod() throws Throwable {
+ getWorkspace = AuthHttpContext.class.getDeclaredMethod("getWorkspace", String.class);
+ getWorkspace.setAccessible(true);
+ }
+
+ @Test
+ public void test_getWorkspace_null() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertNull(getWorkspace.invoke(ahc, (String) null));
+ }
+
+ @Test
+ public void test_getWorkspace_root() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertNull(getWorkspace.invoke(ahc, "/server"));
+ }
+
+ @Test
+ public void test_getWorkspace_root_slash() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertNull(getWorkspace.invoke(ahc, "/server/"));
+ }
+
+ @Test
+ public void test_getWorkspace_root_char() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertNull(getWorkspace.invoke(ahc, "/serverxyz"));
+ }
+
+ @Test
+ public void test_getWorkspace_wsp() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertEquals("w", getWorkspace.invoke(ahc, "/server/w"));
+ TestCase.assertEquals("wsp", getWorkspace.invoke(ahc, "/server/wsp"));
+ }
+
+ @Test
+ public void test_getWorkspace_wsp_slash() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertEquals("w", getWorkspace.invoke(ahc, "/server/w/"));
+ TestCase.assertEquals("wsp", getWorkspace.invoke(ahc, "/server/wsp/"));
+ }
+
+ @Test
+ public void test_getWorkspace_wsp_path() throws Throwable {
+ final AuthHttpContext ahc = new AuthHttpContext("/server");
+ TestCase.assertEquals("w", getWorkspace.invoke(ahc, "/server/w/abc"));
+ TestCase.assertEquals("wsp", getWorkspace.invoke(ahc, "/server/wsp/abc"));
+
+ TestCase.assertEquals("w", getWorkspace.invoke(ahc, "/server/w/abc/xyz"));
+ TestCase.assertEquals("wsp", getWorkspace.invoke(ahc, "/server/wsp/abc/xyz"));
+ }
+
+}