From d116329f9708503d11ef626acd8e09525d400e73 Mon Sep 17 00:00:00 2001
From: Sonia Zorba <sonia.zorba@inaf.it>
Date: Fri, 17 Sep 2021 10:25:08 +0200
Subject: [PATCH] Added error pages

---
 .../ui/controller/ErrorController.java        | 85 +++++++++++++++++++
 .../src/main/resources/application.properties |  3 +
 .../src/main/resources/public/error/404.html  | 14 +++
 .../main/resources/public/error/error.html    | 16 ++++
 4 files changed, 118 insertions(+)
 create mode 100644 vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/ErrorController.java
 create mode 100644 vospace-ui-backend/src/main/resources/public/error/404.html
 create mode 100644 vospace-ui-backend/src/main/resources/public/error/error.html

diff --git a/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/ErrorController.java b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/ErrorController.java
new file mode 100644
index 0000000..e2e714c
--- /dev/null
+++ b/vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/ErrorController.java
@@ -0,0 +1,85 @@
+package it.inaf.ia2.vospace.ui.controller;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Scanner;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
+import org.springframework.boot.web.servlet.error.ErrorAttributes;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${server.error.path:${error.path:/error}}")
+public class ErrorController extends AbstractErrorController {
+
+    @Value("${support.contact.label}")
+    private String supportContactLabel;
+    @Value("${support.contact.email}")
+    private String supportContactEmail;
+
+    @Autowired
+    public ErrorController(ErrorAttributes errorAttributes) {
+        super(errorAttributes);
+    }
+
+    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
+    public void errorHtml(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+        Map<String, Object> errors = super.getErrorAttributes(request, true);
+
+        HttpStatus status = getStatus(request);
+
+        String responseText;
+        if (status == HttpStatus.NOT_FOUND) {
+            responseText = getFileContent("404.html");
+        } else {
+            responseText = getFileContent("error.html")
+                    .replace("#ERROR_TITLE#", (String) errors.get("error"))
+                    .replace("#ERROR_MESSAGE#", (String) errors.get("message"))
+                    .replace("#ADDITIONAL_MESSAGE#", getAdditionalMessage(status));
+        }
+
+        response.setContentType("text/html;charset=UTF-8");
+        response.getOutputStream().print(responseText);
+    }
+
+    private String getAdditionalMessage(HttpStatus status) {
+        if (status.is5xxServerError()) {
+            // unexpected error -> let users report the issue
+            return "<br/>If you need support please contact"
+                    + " <a href=\"mailto:" + supportContactEmail + "\">" + supportContactLabel + "</a>";
+        }
+        return "";
+    }
+
+    @RequestMapping
+    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
+        HttpStatus status = getStatus(request);
+        if (status == HttpStatus.NO_CONTENT) {
+            return new ResponseEntity<>(status);
+        }
+        Map<String, Object> body = getErrorAttributes(request, false);
+        return new ResponseEntity<>(body, status);
+    }
+
+    private String getFileContent(String templateFileName) throws IOException {
+        try (InputStream in = ErrorController.class.getClassLoader()
+                .getResourceAsStream("public/error/" + templateFileName)) {
+            Scanner s = new Scanner(in).useDelimiter("\\A");
+            return s.hasNext() ? s.next() : "";
+        }
+    }
+
+    @Override
+    public String getErrorPath() {
+        return null;
+    }
+}
diff --git a/vospace-ui-backend/src/main/resources/application.properties b/vospace-ui-backend/src/main/resources/application.properties
index 2b7cd11..e72cdd4 100644
--- a/vospace-ui-backend/src/main/resources/application.properties
+++ b/vospace-ui-backend/src/main/resources/application.properties
@@ -11,3 +11,6 @@ cors.allowed.origin=http://localhost:8080
 logging.level.it.inaf=TRACE
 
 trusted.eppn.scope=inaf.it
+
+support.contact.label=IA2 team
+support.contact.email=ia2@inaf.it
diff --git a/vospace-ui-backend/src/main/resources/public/error/404.html b/vospace-ui-backend/src/main/resources/public/error/404.html
new file mode 100644
index 0000000..f9d3cfe
--- /dev/null
+++ b/vospace-ui-backend/src/main/resources/public/error/404.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Page Not Found</title>
+        <meta charset="UTF-8" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
+    </head>
+    <body>
+        <div class="container mt-4">
+            <h1 class="mb-3 text-primary">Page Not Found</h1>
+        </div>
+    </body>
+</html>
diff --git a/vospace-ui-backend/src/main/resources/public/error/error.html b/vospace-ui-backend/src/main/resources/public/error/error.html
new file mode 100644
index 0000000..b0fa515
--- /dev/null
+++ b/vospace-ui-backend/src/main/resources/public/error/error.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>#ERROR_TITLE#</title>
+        <meta charset="UTF-8" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
+    </head>
+    <body>
+        <div class="container mt-4">
+            <h1 class="mb-3 text-danger">#ERROR_TITLE#</h1>
+            <p><strong>#ERROR_MESSAGE#</strong></p>
+            <p>#ADDITIONAL_MESSAGE#</p>
+        </div>
+    </body>
+</html>
-- 
GitLab