Use whiteboard for the files servlet.
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 5 Jun 2020 04:39:28 +0000 (06:39 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 5 Jun 2020 04:39:28 +0000 (06:39 +0200)
org.argeo.cms/OSGI-INF/filesServlet.xml [new file with mode: 0644]
org.argeo.cms/OSGI-INF/filesServletContext.xml [new file with mode: 0644]
org.argeo.cms/bnd.bnd
org.argeo.cms/build.properties
org.argeo.cms/src/org/argeo/cms/internal/http/CmsWebDavServlet.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/http/PrivateServletContextHelper.java [new file with mode: 0644]

diff --git a/org.argeo.cms/OSGI-INF/filesServlet.xml b/org.argeo.cms/OSGI-INF/filesServlet.xml
new file mode 100644 (file)
index 0000000..498d097
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.argeo.cms">
+   <implementation class="org.argeo.cms.internal.http.CmsWebDavServlet"/>
+   <service>
+      <provide interface="javax.servlet.Servlet"/>
+   </service>
+   <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/*"/>
+   <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=filesServletContext)"/>
+   <property name="servlet.init.resource-config" type="String" value="/org/argeo/cms/internal/http/webdav-config.xml"/>  
+   <property name="servlet.init.resource-path-prefix" type="String" value="/files"/>
+   <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" policy="static" target="(cn=ego)"/>
+</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/filesServletContext.xml b/org.argeo.cms/OSGI-INF/filesServletContext.xml
new file mode 100644 (file)
index 0000000..a9993a3
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="org.argeo.cms.filesServletContext">
+   <implementation class="org.argeo.cms.internal.http.PrivateServletContextHelper"/>
+   <service>
+      <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
+   </service>
+   <property name="osgi.http.whiteboard.context.name" type="String" value="filesServletContext"/>
+   <property name="osgi.http.whiteboard.context.path" type="String" value="/files"/>
+</scr:component>
index e89451e3a71e7ecba855cde895c7e91941fb83ff..4eae650a3437ad6cd9d40b5f333f5c9f0760762c 100644 (file)
@@ -10,6 +10,8 @@ org.apache.commons.httpclient.cookie;resolution:=optional,\
 org.osgi.*;version=0.0.0,\
 *
 
-Service-Component: OSGI-INF/cmsUserManager.xml
+Service-Component: OSGI-INF/cmsUserManager.xml,\
+OSGI-INF/filesServletContext.xml,\
+OSGI-INF/filesServlet.xml
 
 Provide-Capability: cms.datamodel;name=argeo;cnd=/org/argeo/cms/argeo.cnd;abstract=true
index 03b14d4341eea3dfddc1156cf1e8b221e2641c23..55f4d9ae5d9d05975c4df6aac6326e89f49e2d63 100644 (file)
@@ -1,9 +1,8 @@
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               OSGI-INF/,\
                bin/,\
-               OSGI-INF/cmsUserManager.xml
+               OSGI-INF/
 source.. = src/,\
            ext/test/
 additional.bundles = org.apache.jackrabbit.data,\
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/http/CmsWebDavServlet.java b/org.argeo.cms/src/org/argeo/cms/internal/http/CmsWebDavServlet.java
new file mode 100644 (file)
index 0000000..f60e3b6
--- /dev/null
@@ -0,0 +1,26 @@
+package org.argeo.cms.internal.http;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
+import org.argeo.api.NodeConstants;
+
+public class CmsWebDavServlet extends SimpleWebdavServlet {
+       private static final long serialVersionUID = 7485800288686328063L;
+       private Repository repository;
+
+       @Override
+       public Repository getRepository() {
+               return repository;
+       }
+
+       public void setRepository(Repository repository, Map<String, String> properties) {
+               this.repository = repository;
+               String alias = properties.get(NodeConstants.CN);
+               if (alias != null)
+                       setSessionProvider(new CmsSessionProvider(alias));
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/http/PrivateServletContextHelper.java b/org.argeo.cms/src/org/argeo/cms/internal/http/PrivateServletContextHelper.java
new file mode 100644 (file)
index 0000000..62e74c3
--- /dev/null
@@ -0,0 +1,77 @@
+package org.argeo.cms.internal.http;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeConstants;
+import org.argeo.cms.auth.HttpRequestCallbackHandler;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.http.context.ServletContextHelper;
+
+public class PrivateServletContextHelper extends ServletContextHelper {
+       private final static Log log = LogFactory.getLog(PrivateServletContextHelper.class);
+
+       // TODO make it configurable
+       private final String httpAuthRealm = "Argeo";
+       private final boolean forceBasic = false;
+
+       // use CMS bundle for resources
+       private Bundle bundle = FrameworkUtil.getBundle(getClass());
+
+       public void init(Map<String, String> properties) {
+
+       }
+
+       public void destroy() {
+
+       }
+
+       @Override
+       public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
+               if (log.isTraceEnabled())
+                       HttpUtils.logRequestHeaders(log, request);
+               LoginContext lc;
+               try {
+                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request, response));
+                       lc.login();
+               } catch (LoginException e) {
+                       askForWwwAuth(request, response);
+                       return false;
+               }
+               return true;
+       }
+
+       protected void askForWwwAuth(HttpServletRequest request, HttpServletResponse response) {
+               response.setStatus(401);
+               // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic
+               // realm=\"" + httpAuthRealm + "\"");
+               if (org.argeo.cms.internal.kernel.Activator.getAcceptorCredentials() != null && !forceBasic)// SPNEGO
+                       response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "Negotiate");
+               else
+                       response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + httpAuthRealm + "\"");
+
+               // response.setDateHeader("Date", System.currentTimeMillis());
+               // response.setDateHeader("Expires", System.currentTimeMillis() + (24 *
+               // 60 * 60 * 1000));
+               // response.setHeader("Accept-Ranges", "bytes");
+               // response.setHeader("Connection", "Keep-Alive");
+               // response.setHeader("Keep-Alive", "timeout=5, max=97");
+               // response.setContentType("text/html; charset=UTF-8");
+
+       }
+
+       @Override
+       public URL getResource(String name) {
+               return bundle.getResource(name);
+       }
+
+}