Browse Source

weiter gebastelt

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 6 months ago
parent
commit
f42a8f5abd
  1. 64
      de.srsoftware.oidc.light/src/main/java/de/srsoftware/LightOICD.java
  2. 20
      de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/Constants.java
  3. 181
      de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/LightOICD.java
  4. 41
      de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/Templates.java
  5. 16
      de.srsoftware.oidc.light/src/main/resources/templates/head.snippet
  6. 16
      de.srsoftware.oidc.light/src/main/resources/templates/login.snippet
  7. 2
      de.srsoftware.oidc.light/src/main/resources/templates/messages.txt
  8. 6
      de.srsoftware.oidc.light/src/main/resources/templates/scaffold.html
  9. 1
      de.srsoftware.oidc.light/src/main/resources/templates/welcome.snippet

64
de.srsoftware.oidc.light/src/main/java/de/srsoftware/LightOICD.java

@ -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());
}
}

20
de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/Constants.java

@ -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";
}

181
de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/LightOICD.java

@ -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();
}
}

41
de.srsoftware.oidc.light/src/main/java/de/srsoftware/Templates.java → de.srsoftware.oidc.light/src/main/java/de/srsoftware/oidc/light/Templates.java

@ -1,11 +1,14 @@
/* © SRSoftware 2024 */ /* © 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.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -15,6 +18,7 @@ public class Templates {
private static Templates singleton = null; private static Templates singleton = null;
private static Logger LOG = LoggerFactory.getLogger(Templates.class); private static Logger LOG = LoggerFactory.getLogger(Templates.class);
private Path dir = searchTemplates(); private Path dir = searchTemplates();
private Map<String, String> messages = null;
public Templates() throws FileNotFoundException {} public Templates() throws FileNotFoundException {}
@ -41,11 +45,14 @@ public class Templates {
return singleton; return singleton;
} }
public Optional<String> get(String path) {
return get(path, Map.of());
}
public Optional<String> get(String path, Map<String, String> replacements) { public Optional<String> get(String path, Map<String, String> replacements) {
var file = dir.resolve(path); var file = dir.resolve(path);
try { try {
return Optional.of(Files.readString(file)).map(s -> replaceKeys(s, replacements)); return Optional.of(Files.readString(file)).map(s -> replaceKeys(s, replacements));
// TODO: replacements
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Failed to read {}", path, e); LOG.warn("Failed to read {}", path, e);
return Optional.empty(); return Optional.empty();
@ -54,7 +61,35 @@ public class Templates {
} }
private String replaceKeys(String text, Map<String, String> replacements) { 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; 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, "{", "}");
}
} }

16
de.srsoftware.oidc.light/src/main/resources/templates/head.snippet

@ -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>

16
de.srsoftware.oidc.light/src/main/resources/templates/login.snippet

@ -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>

2
de.srsoftware.oidc.light/src/main/resources/templates/messages.txt

@ -0,0 +1,2 @@
title_login LightOIDC Login
title_welcome Willkommen bei LightOIDC!

6
de.srsoftware.oidc.light/src/main/resources/templates/scaffold.html

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
{head}
<body>
{body}
</html>

1
de.srsoftware.oidc.light/src/main/resources/templates/welcome.snippet

@ -0,0 +1 @@
Willkommen!
Loading…
Cancel
Save