SLING-2167 : Use Sling authenticator

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1153126 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 25cd11c..40f6f1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,6 +100,19 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.auth.core</artifactId>
+            <version>1.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
             <groupId>javax.jcr</groupId>
             <artifactId>jcr</artifactId>
             <version>2.0</version>
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
new file mode 100644
index 0000000..95e1fb2
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
@@ -0,0 +1,79 @@
+/*
+ * 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.io.IOException;
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.osgi.service.http.HttpContext;
+
+class AuthHttpContext implements HttpContext {
+
+    /**
+     * Handles security
+     *
+     * @see #handleSecurity(HttpServletRequest, HttpServletResponse)
+     */
+    private AuthenticationSupport authenticator;
+
+    public void setAuthenticationSupport(final AuthenticationSupport auth) {
+        this.authenticator = auth;
+    }
+
+    // ---------- HttpContext interface ----------------------------------------
+
+    /**
+     * Returns the MIME type as resolved by the <code>MimeTypeService</code> or
+     * <code>null</code> if the service is not available.
+     */
+    public String getMimeType(String name) {
+        return null;
+    }
+
+    /**
+     * Always returns <code>null</code> because resources are all provided
+     * through the {@link MainServlet}.
+     */
+    public URL getResource(String name) {
+        return null;
+    }
+
+    /**
+     * Tries to authenticate the request using the
+     * <code>SlingAuthenticator</code>. If the authenticator or the Repository
+     * 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 {
+        final AuthenticationSupport localAuthenticator = this.authenticator;
+        if ( localAuthenticator != null ) {
+            return localAuthenticator.handleSecurity(request, response);
+        }
+        // send 503/SERVICE UNAVAILABLE, flush to ensure delivery
+        response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+        response.flushBuffer();
+
+        // terminate this request now
+        return false;
+    }
+}
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 8616ab3..6b4d524 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
@@ -16,15 +16,30 @@
  */
 package org.apache.sling.jcr.davex.impl.servlets;
 
-import javax.jcr.Repository;
-import javax.servlet.Servlet;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
 
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.server.SessionProvider;
 import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.HttpService;
 
 /**
  * DavEx WebDav servlet which acquires a Repository instance via the OSGi
@@ -32,7 +47,6 @@
  *
  */
 @Component(label = "%dav.name", description = "%dav.description")
-@Service(Servlet.class)
 @Properties( { @Property(name = "alias", value = "/server"),
         @Property(name = "init.resource-path-prefix", value = "/server"),
         @Property(name = "init.missing-auth-mapping", value = ""),
@@ -40,12 +54,73 @@
         @Property(name = "service.vendor", value = "The Apache Software Foundation") })
 public class SlingDavExServlet extends JcrRemotingServlet {
 
+    private static final String INIT_KEY_PREFIX = "init.";
+
     @Reference
     private Repository repository;
 
+    @Reference
+    private HttpService httpService;
+
+    @Reference
+    private AuthenticationSupport authentiator;
+
+    @Activate
+    protected void activate(final ComponentContext ctx)
+    throws Exception {
+        final AuthHttpContext context = new AuthHttpContext();
+        context.setAuthenticationSupport(authentiator);
+
+        final String alias = (String)ctx.getProperties().get("alias");
+        final Dictionary<String, String> initProps = new Hashtable<String, String>();
+        @SuppressWarnings("unchecked")
+        final Enumeration<String> keyEnum = ctx.getProperties().keys();
+        while ( keyEnum.hasMoreElements() ) {
+            final String key = keyEnum.nextElement();
+            if ( key.startsWith(INIT_KEY_PREFIX) ) {
+                final String paramKey = key.substring(INIT_KEY_PREFIX.length());
+                final Object paramValue = ctx.getProperties().get(key);
+
+                if (paramValue != null) {
+                    initProps.put(paramKey, paramValue.toString());
+                }
+            }
+        }
+
+        this.httpService.registerServlet(alias, this, initProps, context);
+    }
+
+    @Deactivate
+    protected void deactivate(final Map<String, Object> props) {
+        final String alias = (String)props.get("alias");
+        this.httpService.unregister(alias);
+    }
+
     @Override
     protected Repository getRepository() {
         return repository;
     }
 
+    @Override
+    protected SessionProvider getSessionProvider() {
+        return new SessionProvider() {
+
+            public Session getSession(final HttpServletRequest req,
+                    final Repository paramRepository,
+                    final String paramString)
+            throws LoginException, ServletException, RepositoryException {
+                final ResourceResolver resolver = (ResourceResolver) req.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+                if ( resolver != null ) {
+                    return resolver.adaptTo(Session.class);
+                }
+                return null;
+            }
+
+            public void releaseSession(Session paramSession) {
+                // nothing to do
+
+            }
+        };
+    }
+
 }