From 21812d2b423e4ed3b10f6427db9b28b642187ee1 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 10 Jul 2025 10:56:03 +0200 Subject: [PATCH] major refactoring: working towards more interface-implementation splitting --- backend/build.gradle.kts | 2 +- .../umbrella/backend/Application.java | 52 ++++++++----------- company/build.gradle.kts | 6 +++ .../umbrella/company/CompanyModule.java | 21 ++++++++ .../srsoftware/umbrella/core/BaseHandler.java | 5 ++ .../umbrella/core/ConnectionProvider.java | 15 ++++-- .../umbrella/core/UmbrellaException.java | 9 ++-- .../umbrella/core/api/CompanyService.java | 9 ++++ .../api/{UserHelper.java => UserService.java} | 5 +- .../umbrella/core}/model/Session.java | 4 +- .../umbrella/core/{ => model}/Token.java | 3 +- .../umbrella/documents/Constants.java | 2 + .../umbrella/documents/DocumentApi.java | 41 ++++++++++----- .../srsoftware/umbrella/legacy/LegacyApi.java | 10 ++-- .../umbrella/message/Constants.java | 8 ++- .../umbrella/message/MessageSystem.java | 16 +++--- settings.gradle.kts | 3 +- translations/src/main/resources/de.json | 2 +- .../srsoftware/umbrella/user/Constants.java | 1 + .../srsoftware/umbrella/user/UserModule.java | 28 +++++++--- .../srsoftware/umbrella/user/api/UserDb.java | 4 +- .../umbrella/user/sqlite/SqliteDB.java | 6 ++- 22 files changed, 168 insertions(+), 84 deletions(-) create mode 100644 company/build.gradle.kts create mode 100644 company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java create mode 100644 core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java rename core/src/main/java/de/srsoftware/umbrella/core/api/{UserHelper.java => UserService.java} (74%) rename {user/src/main/java/de/srsoftware/umbrella/user => core/src/main/java/de/srsoftware/umbrella/core}/model/Session.java (74%) rename core/src/main/java/de/srsoftware/umbrella/core/{ => model}/Token.java (91%) diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 49a0b57..d786457 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -1,4 +1,3 @@ - import org.gradle.jvm.tasks.Jar description = "Umbrella : Backend" @@ -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") } diff --git a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java index a574561..252cb71 100644 --- a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java +++ b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java @@ -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; 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 { 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 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 config = configureLogging(new JsonConfig(UMBRELLA)); + var port = config.get("umbrella.http.port", 8080); + var threads = config.get("umbrella.threads", 16); + + var translationModule = new Translations(); + var messageSystem = new MessageSystem(translationModule,config); + var server = HttpServer.create(new InetSocketAddress(port), 0); + + 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); + webHandler .bindPath("/") .on(server); - var messageSystem = new MessageSystem(messageDb,translationModule,moduleConfig.subset("message").orElseThrow(() -> new RuntimeException(format(ERROR_MISSING_CONFIG,"umbrella.modules.message")))); - 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); - userModule .bindPath("/api/user") .on(server); - new WebHandler() .bindPath("/") .on(server); server.start(); LOG.log(INFO,"Started web server at {0}",port); } diff --git a/company/build.gradle.kts b/company/build.gradle.kts new file mode 100644 index 0000000..3c67e9c --- /dev/null +++ b/company/build.gradle.kts @@ -0,0 +1,6 @@ +description = "Umbrella : Companies" + +dependencies{ + implementation(project(":core")) +} + diff --git a/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java new file mode 100644 index 0000000..5d0f936 --- /dev/null +++ b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java @@ -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 getMembers(long companyId) { + return null; + } +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java b/core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java index 957ac13..52fbca8 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java @@ -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 { 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())); + } } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java b/core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java index b14b9db..c5f5df1 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/ConnectionProvider.java @@ -7,12 +7,17 @@ import java.sql.SQLException; import java.util.HashMap; import org.sqlite.SQLiteDataSource; -public class ConnectionProvider extends HashMap { - public Connection get(Object o) { +public class ConnectionProvider { + + private static final HashMap 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 { 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(); diff --git a/core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java b/core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java index f19c43b..3f8b404 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/UmbrellaException.java @@ -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) { diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java new file mode 100644 index 0000000..35a1fcf --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/CompanyService.java @@ -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 getMembers(long companyId); +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/UserHelper.java b/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java similarity index 74% rename from core/src/main/java/de/srsoftware/umbrella/core/api/UserHelper.java rename to core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java index 3ac728d..a2739e2 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/UserHelper.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java @@ -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 loadUser(Optional sessionToken) throws UmbrellaException; Optional loadUser(HttpExchange ex) throws UmbrellaException; } diff --git a/user/src/main/java/de/srsoftware/umbrella/user/model/Session.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Session.java similarity index 74% rename from user/src/main/java/de/srsoftware/umbrella/user/model/Session.java rename to core/src/main/java/de/srsoftware/umbrella/core/model/Session.java index a0c3c0b..213d111 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/model/Session.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Session.java @@ -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 */ diff --git a/core/src/main/java/de/srsoftware/umbrella/core/Token.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Token.java similarity index 91% rename from core/src/main/java/de/srsoftware/umbrella/core/Token.java rename to core/src/main/java/de/srsoftware/umbrella/core/model/Token.java index e396690..ba29617 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/Token.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Token.java @@ -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{ diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java index f5e0ee6..c3105cc 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/Constants.java @@ -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"; diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java b/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java index 89097d9..41f92bc 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java @@ -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; 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 { 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 { var map = types.values().stream().collect(Collectors.toMap(Type::id, Type::name)); return sendContent(ex,map); } + private HashMap> 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>(); 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 { 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); + } } diff --git a/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java b/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java index c5a14d4..b4835d5 100644 --- a/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java +++ b/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java @@ -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; 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; diff --git a/messages/src/main/java/de/srsoftware/umbrella/message/Constants.java b/messages/src/main/java/de/srsoftware/umbrella/message/Constants.java index 0abc3c1..755f4f4 100644 --- a/messages/src/main/java/de/srsoftware/umbrella/message/Constants.java +++ b/messages/src/main/java/de/srsoftware/umbrella/message/Constants.java @@ -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 { 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"; diff --git a/messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java b/messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java index 8fdf386..ad13908 100644 --- a/messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java +++ b/messages/src/main/java/de/srsoftware/umbrella/message/MessageSystem.java @@ -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 { private final HashMap> 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(); diff --git a/settings.gradle.kts b/settings.gradle.kts index dfcbdf2..e2f9bfe 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -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") \ No newline at end of file +include("company") \ No newline at end of file diff --git a/translations/src/main/resources/de.json b/translations/src/main/resources/de.json index 367af8c..98fc286 100644 --- a/translations/src/main/resources/de.json +++ b/translations/src/main/resources/de.json @@ -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", diff --git a/user/src/main/java/de/srsoftware/umbrella/user/Constants.java b/user/src/main/java/de/srsoftware/umbrella/user/Constants.java index ec7346e..6a91b36 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/Constants.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/Constants.java @@ -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"; diff --git a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java index ffb966a..967b927 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java @@ -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; 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; 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; 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 { } } - 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 { } } + @Override + public UmbrellaUser loadUser(long userId) throws UmbrellaException { + return users.load(userId); + } + public Optional loadUser(Optional sessionToken) throws UmbrellaException { if (sessionToken.isEmpty()) return empty(); var session = users.load(sessionToken.get()); diff --git a/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java b/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java index 75959d6..6ac4114 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java @@ -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 { diff --git a/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java b/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java index ec70df9..4fc75bd 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java @@ -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;