weiter gebastelt
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware;
|
||||
|
||||
import de.srsoftware.oidc.api.User;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@WebServlet(urlPatterns = "/")
|
||||
public class LightOICD extends HttpServlet {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LightOICD.class);
|
||||
private static final Templates templates;
|
||||
static {
|
||||
try {
|
||||
templates = Templates.singleton();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
|
||||
var path = Arrays.stream(req.getRequestURI().split("/")).skip(1).toList();
|
||||
User user = null;
|
||||
if (path.isEmpty()) {
|
||||
landingPage(req, resp, user);
|
||||
return;
|
||||
}
|
||||
switch (path.remove(0)) {
|
||||
default:
|
||||
helloWorld(req, resp, path);
|
||||
}
|
||||
}
|
||||
|
||||
private void helloWorld(HttpServletRequest req, HttpServletResponse resp, List<String> path) throws IOException {
|
||||
LOG.debug("helloWorld(…), path = {}", path);
|
||||
resp.setContentType("text/html");
|
||||
PrintWriter out = resp.getWriter();
|
||||
out.println("<html><head><title>Hello World Servlet</title></head>");
|
||||
out.println("<body>");
|
||||
out.println("<h1>Hello Guys!</h1>");
|
||||
out.println("<ul>");
|
||||
path.forEach(part -> out.println("<li>" + part + "</li>"));
|
||||
out.println("</ul>");
|
||||
out.println("</body></html>");
|
||||
out.close();
|
||||
}
|
||||
|
||||
private void landingPage(HttpServletRequest req, HttpServletResponse resp, User user) throws IOException {
|
||||
LOG.debug("landingPage(…)");
|
||||
var index = templates.get("index.html", Map.of("user","Darling"));
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().println(index.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.light;
|
||||
|
||||
public class Constants {
|
||||
public static final String BODY = "body";
|
||||
public static final String EMAIL = "email";
|
||||
public static final String ERR_PAGE_NOT_FOUND = "page_not_found";
|
||||
public static final String ERR_REDIRECT_FAILED = "redirect_failed";
|
||||
public static final String HEAD = "head";
|
||||
public static final String MESSAGES = "messages.txt";
|
||||
public static final String PAGE_LOGIN = "login";
|
||||
public static final String PAGE_START = "start";
|
||||
public static final String PAGE_WELCOME = "welcome";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String TARGET = "target";
|
||||
public static final String TITLE = "title";
|
||||
public static final String TITLE_LOGIN = "title_login";
|
||||
public static final String TITLE_WELCOME = "title_welcom";
|
||||
public static final String USER = "user";
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.light;
|
||||
|
||||
import static de.srsoftware.oidc.light.Constants.*;
|
||||
import static de.srsoftware.oidc.light.Templates.braced;
|
||||
|
||||
import de.srsoftware.oidc.api.User;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@WebServlet(urlPatterns = "/")
|
||||
public class LightOICD extends HttpServlet {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LightOICD.class);
|
||||
private static final Templates templates;
|
||||
static {
|
||||
try {
|
||||
templates = Templates.singleton();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
|
||||
var uri = req.getRequestURI();
|
||||
var path = Arrays.stream(uri.split("/")).skip(1).collect(Collectors.toList());
|
||||
if (path.isEmpty()) {
|
||||
path.add(PAGE_START);
|
||||
}
|
||||
|
||||
var optUser = loadUser(req);
|
||||
handleGet(path, optUser, req, resp).ifPresent(resp.getWriter()::println);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
var uri = req.getRequestURI();
|
||||
var path = Arrays.stream(uri.split("/")).skip(1).collect(Collectors.toList());
|
||||
if (path.isEmpty()) {
|
||||
path.add(PAGE_START);
|
||||
}
|
||||
|
||||
var optUser = loadUser(req);
|
||||
handlePost(path, optUser, req, resp).ifPresent(resp.getWriter()::println);
|
||||
}
|
||||
|
||||
private Optional<String> handleGet(List<String> path, Optional<User> optUser, HttpServletRequest req, HttpServletResponse resp) {
|
||||
String token = path.remove(0);
|
||||
if (optUser.isPresent()) {
|
||||
var user = optUser.get();
|
||||
switch (token) {
|
||||
case PAGE_START:
|
||||
return pageStart(user, req, resp);
|
||||
case PAGE_WELCOME:
|
||||
return pageWelcome(user,req, resp);
|
||||
}
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case PAGE_LOGIN:
|
||||
return pageLogin(req, resp);
|
||||
case PAGE_START:
|
||||
case PAGE_WELCOME:
|
||||
return redirect(resp, PAGE_LOGIN);
|
||||
}
|
||||
return templates.message(ERR_PAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Optional<String> handlePost(List<String> path, Optional<User> optUser, HttpServletRequest req, HttpServletResponse resp) {
|
||||
String token = path.remove(0);
|
||||
if (optUser.isPresent()) {
|
||||
var user = optUser.get();
|
||||
switch (token) {
|
||||
case PAGE_START:
|
||||
return pageStart(user, req, resp);
|
||||
}
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case PAGE_LOGIN:
|
||||
return postLogin(req, resp);
|
||||
case PAGE_START:
|
||||
return redirect(resp, PAGE_LOGIN);
|
||||
}
|
||||
return templates.message(ERR_PAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
private Optional<User> loadUser(HttpServletRequest req) {
|
||||
HttpSession session = req.getSession();
|
||||
if (session.getAttribute(USER) instanceof User user) {
|
||||
return Optional.of(user);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Optional<String> pageLogin(HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOG.debug("pageLogin(…)");
|
||||
try {
|
||||
var title = templates.message(TITLE_LOGIN).orElse(TITLE_LOGIN);
|
||||
var head = templates.get("head.snippet", Map.of(TITLE, title)).get();
|
||||
var login = templates.get("login.snippet", Map.of(USER, "Darling", EMAIL, "", PASSWORD, "")).get();
|
||||
var page = templates.get("scaffold.html", Map.of(BODY, login, HEAD, head)).get();
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().println(page);
|
||||
return Optional.empty();
|
||||
} catch (Exception e) {
|
||||
return Optional.of(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> pageStart(User user, HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOG.debug("pageStart(…)");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<String> pageWelcome(User user, HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOG.debug("pageWelcome(…)");
|
||||
try {
|
||||
var title = templates.message(TITLE_WELCOME).orElse(TITLE_WELCOME);
|
||||
var head = templates.get("head.snippet", Map.of(TITLE, title)).get();
|
||||
var login = templates.get("welcome.snippet", Map.of(USER, "Darling", EMAIL, "", PASSWORD, "")).get();
|
||||
var page = templates.get("scaffold.html", Map.of(BODY, login, HEAD, head)).get();
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().println(page);
|
||||
return Optional.empty();
|
||||
} catch (Exception e) {
|
||||
return Optional.of(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> postLogin(HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOG.debug("postLogin(…)");
|
||||
var email = req.getParameter(EMAIL);
|
||||
if (braced(EMAIL).equals(email)) email = "";
|
||||
var pass = req.getParameter(PASSWORD);
|
||||
var user = tryLogin(email, pass);
|
||||
if (user.isPresent()) {
|
||||
req.getSession().setAttribute(USER, user.get());
|
||||
return redirect(resp, PAGE_WELCOME);
|
||||
}
|
||||
try {
|
||||
var title = templates.message(TITLE_LOGIN).orElse(TITLE_LOGIN);
|
||||
var head = templates.get("head.snippet", Map.of(TITLE, title)).get();
|
||||
var login = templates.get("login.snippet", Map.of(USER, "Darling", EMAIL, email, PASSWORD, "")).get();
|
||||
var page = templates.get("scaffold.html", Map.of(BODY, login, HEAD, head)).get();
|
||||
resp.setContentType("text/html");
|
||||
resp.getWriter().println(page);
|
||||
return Optional.empty();
|
||||
} catch (Exception e) {
|
||||
return Optional.of(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<User> tryLogin(String email, String pass) {
|
||||
if (email == null || pass == null) return Optional.empty();
|
||||
if (email.equals(pass)) return Optional.of(new User());
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<String> redirect(HttpServletResponse resp, String path) {
|
||||
try {
|
||||
resp.sendRedirect(path);
|
||||
} catch (IOException e) {
|
||||
return templates.message(ERR_REDIRECT_FAILED, Map.of(TARGET, path));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware;
|
||||
package de.srsoftware.oidc.light;
|
||||
|
||||
import static de.srsoftware.oidc.light.Constants.MESSAGES;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import org.slf4j.Logger;
|
||||
@@ -15,6 +18,7 @@ public class Templates {
|
||||
private static Templates singleton = null;
|
||||
private static Logger LOG = LoggerFactory.getLogger(Templates.class);
|
||||
private Path dir = searchTemplates();
|
||||
private Map<String, String> messages = null;
|
||||
|
||||
public Templates() throws FileNotFoundException {}
|
||||
|
||||
@@ -41,11 +45,14 @@ public class Templates {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public Optional<String> get(String path) {
|
||||
return get(path, Map.of());
|
||||
}
|
||||
|
||||
public Optional<String> get(String path, Map<String, String> replacements) {
|
||||
var file = dir.resolve(path);
|
||||
try {
|
||||
return Optional.of(Files.readString(file)).map(s -> replaceKeys(s,replacements));
|
||||
// TODO: replacements
|
||||
return Optional.of(Files.readString(file)).map(s -> replaceKeys(s, replacements));
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to read {}", path, e);
|
||||
return Optional.empty();
|
||||
@@ -54,7 +61,35 @@ public class Templates {
|
||||
}
|
||||
|
||||
private String replaceKeys(String text, Map<String, String> replacements) {
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet()) text = text.replace("{"+replacement.getKey()+"}",replacement.getValue());
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
||||
text = text.replace(braced(replacement.getKey()), replacement.getValue());
|
||||
return text;
|
||||
}
|
||||
|
||||
public Optional<String> message(String code) {
|
||||
return message(code, Map.of());
|
||||
}
|
||||
|
||||
public Optional<String> message(String code, Map<String, String> replacements) {
|
||||
if (this.messages == null) {
|
||||
get(MESSAGES).map(s -> s.split("\n")).ifPresent(this::setMessages);
|
||||
}
|
||||
return Optional.ofNullable(messages.get(code)).map(text -> replaceKeys(text, replacements));
|
||||
}
|
||||
|
||||
private void setMessages(String[] lines) {
|
||||
this.messages = new HashMap<>();
|
||||
for (String line : lines) {
|
||||
var parts = line.split(" ", 2);
|
||||
if (parts.length < 2) {
|
||||
LOG.warn("Invalid format in {} file, skipped {}", MESSAGES, line);
|
||||
continue;
|
||||
}
|
||||
messages.put(parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public static String braced(String key) {
|
||||
return String.join(key, "{", "}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>{title}</title>
|
||||
<style>
|
||||
body{
|
||||
background-color: #555;
|
||||
color: #eeffee;
|
||||
}
|
||||
label{
|
||||
display: block;
|
||||
}
|
||||
fieldset{
|
||||
border-radius: 10px;
|
||||
display: inline;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,16 @@
|
||||
<h1>Login</h1>
|
||||
|
||||
<form action="login" method="POST">
|
||||
<fieldset>
|
||||
<legend>Light OIDC Login</legend>
|
||||
<label>
|
||||
<input type="text" name="email" value="{email}" />
|
||||
Email address
|
||||
</label>
|
||||
<label>
|
||||
<input type="password" name="password" value="{password}" />
|
||||
Password
|
||||
</label>
|
||||
<button type="submit">Login</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
@@ -0,0 +1,2 @@
|
||||
title_login LightOIDC Login
|
||||
title_welcome Willkommen bei LightOIDC!
|
||||
@@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{head}
|
||||
<body>
|
||||
{body}
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Willkommen!
|
||||
Reference in New Issue
Block a user