From 54c089b82c80edabcaae4a2985e220ed140f87c2 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Tue, 8 Nov 2022 14:32:19 +0100
Subject: [PATCH] SSDM-13152 : Exports for master data and metadata UI - AS
 session workspace download servlet with PAT support

---
 .../web/server/DownloadServiceServlet.java    | 156 ++++++++++++++++++
 1 file changed, 156 insertions(+)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/DownloadServiceServlet.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/DownloadServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/DownloadServiceServlet.java
new file mode 100644
index 00000000000..30ec6cfbe33
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/DownloadServiceServlet.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.server;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
+import ch.systemsx.cisd.common.servlet.HttpServletRequestUtils;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+
+/**
+ * Servlet that handles the download of files from the session workspace. The content type of the response is guessed from the downloaded file name.
+ * <ul>
+ * <li>Accepted HTTP methods: GET</li>
+ * <li>HTTP request parameters: sessionID (String required), filePath (String required)</li>
+ * </ul>
+ *
+ * @author pkupczyk
+ */
+@Controller
+public class DownloadServiceServlet extends HttpServlet
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String SESSION_ID_PARAM = "sessionID";
+
+    private static final String FILE_PATH_PARAM = "filePath";
+
+    @Override
+    @RequestMapping({ "/download", "/openbis/download" })
+    protected void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException
+    {
+        DownloadRequest downloadRequest = new DownloadRequest(request);
+
+        downloadRequest.validate();
+
+        File sessionWorkspace = CommonServiceProvider.getSessionWorkspaceProvider().getSessionWorkspace(downloadRequest.getSessionId());
+        File file = new File(sessionWorkspace, downloadRequest.getFilePath());
+
+        DownloadResponse downloadResponse = new DownloadResponse(response);
+        downloadResponse.writeFile(downloadRequest.getFilePath(), new BufferedInputStream(new FileInputStream(file)));
+    }
+
+    private static class DownloadRequest
+    {
+
+        private final HttpServletRequest request;
+
+        public DownloadRequest(HttpServletRequest request)
+        {
+            this.request = request;
+        }
+
+        public String getSessionId()
+        {
+            String sessionId = HttpServletRequestUtils.getStringParameter(request, SESSION_ID_PARAM);
+            sessionId = CommonServiceProvider.getPersonalAccessTokenConverter().convert(sessionId);
+            return sessionId;
+        }
+
+        public String getFilePath()
+        {
+            return HttpServletRequestUtils.getStringParameter(request, FILE_PATH_PARAM);
+        }
+
+        public void validate()
+        {
+            if (getSessionId() == null)
+            {
+                throw new IllegalArgumentException(SESSION_ID_PARAM
+                        + " parameter cannot be null");
+            }
+
+            if (!CommonServiceProvider.getApplicationServerApi().isSessionActive(getSessionId()))
+            {
+                throw new IllegalArgumentException(SESSION_ID_PARAM + " parameter contains an invalid session token");
+            }
+
+            if (getFilePath() == null)
+            {
+                throw new IllegalArgumentException(FILE_PATH_PARAM + " parameter cannot be null");
+            }
+
+            if (getFilePath().contains("../"))
+            {
+                throw new IOExceptionUnchecked(FILE_PATH_PARAM + " parameter must not contain '../'");
+            }
+
+        }
+
+    }
+
+    private static class DownloadResponse
+    {
+
+        private final HttpServletResponse response;
+
+        public DownloadResponse(HttpServletResponse response)
+        {
+            this.response = response;
+        }
+
+        public void writeFile(String filePath, InputStream fileStream) throws IOException
+        {
+            ServletOutputStream outputStream = null;
+
+            try
+            {
+                String fileName = FilenameUtils.getName(filePath);
+                response.setHeader("Content-Disposition", "inline; filename=" + fileName);
+                response.setContentType(URLConnection.guessContentTypeFromName(fileName));
+                response.setStatus(HttpServletResponse.SC_OK);
+                outputStream = response.getOutputStream();
+                IOUtils.copyLarge(fileStream, outputStream);
+            } finally
+            {
+                IOUtils.closeQuietly(fileStream);
+                IOUtils.closeQuietly(outputStream);
+            }
+        }
+
+    }
+
+}
-- 
GitLab