Browse Source

major refactoring: working towards more interface-implementation splitting

feature/document
Stephan Richter 4 months ago
parent
commit
21812d2b42
  1. 2
      backend/build.gradle.kts
  2. 46
      backend/src/main/java/de/srsoftware/umbrella/backend/Application.java
  3. 6
      company/build.gradle.kts
  4. 21
      company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java
  5. 5
      core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java
  6. 15
      core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java
  7. 9
      core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java
  8. 9
      core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java
  9. 5
      core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java
  10. 4
      core/src/main/java/de/srsoftware/umbrella/core/model/Session.java
  11. 3
      core/src/main/java/de/srsoftware/umbrella/core/model/Token.java
  12. 2
      documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java
  13. 41
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  14. 10
      legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java
  15. 8
      messages/src/main/java/de/srsoftware/umbrella/message/Constants.java
  16. 16
      messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java
  17. 3
      settings.gradle.kts
  18. 2
      translations/src/main/resources/de.json
  19. 1
      user/src/main/java/de/srsoftware/umbrella/user/Constants.java
  20. 28
      user/src/main/java/de/srsoftware/umbrella/user/UserModule.java
  21. 4
      user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java
  22. 6
      user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java

2
backend/build.gradle.kts

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
import org.gradle.jvm.tasks.Jar
description = "Umbrella : Backend"
@ -22,6 +21,7 @@ dependencies{ @@ -22,6 +21,7 @@ dependencies{
implementation("de.srsoftware:configuration.api:1.0.2")
implementation("de.srsoftware:configuration.json:1.0.3")
implementation("de.srsoftware:tools.optionals:1.0.0")
implementation("de.srsoftware:tools.slf4j2syslog:1.0.1") // this provides a slf4j implementation that forwards to System.Logger
implementation("de.srsoftware:tools.util:2.0.3")
implementation("org.json:json:20240303")
}

46
backend/src/main/java/de/srsoftware/umbrella/backend/Application.java

@ -4,22 +4,17 @@ package de.srsoftware.umbrella.backend; @@ -4,22 +4,17 @@ package de.srsoftware.umbrella.backend;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Util.mapLogLevel;
import static java.lang.System.Logger.Level.INFO;
import static java.text.MessageFormat.format;
import com.sun.net.httpserver.HttpServer;
import de.srsoftware.configuration.JsonConfig;
import de.srsoftware.tools.ColorLogger;
import de.srsoftware.umbrella.core.ConnectionProvider;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.documents.DocumentApi;
import de.srsoftware.umbrella.documents.SqliteDb;
import de.srsoftware.umbrella.legacy.LegacyApi;
import de.srsoftware.umbrella.message.MessageApi;
import de.srsoftware.umbrella.message.MessageSystem;
import de.srsoftware.umbrella.message.SqliteMessageDb;
import de.srsoftware.umbrella.translations.Translations;
import de.srsoftware.umbrella.user.UserModule;
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
import de.srsoftware.umbrella.web.WebHandler;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -29,7 +24,7 @@ import org.json.JSONObject; @@ -29,7 +24,7 @@ import org.json.JSONObject;
public class Application {
private static final System.Logger LOG = System.getLogger("Umbrella");
private static void configureLogging(JsonConfig jsonConfig) {
private static JsonConfig configureLogging(JsonConfig jsonConfig) {
var rootLevel = jsonConfig.get("umbrella.logging.rootLevel", "INFO");
ColorLogger.setRootLogLevel(mapLogLevel(rootLevel));
@ -40,36 +35,33 @@ public class Application { @@ -40,36 +35,33 @@ public class Application {
ColorLogger.setLogLevel(key,lvl);
});
}
return jsonConfig;
}
public static void main(String[] args) throws IOException, UmbrellaException {
LOG.log(INFO, "Starting Umbrella:");
var config = new JsonConfig(UMBRELLA);
configureLogging(config);
var config = configureLogging(new JsonConfig(UMBRELLA));
var port = config.get("umbrella.http.port", 8080);
var threads = config.get("umbrella.threads", 16);
var docDbFile = config.get("umbrella.database.documents",config.file().getParent()+"/documents.db");
var userDbFile = config.get("umbrella.database.user", config.file().getParent()+"/umbrella.db");
var loginDbFile = config.get("umbrella.database.login_services",config.file().getParent()+"/umbrella.db");
var messageDbFile = config.get("umbrella.database.messages", config.file().getParent()+"/umbrella.db");
var connectionProvider = new ConnectionProvider();
var documentDb = new SqliteDb(connectionProvider.get(docDbFile));
var messageDb = new SqliteMessageDb(connectionProvider.get(messageDbFile));
var userDb = new SqliteDB(connectionProvider.get(userDbFile));
var loginServiceDb = new SqliteDB(connectionProvider.get(loginDbFile));
var moduleConfig = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException(format(ERROR_MISSING_CONFIG,"umbrella.modules")));
var translationModule = new Translations();
var messageSystem = new MessageSystem(messageDb,translationModule,moduleConfig.subset("message").orElseThrow(() -> new RuntimeException(format(ERROR_MISSING_CONFIG,"umbrella.modules.message"))));
var translationModule = new Translations();
var messageSystem = new MessageSystem(translationModule,config);
var server = HttpServer.create(new InetSocketAddress(port), 0);
server.setExecutor(Executors.newFixedThreadPool(threads));
var userModule = new UserModule(userDb,loginServiceDb,messageSystem);
new LegacyApi(userDb,config) .bindPath("/legacy") .on(server);
new DocumentApi(documentDb, userModule, moduleConfig) .bindPath("/api/document") .on(server);
new MessageApi(messageSystem).bindPath("/api/messages") .on(server);
translationModule .bindPath("/api/translations").on(server);
var userModule = new UserModule(config,messageSystem);
var documentApi = new DocumentApi(userModule, config);
var legacyApi = new LegacyApi(userModule.userDb(),config);
var messageApi = new MessageApi(messageSystem);
var webHandler = new WebHandler();
documentApi .bindPath("/api/document") .on(server);
legacyApi .bindPath("/legacy") .on(server);
messageApi .bindPath("/api/messages") .on(server);
translationModule.bindPath("/api/translations").on(server);
userModule .bindPath("/api/user") .on(server);
new WebHandler() .bindPath("/") .on(server);
webHandler .bindPath("/") .on(server);
server.setExecutor(Executors.newFixedThreadPool(threads));
server.start();
LOG.log(INFO,"Started web server at {0}",port);
}

6
company/build.gradle.kts

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
description = "Umbrella : Companies"
dependencies{
implementation(project(":core"))
}

21
company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.company;
import de.srsoftware.umbrella.core.api.CompanyService;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.List;
public class CompanyModule implements CompanyService {
private final UserService users;
public CompanyModule(UserService userService){
users = userService;
}
@Override
public List<UmbrellaUser> getMembers(long companyId) {
return null;
}
}

5
core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java

@ -5,6 +5,7 @@ import static de.srsoftware.tools.Optionals.nullable; @@ -5,6 +5,7 @@ import static de.srsoftware.tools.Optionals.nullable;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.WARNING;
import static java.net.HttpURLConnection.*;
import static java.text.MessageFormat.format;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.tools.Path;
@ -73,4 +74,8 @@ public abstract class BaseHandler extends PathHandler { @@ -73,4 +74,8 @@ public abstract class BaseHandler extends PathHandler {
public boolean unauthorized(HttpExchange ex) throws IOException {
return sendEmptyResponse(HTTP_FORBIDDEN,ex);
}
public boolean notImplemented(HttpExchange ex,String message,Object clazz) throws IOException{
return sendContent(ex,HTTP_NOT_IMPLEMENTED,format(message,clazz.getClass().getSimpleName()));
}
}

15
core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java

@ -7,12 +7,17 @@ import java.sql.SQLException; @@ -7,12 +7,17 @@ import java.sql.SQLException;
import java.util.HashMap;
import org.sqlite.SQLiteDataSource;
public class ConnectionProvider extends HashMap<File, Connection> {
public Connection get(Object o) {
public class ConnectionProvider {
private static final HashMap<File, Connection> connections = new HashMap<>();
private ConnectionProvider(){}
public static Connection connect(Object o) {
if (o instanceof String filename) o = new File(filename);
if (o instanceof File dbFile) try {
var conn = super.get(dbFile);
if (conn == null) put(dbFile, conn = open(dbFile));
var conn = connections.get(dbFile);
if (conn == null) connections.put(dbFile, conn = open(dbFile));
return conn;
} catch (SQLException sqle) {
throw new RuntimeException(sqle);
@ -20,7 +25,7 @@ public class ConnectionProvider extends HashMap<File, Connection> { @@ -20,7 +25,7 @@ public class ConnectionProvider extends HashMap<File, Connection> {
return null;
}
private Connection open(File dbFile) throws SQLException {
private static Connection open(File dbFile) throws SQLException {
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl("jdbc:sqlite:%s".formatted(dbFile));
return dataSource.getConnection();

9
core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java

@ -1,19 +1,20 @@ @@ -1,19 +1,20 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core;
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
import static java.text.MessageFormat.format;
public class UmbrellaException extends Exception{
private final int statusCode;
public UmbrellaException(int statusCode, String message){
super(message);
this.statusCode = statusCode;
public UmbrellaException(String message, Object ... fills){
this(HTTP_SERVER_ERROR,message,fills);
}
public UmbrellaException(int statusCode, String message, Object ... fills){
this(statusCode,format(message,fills));
super(format(message,fills));
this.statusCode = statusCode;
}
public UmbrellaException causedBy(Exception e) {

9
core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core.api;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.List;
public interface CompanyService {
public List<UmbrellaUser> getMembers(long companyId);
}

5
core/src/main/java/de/srsoftware/umbrella/core/api/UserHelper.java → core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java

@ -2,12 +2,13 @@ @@ -2,12 +2,13 @@
package de.srsoftware.umbrella.core.api;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.util.Optional;
public interface UserHelper {
public interface UserService {
UmbrellaUser loadUser(long userId) throws UmbrellaException;
Optional<UmbrellaUser> loadUser(Optional<Token> sessionToken) throws UmbrellaException;
Optional<UmbrellaUser> loadUser(HttpExchange ex) throws UmbrellaException;
}

4
user/src/main/java/de/srsoftware/umbrella/user/model/Session.java → core/src/main/java/de/srsoftware/umbrella/core/model/Session.java

@ -1,9 +1,7 @@ @@ -1,9 +1,7 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.user.model;
package de.srsoftware.umbrella.core.model;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.time.Instant;
/* © SRSoftware 2025 */

3
core/src/main/java/de/srsoftware/umbrella/core/Token.java → core/src/main/java/de/srsoftware/umbrella/core/model/Token.java

@ -1,9 +1,10 @@ @@ -1,9 +1,10 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core;
package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.TOKEN;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.AddableMap;
import java.util.UUID;
public class Token implements CharSequence{

2
documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java

@ -10,6 +10,8 @@ public class Constants { @@ -10,6 +10,8 @@ public class Constants {
private Constants(){}
public static final Pattern POST_CODE = compile("(.*\\w+.*)\n(.*\\d+.*)\n(\\d{5}) (\\w+)",DOTALL);
public static final String CONFIG_DATABASE = "umbrella.modules.document.database";
public static final String CONTACTS = "contacts";
public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix";

41
documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java

@ -2,10 +2,12 @@ @@ -2,10 +2,12 @@
package de.srsoftware.umbrella.documents;
import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
import static de.srsoftware.umbrella.core.Paths.LIST;
import static de.srsoftware.umbrella.core.Util.request;
import static de.srsoftware.umbrella.documents.Constants.*;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.WARNING;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
@ -14,29 +16,29 @@ import de.srsoftware.configuration.Configuration; @@ -14,29 +16,29 @@ import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.api.UserHelper;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.documents.model.Type;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import de.srsoftware.umbrella.documents.model.Type;
import org.json.JSONArray;
import org.json.JSONObject;
public class DocumentApi extends BaseHandler {
private final UserHelper users;
private final UserService users;
private final Configuration config;
private final DocumentDb db;
public DocumentApi(DocumentDb documentDb, UserHelper userHelper, Configuration moduleConfig){
config = moduleConfig;
db = documentDb;
public DocumentApi(UserService userHelper, Configuration config) throws UmbrellaException {
this.config = config;
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> new UmbrellaException(ERROR_MISSING_FIELD,CONFIG_DATABASE));
db = new SqliteDb(connect(dbFile));
users = userHelper;
}
@ -69,7 +71,8 @@ public class DocumentApi extends BaseHandler { @@ -69,7 +71,8 @@ public class DocumentApi extends BaseHandler {
var head = path.pop();
return switch (head){
case LIST -> listDocuments(ex,user.get(),token.orElse(null));
case null, default -> super.doPost(path,ex);
case null -> postDocument(ex,user.get());
default -> super.doPost(path,ex);
};
} catch (UmbrellaException e) {
return send(ex,e);
@ -89,17 +92,17 @@ public class DocumentApi extends BaseHandler { @@ -89,17 +92,17 @@ public class DocumentApi extends BaseHandler {
var map = types.values().stream().collect(Collectors.toMap(Type::id, Type::name));
return sendContent(ex,map);
}
private HashMap<Long, Map<String, Object>> getLegacyCompanies(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
var location = config.get("company.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
var location = config.get("umbrella.modules.company.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
if (!(resp instanceof JSONObject json)) throw new UmbrellaException(500,"{0} did not return JSON!",location);
var result = new HashMap<Long, Map<String,Object>>();
for (var key : json.keySet()) result.put(Long.parseLong(key),json.getJSONObject(key).toMap());
return result;
}
private JSONArray getLegacyContacts(HttpExchange ex, UmbrellaUser umbrellaUser, Token token) throws IOException, UmbrellaException {
var location = config.get("contact.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.company.baseUrl not configured!"));
var location = config.get("umbrella.modules.contact.baseUrl").map(s -> s+"/json").orElseThrow(() -> new UmbrellaException(500,"umbrella.modules.contact.baseUrl not configured!"));
var resp = request(location, token.asMap(),MIME_FORM_URL,null);
if (!(resp instanceof String s && s.startsWith("["))) throw new UmbrellaException(500,"{0} did not return JSON Array!",location);
return new JSONArray(s);
@ -122,4 +125,18 @@ public class DocumentApi extends BaseHandler { @@ -122,4 +125,18 @@ public class DocumentApi extends BaseHandler {
throw new UmbrellaException( 500,"Failed to parse JSON data from request").causedBy(e);
}
}
private boolean postDocument(HttpExchange ex, UmbrellaUser umbrellaUser) throws IOException, UmbrellaException {
var json = json(ex);
if (!(json.has(COMPANY) && json.get(COMPANY) instanceof String cid) || cid.isBlank()) throw new UmbrellaException(HTTP_BAD_REQUEST,ERROR_MISSING_FIELD,COMPANY);
long companyId;
try {
companyId = Long.parseLong(cid);
} catch (NumberFormatException nfe){
throw new UmbrellaException(HTTP_BAD_REQUEST,nfe.getMessage());
}
LOG.log(DEBUG,json.toString(2));
return notImplemented(ex,"{0}.postDocument(…)",this);
}
}

10
legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java

@ -19,11 +19,11 @@ import de.srsoftware.configuration.Configuration; @@ -19,11 +19,11 @@ import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.model.Session;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.user.model.Session;
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
import de.srsoftware.umbrella.user.api.UserDb;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
@ -32,11 +32,11 @@ import org.json.JSONObject; @@ -32,11 +32,11 @@ import org.json.JSONObject;
public class LegacyApi extends BaseHandler {
private final SqliteDB users;
private final UserDb users;
private final Configuration config;
private final String messageUrl;
public LegacyApi(SqliteDB userDb, Configuration config) {
public LegacyApi(UserDb userDb, Configuration config) {
users = userDb;
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
this.messageUrl = null;

8
messages/src/main/java/de/srsoftware/umbrella/message/Constants.java

@ -3,6 +3,13 @@ package de.srsoftware.umbrella.message; @@ -3,6 +3,13 @@ package de.srsoftware.umbrella.message;
public class Constants {
public static final String AUTH = "mail.smtp.auth";
public static final String CONFIG_DB = "umbrella.modules.message.database";
public static final String CONFIG_SMTP_HOST = "umbrella.modules.message.smtp.host";
public static final String CONFIG_SMTP_PASS = "umbrella.modules.message.smtp.pass";
public static final String CONFIG_SMTP_PORT = "umbrella.modules.message.smtp.port";
public static final String CONFIG_SMTP_USER = "umbrella.modules.message.smtp.user";
public static final String DEBUG_ADDREESS = "debug_addres";
public static final String ENVELOPE_FROM = "mail.smtp.from";
public static final String FIELD_MESSAGES = "messages";
@ -13,7 +20,6 @@ public class Constants { @@ -13,7 +20,6 @@ public class Constants {
public static final String JSONOBJECT = "json object";
public static final String PORT = "mail.smtp.port";
public static final String RECEIVERS = "receivers";
public static final String SMTP = "smtp";
public static final String SSL = "mail.smtp.ssl.enable";
public static final String SUBMISSION = "submission";

16
messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
package de.srsoftware.umbrella.message;
import static de.srsoftware.tools.PathHandler.CONTENT_TYPE;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.message.Constants.*;
import static java.lang.System.Logger.Level.*;
@ -68,15 +69,16 @@ public class MessageSystem implements PostBox { @@ -68,15 +69,16 @@ public class MessageSystem implements PostBox {
private final HashMap<Receiver,List<Exception>> exceptions = new HashMap<>();
private final Translator translator;
public MessageSystem(SqliteMessageDb messageDb, Translator translator, Configuration config) {
db = messageDb;
public MessageSystem(Translator translator, Configuration config) throws UmbrellaException {
var messageDbFile = config.get(CONFIG_DB).orElseThrow(() -> new UmbrellaException(500,ERROR_MISSING_CONFIG,CONFIG_DB));
db = new SqliteMessageDb(connect(messageDbFile));
this.translator = translator;
debugAddress = config.get(DEBUG_ADDREESS).map(Object::toString).orElse(null);
config = config.subset(SMTP).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp not configured!"));
port = config.get(FIELD_PORT,587);
host = config.get(FIELD_HOST).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.host not configured!"));
user = config.get(USER).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.user not configured!"));
pass = config.get(PASS).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.pass not configured!"));
port = config.get(CONFIG_SMTP_PORT,587);
host = config.get(CONFIG_SMTP_HOST).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.host not configured!"));
user = config.get(CONFIG_SMTP_USER).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.user not configured!"));
pass = config.get(CONFIG_SMTP_PASS).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.pass not configured!"));
from = user;
new SubmissionTask(8).schedule();
new SubmissionTask(10).schedule();

3
settings.gradle.kts

@ -2,10 +2,11 @@ rootProject.name = "Umbrella25" @@ -2,10 +2,11 @@ rootProject.name = "Umbrella25"
include("backend")
include("core")
include("documents")
include("legacy")
include("messages")
include("translations")
include("user")
include("web")
include("documents")
include("company")

2
translations/src/main/resources/de.json

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
"list_of": "Dokumente von {0}",
"number": "Nummer",
"select_company" : "Wählen Sie eine ihrer Firmen:",
"select customer": "Kunde auswählen",
"select_customer": "Kunde auswählen",
"sender": "Absender",
"state": "Status",
"state_declined": "abgelehnt",

1
user/src/main/java/de/srsoftware/umbrella/user/Constants.java

@ -12,6 +12,7 @@ public class Constants { @@ -12,6 +12,7 @@ public class Constants {
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String CODE = "code";
public static final String CONFIG_DATABASE = "umbrella.modules.user.database";
public static final String DB_VERSION = "user_db_version";

28
user/src/main/java/de/srsoftware/umbrella/user/UserModule.java

@ -4,6 +4,7 @@ package de.srsoftware.umbrella.user; @@ -4,6 +4,7 @@ package de.srsoftware.umbrella.user;
import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
import static de.srsoftware.tools.Optionals.*;
import static de.srsoftware.tools.Strings.uuid;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Paths.LIST;
import static de.srsoftware.umbrella.core.Paths.LOGOUT;
@ -24,13 +25,14 @@ import static java.time.temporal.ChronoUnit.DAYS; @@ -24,13 +25,14 @@ import static java.time.temporal.ChronoUnit.DAYS;
import static java.util.Optional.empty;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.api.UserHelper;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.model.EmailAddress;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.message.MessageSystem;
import de.srsoftware.umbrella.message.model.Envelope;
@ -38,6 +40,9 @@ import de.srsoftware.umbrella.message.model.Message; @@ -38,6 +40,9 @@ import de.srsoftware.umbrella.message.model.Message;
import de.srsoftware.umbrella.user.api.LoginServiceDb;
import de.srsoftware.umbrella.user.api.UserDb;
import de.srsoftware.umbrella.user.model.*;
import de.srsoftware.umbrella.user.model.DbUser;
import de.srsoftware.umbrella.user.model.Password;
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.*;
@ -53,7 +58,7 @@ import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; @@ -53,7 +58,7 @@ import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver;
import org.json.JSONObject;
public class UserModule extends BaseHandler implements UserHelper {
public class UserModule extends BaseHandler implements UserService {
private record State(LoginService loginService, JSONObject config){
@ -78,13 +83,17 @@ public class UserModule extends BaseHandler implements UserHelper { @@ -78,13 +83,17 @@ public class UserModule extends BaseHandler implements UserHelper {
}
}
public UserModule(UserDb userDb, LoginServiceDb loginDb, MessageSystem messageSystem){
logins = loginDb;
public UserModule(Configuration config, MessageSystem messageSystem) throws UmbrellaException {
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> new UmbrellaException(ERROR_MISSING_CONFIG,CONFIG_DATABASE));
// may be splitted in separate db files later
logins = new SqliteDB(connect(dbFile));
messages = messageSystem;
users = userDb;
users = new SqliteDB(connect(dbFile));
}
public UserDb userDb(){
return users;
}
private boolean deleteOIDC(HttpExchange ex, UmbrellaUser user, Path path) throws IOException {
var head = path.pop();
@ -126,6 +135,11 @@ public class UserModule extends BaseHandler implements UserHelper { @@ -126,6 +135,11 @@ public class UserModule extends BaseHandler implements UserHelper {
}
}
@Override
public UmbrellaUser loadUser(long userId) throws UmbrellaException {
return users.load(userId);
}
public Optional<UmbrellaUser> loadUser(Optional<Token> sessionToken) throws UmbrellaException {
if (sessionToken.isEmpty()) return empty();
var session = users.load(sessionToken.get());

4
user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java

@ -1,13 +1,13 @@ @@ -1,13 +1,13 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.user.api;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.model.EmailAddress;
import de.srsoftware.umbrella.core.model.Session;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.user.model.DbUser;
import de.srsoftware.umbrella.user.model.Password;
import de.srsoftware.umbrella.user.model.Session;
import java.util.List;
public interface UserDb {

6
user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java

@ -12,15 +12,17 @@ import static java.text.MessageFormat.format; @@ -12,15 +12,17 @@ import static java.text.MessageFormat.format;
import de.srsoftware.tools.PasswordHasher;
import de.srsoftware.tools.jdbc.Query;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.core.model.EmailAddress;
import de.srsoftware.umbrella.core.model.Session;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import de.srsoftware.umbrella.user.BadHasher;
import de.srsoftware.umbrella.user.api.LoginServiceDb;
import de.srsoftware.umbrella.user.api.UserDb;
import de.srsoftware.umbrella.user.model.*;
import de.srsoftware.umbrella.user.model.Session;
import de.srsoftware.umbrella.user.model.DbUser;
import de.srsoftware.umbrella.user.model.Password;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.ResultSet;

Loading…
Cancel
Save