moved various modules and classes to tools realm, replaced gradle buildscripts by gradle kotlin buildscripts
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
36
build.gradle
36
build.gradle
@@ -1,36 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id "com.diffplug.spotless" version "6.25.0"
|
||||
}
|
||||
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0.1'
|
||||
|
||||
jar.enabled = false
|
||||
build.enabled = false
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
spotless {
|
||||
java {
|
||||
target '*/src/*/java/**/*.java'
|
||||
removeUnusedImports()
|
||||
importOrder()
|
||||
clangFormat('18.1.8').style('file:config/clang-format')
|
||||
licenseHeader '/* © SRSoftware $YEAR */' // or licenseHeaderFile
|
||||
}
|
||||
}
|
||||
|
||||
compileJava.dependsOn 'spotlessApply'
|
||||
50
build.gradle.kts
Normal file
50
build.gradle.kts
Normal file
@@ -0,0 +1,50 @@
|
||||
plugins {
|
||||
id("com.diffplug.spotless") version "latest.release"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
|
||||
spotless {
|
||||
java {
|
||||
target("**/src/**/java/**/*.java")
|
||||
removeUnusedImports()
|
||||
importOrder()
|
||||
clangFormat("18.1.8").style("file:config/clang-format")
|
||||
licenseHeader("/* © SRSoftware 2024 */")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
subprojects {
|
||||
group = "de.srsoftware"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.diffplug.spotless")
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
|
||||
|
||||
val implementation by configurations
|
||||
val compileOnly by configurations
|
||||
val testImplementation by configurations
|
||||
val testRuntimeOnly by configurations
|
||||
|
||||
|
||||
dependencies {
|
||||
testImplementation(platform("org.junit:junit-bom:5.10.0"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
}
|
||||
|
||||
tasks.withType<Test>() {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation 'org.json:json:20240303'
|
||||
implementation project(':de.srsoftware.utils')
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.http;
|
||||
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Cookie implements Map.Entry<String, String> {
|
||||
static final System.Logger LOG = System.getLogger(SessionToken.class.getSimpleName());
|
||||
private final String key;
|
||||
private String value = null;
|
||||
|
||||
Cookie(String key, String value) {
|
||||
this.key = key;
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
public <T extends Cookie> T addTo(Headers headers) {
|
||||
LOG.log(INFO, "sending cookie {0}={1}", key, value);
|
||||
headers.add("Set-Cookie", "%s=%s".formatted(key, value));
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
public <T extends Cookie> T addTo(HttpExchange ex) {
|
||||
return this.addTo(ex.getResponseHeaders());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected static List<String> of(HttpExchange ex) {
|
||||
return nullable(ex.getRequestHeaders().get("Cookie")).stream().flatMap(List::stream).flatMap(s -> Arrays.stream(s.split(";"))).map(String::trim).peek(cookie -> LOG.log(INFO, "received cookie {0}", cookie)).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String setValue(String s) {
|
||||
var oldVal = value;
|
||||
value = s;
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.http;
|
||||
|
||||
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
import static java.net.HttpURLConnection.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsExchange;
|
||||
import de.srsoftware.utils.Error;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public abstract class PathHandler implements HttpHandler {
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
public static final String CONTENT_TYPE = "Content-Type";
|
||||
public static final String DEFAULT_LANGUAGE = "en";
|
||||
public static final String DELETE = "DELETE";
|
||||
private static final String FORWARDED_HOST = "x-forwarded-host";
|
||||
public static final String GET = "GET";
|
||||
public static final String HOST = "host";
|
||||
public static final String JSON = "application/json";
|
||||
public static System.Logger LOG = System.getLogger(PathHandler.class.getSimpleName());
|
||||
public static final String POST = "POST";
|
||||
|
||||
private String[] paths;
|
||||
|
||||
public record BasicAuth(String userId, String pass) {
|
||||
}
|
||||
|
||||
public class Bond {
|
||||
Bond(String[] paths) {
|
||||
PathHandler.this.paths = paths;
|
||||
}
|
||||
public PathHandler on(HttpServer server) {
|
||||
for (var path : paths) server.createContext(path, PathHandler.this);
|
||||
return PathHandler.this;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean badRequest(HttpExchange ex, byte[] bytes) throws IOException {
|
||||
return sendContent(ex, HTTP_BAD_REQUEST, bytes);
|
||||
}
|
||||
|
||||
public static boolean badRequest(HttpExchange ex, Object o) throws IOException {
|
||||
return sendContent(ex, HTTP_BAD_REQUEST, o);
|
||||
}
|
||||
|
||||
public Bond bindPath(String... path) {
|
||||
return new Bond(path);
|
||||
}
|
||||
|
||||
public boolean doDelete(String path, HttpExchange ex) throws IOException {
|
||||
return notFound(ex);
|
||||
}
|
||||
|
||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
||||
return notFound(ex);
|
||||
}
|
||||
|
||||
public boolean doPost(String path, HttpExchange ex) throws IOException {
|
||||
return notFound(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange ex) throws IOException {
|
||||
String path = relativePath(ex);
|
||||
String method = ex.getRequestMethod();
|
||||
LOG.log(INFO, "{0} {1}", method, path);
|
||||
boolean ignored = switch (method) {
|
||||
case DELETE -> doDelete(path,ex);
|
||||
case GET -> doGet(path,ex);
|
||||
case POST -> doPost(path,ex);
|
||||
default -> false;
|
||||
};
|
||||
ex.getResponseBody().close();
|
||||
}
|
||||
|
||||
public String relativePath(HttpExchange ex) {
|
||||
var requestPath = ex.getRequestURI().toString();
|
||||
for (var path : paths){
|
||||
if (requestPath.startsWith(path)) {
|
||||
requestPath = requestPath.substring(path.length());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!requestPath.startsWith("/")) requestPath = "/" + requestPath;
|
||||
var pos = requestPath.indexOf("?");
|
||||
if (pos >= 0) requestPath = requestPath.substring(0, pos);
|
||||
return requestPath;
|
||||
}
|
||||
|
||||
/******* begin of static methods *************/
|
||||
|
||||
public static String body(HttpExchange ex) throws IOException {
|
||||
return new String(ex.getRequestBody().readAllBytes(), UTF_8);
|
||||
}
|
||||
|
||||
public static Optional<String> getAuthToken(HttpExchange ex) {
|
||||
return getHeader(ex, AUTHORIZATION);
|
||||
}
|
||||
|
||||
public static Optional<BasicAuth> getBasicAuth(HttpExchange ex) {
|
||||
return getAuthToken(ex)
|
||||
.filter(token -> token.startsWith("Basic ")) //
|
||||
.map(token -> token.substring(6))
|
||||
.map(Base64.getDecoder()::decode)
|
||||
.map(bytes -> new String(bytes, UTF_8))
|
||||
.map(token -> token.split(":", 2))
|
||||
.map(arr -> new BasicAuth(arr[0], arr[1]));
|
||||
}
|
||||
|
||||
public static Optional<String> getBearer(HttpExchange ex) {
|
||||
return getAuthToken(ex).filter(token -> token.startsWith("Bearer ")).map(token -> token.substring(7));
|
||||
}
|
||||
|
||||
public static Optional<String> getHeader(HttpExchange ex, String key) {
|
||||
return nullable(ex.getRequestHeaders().get(key)).map(List::stream).flatMap(Stream::findFirst);
|
||||
}
|
||||
|
||||
public static String hostname(HttpExchange ex) {
|
||||
var headers = ex.getRequestHeaders();
|
||||
var host = headers.getFirst(FORWARDED_HOST);
|
||||
if (host == null) host = headers.getFirst(HOST);
|
||||
var proto = nullable(headers.getFirst("X-forwarded-proto")).orElseGet(() -> ex instanceof HttpsExchange ? "https" : "http");
|
||||
return host == null ? null : proto + "://" + host;
|
||||
}
|
||||
|
||||
public static JSONObject json(HttpExchange ex) throws IOException {
|
||||
return new JSONObject(body(ex));
|
||||
}
|
||||
|
||||
public static String language(HttpExchange ex) {
|
||||
return getHeader(ex, "Accept-Language") //
|
||||
.map(s -> Arrays.stream(s.split(",")))
|
||||
.flatMap(Stream::findFirst)
|
||||
.orElse(DEFAULT_LANGUAGE);
|
||||
}
|
||||
|
||||
public static boolean notFound(HttpExchange ex) throws IOException {
|
||||
LOG.log(ERROR, "not implemented");
|
||||
return sendEmptyResponse(HTTP_NOT_FOUND, ex);
|
||||
}
|
||||
|
||||
public Map<String, String> queryParam(HttpExchange ex) {
|
||||
return Arrays
|
||||
.stream(ex.getRequestURI().getQuery().split("&")) //
|
||||
.map(s -> s.split("=", 2))
|
||||
.collect(Collectors.toMap(arr -> arr[0], arr -> arr[1]));
|
||||
}
|
||||
|
||||
public static boolean sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException {
|
||||
ex.sendResponseHeaders(statusCode, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean sendRedirect(HttpExchange ex, String url) throws IOException {
|
||||
ex.getResponseHeaders().add("Location", url);
|
||||
return sendEmptyResponse(HTTP_MOVED_TEMP, ex);
|
||||
}
|
||||
|
||||
public static boolean sendContent(HttpExchange ex, int status, byte[] bytes) throws IOException {
|
||||
LOG.log(DEBUG, "sending {0} response…", status);
|
||||
ex.sendResponseHeaders(status, bytes.length);
|
||||
ex.getResponseBody().write(bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean sendContent(HttpExchange ex, int status, Object o) throws IOException {
|
||||
if (o instanceof List<?> list) o = new JSONArray(list);
|
||||
if (o instanceof Map<?, ?> map) o = new JSONObject(map);
|
||||
if (o instanceof Error<?> error) o = error.json();
|
||||
if (o instanceof JSONObject) ex.getResponseHeaders().add(CONTENT_TYPE, JSON);
|
||||
return sendContent(ex, status, o.toString().getBytes(UTF_8));
|
||||
}
|
||||
|
||||
|
||||
public static boolean sendContent(HttpExchange ex, byte[] bytes) throws IOException {
|
||||
return sendContent(ex, HTTP_OK, bytes);
|
||||
}
|
||||
|
||||
public static boolean sendContent(HttpExchange ex, Object o) throws IOException {
|
||||
return sendContent(ex, HTTP_OK, o);
|
||||
}
|
||||
|
||||
public static boolean serverError(HttpExchange ex, Object o) throws IOException {
|
||||
sendContent(ex, HTTP_INTERNAL_ERROR, o);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String url(HttpExchange ex) {
|
||||
return hostname(ex) + ex.getRequestURI();
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.http;
|
||||
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class SessionToken extends Cookie {
|
||||
private final String sessionId;
|
||||
private static final DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss O");
|
||||
|
||||
public SessionToken(String sessionId, Instant expiration, boolean trust) {
|
||||
super("sessionToken", sessionToken(sessionId, expiration, trust));
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
private static String sessionToken(String sessionId, Instant expiration, boolean trust) {
|
||||
if (trust) return "%s; Path=/api; Expires=%s".formatted(sessionId, FORMAT.format(expiration.atZone(ZoneOffset.UTC)));
|
||||
return "%s; Path=/api".formatted(sessionId);
|
||||
}
|
||||
|
||||
public SessionToken(String sessionId) {
|
||||
super("sessionToken", sessionId + "; Path=/api");
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cookie> T addTo(Headers headers) {
|
||||
headers.add("session", getValue());
|
||||
return super.addTo(headers);
|
||||
}
|
||||
|
||||
public static Optional<SessionToken> from(HttpExchange ex) {
|
||||
return Cookie.of(ex)
|
||||
.stream()
|
||||
.filter(cookie -> cookie.startsWith("sessionToken="))
|
||||
|
||||
.map(cookie -> cookie.split("=", 2)[1])
|
||||
.map(id -> new SessionToken(id))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public String sessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.logging;
|
||||
|
||||
import static de.srsoftware.logging.ConsoleColors.*;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class ColorLogger implements System.Logger {
|
||||
private final String name;
|
||||
private static int rootLevel = INFO.getSeverity();
|
||||
private static DateFormat TIME = new SimpleDateFormat("hh:mm:ss.SSS");
|
||||
private static DateFormat DATE = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private static String lastDate = null;
|
||||
|
||||
public ColorLogger(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(Level level) {
|
||||
return level.getSeverity() >= rootLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
|
||||
if (isLoggable(level)) {
|
||||
System.out.println(colorize(msg, level.getSeverity()));
|
||||
thrown.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, ResourceBundle bundle, String format, Object... params) {
|
||||
if (isLoggable(level)) {
|
||||
System.out.println(colorize(MessageFormat.format(format, params), level.getSeverity()));
|
||||
}
|
||||
}
|
||||
|
||||
public ColorLogger setLogLevel(Level level) {
|
||||
rootLevel = level.getSeverity();
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String colorize(String message, int severity) {
|
||||
var color = severity >= ERROR.getSeverity() ? RED : severity >= WARNING.getSeverity() ? YELLOW : severity >= INFO.getSeverity() ? WHITE_BRIGHT : WHITE;
|
||||
var date = new Date();
|
||||
var day = DATE.format(date);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!day.equals(lastDate)) {
|
||||
lastDate = day;
|
||||
sb.append(WHITE).append(day).append("\n");
|
||||
}
|
||||
return sb.append(WHITE).append(TIME.format(date)).append(" ").append(color).append(message).append(RESET).toString();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.logging;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ColorLoggerFinder extends System.LoggerFinder {
|
||||
private static final Map<String, ColorLogger> LOGGERS = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public System.Logger getLogger(String name, Module module) {
|
||||
return LOGGERS.computeIfAbsent(name, ColorLogger::new);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.logging;
|
||||
|
||||
public class ConsoleColors {
|
||||
// Reset
|
||||
public static final String RESET = "\033[0m"; // Text Reset
|
||||
|
||||
// Regular Colors
|
||||
public static final String BLACK = "\033[0;30m"; // BLACK
|
||||
public static final String RED = "\033[0;31m"; // RED
|
||||
public static final String GREEN = "\033[0;32m"; // GREEN
|
||||
public static final String YELLOW = "\033[0;33m"; // YELLOW
|
||||
public static final String BLUE = "\033[0;34m"; // BLUE
|
||||
public static final String PURPLE = "\033[0;35m"; // PURPLE
|
||||
public static final String CYAN = "\033[0;36m"; // CYAN
|
||||
public static final String WHITE = "\033[0;37m"; // WHITE
|
||||
|
||||
// Bold
|
||||
public static final String BLACK_BOLD = "\033[1;30m"; // BLACK
|
||||
public static final String RED_BOLD = "\033[1;31m"; // RED
|
||||
public static final String GREEN_BOLD = "\033[1;32m"; // GREEN
|
||||
public static final String YELLOW_BOLD = "\033[1;33m"; // YELLOW
|
||||
public static final String BLUE_BOLD = "\033[1;34m"; // BLUE
|
||||
public static final String PURPLE_BOLD = "\033[1;35m"; // PURPLE
|
||||
public static final String CYAN_BOLD = "\033[1;36m"; // CYAN
|
||||
public static final String WHITE_BOLD = "\033[1;37m"; // WHITE
|
||||
|
||||
// Underline
|
||||
public static final String BLACK_UNDERLINED = "\033[4;30m"; // BLACK
|
||||
public static final String RED_UNDERLINED = "\033[4;31m"; // RED
|
||||
public static final String GREEN_UNDERLINED = "\033[4;32m"; // GREEN
|
||||
public static final String YELLOW_UNDERLINED = "\033[4;33m"; // YELLOW
|
||||
public static final String BLUE_UNDERLINED = "\033[4;34m"; // BLUE
|
||||
public static final String PURPLE_UNDERLINED = "\033[4;35m"; // PURPLE
|
||||
public static final String CYAN_UNDERLINED = "\033[4;36m"; // CYAN
|
||||
public static final String WHITE_UNDERLINED = "\033[4;37m"; // WHITE
|
||||
|
||||
// Background
|
||||
public static final String BLACK_BACKGROUND = "\033[40m"; // BLACK
|
||||
public static final String RED_BACKGROUND = "\033[41m"; // RED
|
||||
public static final String GREEN_BACKGROUND = "\033[42m"; // GREEN
|
||||
public static final String YELLOW_BACKGROUND = "\033[43m"; // YELLOW
|
||||
public static final String BLUE_BACKGROUND = "\033[44m"; // BLUE
|
||||
public static final String PURPLE_BACKGROUND = "\033[45m"; // PURPLE
|
||||
public static final String CYAN_BACKGROUND = "\033[46m"; // CYAN
|
||||
public static final String WHITE_BACKGROUND = "\033[47m"; // WHITE
|
||||
|
||||
// High Intensity
|
||||
public static final String BLACK_BRIGHT = "\033[0;90m"; // BLACK
|
||||
public static final String RED_BRIGHT = "\033[0;91m"; // RED
|
||||
public static final String GREEN_BRIGHT = "\033[0;92m"; // GREEN
|
||||
public static final String YELLOW_BRIGHT = "\033[0;93m"; // YELLOW
|
||||
public static final String BLUE_BRIGHT = "\033[0;94m"; // BLUE
|
||||
public static final String PURPLE_BRIGHT = "\033[0;95m"; // PURPLE
|
||||
public static final String CYAN_BRIGHT = "\033[0;96m"; // CYAN
|
||||
public static final String WHITE_BRIGHT = "\033[0;97m"; // WHITE
|
||||
|
||||
// Bold High Intensity
|
||||
public static final String BLACK_BOLD_BRIGHT = "\033[1;90m"; // BLACK
|
||||
public static final String RED_BOLD_BRIGHT = "\033[1;91m"; // RED
|
||||
public static final String GREEN_BOLD_BRIGHT = "\033[1;92m"; // GREEN
|
||||
public static final String YELLOW_BOLD_BRIGHT = "\033[1;93m"; // YELLOW
|
||||
public static final String BLUE_BOLD_BRIGHT = "\033[1;94m"; // BLUE
|
||||
public static final String PURPLE_BOLD_BRIGHT = "\033[1;95m"; // PURPLE
|
||||
public static final String CYAN_BOLD_BRIGHT = "\033[1;96m"; // CYAN
|
||||
public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE
|
||||
|
||||
// High Intensity backgrounds
|
||||
public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m"; // BLACK
|
||||
public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m"; // RED
|
||||
public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m"; // GREEN
|
||||
public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m"; // YELLOW
|
||||
public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m"; // BLUE
|
||||
public static final String PURPLE_BACKGROUND_BRIGHT = "\033[0;105m"; // PURPLE
|
||||
public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN
|
||||
public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
de.srsoftware.logging.ColorLoggerFinder
|
||||
@@ -1,24 +1,15 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
description = 'SRSoftware OIDC: api'
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation project(':de.srsoftware.utils')
|
||||
implementation 'org.json:json:20240303'
|
||||
implementation 'org.bitbucket.b_c:jose4j:0.9.6'
|
||||
implementation 'com.sun.mail:jakarta.mail:2.0.1'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
implementation 'de.srsoftware:tools.optionals:1.0.0'
|
||||
implementation 'de.srsoftware:tools.util:1.0.2'
|
||||
implementation 'org.bitbucket.b_c:jose4j:0.9.6'
|
||||
implementation 'org.json:json:20240303'
|
||||
implementation 'com.sun.mail:jakarta.mail:2.0.1'
|
||||
}
|
||||
|
||||
task jarTests (type: Jar) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import static java.util.Optional.empty;
|
||||
import de.srsoftware.oidc.api.data.AccessToken;
|
||||
import de.srsoftware.oidc.api.data.Lock;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.Result;
|
||||
import de.srsoftware.tools.Result;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package de.srsoftware.oidc.api.data;
|
||||
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.OPENID;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.EXPIRATION;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.jose4j.jws.AlgorithmIdentifiers.RSA_USING_SHA256;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import jakarta.mail.Authenticator;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.UuidHasher;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.UuidHasher;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -6,8 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import de.srsoftware.oidc.api.data.Permission;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.UuidHasher;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.UuidHasher;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation project(':de.srsoftware.http')
|
||||
implementation project(':de.srsoftware.logging')
|
||||
implementation project(':de.srsoftware.oidc.api')
|
||||
implementation project(':de.srsoftware.oidc.backend')
|
||||
implementation project(':de.srsoftware.oidc.datastore.encrypted')
|
||||
implementation project(':de.srsoftware.oidc.datastore.file')
|
||||
implementation project(':de.srsoftware.oidc.web')
|
||||
implementation project(':de.srsoftware.utils')
|
||||
implementation 'org.json:json:20240303'
|
||||
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
task run(type: JavaExec) {
|
||||
group = "application"
|
||||
description = "Run the main class with JavaExecTask"
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
mainClass = 'de.srsoftware.oidc.app.Application'
|
||||
args = ['--base','/home/srichter/workspace/LightOIDC/de.srsoftware.oidc.web/src/main/resources']
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes "Main-Class": "de.srsoftware.oidc.app.Application"
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
from {
|
||||
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
}
|
||||
14
de.srsoftware.oidc.app/build.gradle.kts
Normal file
14
de.srsoftware.oidc.app/build.gradle.kts
Normal file
@@ -0,0 +1,14 @@
|
||||
description = "SRSoftware OIDC: app"
|
||||
|
||||
dependencies{
|
||||
implementation("org.json:json:20240303")
|
||||
implementation("de.srsoftware:tools.http:1.0.0")
|
||||
implementation("de.srsoftware:tools.logging:1.0.0")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:1.0.2")
|
||||
implementation(project(":de.srsoftware.oidc.api"))
|
||||
implementation(project(":de.srsoftware.oidc.backend"))
|
||||
implementation(project(":de.srsoftware.oidc.datastore.encrypted"))
|
||||
implementation(project(":de.srsoftware.oidc.datastore.file"))
|
||||
implementation(project(":de.srsoftware.oidc.web"))
|
||||
}
|
||||
@@ -4,17 +4,16 @@ package de.srsoftware.oidc.app;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.oidc.api.data.Permission.*;
|
||||
import static de.srsoftware.utils.Optionals.emptyIfBlank;
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.utils.Paths.configDir;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Optionals.absentIfBlank;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Paths.configDir;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.lang.System.getenv;
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import de.srsoftware.logging.ColorLogger;
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.oidc.backend.*;
|
||||
@@ -26,7 +25,8 @@ import de.srsoftware.oidc.datastore.file.FileStoreProvider;
|
||||
import de.srsoftware.oidc.datastore.file.PlaintextKeyStore;
|
||||
import de.srsoftware.oidc.web.Forward;
|
||||
import de.srsoftware.oidc.web.StaticPages;
|
||||
import de.srsoftware.utils.UuidHasher;
|
||||
import de.srsoftware.tools.ColorLogger;
|
||||
import de.srsoftware.tools.UuidHasher;
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Path;
|
||||
@@ -146,8 +146,8 @@ public class Application {
|
||||
var tokens = new ArrayList<>(List.of(args));
|
||||
var map = new HashMap<String, Object>();
|
||||
|
||||
emptyIfBlank(getenv(BASE_PATH)).map(Path::of).ifPresent(path -> map.put(BASE_PATH, path));
|
||||
emptyIfBlank(getenv(CONFIG_PATH)).map(Path::of).ifPresent(path -> map.put(CONFIG_PATH, path));
|
||||
absentIfBlank(getenv(BASE_PATH)).map(Path::of).ifPresent(path -> map.put(BASE_PATH, path));
|
||||
absentIfBlank(getenv(CONFIG_PATH)).map(Path::of).ifPresent(path -> map.put(CONFIG_PATH, path));
|
||||
|
||||
// Command line arguments override environment
|
||||
while (!tokens.isEmpty()) {
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation project(':de.srsoftware.http')
|
||||
implementation project(':de.srsoftware.logging')
|
||||
implementation project(':de.srsoftware.oidc.api')
|
||||
implementation project(':de.srsoftware.utils')
|
||||
implementation 'org.json:json:20240303'
|
||||
implementation 'org.bitbucket.b_c:jose4j:0.9.6'
|
||||
implementation 'com.sun.mail:jakarta.mail:2.0.1'
|
||||
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
13
de.srsoftware.oidc.backend/build.gradle.kts
Normal file
13
de.srsoftware.oidc.backend/build.gradle.kts
Normal file
@@ -0,0 +1,13 @@
|
||||
description = "SRSoftware OIDC: backend"
|
||||
|
||||
dependencies{
|
||||
implementation("com.sun.mail:jakarta.mail:2.0.1")
|
||||
implementation("de.srsoftware:tools.http:1.0.0")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:1.0.2")
|
||||
implementation("org.bitbucket.b_c:jose4j:0.9.6")
|
||||
implementation("org.json:json:20240303")
|
||||
|
||||
implementation(project(":de.srsoftware.oidc.api"))
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import de.srsoftware.oidc.api.data.AuthorizedScopes;
|
||||
import de.srsoftware.oidc.api.data.Client;
|
||||
import de.srsoftware.oidc.api.data.Session;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.Error;
|
||||
import de.srsoftware.utils.Optionals;
|
||||
import de.srsoftware.tools.Error;
|
||||
import de.srsoftware.tools.Optionals;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
package de.srsoftware.oidc.backend;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.http.SessionToken;
|
||||
import de.srsoftware.oidc.api.SessionService;
|
||||
import de.srsoftware.oidc.api.data.Session;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import de.srsoftware.tools.SessionToken;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
package de.srsoftware.oidc.backend;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.oidc.api.KeyStorage;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import java.io.IOException;
|
||||
import org.jose4j.jwk.JsonWebKey;
|
||||
import org.jose4j.jwk.PublicJsonWebKey;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
package de.srsoftware.oidc.backend;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.EXPIRATION;
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.jose4j.jws.AlgorithmIdentifiers.RSA_USING_SHA256;
|
||||
|
||||
import de.srsoftware.oidc.api.KeyManager;
|
||||
|
||||
@@ -3,16 +3,16 @@ package de.srsoftware.oidc.backend;
|
||||
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.oidc.api.Constants.ERROR;
|
||||
import static de.srsoftware.utils.Optionals.emptyIfBlank;
|
||||
import static de.srsoftware.tools.Optionals.absentIfBlank;
|
||||
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import de.srsoftware.oidc.api.data.AccessToken;
|
||||
import de.srsoftware.oidc.api.data.Client;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -68,7 +68,7 @@ public class TokenController extends PathHandler {
|
||||
private HashMap<String, String> tokenResponse(String errorCode, String description) throws IOException {
|
||||
var map = new HashMap<String, String>();
|
||||
map.put(ERROR, errorCode);
|
||||
emptyIfBlank(description).ifPresent(d -> map.put(ERROR_DESCRIPTION, d));
|
||||
absentIfBlank(description).ifPresent(d -> map.put(ERROR_DESCRIPTION, d));
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@ package de.srsoftware.oidc.backend;
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.oidc.api.data.Permission.MANAGE_USERS;
|
||||
import static de.srsoftware.oidc.api.data.User.*;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.net.HttpURLConnection.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.SessionToken;
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import de.srsoftware.oidc.api.data.Permission;
|
||||
import de.srsoftware.oidc.api.data.Session;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.Payload;
|
||||
import de.srsoftware.utils.Result;
|
||||
import de.srsoftware.tools.Payload;
|
||||
import de.srsoftware.tools.Result;
|
||||
import de.srsoftware.tools.SessionToken;
|
||||
import jakarta.mail.*;
|
||||
import jakarta.mail.internet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -3,7 +3,7 @@ package de.srsoftware.oidc.backend;
|
||||
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
testImplementation project(path: ':de.srsoftware.oidc.api', configuration: "testBundle")
|
||||
implementation project(':de.srsoftware.oidc.api')
|
||||
implementation project(':de.srsoftware.utils')
|
||||
implementation 'com.sun.mail:jakarta.mail:2.0.1'
|
||||
implementation 'org.bitbucket.b_c:jose4j:0.9.6'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
11
de.srsoftware.oidc.datastore.encrypted/build.gradle.kts
Normal file
11
de.srsoftware.oidc.datastore.encrypted/build.gradle.kts
Normal file
@@ -0,0 +1,11 @@
|
||||
description = "SRSoftware OIDC: encrypted datastore module"
|
||||
|
||||
dependencies{
|
||||
implementation("com.sun.mail:jakarta.mail:2.0.1")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:1.0.2")
|
||||
|
||||
implementation(project(":de.srsoftware.oidc.api"))
|
||||
testImplementation(project(":de.srsoftware.oidc.api","testBundle"))
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import static java.util.Optional.empty;
|
||||
import de.srsoftware.oidc.api.UserService;
|
||||
import de.srsoftware.oidc.api.data.AccessToken;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.utils.Error;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.Payload;
|
||||
import de.srsoftware.utils.Result;
|
||||
import de.srsoftware.tools.Error;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.Payload;
|
||||
import de.srsoftware.tools.Result;
|
||||
import java.util.*;
|
||||
|
||||
public class EncryptedUserService extends EncryptedConfig implements UserService {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* © SRSoftware 2024 */
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
package de.srsoftware.oidc.datastore.encrypted; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
|
||||
import de.srsoftware.oidc.api.ClientService;
|
||||
import de.srsoftware.oidc.api.ClientServiceTest;
|
||||
import de.srsoftware.oidc.api.data.Client;
|
||||
import de.srsoftware.oidc.datastore.encrypted.EncryptedClientService;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -1,8 +1,8 @@
|
||||
/* © SRSoftware 2024 */
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
package de.srsoftware.oidc.datastore.encrypted; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import de.srsoftware.oidc.datastore.encrypted.EncryptedConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class EncryptedConfigTest {
|
||||
@@ -1,9 +1,9 @@
|
||||
/* © SRSoftware 2024 */
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
package de.srsoftware.oidc.datastore.encrypted; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
|
||||
import de.srsoftware.oidc.api.KeyStorage;
|
||||
import de.srsoftware.oidc.api.KeyStoreTest;
|
||||
import de.srsoftware.oidc.datastore.encrypted.EncryptedKeyStore;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
@@ -1,9 +1,9 @@
|
||||
/* © SRSoftware 2024 */
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
package de.srsoftware.oidc.datastore.encrypted; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import de.srsoftware.oidc.api.MailConfig;
|
||||
import de.srsoftware.oidc.datastore.encrypted.EncryptedMailConfig;
|
||||
import jakarta.mail.Authenticator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -1,17 +1,17 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.datastore.encrypted; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import de.srsoftware.oidc.api.data.AccessToken;
|
||||
import de.srsoftware.oidc.api.data.User;
|
||||
import de.srsoftware.oidc.datastore.encrypted.EncryptedUserService;
|
||||
import de.srsoftware.utils.Error;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.Payload;
|
||||
import de.srsoftware.utils.Result;
|
||||
import de.srsoftware.tools.Error;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.Payload;
|
||||
import de.srsoftware.tools.Result;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -1,26 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
testImplementation project(path: ':de.srsoftware.oidc.api', configuration: "testBundle")
|
||||
implementation project(':de.srsoftware.oidc.api')
|
||||
implementation project(':de.srsoftware.utils')
|
||||
implementation 'org.json:json:20240303'
|
||||
implementation 'org.bitbucket.b_c:jose4j:0.9.6'
|
||||
implementation 'com.sun.mail:jakarta.mail:2.0.1'
|
||||
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
13
de.srsoftware.oidc.datastore.file/build.gradle.kts
Normal file
13
de.srsoftware.oidc.datastore.file/build.gradle.kts
Normal file
@@ -0,0 +1,13 @@
|
||||
description = "SRSoftware OIDC: file datastore module"
|
||||
|
||||
dependencies{
|
||||
implementation("com.sun.mail:jakarta.mail:2.0.1")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:1.0.2")
|
||||
implementation("org.json:json:20240303")
|
||||
|
||||
implementation(project(":de.srsoftware.oidc.api"))
|
||||
implementation(project(":de.srsoftware.oidc.web"))
|
||||
testImplementation(project(":de.srsoftware.oidc.api","testBundle"))
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
package de.srsoftware.oidc.datastore.file; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static de.srsoftware.oidc.api.data.User.*;
|
||||
import static de.srsoftware.utils.Optionals.nullable;
|
||||
import static de.srsoftware.utils.Strings.uuid;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
import static de.srsoftware.tools.Strings.uuid;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import de.srsoftware.oidc.api.data.*;
|
||||
import de.srsoftware.utils.Error;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.Payload;
|
||||
import de.srsoftware.utils.Result;
|
||||
import de.srsoftware.tools.Error;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.Payload;
|
||||
import de.srsoftware.tools.Result;
|
||||
import jakarta.mail.Authenticator;
|
||||
import jakarta.mail.PasswordAuthentication;
|
||||
import java.io.File;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.datastore.file;
|
||||
|
||||
import de.srsoftware.utils.UuidHasher;
|
||||
import de.srsoftware.tools.UuidHasher;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -3,8 +3,8 @@ package de.srsoftware.oidc.datastore.file;
|
||||
|
||||
import de.srsoftware.oidc.api.UserService;
|
||||
import de.srsoftware.oidc.api.UserServiceTest;
|
||||
import de.srsoftware.utils.PasswordHasher;
|
||||
import de.srsoftware.utils.UuidHasher;
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.UuidHasher;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation project(':de.srsoftware.oidc.api')
|
||||
implementation project(':de.srsoftware.http')
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
8
de.srsoftware.oidc.web/build.gradle.kts
Normal file
8
de.srsoftware.oidc.web/build.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
||||
description = "SRSoftware OIDC: web module"
|
||||
|
||||
dependencies{
|
||||
implementation("de.srsoftware:tools.http:1.0.0")
|
||||
|
||||
implementation(project(":de.srsoftware.oidc.api"))
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ package de.srsoftware.oidc.web;
|
||||
import static java.lang.System.Logger.Level.INFO;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Forward extends PathHandler {
|
||||
|
||||
@@ -5,8 +5,8 @@ import static java.lang.System.Logger.Level.*;
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.http.PathHandler;
|
||||
import de.srsoftware.oidc.api.ResourceLoader;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.srsoftware'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation platform('org.junit:junit-bom:5.10.0')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
implementation 'org.json:json:20240303'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Error<T> implements Result<T> {
|
||||
private final String cause;
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
public Error(String cause) {
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public String cause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isError() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static <T> Error<T> message(String cause, Object... tokens) {
|
||||
var err = new Error<T>(cause);
|
||||
err.metadata = new HashMap<>();
|
||||
for (int i = 0; i < tokens.length - 1; i += 2) {
|
||||
err.metadata.put(tokens[i].toString(), tokens[i + 1]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
public JSONObject json() {
|
||||
var json = new JSONObject(Map.of("error", cause));
|
||||
if (metadata != null) json.put("metadata", metadata);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class Optionals {
|
||||
public static <T> Optional<T> nullable(T val) {
|
||||
return Optional.ofNullable(val);
|
||||
}
|
||||
|
||||
public static Optional<String> emptyIfBlank(String text) {
|
||||
return text == null || text.isBlank() ? empty() : nullable(text.trim());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
public interface PasswordHasher<T> {
|
||||
public String hash(String password, String salt);
|
||||
public String salt(String hashedPassword);
|
||||
|
||||
public default boolean matches(String plaintextPassword, String hashedPassword) {
|
||||
return hash(plaintextPassword, salt(hashedPassword)).equals(hashedPassword);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class Paths {
|
||||
public static Path configDir(String applicationName) {
|
||||
String home = System.getProperty("user.home");
|
||||
return Path.of(home, ".config", applicationName);
|
||||
}
|
||||
|
||||
public static Path configDir(Class clazz) {
|
||||
return configDir(clazz.getSimpleName());
|
||||
}
|
||||
|
||||
public static Path configDir(Object clazz) {
|
||||
return configDir(clazz.getClass());
|
||||
}
|
||||
|
||||
public static String extension(File file) {
|
||||
var parts = file.getName().split("\\.");
|
||||
return parts.length == 1 ? "" : parts[parts.length - 1];
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
|
||||
public class Payload<T> implements Result<T> {
|
||||
private final T object;
|
||||
|
||||
public Payload(T object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public static <T> Payload<T> of(T object) {
|
||||
return new Payload<>(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isError() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
public interface Result<T> {
|
||||
public boolean isError();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Strings {
|
||||
public static String uuid() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.utils;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
|
||||
public class UuidHasher implements PasswordHasher<String> {
|
||||
private static final String SHA256 = "SHA-256";
|
||||
|
||||
private final MessageDigest digest;
|
||||
|
||||
public UuidHasher() throws NoSuchAlgorithmException {
|
||||
digest = MessageDigest.getInstance(SHA256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String hash(String password, String uuid) {
|
||||
var salt = uuid;
|
||||
var saltedPass = "%s %s".formatted(salt, password);
|
||||
var bytes = digest.digest(saltedPass.getBytes(UTF_8));
|
||||
|
||||
return "%s@%s".formatted(hex(bytes), salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String salt(String hashedPassword) {
|
||||
return hashedPassword.split("@", 2)[1];
|
||||
}
|
||||
|
||||
public static String hex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length * 2);
|
||||
for (byte b : bytes) sb.append(String.format("%02x", b));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
rootProject.name = 'LightOIDC'
|
||||
include 'de.srsoftware.http'
|
||||
include 'de.srsoftware.logging'
|
||||
include 'de.srsoftware.oidc.api'
|
||||
include 'de.srsoftware.oidc.app'
|
||||
include 'de.srsoftware.oidc.backend'
|
||||
include 'de.srsoftware.oidc.datastore.encrypted'
|
||||
include 'de.srsoftware.oidc.datastore.file'
|
||||
include 'de.srsoftware.oidc.web'
|
||||
include 'de.srsoftware.utils'
|
||||
|
||||
8
settings.gradle.kts
Normal file
8
settings.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
||||
rootProject.name = "LightOIDC"
|
||||
include("de.srsoftware.oidc.api")
|
||||
include("de.srsoftware.oidc.app")
|
||||
include("de.srsoftware.oidc.backend")
|
||||
include("de.srsoftware.oidc.datastore.encrypted")
|
||||
include("de.srsoftware.oidc.datastore.file")
|
||||
include("de.srsoftware.oidc.web")
|
||||
|
||||
Reference in New Issue
Block a user