diff --git a/pom.xml b/pom.xml
index d1add8b..659ab99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,18 @@
org.example
Widerhall
1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 16
+
+
+
+
17
@@ -14,6 +26,25 @@
+
+
+ org.eclipse.jetty
+ jetty-server
+ 10.0.9
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 10.0.9
+
+
+
+ de.srsoftware
+ tools
+ 1.1.18
+
+
com.sun.mail
javax.mail
diff --git a/src/main/java/de/srsoftware/widerhall/Application.java b/src/main/java/de/srsoftware/widerhall/Application.java
index 32398b3..e531bcf 100644
--- a/src/main/java/de/srsoftware/widerhall/Application.java
+++ b/src/main/java/de/srsoftware/widerhall/Application.java
@@ -1,5 +1,15 @@
package de.srsoftware.widerhall;
+import de.srsoftware.widerhall.mail.Forwarder;
+import de.srsoftware.widerhall.mail.ImapClient;
+import de.srsoftware.widerhall.mail.MessageHandler;
+import de.srsoftware.widerhall.web.Index;
+import de.srsoftware.widerhall.web.Login;
+import de.srsoftware.widerhall.web.Rest;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
@@ -7,17 +17,35 @@ import org.json.simple.parser.ParseException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import static de.srsoftware.widerhall.Constants.*;
public class Application {
- public static void main(String[] args) throws IOException, ParseException {
- var parser = new JSONParser();
- var config = Files.readString(new File("/tmp/config.json").toPath());
- JSONObject json = (JSONObject) parser.parse(config);
+ public static void main(String[] args) throws Exception {
+ var config = Configuration.setFile(new File("/tmp/config.json"));
+ //startMailSystem(json);
+ startWebserver(config);
+ }
+
+ private static void startWebserver(Configuration config) throws Exception {
+ var server = new Server();
+ var connector = new ServerConnector(server);
+ connector.setPort(config.serverPort());
+ server.setConnectors(new Connector[]{connector});
+ ServletContextHandler context = new ServletContextHandler(server, "/");
+ context.addServlet(Rest.class,"/api");
+ context.addServlet(Login.class,"/login");
+ context.addServlet(Index.class,"/");
+
+ server.start();
+ }
+ private static void startMailSystem(JSONObject json) {
MessageHandler forward = new Forwarder(json);
- new ImapClient(json)
- .addListener(forward)
- .start();
+ new ImapClient(json)
+ .addListener(forward)
+ .start();
}
}
diff --git a/src/main/java/de/srsoftware/widerhall/Configuration.java b/src/main/java/de/srsoftware/widerhall/Configuration.java
new file mode 100644
index 0000000..25a19da
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/Configuration.java
@@ -0,0 +1,81 @@
+package de.srsoftware.widerhall;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Files;
+import static de.srsoftware.widerhall.Constants.*;
+public class Configuration {
+ private static Configuration singleton = null;
+ private JSONObject data;
+ private final File file;
+
+ public Configuration(File configFile) throws IOException, ParseException {
+ this.file = configFile;
+ if (!configFile.exists()){
+ setDefaults();
+ save();
+ }
+ var content = Files.readString(configFile.toPath());
+ data = (JSONObject) new JSONParser().parse(content);
+ }
+
+ public static Configuration setFile(File file) throws IOException, ParseException {
+ singleton = new Configuration(file);
+ return singleton;
+ }
+
+ public static Configuration instance() {
+ return singleton;
+ }
+
+ private void setDefaults() throws MalformedURLException {
+ if (data == null) data = new JSONObject();
+ serverPort();
+ tokenUrl();
+ loginUrl();
+ baseUrl();
+ clientId();
+ clientSecret();
+ }
+
+ private void save() throws IOException {
+ Files.writeString(file.toPath(),data.toJSONString());
+ }
+
+ public int serverPort() {
+ if (!data.containsKey(PORT)) data.put(PORT,80L);
+ var o = data.get(PORT);
+ return (int) (long) o;
+ }
+
+ public URL tokenUrl() throws MalformedURLException {
+ if (!data.containsKey(TOKEN_URL)) data.put(TOKEN_URL,"http://localhost:"+serverPort()+"/oauth/token");
+ return new URL((String) data.get(TOKEN_URL));
+ }
+
+ public String loginUrl() {
+ if (!data.containsKey(LOGIN_URL)) data.put(LOGIN_URL,"http://localhost:"+serverPort()+"/oauth/login");
+ return (String) data.get(LOGIN_URL);
+ }
+
+ public String baseUrl() {
+ if (!data.containsKey(BASE_URL)) data.put(BASE_URL,"http://localhost");
+ return (String) data.get(BASE_URL);
+ }
+
+ public String clientId() {
+ if (!data.containsKey(Constants.CLIENT_ID)) data.put(CLIENT_ID,"widerhall");
+ return (String) data.get(CLIENT_ID);
+ }
+
+ public Object clientSecret() {
+ if (!data.containsKey(Constants.CLIENT_SECRET)) data.put(CLIENT_SECRET,"changeme");
+ return (String) data.get(CLIENT_SECRET);
+ }
+}
diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java
index 796f2ba..504771a 100644
--- a/src/main/java/de/srsoftware/widerhall/Constants.java
+++ b/src/main/java/de/srsoftware/widerhall/Constants.java
@@ -7,4 +7,10 @@ public class Constants {
public static final String USER = "user";
public static final String PASSWORD = "password";
public static final String INBOX = "inbox";
+ public static final Object PORT = "port";
+ public static final String TOKEN_URL = "token_url";
+ public static final String LOGIN_URL = "login_url";
+ public static final String BASE_URL = "base_url";
+ public static final String CLIENT_ID = "client_id";
+ public static final String CLIENT_SECRET = "client_secret";
}
diff --git a/src/main/java/de/srsoftware/widerhall/Forwarder.java b/src/main/java/de/srsoftware/widerhall/mail/Forwarder.java
similarity index 96%
rename from src/main/java/de/srsoftware/widerhall/Forwarder.java
rename to src/main/java/de/srsoftware/widerhall/mail/Forwarder.java
index 2bd48f1..9f1c687 100644
--- a/src/main/java/de/srsoftware/widerhall/Forwarder.java
+++ b/src/main/java/de/srsoftware/widerhall/mail/Forwarder.java
@@ -1,4 +1,4 @@
-package de.srsoftware.widerhall;
+package de.srsoftware.widerhall.mail;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
diff --git a/src/main/java/de/srsoftware/widerhall/ImapClient.java b/src/main/java/de/srsoftware/widerhall/mail/ImapClient.java
similarity index 96%
rename from src/main/java/de/srsoftware/widerhall/ImapClient.java
rename to src/main/java/de/srsoftware/widerhall/mail/ImapClient.java
index 283b97a..082402b 100644
--- a/src/main/java/de/srsoftware/widerhall/ImapClient.java
+++ b/src/main/java/de/srsoftware/widerhall/mail/ImapClient.java
@@ -1,8 +1,7 @@
-package de.srsoftware.widerhall;
+package de.srsoftware.widerhall.mail;
-import com.sun.mail.iap.ProtocolException;
import com.sun.mail.imap.IMAPFolder;
-import com.sun.mail.imap.protocol.IMAPProtocol;
+import de.srsoftware.widerhall.Constants;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -106,7 +105,7 @@ public class ImapClient {
}
}
}
- ImapClient(JSONObject config){
+ public ImapClient(JSONObject config){
this.config = config;
}
diff --git a/src/main/java/de/srsoftware/widerhall/MessageHandler.java b/src/main/java/de/srsoftware/widerhall/mail/MessageHandler.java
similarity index 82%
rename from src/main/java/de/srsoftware/widerhall/MessageHandler.java
rename to src/main/java/de/srsoftware/widerhall/mail/MessageHandler.java
index 7aa7663..dc54f53 100644
--- a/src/main/java/de/srsoftware/widerhall/MessageHandler.java
+++ b/src/main/java/de/srsoftware/widerhall/mail/MessageHandler.java
@@ -1,4 +1,4 @@
-package de.srsoftware.widerhall;
+package de.srsoftware.widerhall.mail;
import javax.mail.Message;
import javax.mail.MessagingException;
diff --git a/src/main/java/de/srsoftware/widerhall/SmtpClient.java b/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
similarity index 91%
rename from src/main/java/de/srsoftware/widerhall/SmtpClient.java
rename to src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
index a56b23c..3b543a8 100644
--- a/src/main/java/de/srsoftware/widerhall/SmtpClient.java
+++ b/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
@@ -1,18 +1,13 @@
-package de.srsoftware.widerhall;
+package de.srsoftware.widerhall.mail;
import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
-import java.io.File;
-import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
diff --git a/src/main/java/de/srsoftware/widerhall/web/Index.java b/src/main/java/de/srsoftware/widerhall/web/Index.java
new file mode 100644
index 0000000..7a76cda
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/web/Index.java
@@ -0,0 +1,43 @@
+package de.srsoftware.widerhall.web;
+
+import de.srsoftware.tools.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class Index extends HttpServlet {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Index.class);
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.setContentType("text/html");
+ resp.setStatus(HttpServletResponse.SC_OK);
+ String auth = req.getHeader("Authorization");
+ if (auth == null) {
+ resp.sendRedirect("login");
+ return;
+ }
+ LOG.debug("Authorization: {}",auth);
+
+ resp.getWriter().println(page(auth));
+
+ }
+
+ private Tag head() {
+ return new Tag("meta")
+ .attr("charset","utf-8")
+ .addTo(new Tag("head"));
+
+ }
+
+ private Tag page(String auth) {
+ var body = new Tag("body").content(auth);
+ return body.addTo(head().addTo(new Tag("html")));
+ }
+}
diff --git a/src/main/java/de/srsoftware/widerhall/web/Login.java b/src/main/java/de/srsoftware/widerhall/web/Login.java
new file mode 100644
index 0000000..eb82a73
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/web/Login.java
@@ -0,0 +1,127 @@
+package de.srsoftware.widerhall.web;
+
+import de.srsoftware.widerhall.Configuration;
+import de.srsoftware.widerhall.web.tags.Page;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class Login extends HttpServlet {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Login.class);
+ private final Configuration config;
+
+ public Login(){
+ this.config = Configuration.instance();
+ LOG.debug("Creating new instance of Login.class");
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ var error = req.getParameter("error");
+ if (error != null){
+ var description = req.getParameter("error_description");
+ sendError(resp,error+": "+description);
+ return;
+ }
+ LOG.debug("params: {}",req.getParameterMap());
+ var code = req.getParameter("code");
+ if (code != null){
+ getTokenFor(code,resp);
+ resp.getWriter().println(new Page("rceived code: "+code));
+ return;
+ }
+ resp.sendRedirect(loginUrl());
+ }
+
+ private static String urlEncode(Map data) {
+ String params = data.entrySet()
+ .stream()
+ .map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
+ .collect(Collectors.joining("&"));
+ return params;
+ }
+
+ private static String encode(Object value) {
+ return URLEncoder.encode(value.toString(),StandardCharsets.UTF_8);
+ }
+
+ private void getTokenFor(String code, HttpServletResponse resp) throws IOException {
+ var url = config.tokenUrl();
+ LOG.debug("Sending 'POST' request to URL '{}'",url);
+ HttpsURLConnection httpClient = (HttpsURLConnection) url.openConnection();
+
+ //add reuqest header
+ httpClient.setRequestMethod("POST");
+ httpClient.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
+ httpClient.setRequestProperty( "Accept", "*/*" );
+ //httpClient.setRequestProperty("User-Agent", "Mozilla/5.0");
+ //httpClient.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+
+ String urlParameters = urlEncode(Map.of(
+ "code",code,
+ "client_id",config.clientId(),
+ "client_secret",config.clientSecret(),
+ "grant_type","authorization_code"));
+
+ LOG.debug("Posting parameters '{}'",urlParameters);
+
+ // Send post request
+ httpClient.setDoOutput(true);
+ httpClient.setDoInput(true);
+ try (DataOutputStream wr = new DataOutputStream(httpClient.getOutputStream())) {
+ wr.writeBytes(urlParameters);
+ wr.flush();
+ }
+
+ int responseCode = httpClient.getResponseCode();
+ LOG.debug("Response Code: {}",responseCode);
+
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(httpClient.getInputStream()))) {
+
+ String line;
+ StringBuilder response = new StringBuilder();
+
+ while ((line = in.readLine()) != null) {
+ response.append(line);
+ }
+
+ //print result
+ //System.out.println(response.toString());
+ resp.getWriter().println(response);
+
+ }
+ }
+
+ private void sendError(HttpServletResponse resp, String error) throws IOException {
+ LOG.debug("error: {}",error);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST,error);
+ }
+
+ private String loginUrl() {
+ return config.loginUrl()+"?"+urlEncode(Map.of(
+ "response_type","code",
+ "client_id",config.clientId(),
+ "state",123456,
+ "redirect_uri",redirectUri(),
+ "scope","openid"
+ ));
+ }
+
+ private String redirectUri() {
+ int port = config.serverPort();
+ return config.baseUrl()+(port == 80 ? "" : ":"+port)+"/login";
+ }
+}
diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java
new file mode 100644
index 0000000..1b82471
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java
@@ -0,0 +1,21 @@
+package de.srsoftware.widerhall.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class Rest extends HttpServlet {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Rest.class);
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String method = req.getMethod();
+ LOG.debug("GET {}"+method);
+
+ }
+}
diff --git a/src/main/java/de/srsoftware/widerhall/web/tags/Header.java b/src/main/java/de/srsoftware/widerhall/web/tags/Header.java
new file mode 100644
index 0000000..a302815
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/web/tags/Header.java
@@ -0,0 +1,10 @@
+package de.srsoftware.widerhall.web.tags;
+
+import de.srsoftware.tools.Tag;
+
+public class Header extends Tag {
+ public Header() {
+ super("head");
+ new Tag("meta").attr("charset","utf-8").addTo(this);
+ }
+}
diff --git a/src/main/java/de/srsoftware/widerhall/web/tags/Page.java b/src/main/java/de/srsoftware/widerhall/web/tags/Page.java
new file mode 100644
index 0000000..4a079ac
--- /dev/null
+++ b/src/main/java/de/srsoftware/widerhall/web/tags/Page.java
@@ -0,0 +1,11 @@
+package de.srsoftware.widerhall.web.tags;
+
+import de.srsoftware.tools.Tag;
+
+public class Page extends Tag {
+ public Page(String content) {
+ super("html");
+ new Header().addTo(this);
+ new Tag("body").content(content).addTo(this);
+ }
+}