implemented document creation
this required a major refactoring of the object model
This commit is contained in:
@@ -11,6 +11,7 @@ application{
|
||||
}
|
||||
|
||||
dependencies{
|
||||
implementation(project(":company"))
|
||||
implementation(project(":core"))
|
||||
implementation(project(":documents"))
|
||||
implementation(project(":legacy"))
|
||||
@@ -23,7 +24,6 @@ dependencies{
|
||||
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")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
|
||||
@@ -8,7 +8,8 @@ import static java.lang.System.Logger.Level.INFO;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import de.srsoftware.configuration.JsonConfig;
|
||||
import de.srsoftware.tools.ColorLogger;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.company.CompanyModule;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.documents.DocumentApi;
|
||||
import de.srsoftware.umbrella.legacy.LegacyApi;
|
||||
import de.srsoftware.umbrella.message.MessageApi;
|
||||
@@ -49,7 +50,8 @@ public class Application {
|
||||
var server = HttpServer.create(new InetSocketAddress(port), 0);
|
||||
|
||||
var userModule = new UserModule(config,messageSystem);
|
||||
var documentApi = new DocumentApi(userModule, config);
|
||||
var companyModule = new CompanyModule(config, userModule);
|
||||
var documentApi = new DocumentApi(companyModule, config);
|
||||
var legacyApi = new LegacyApi(userModule.userDb(),config);
|
||||
var messageApi = new MessageApi(messageSystem);
|
||||
var webHandler = new WebHandler();
|
||||
|
||||
@@ -42,6 +42,7 @@ subprojects {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
implementation("de.srsoftware:tools.http:6.0.4")
|
||||
implementation("de.srsoftware:tools.logging:1.3.2")
|
||||
implementation("org.json:json:20240303")
|
||||
}
|
||||
|
||||
tasks.withType<Test>() {
|
||||
|
||||
@@ -2,5 +2,7 @@ description = "Umbrella : Companies"
|
||||
|
||||
dependencies{
|
||||
implementation(project(":core"))
|
||||
implementation("de.srsoftware:configuration.api:1.0.2")
|
||||
implementation("de.srsoftware:tools.jdbc:1.3.2")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,45 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.company;
|
||||
|
||||
import static de.srsoftware.umbrella.company.Constants.CONFIG_DATABASE;
|
||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
|
||||
import de.srsoftware.configuration.Configuration;
|
||||
import de.srsoftware.umbrella.company.api.CompanyDb;
|
||||
import de.srsoftware.umbrella.core.api.CompanyService;
|
||||
import de.srsoftware.umbrella.core.api.UserService;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Company;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class CompanyModule implements CompanyService {
|
||||
|
||||
private final UserService users;
|
||||
private final CompanyDb companyDb;
|
||||
|
||||
public CompanyModule(UserService userService){
|
||||
public CompanyModule(Configuration config, UserService userService) throws UmbrellaException {
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
|
||||
companyDb = new SqliteDb(connect(dbFile));
|
||||
users = userService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UmbrellaUser> getMembers(long companyId) {
|
||||
return null;
|
||||
public Company get(long companyId) throws UmbrellaException {
|
||||
return companyDb.load(companyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<UmbrellaUser> getMembers(long companyId) throws UmbrellaException {
|
||||
var members = new HashSet<UmbrellaUser>();
|
||||
for (var userId : companyDb.getMembers(companyId)) members.add(users.loadUser(userId));
|
||||
return members;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserService userService() {
|
||||
return users;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.company;
|
||||
|
||||
public class Constants {
|
||||
private Constants(){}
|
||||
|
||||
public static final String CONFIG_DATABASE = "umbrella.modules.company.database";
|
||||
public static final String TABLE_COMPANIES_USERS = "companies_users";
|
||||
public static final String TABLE_COMPANIES = "companies";
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.company;
|
||||
|
||||
import static de.srsoftware.tools.jdbc.Condition.equal;
|
||||
import static de.srsoftware.tools.jdbc.Query.select;
|
||||
import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES;
|
||||
import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES_USERS;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
|
||||
import de.srsoftware.umbrella.company.api.CompanyDb;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Company;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class SqliteDb implements CompanyDb {
|
||||
|
||||
private final Connection db;
|
||||
|
||||
public SqliteDb(Connection connection) {
|
||||
db = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Long> getMembers(long companyId) throws UmbrellaException {
|
||||
try {
|
||||
var rs = select("*").from(TABLE_COMPANIES_USERS).where(COMPANY_ID, equal(companyId)).exec(db);
|
||||
var ids = new HashSet<Long>();
|
||||
while (rs.next()) ids.add(rs.getLong(USER_ID));
|
||||
rs.close();
|
||||
return ids;
|
||||
} catch (SQLException e) {
|
||||
throw new UmbrellaException("Failed to load members of company {0}",companyId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Company load(long companyId) throws UmbrellaException {
|
||||
try {
|
||||
var rs = select("*").from(TABLE_COMPANIES).where(ID, equal(companyId)).exec(db);
|
||||
Company company = null;
|
||||
if (rs.next()) company = Company.of(rs);
|
||||
rs.close();
|
||||
if (company == null) throw new UmbrellaException("Could not load company {0}",companyId);
|
||||
return company;
|
||||
} catch (SQLException e){
|
||||
throw new UmbrellaException("Could not load company {0}",companyId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.company.api;
|
||||
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Company;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface CompanyDb {
|
||||
Collection<Long> getMembers(long companyId) throws UmbrellaException;
|
||||
|
||||
Company load(long companyId) throws UmbrellaException;
|
||||
}
|
||||
@@ -13,7 +13,6 @@ dependencies {
|
||||
implementation("de.srsoftware:tools.mime:1.1.2")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.json:json:20240303")
|
||||
implementation("org.xerial:sqlite-jdbc:3.49.0.0")
|
||||
testImplementation(platform("org.junit:junit-bom:5.10.0"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
|
||||
@@ -10,6 +10,7 @@ import static java.text.MessageFormat.format;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.tools.Path;
|
||||
import de.srsoftware.tools.PathHandler;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -35,7 +36,7 @@ public abstract class BaseHandler extends PathHandler {
|
||||
return sendEmptyResponse(HTTP_FORBIDDEN,ex);
|
||||
}
|
||||
|
||||
public record Document(String mime, byte[] bytes){}
|
||||
public record Page(String mime, byte[] bytes){}
|
||||
|
||||
public boolean load(Path path, HttpExchange ex) throws IOException {
|
||||
try {
|
||||
@@ -47,7 +48,7 @@ public abstract class BaseHandler extends PathHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public Document load(String resourcePath) throws IOException, UmbrellaException {
|
||||
public Page load(String resourcePath) throws IOException, UmbrellaException {
|
||||
var url = getClass().getClassLoader().getResource(resourcePath);
|
||||
if (url == null) throw new UmbrellaException(HTTP_NOT_FOUND,"{0} not found!",resourcePath);
|
||||
LOG.log(DEBUG,"Trying to load {0}",url);
|
||||
@@ -56,7 +57,7 @@ public abstract class BaseHandler extends PathHandler {
|
||||
var mime = conn.getContentType();
|
||||
try (var stream = conn.getInputStream()){
|
||||
stream.transferTo(bos);
|
||||
return new Document(mime,bos.toByteArray());
|
||||
return new Page(mime,bos.toByteArray());
|
||||
} catch (Exception e) {
|
||||
LOG.log(WARNING,"Failed to load {0}",url);
|
||||
throw new UmbrellaException(HTTP_NOT_FOUND,"Failed to load {0}",url);
|
||||
|
||||
@@ -64,4 +64,16 @@ public class Constants {
|
||||
public static final String USER_LIST = "user_list";
|
||||
public static final String UTF8 = UTF_8.displayName();
|
||||
public static final String VALUE = "value";
|
||||
|
||||
public static final String COMPANY_ID = "company_id";
|
||||
public static final String FIELD_COURT = "court";
|
||||
public static final String FIELD_TAX_NUMBER = "tax_number";
|
||||
public static final String FIELD_PHONE = "phone";
|
||||
public static final String DECIMAL_SEPARATOR = "decimal_separator";
|
||||
public static final String THOUSANDS_SEPARATOR = "thousands_separator";
|
||||
public static final String LAST_CUSTOMER_NUMBER = "last_customer_number";
|
||||
public static final String DECIMALS = "decimals";
|
||||
public static final String CUSTOMER_NUMBER_PREFIX = "customer_number_prefix";
|
||||
public static final String FIELD_CURRENCY = "currency";
|
||||
public static final String FIELD_BANK_ACCOUNT = "bank_account";
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/* © 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(String message, Object ... fills){
|
||||
this(HTTP_SERVER_ERROR,message,fills);
|
||||
}
|
||||
|
||||
public UmbrellaException(int statusCode, String message, Object ... fills){
|
||||
super(format(message,fills));
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public UmbrellaException causedBy(Exception e) {
|
||||
initCause(e);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int statusCode(){
|
||||
return statusCode;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import de.srsoftware.tools.Query;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.core.api;
|
||||
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Company;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface CompanyService {
|
||||
public List<UmbrellaUser> getMembers(long companyId);
|
||||
public Collection<UmbrellaUser> getMembers(long companyId) throws UmbrellaException;
|
||||
public UserService userService();
|
||||
|
||||
Company get(long companyId) throws UmbrellaException;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.umbrella.core.api;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.core.exceptions;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
|
||||
public class UmbrellaException extends Exception{
|
||||
private final int statusCode;
|
||||
|
||||
public UmbrellaException(String message, Object ... fills){
|
||||
this(HTTP_SERVER_ERROR,message,fills);
|
||||
}
|
||||
|
||||
public UmbrellaException(int statusCode, String message, Object ... fills){
|
||||
super(format(message,fills));
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public UmbrellaException causedBy(Exception e) {
|
||||
initCause(e);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static UmbrellaException invalidFieldException(String field,String expected){
|
||||
return new UmbrellaException(HTTP_UNPROCESSABLE, ERROR_INVALID_FIELD, field, expected);
|
||||
}
|
||||
|
||||
|
||||
public static UmbrellaException missingConfigException(String field){
|
||||
System.getLogger("Configuration").log(ERROR,ERROR_MISSING_CONFIG, field);
|
||||
return new UmbrellaException(HTTP_SERVER_ERROR, ERROR_MISSING_CONFIG, field);
|
||||
}
|
||||
|
||||
|
||||
public static UmbrellaException missingFieldException(String field){
|
||||
return new UmbrellaException(HTTP_UNPROCESSABLE, ERROR_MISSING_FIELD, field);
|
||||
}
|
||||
|
||||
public int statusCode(){
|
||||
return statusCode;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
package de.srsoftware.umbrella.core.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -31,4 +32,26 @@ public record Company(long id, String name, String address, String court, String
|
||||
throw new UmbrellaException(500,"Failed to convert JSON to Company!").causedBy(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Company of(ResultSet json) throws UmbrellaException {
|
||||
try {
|
||||
var id = json.getLong(ID);
|
||||
var name = json.getString(NAME);
|
||||
var address = json.getString(ADDRESS);
|
||||
var email = json.getString(EMAIL);
|
||||
var phone = json.getString(FIELD_PHONE);
|
||||
var bankAccount = json.getString(FIELD_BANK_ACCOUNT);
|
||||
var court = json.getString(FIELD_COURT);
|
||||
var currency = json.getString(FIELD_CURRENCY);
|
||||
var taxId = json.getString(FIELD_TAX_NUMBER);
|
||||
var decimals = json.getInt(DECIMALS);
|
||||
var decimalSep = json.getString(DECIMAL_SEPARATOR);
|
||||
var thousandsSep = json.getString(THOUSANDS_SEPARATOR);
|
||||
var lastCustomerNumber = json.getLong(LAST_CUSTOMER_NUMBER);
|
||||
var customerNumberPrefix = json.getString(CUSTOMER_NUMBER_PREFIX);
|
||||
return new Company(id,name,address,court,taxId,phone,decimalSep,thousandsSep,lastCustomerNumber,decimals,customerNumberPrefix,currency,email,bankAccount);
|
||||
} catch (SQLException e){
|
||||
throw new UmbrellaException(500,"Failed to convert ResultSet to Company!").causedBy(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@ package de.srsoftware.umbrella.core.model;
|
||||
import static de.srsoftware.tools.Optionals.allSet;
|
||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class EmailAddress {
|
||||
private final String email;
|
||||
@@ -15,6 +16,11 @@ public class EmailAddress {
|
||||
email = addr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof EmailAddress other && Objects.equals(email,other.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return email;
|
||||
|
||||
@@ -3,10 +3,10 @@ package de.srsoftware.umbrella.core.model;
|
||||
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
|
||||
import de.srsoftware.tools.Mappable;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -60,7 +60,7 @@ public class UmbrellaUser implements Mappable {
|
||||
|
||||
public static UmbrellaUser of(JSONObject json) throws UmbrellaException {
|
||||
if (json.has(USER)) json = json.getJSONObject(USER);
|
||||
if (!json.has(ID)) throw new UmbrellaException(HTTP_BAD_REQUEST,ERROR_MISSING_FIELD,ID);
|
||||
if (!json.has(ID)) throw missingFieldException(ID);
|
||||
var id = json.getLong(ID);
|
||||
var name = json.has(NAME) ? json.getString(NAME) : null;
|
||||
var email = json.has(EMAIL) ? new EmailAddress(json.getString(EMAIL)) : null;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
description = "Umbrella : Documents"
|
||||
|
||||
dependencies{
|
||||
implementation(project(":company"))
|
||||
implementation(project(":core"))
|
||||
implementation("de.srsoftware:configuration.api:1.0.2")
|
||||
implementation("de.srsoftware:tools.jdbc:1.3.2")
|
||||
implementation("de.srsoftware:tools.mime:1.1.2")
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.json:json:20240303")
|
||||
}
|
||||
@@ -14,26 +14,18 @@ public class Constants {
|
||||
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";
|
||||
public static final String DECIMAL_SEPARATOR = "decimal_separator";
|
||||
public static final String DECIMALS = "decimals";
|
||||
public static final String ERROR_ADDRESS_MISSING = "{0} address does not contain street address / post code / city";
|
||||
public static final String LAST_CUSTOMER_NUMBER = "last_customer_number";
|
||||
public static final String THOUSANDS_SEPARATOR = "thousands_separator";
|
||||
public static final String PROJECT_ID = "project_id";
|
||||
|
||||
|
||||
public static final String FIELD_AMOUNT = "amount";
|
||||
public static final String FIELD_BANK_ACCOUNT = "bank_account";
|
||||
public static final String FIELD_CODE = "code";
|
||||
public static final String FIELD_COMPANY = "company";
|
||||
public static final String FIELD_COMPANY_ID = "company_id";
|
||||
public static final String FIELD_COURT = "court";
|
||||
public static final String FIELD_CUSTOMER = "customer";
|
||||
public static final String FIELD_CUSTOMER_EMAIL = "customer_email";
|
||||
public static final String FIELD_CUSTOMER_NUMBER = "customer_number";
|
||||
public static final String FIELD_CUSTOMER_TAX_NUMBER = "customer_tax_number";
|
||||
public static final String FIELD_CURRENCY = "currency";
|
||||
public static final String FIELD_DEFAULT_HEADER = "default_header";
|
||||
public static final String FIELD_DEFAULT_FOOTER = "default_footer";
|
||||
public static final String FIELD_DEFAULT_MAIL = "type_mail_text";
|
||||
@@ -53,7 +45,6 @@ public class Constants {
|
||||
public static final String FIELD_NET_PRICE = "net_price";
|
||||
public static final String FIELD_NET_SUM = "net_sum";
|
||||
public static final String FIELD_NEXT_TYPE = "next_type_id";
|
||||
public static final String FIELD_PHONE = "phone";
|
||||
public static final String FIELD_POS = "pos";
|
||||
public static final String FIELD_POSITIONS = "positions";
|
||||
public static final String FIELD_PRICE = "single_price";
|
||||
@@ -61,7 +52,6 @@ public class Constants {
|
||||
public static final String FIELD_PROJECTS = "projects";
|
||||
public static final String FIELD_RECEIVER = "receiver";
|
||||
public static final String FIELD_START_TIME = "start_time";
|
||||
public static final String FIELD_TAX_NUMBER = "tax_number";
|
||||
public static final String FIELD_TEMPLATE_ID = "template_id";
|
||||
public static final String FIELD_TASKS = "tasks";
|
||||
public static final String FIELD_TAX = "tax";
|
||||
|
||||
@@ -3,25 +3,29 @@ 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.Constants.SENDER;
|
||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||
import static de.srsoftware.umbrella.core.Util.request;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.State.NEW;
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||
import static java.net.HttpURLConnection.*;
|
||||
|
||||
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.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.api.CompanyService;
|
||||
import de.srsoftware.umbrella.core.api.UserService;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import de.srsoftware.umbrella.documents.model.Type;
|
||||
import de.srsoftware.umbrella.documents.model.*;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -31,15 +35,17 @@ import org.json.JSONObject;
|
||||
|
||||
public class DocumentApi extends BaseHandler {
|
||||
|
||||
private final UserService users;
|
||||
private final CompanyService companies;
|
||||
private final Configuration config;
|
||||
private final DocumentDb db;
|
||||
private final UserService users;
|
||||
|
||||
public DocumentApi(UserService userHelper, Configuration config) throws UmbrellaException {
|
||||
public DocumentApi(CompanyService companyService, Configuration config) throws UmbrellaException {
|
||||
this.config = config;
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> new UmbrellaException(ERROR_MISSING_FIELD,CONFIG_DATABASE));
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
|
||||
db = new SqliteDb(connect(dbFile));
|
||||
users = userHelper;
|
||||
companies = companyService;
|
||||
users = companyService.userService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,7 +117,7 @@ public class DocumentApi extends BaseHandler {
|
||||
private boolean listDocuments(HttpExchange ex, UmbrellaUser user, Token token) throws UmbrellaException {
|
||||
try {
|
||||
var json = json(ex);
|
||||
if (!json.has(COMPANY)) throw new UmbrellaException(HTTP_BAD_REQUEST,ERROR_MISSING_FIELD, COMPANY);
|
||||
if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
|
||||
long companyId = json.getLong(COMPANY);
|
||||
var companies = getLegacyCompanies(ex,user, token);
|
||||
var company = companies.get(companyId);
|
||||
@@ -126,17 +132,34 @@ public class DocumentApi extends BaseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean postDocument(HttpExchange ex, UmbrellaUser umbrellaUser) throws IOException, UmbrellaException {
|
||||
private boolean postDocument(HttpExchange ex, UmbrellaUser user) 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());
|
||||
}
|
||||
if (!(json.has(SENDER) && json.get(SENDER) instanceof JSONObject senderData)) throw missingFieldException(SENDER);
|
||||
if (!senderData.has(FIELD_COMPANY) || !(senderData.get(FIELD_COMPANY) instanceof Number companyId)) throw missingFieldException(FIELD_COMPANY);
|
||||
|
||||
var company = companies.get(companyId.longValue());
|
||||
var members = companies.getMembers(companyId.longValue());
|
||||
var match = false;
|
||||
for (var member : members) match |= user.equals(member);
|
||||
if (!match) return sendContent(ex,HTTP_FORBIDDEN,"You are mot a member of company "+companyId);
|
||||
|
||||
if (!json.has(FIELD_CUSTOMER) || !(json.get(FIELD_CUSTOMER) instanceof JSONObject customerData)) throw missingFieldException(FIELD_CUSTOMER);
|
||||
if (!json.has(FIELD_TYPE) || !(json.get(FIELD_TYPE) instanceof Number docTypeId)) throw missingFieldException(FIELD_TYPE);
|
||||
var type = db.getType(docTypeId.intValue());
|
||||
var customer = Customer.of(customerData);
|
||||
Template template = new Template(6,companyId.longValue(),"unknwon",null);
|
||||
String currency = company.currency();
|
||||
String sep = company.decimalSeparator();
|
||||
var settings = db.getCustomerSettings(companyId.longValue(),type,customer.id());
|
||||
var companySettings = db.getCompanySettings(companyId.longValue(),type);
|
||||
var nextNumber = companySettings.nextDocId();
|
||||
String lastHead = settings.header();
|
||||
String lastFooter = settings.footer();
|
||||
var sender = Sender.of(senderData);
|
||||
LOG.log(DEBUG,json.toString(2));
|
||||
return notImplemented(ex,"{0}.postDocument(…)",this);
|
||||
var doc = new Document(0,companyId.longValue(),nextNumber,type, LocalDate.now(), NEW,template,null,lastHead,lastFooter,currency,sep,sender,customer,new PositionList());
|
||||
var saved = db.save(doc);
|
||||
db.step(companySettings);
|
||||
return sendContent(ex,saved.toMap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package de.srsoftware.umbrella.documents;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.documents.model.CompanySettings;
|
||||
import de.srsoftware.umbrella.documents.model.CustomerSettings;
|
||||
import de.srsoftware.umbrella.documents.model.Document;
|
||||
|
||||
@@ -6,6 +6,7 @@ import static de.srsoftware.tools.jdbc.Condition.equal;
|
||||
import static de.srsoftware.tools.jdbc.Condition.in;
|
||||
import static de.srsoftware.tools.jdbc.Query.*;
|
||||
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
|
||||
import static de.srsoftware.umbrella.company.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.model.Document.DEFAULT_THOUSANDS_SEPARATOR;
|
||||
@@ -16,7 +17,7 @@ import static java.time.ZoneOffset.UTC;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.tools.jdbc.Query;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.documents.model.*;
|
||||
import de.srsoftware.umbrella.documents.model.Type;
|
||||
import java.sql.Connection;
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.FIELD_TAX_ID;
|
||||
|
||||
import de.srsoftware.tools.Mappable;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -63,10 +64,10 @@ public final class Customer implements Mappable {
|
||||
}
|
||||
|
||||
public static Customer of(JSONObject json) throws UmbrellaException {
|
||||
if (!json.has(ID) || !(json.get(ID) instanceof String id)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,ID);
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,NAME);
|
||||
if (!json.has(EMAIL) || !(json.get(EMAIL) instanceof String email)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,EMAIL);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_TAX_ID);
|
||||
if (!json.has(ID) || !(json.get(ID) instanceof String id)) throw missingFieldException(ID);
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME);
|
||||
if (!json.has(EMAIL) || !(json.get(EMAIL) instanceof String email)) throw missingFieldException(EMAIL);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw missingFieldException(FIELD_TAX_ID);
|
||||
return new Customer(id,name,email,taxId);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.tools.Pair;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.documents.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
||||
import static de.srsoftware.umbrella.core.Constants.NAME;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.documents.Constants.*;
|
||||
|
||||
import de.srsoftware.tools.Mappable;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -65,10 +65,10 @@ public final class Sender implements Mappable {
|
||||
}
|
||||
|
||||
public static Sender of(JSONObject json) throws UmbrellaException {
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,NAME);
|
||||
if (!json.has(FIELD_BANK_ACCOUNT) || !(json.get(FIELD_BANK_ACCOUNT) instanceof String bankAccount)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_BANK_ACCOUNT);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_TAX_ID);
|
||||
if (!json.has(FIELD_COURT) || !(json.get(FIELD_COURT) instanceof String court)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,FIELD_COURT);
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name)) throw missingFieldException(NAME);
|
||||
if (!json.has(FIELD_BANK_ACCOUNT) || !(json.get(FIELD_BANK_ACCOUNT) instanceof String bankAccount)) throw missingFieldException(FIELD_BANK_ACCOUNT);
|
||||
if (!json.has(FIELD_TAX_ID) || !(json.get(FIELD_TAX_ID) instanceof String taxId)) throw missingFieldException(FIELD_TAX_ID);
|
||||
if (!json.has(FIELD_COURT) || !(json.get(FIELD_COURT) instanceof String court)) throw missingFieldException(FIELD_COURT);
|
||||
return new Sender(name,bankAccount,taxId,court);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
let error = null;
|
||||
let docType = $state(null);
|
||||
let document = $state({
|
||||
type : router.query.document_type,
|
||||
company : router.query.company_id,
|
||||
type : +router.query.document_type,
|
||||
customer : {
|
||||
addr : ''
|
||||
name : ''
|
||||
},
|
||||
sender : {
|
||||
name : 'sender'
|
||||
name : 'sender',
|
||||
company : +router.query.company_id
|
||||
}
|
||||
});
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
var resp = await fetch(url,{ credentials: 'include'});
|
||||
if (resp.ok){
|
||||
const companies = await resp.json();
|
||||
company = companies[document.company];
|
||||
company = companies[document.sender.company];
|
||||
document.sender.name = '';
|
||||
if (company.name) document.sender.name += company.name+"\n";
|
||||
if (company.address) document.sender.name += company.address+"\n";
|
||||
if (company.tax_number) document.sender.tax_id = company.tax_number;
|
||||
if (company.name) document.sender.name += company.name+"\n";
|
||||
if (company.address) document.sender.name += company.address+"\n";
|
||||
if (company.tax_number) document.sender.tax_id = company.tax_number;
|
||||
if (company.bank_account) document.sender.bank_account = company.bank_account;
|
||||
if (company.court) document.sender.court = company.court;
|
||||
if (company.court) document.sender.court = company.court;
|
||||
} else {
|
||||
error = await resp.text();
|
||||
}
|
||||
@@ -59,13 +59,13 @@
|
||||
var name = (contact.N.given+" "+contact.N.family).trim()+"\n";
|
||||
if (name != addr) addr += name;
|
||||
}
|
||||
if (contact.ADR.street) addr += contact.ADR.street+"\n";
|
||||
if (contact.ADR.street) addr += contact.ADR.street+"\n";
|
||||
if (contact.ADR.locality) addr += contact.ADR.post_code + " "+ contact.ADR.locality + "\n";
|
||||
if (contact.ADR.county) addr += contact.ADR.country+"\n";
|
||||
document.customer.addr = addr;
|
||||
document.customer.tax_number = contact['X-TAX-NUMBER'];
|
||||
document.customer.id = contact['X-CUSTOMER-NUMBER'];
|
||||
document.customer.email = contact.EMAIL.val;
|
||||
if (contact.ADR.county) addr += contact.ADR.country+"\n";
|
||||
document.customer.name = addr;
|
||||
document.customer.tax_id = contact['X-TAX-NUMBER'];
|
||||
document.customer.id = contact['X-CUSTOMER-NUMBER'];
|
||||
document.customer.email = contact.EMAIL.val;
|
||||
}
|
||||
|
||||
async function submit(){
|
||||
@@ -76,6 +76,8 @@
|
||||
body: JSON.stringify(document)
|
||||
});
|
||||
if (resp.ok){
|
||||
const json = await resp.json();
|
||||
router.navigate(`/document/${json.id}/view`);
|
||||
} else {
|
||||
error = await resp.text();
|
||||
}
|
||||
@@ -101,12 +103,12 @@
|
||||
<legend>{t('document.customer')}</legend>
|
||||
<ContactSelector caption={t('document.select_customer')} onselect={contactSelected} />
|
||||
<label>
|
||||
<textarea bind:value={document.customer.addr}></textarea>
|
||||
<textarea bind:value={document.customer.name}></textarea>
|
||||
{t('document.customer_address')}
|
||||
</label>
|
||||
<label>
|
||||
<input bind:value={document.customer.tax_number} />
|
||||
{t('document.tax_number')}
|
||||
<input bind:value={document.customer.tax_id} />
|
||||
{t('document.tax_id')}
|
||||
</label>
|
||||
<label>
|
||||
<input bind:value={document.customer.id} />
|
||||
|
||||
@@ -9,6 +9,5 @@ dependencies{
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.bitbucket.b_c:jose4j:0.9.6")
|
||||
implementation("org.json:json:20240303")
|
||||
implementation("org.xerial:sqlite-jdbc:3.49.0.0")
|
||||
}
|
||||
@@ -19,7 +19,7 @@ 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.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Session;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
|
||||
@@ -9,6 +9,5 @@ dependencies{
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.bitbucket.b_c:jose4j:0.9.6")
|
||||
implementation("org.json:json:20240303")
|
||||
implementation("org.xerial:sqlite-jdbc:3.49.0.0")
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.message;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import de.srsoftware.umbrella.message.model.Settings;
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@ 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.core.exceptions.UmbrellaException.missingConfigException;
|
||||
import static de.srsoftware.umbrella.message.Constants.*;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
import de.srsoftware.configuration.Configuration;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.api.Translator;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import de.srsoftware.umbrella.message.model.CombinedMessage;
|
||||
import de.srsoftware.umbrella.message.model.Envelope;
|
||||
@@ -70,7 +71,7 @@ public class MessageSystem implements PostBox {
|
||||
private final Translator translator;
|
||||
|
||||
public MessageSystem(Translator translator, Configuration config) throws UmbrellaException {
|
||||
var messageDbFile = config.get(CONFIG_DB).orElseThrow(() -> new UmbrellaException(500,ERROR_MISSING_CONFIG,CONFIG_DB));
|
||||
var messageDbFile = config.get(CONFIG_DB).orElseThrow(() -> missingConfigException(CONFIG_DB));
|
||||
db = new SqliteMessageDb(connect(messageDbFile));
|
||||
|
||||
this.translator = translator;
|
||||
|
||||
@@ -9,7 +9,7 @@ import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import de.srsoftware.umbrella.message.model.Settings;
|
||||
import java.sql.Connection;
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
package de.srsoftware.umbrella.message.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
@@ -16,11 +18,11 @@ public record Attachment(String name, String mime, byte[] content) {
|
||||
|
||||
public static <T> Attachment of(JSONObject json) throws UmbrellaException {
|
||||
for (var key : Set.of(NAME, MIME, DATA)) {
|
||||
if (!json.has(key)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,key);
|
||||
if (!json.has(key)) throw missingFieldException(key);
|
||||
}
|
||||
if (!(json.get(NAME) instanceof String name)) throw new UmbrellaException(400,ERROR_INVALID_FIELD, NAME,STRING);
|
||||
if (!(json.get(MIME) instanceof String mime)) throw new UmbrellaException(400,ERROR_INVALID_FIELD, MIME,STRING);
|
||||
if (!(json.get(DATA) instanceof String data)) throw new UmbrellaException(400,ERROR_INVALID_FIELD, DATA,STRING);
|
||||
if (!(json.get(NAME) instanceof String name)) throw invalidFieldException(NAME,STRING);
|
||||
if (!(json.get(MIME) instanceof String mime)) throw invalidFieldException(MIME,STRING);
|
||||
if (!(json.get(DATA) instanceof String data)) throw invalidFieldException(DATA,STRING);
|
||||
return new Attachment(name,mime, BASE64.decode(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.message.model;
|
||||
|
||||
import static de.srsoftware.umbrella.core.Constants.ERROR_INVALID_FIELD;
|
||||
import static de.srsoftware.umbrella.core.Constants.ERROR_MISSING_FIELD;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.message.Constants.*;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.EmailAddress;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import java.util.HashSet;
|
||||
@@ -36,14 +36,14 @@ public class Envelope {
|
||||
* @throws UmbrellaException
|
||||
*/
|
||||
public static Envelope from(JSONObject json) throws UmbrellaException {
|
||||
if (!json.has(RECEIVERS)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,RECEIVERS);
|
||||
if (!json.has(RECEIVERS)) throw missingFieldException(RECEIVERS);
|
||||
var message = Message.from(json);
|
||||
var obj = json.get(RECEIVERS);
|
||||
if (obj instanceof JSONObject) obj = new JSONArray(List.of(obj));
|
||||
if (!(obj instanceof JSONArray receiverList)) throw new UmbrellaException(400,ERROR_INVALID_FIELD,RECEIVERS,JSONARRAY);
|
||||
if (!(obj instanceof JSONArray receiverList)) throw invalidFieldException(RECEIVERS,JSONARRAY);
|
||||
var receivers = new HashSet<UmbrellaUser>();
|
||||
for (var o : receiverList){
|
||||
if (!(o instanceof JSONObject receiverData)) throw new UmbrellaException(400,ERROR_INVALID_FIELD,"entries of "+RECEIVERS,JSONOBJECT);
|
||||
if (!(o instanceof JSONObject receiverData)) throw invalidFieldException("entries of "+RECEIVERS,JSONOBJECT);
|
||||
receivers.add(UmbrellaUser.of(receiverData));
|
||||
}
|
||||
return new Envelope(message,receivers);
|
||||
|
||||
@@ -3,10 +3,12 @@ package de.srsoftware.umbrella.message.model;
|
||||
|
||||
import static de.srsoftware.tools.Optionals.isSet;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.message.Constants.*;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import java.util.*;
|
||||
import org.json.JSONArray;
|
||||
@@ -15,11 +17,11 @@ import org.json.JSONObject;
|
||||
public record Message(UmbrellaUser sender, String subject, String body, Map<String,String> fills, List<Attachment> attachments) {
|
||||
public static Message from(JSONObject json) throws UmbrellaException {
|
||||
for (var key : Set.of(SENDER, SUBJECT, BODY)) {
|
||||
if (!json.has(key)) throw new UmbrellaException(400,ERROR_MISSING_FIELD,key);
|
||||
if (!json.has(key)) throw missingFieldException(key);
|
||||
}
|
||||
if (!(json.get(SENDER) instanceof JSONObject senderObject)) throw new UmbrellaException(400,ERROR_INVALID_FIELD, SENDER,JSONOBJECT);
|
||||
if (!(json.get(SUBJECT) instanceof String subject && isSet(subject))) throw new UmbrellaException(400,ERROR_INVALID_FIELD, SUBJECT,STRING);
|
||||
if (!(json.get(BODY) instanceof String body && isSet(body))) throw new UmbrellaException(400,ERROR_INVALID_FIELD, BODY,STRING);
|
||||
if (!(json.get(SENDER) instanceof JSONObject senderObject)) throw invalidFieldException(SENDER,JSONOBJECT);
|
||||
if (!(json.get(SUBJECT) instanceof String subject && isSet(subject))) throw invalidFieldException(SUBJECT,STRING);
|
||||
if (!(json.get(BODY) instanceof String body && isSet(body))) throw invalidFieldException(BODY,STRING);
|
||||
|
||||
var user = UmbrellaUser.of(senderObject);
|
||||
if (!(user instanceof UmbrellaUser sender)) throw new UmbrellaException(400,"Sender is not an umbrella user!");
|
||||
|
||||
@@ -2,5 +2,4 @@ description = "Umbrella : Translations"
|
||||
|
||||
dependencies{
|
||||
implementation(project(":core"))
|
||||
implementation("org.json:json:20240303")
|
||||
}
|
||||
@@ -9,6 +9,5 @@ dependencies{
|
||||
implementation("de.srsoftware:tools.optionals:1.0.0")
|
||||
implementation("de.srsoftware:tools.util:2.0.3")
|
||||
implementation("org.bitbucket.b_c:jose4j:0.9.6")
|
||||
implementation("org.json:json:20240303")
|
||||
implementation("org.xerial:sqlite-jdbc:3.49.0.0")
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import static de.srsoftware.umbrella.core.ResponseCode.*;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
|
||||
import static de.srsoftware.umbrella.core.Util.open;
|
||||
import static de.srsoftware.umbrella.core.Util.request;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingConfigException;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
|
||||
import static de.srsoftware.umbrella.user.Constants.*;
|
||||
import static de.srsoftware.umbrella.user.Paths.*;
|
||||
import static de.srsoftware.umbrella.user.Paths.IMPERSONATE;
|
||||
@@ -29,8 +31,8 @@ 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.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.api.UserService;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.EmailAddress;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
@@ -84,7 +86,7 @@ public class UserModule extends BaseHandler implements UserService {
|
||||
}
|
||||
|
||||
public UserModule(Configuration config, MessageSystem messageSystem) throws UmbrellaException {
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> new UmbrellaException(ERROR_MISSING_CONFIG,CONFIG_DATABASE));
|
||||
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingConfigException(CONFIG_DATABASE));
|
||||
// may be splitted in separate db files later
|
||||
logins = new SqliteDB(connect(dbFile));
|
||||
messages = messageSystem;
|
||||
@@ -97,11 +99,15 @@ public class UserModule extends BaseHandler implements UserService {
|
||||
|
||||
private boolean deleteOIDC(HttpExchange ex, UmbrellaUser user, Path path) throws IOException {
|
||||
var head = path.pop();
|
||||
return switch (head){
|
||||
case CONNECTED -> deleteServiceConnection(ex,user);
|
||||
case null -> super.doGet(path,ex);
|
||||
default -> deleteService(ex,user,head);
|
||||
};
|
||||
try {
|
||||
return switch (head) {
|
||||
case CONNECTED -> deleteServiceConnection(ex, user);
|
||||
case null -> super.doGet(path, ex);
|
||||
default -> deleteService(ex, user, head);
|
||||
};
|
||||
} catch (UmbrellaException e) {
|
||||
return send(ex,e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean deleteService(HttpExchange ex, UmbrellaUser user, String serviceName) throws IOException {
|
||||
@@ -114,7 +120,7 @@ public class UserModule extends BaseHandler implements UserService {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean deleteServiceConnection(HttpExchange ex, UmbrellaUser user) throws IOException {
|
||||
private boolean deleteServiceConnection(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
|
||||
if (user == null) return sendContent(ex,HTTP_SERVER_ERROR,"Expected user object to be of type DbUser");
|
||||
JSONObject json;
|
||||
try {
|
||||
@@ -123,8 +129,8 @@ public class UserModule extends BaseHandler implements UserService {
|
||||
LOG.log(WARNING,"Request does not contain valid JSON",e);
|
||||
return sendContent(ex,HTTP_FAILED_DEPENDENCY,"Request does not contain valid JSON");
|
||||
}
|
||||
if (!(json.has(FOREIGN_ID) && json.get(FOREIGN_ID) instanceof String foreignId && !foreignId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,FOREIGN_ID));
|
||||
if (!(json.has(SERVICE_ID) && json.get(SERVICE_ID) instanceof String serviceId && !serviceId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,SERVICE_ID));
|
||||
if (!(json.has(FOREIGN_ID) && json.get(FOREIGN_ID) instanceof String foreignId && !foreignId.isBlank())) throw missingFieldException(FOREIGN_ID);
|
||||
if (!(json.has(SERVICE_ID) && json.get(SERVICE_ID) instanceof String serviceId && !serviceId.isBlank())) throw missingFieldException(SERVICE_ID);
|
||||
|
||||
|
||||
try {
|
||||
@@ -501,10 +507,10 @@ public class UserModule extends BaseHandler implements UserService {
|
||||
if (!(requestingUser instanceof DbUser user && user.permissions().contains(MANAGE_LOGIN_SERVICES))) return forbidden(ex);
|
||||
try {
|
||||
var json = json(ex);
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name) || name.isBlank()) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,NAME));
|
||||
if (!json.has(URL) || !(json.get(URL) instanceof String url) || url.isBlank()) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,URL));
|
||||
if (!json.has(CLIENT_ID) || !(json.get(CLIENT_ID) instanceof String clientId) || clientId.isBlank()) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,CLIENT_ID));
|
||||
if (!json.has(CLIENT_SECRET) || !(json.get(CLIENT_SECRET) instanceof String secret) || secret.isBlank()) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,CLIENT_SECRET));
|
||||
if (!json.has(NAME) || !(json.get(NAME) instanceof String name) || name.isBlank()) throw missingFieldException(NAME);
|
||||
if (!json.has(URL) || !(json.get(URL) instanceof String url) || url.isBlank()) throw missingFieldException(URL);
|
||||
if (!json.has(CLIENT_ID) || !(json.get(CLIENT_ID) instanceof String clientId) || clientId.isBlank()) throw missingFieldException(CLIENT_ID);
|
||||
if (!json.has(CLIENT_SECRET) || !(json.get(CLIENT_SECRET) instanceof String secret) || secret.isBlank()) throw missingFieldException(CLIENT_SECRET);
|
||||
var service = logins.save(new LoginService(name,url,clientId,secret, DEFAULT_FIELD));
|
||||
return sendContent(ex,service.toMap());
|
||||
} catch (UmbrellaException e) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.user.api;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.user.model.ForeignLogin;
|
||||
import de.srsoftware.umbrella.user.model.LoginService;
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.user.api;
|
||||
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.EmailAddress;
|
||||
import de.srsoftware.umbrella.core.model.Session;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
|
||||
@@ -12,7 +12,7 @@ import static java.text.MessageFormat.format;
|
||||
|
||||
import de.srsoftware.tools.PasswordHasher;
|
||||
import de.srsoftware.tools.jdbc.Query;
|
||||
import de.srsoftware.umbrella.core.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.EmailAddress;
|
||||
import de.srsoftware.umbrella.core.model.Session;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
|
||||
Reference in New Issue
Block a user