Browse Source

conveniance modification: added registry and getters for modules to BaseHandler

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
feature/brute_force_protection
Stephan Richter 3 months ago
parent
commit
a50a451b95
  1. 2
      backend/src/main/java/de/srsoftware/umbrella/backend/Application.java
  2. 11
      bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkApi.java
  3. 21
      company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java
  4. 47
      core/src/main/java/de/srsoftware/umbrella/core/BaseHandler.java
  5. 97
      core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java
  6. 35
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  7. 9
      items/src/main/java/de/srsoftware/umbrella/items/ItemApi.java
  8. 7
      legacy/src/main/java/de/srsoftware/umbrella/legacy/CompanyLegacy.java
  9. 9
      legacy/src/main/java/de/srsoftware/umbrella/legacy/NotesLegacy.java
  10. 7
      legacy/src/main/java/de/srsoftware/umbrella/legacy/ProjectLegacy.java
  11. 72
      legacy/src/main/java/de/srsoftware/umbrella/legacy/TaskLegacy.java
  12. 17
      legacy/src/main/java/de/srsoftware/umbrella/legacy/UserLegacy.java
  13. 5
      markdown/src/main/java/de/srsoftware/umbrella/markdown/MarkdownApi.java
  14. 14
      messages/src/main/java/de/srsoftware/umbrella/message/MessageApi.java
  15. 13
      notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java
  16. 25
      project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java
  17. 9
      tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java
  18. 37
      task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java
  19. 11
      time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java
  20. 5
      user/src/main/java/de/srsoftware/umbrella/user/UserModule.java
  21. 5
      web/src/main/java/de/srsoftware/umbrella/web/WebHandler.java

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

@ -80,7 +80,7 @@ public class Application { @@ -80,7 +80,7 @@ public class Application {
new ProjectLegacy(registry,config).bindPath("/legacy/project").on(server);
new TaskModule(registry, config).bindPath("/api/task").on(server);
new TimeModule(registry, config).bindPath("/api/times").on(server);
new WebHandler().bindPath("/").on(server);
new WebHandler(registry).bindPath("/").on(server);
server.setExecutor(Executors.newFixedThreadPool(threads));
server.start();

11
bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkApi.java

@ -26,12 +26,11 @@ import org.json.JSONArray; @@ -26,12 +26,11 @@ import org.json.JSONArray;
public class BookmarkApi extends BaseHandler implements BookmarkService {
private final BookmarkDb db;
private final ModuleRegistry registry;
public BookmarkApi(ModuleRegistry registry, Configuration config) {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
db = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
@Override
@ -39,7 +38,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService { @@ -39,7 +38,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -59,7 +58,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService { @@ -59,7 +58,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
private boolean getBookmark(UmbrellaUser user, long id, HttpExchange ex) throws IOException {
var bookmark = db.load(id,user.id());
registry.tagService().getTags(BOOKMARK, id, user).forEach(bookmark.tags()::add);
tagService().getTags(BOOKMARK, id, user).forEach(bookmark.tags()::add);
return sendContent(ex,bookmark);
}
@ -68,7 +67,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService { @@ -68,7 +67,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -115,7 +114,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService { @@ -115,7 +114,7 @@ public class BookmarkApi extends BaseHandler implements BookmarkService {
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray tagList){
var list = tagList.toList().stream().map(Object::toString).toList();
registry.tagService().save(BOOKMARK,bookmark.urlId(), userList, list);
tagService().save(BOOKMARK,bookmark.urlId(), userList, list);
}
return sendContent(ex,bookmark);
}

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

@ -24,20 +24,19 @@ import java.util.*; @@ -24,20 +24,19 @@ import java.util.*;
public class CompanyModule extends BaseHandler implements CompanyService {
private final CompanyDb companyDb;
private final ModuleRegistry registry;
public CompanyModule(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
companyDb = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
private boolean deleteCompany(long companyId, UmbrellaUser user, HttpExchange ex) throws IOException {
var company = get(companyId);
if (!membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
if (!registry.documentService().list(companyId).isEmpty()) throw forbidden("There are documents owned by {0}",company.name());
if (!registry.itemService().list(companyId).isEmpty()) throw forbidden("There are items owned by {0}",company.name());
if (!registry.projectService().listCompanyProjects(companyId,true).isEmpty()) throw forbidden("There are projects owned by {0}",company.name());
if (!documentService().list(companyId).isEmpty()) throw forbidden("There are documents owned by {0}",company.name());
if (!itemService().list(companyId).isEmpty()) throw forbidden("There are items owned by {0}",company.name());
if (!projectService().listCompanyProjects(companyId,true).isEmpty()) throw forbidden("There are projects owned by {0}",company.name());
return sendContent(ex, companyDb.drop(companyId));
}
@ -46,7 +45,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -46,7 +45,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -65,7 +64,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -65,7 +64,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head){
@ -83,7 +82,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -83,7 +82,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -102,7 +101,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -102,7 +101,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -130,7 +129,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -130,7 +129,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
@Override
public Collection<UmbrellaUser> getMembers(long companyId) throws UmbrellaException {
var members = new HashSet<UmbrellaUser>();
for (var userId : companyDb.getMembers(companyId)) members.add(registry.userService().loadUser(userId));
for (var userId : companyDb.getMembers(companyId)) members.add(userService().loadUser(userId));
return members;
}
@ -148,7 +147,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { @@ -148,7 +147,7 @@ public class CompanyModule extends BaseHandler implements CompanyService {
var userMap = new HashMap<Long,UmbrellaUser>();
for (var company : companyList){
for (var userId : companyDb.getMembers(company.id())){
var user = userMap.computeIfAbsent(userId,k -> registry.userService().loadUser(userId));
var user = userMap.computeIfAbsent(userId,k -> userService().loadUser(userId));
company.members().put(userId,user);
}
}

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

@ -9,6 +9,7 @@ import static java.net.HttpURLConnection.*; @@ -9,6 +9,7 @@ import static java.net.HttpURLConnection.*;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.PathHandler;
import de.srsoftware.umbrella.core.api.*;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -16,8 +17,14 @@ import java.util.List; @@ -16,8 +17,14 @@ import java.util.List;
public abstract class BaseHandler extends PathHandler {
private final ModuleRegistry registry;
public record Page(String mime, byte[] bytes){}
public BaseHandler(ModuleRegistry registry){
this.registry = registry.add(this);
}
public HttpExchange addCors(HttpExchange ex){
var headers = ex.getRequestHeaders();
var origin = nullable(headers.get("Origin")).orElse(List.of()).stream().filter(url -> url.contains("://localhost")||url.contains("://127.0.0.1")).findAny();
@ -34,11 +41,23 @@ public abstract class BaseHandler extends PathHandler { @@ -34,11 +41,23 @@ public abstract class BaseHandler extends PathHandler {
return ex;
}
public CompanyService companyService(){
return registry.companyService();
}
public DocumentService documentService(){
return registry.documentService();
}
@Override
public boolean doOptions(Path path, HttpExchange ex) throws IOException {
return ok(addCors(ex));
}
public ItemService itemService(){
return registry.itemService();
}
public boolean load(Path path, HttpExchange ex) throws IOException {
try {
var doc = load(path.toString());
@ -65,17 +84,43 @@ public abstract class BaseHandler extends PathHandler { @@ -65,17 +84,43 @@ public abstract class BaseHandler extends PathHandler {
}
}
public NoteService noteService(){
return registry.noteService();
}
public boolean ok(HttpExchange ex) throws IOException {
return sendEmptyResponse(HTTP_OK,ex);
}
public PostBox postBox() {
return registry.postBox();
}
public ProjectService projectService(){
return registry.projectService();
}
public boolean send(HttpExchange ex, UmbrellaException e) throws IOException {
return sendContent(ex,e.statusCode(),e.getMessage());
}
public TagService tagService(){
return registry.tagService();
}
public TaskService taskService(){
return registry.taskService();
}
public Translator translator(){
return registry.translator();
}
public boolean unauthorized(HttpExchange ex) throws IOException {
return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
}
public UserService userService(){
return registry.userService();
}
}

97
core/src/main/java/de/srsoftware/umbrella/core/ModuleRegistry.java

@ -1,86 +1,47 @@ @@ -1,86 +1,47 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core;
import static java.text.MessageFormat.format;
import de.srsoftware.umbrella.core.api.*;
public class ModuleRegistry {
private Translator translator;
private PostBox postBox;
private UserService userService;
private TagService tagService;
private BookmarkService bookmarkService;
private CompanyService companyService;
private DocumentService documentService;
private ItemService itemService;
private MarkdownService markdownService;
private NoteService noteService;
private PostBox postBox;
private ProjectService projectService;
private TagService tagService;
private TaskService taskService;
private TimeService timeService;
private Translator translator;
private UserService userService;
public ModuleRegistry add(BookmarkService bookmarkService) {
this.bookmarkService = bookmarkService;
return this;
}
public ModuleRegistry add(CompanyService companyService) {
this.companyService = companyService;
return this;
}
public ModuleRegistry add(DocumentService documentService) {
this.documentService = documentService;
return this;
}
public ModuleRegistry add(ItemService itemService) {
this.itemService = itemService;
return this;
}
public ModuleRegistry add(MarkdownService markdownService) {
this.markdownService = markdownService;
return this;
}
public ModuleRegistry add(NoteService noteService) {
this.noteService = noteService;
return this;
}
public ModuleRegistry add(PostBox postBox) {
this.postBox = postBox;
return this;
}
public ModuleRegistry add(ProjectService projectService) {
this.projectService = projectService;
return this;
}
public ModuleRegistry add(TagService tagService) {
this.tagService = tagService;
return this;
}
public ModuleRegistry add(TaskService taskService) {
this.taskService = taskService;
return this;
}
public ModuleRegistry add(TimeService timeService) {
this.timeService = timeService;
public ModuleRegistry add(Object service) {
switch (service) {
case BookmarkService bs: bookmarkService = bs; break;
case CompanyService cs: companyService = cs; break;
case DocumentService ds: documentService = ds; break;
case ItemService is: itemService = is; break;
case MarkdownService ms: markdownService = ms; break;
case NoteService ns: noteService = ns; break;
case PostBox pb: postBox = pb; break;
case ProjectService ps: projectService = ps; break;
case TagService ts: tagService = ts; break;
case TaskService ts: taskService = ts; break;
case TimeService ts: timeService = ts; break;
case Translator tr: translator = tr; break;
case UserService us: userService = us; break;
default: throw new RuntimeException(format("Trying to add unknown service ({0}) to {1}",service.getClass().getSimpleName(),getClass().getSimpleName()));
}
return this;
}
public ModuleRegistry add(Translator translator) {
this.translator = translator;
return this;
}
public ModuleRegistry add(UserService userService) {
this.userService = userService;
return this;
public BookmarkService bookmarkService(){
return bookmarkService;
}
public CompanyService companyService(){
@ -95,6 +56,10 @@ public class ModuleRegistry { @@ -95,6 +56,10 @@ public class ModuleRegistry {
return itemService;
}
public MarkdownService markdownService(){
return markdownService;
}
public NoteService noteService(){
return noteService;
}
@ -115,6 +80,10 @@ public class ModuleRegistry { @@ -115,6 +80,10 @@ public class ModuleRegistry {
return taskService;
}
public TimeService timeService(){
return timeService;
}
public Translator translator(){
return translator;
}

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

@ -74,13 +74,12 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -74,13 +74,12 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private final Configuration config;
private final DocumentDb db;
private final ModuleRegistry modules;
public DocumentApi(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
this.config = config;
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
db = new SqliteDb(connect(dbFile));
modules = registry.add(this);
Optional<String> templates = config.get(CONFIG_TEMPLATES);
if (templates.isEmpty()) throw missingFieldException(CONFIG_TEMPLATES);
@ -95,7 +94,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -95,7 +94,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = modules.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
long docId = Long.parseLong(head);
@ -114,7 +113,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -114,7 +113,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private boolean deleteDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (doc.state() != NEW) throw new UmbrellaException(HTTP_BAD_REQUEST,"This document has already been sent");
return sendContent(ex,db.deleteDoc(docId));
}
@ -122,7 +121,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -122,7 +121,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private boolean deletePosition(HttpExchange ex, long docId, UmbrellaUser user) throws UmbrellaException, IOException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (doc.state() != NEW) throw new UmbrellaException(HTTP_BAD_REQUEST,"This document has already been sent");
var json = json(ex);
if (!(json.has(POSITION) && json.get(POSITION) instanceof Number number)) throw missingFieldException(POSITION);
@ -135,7 +134,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -135,7 +134,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = modules.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head){
@ -166,7 +165,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -166,7 +165,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = modules.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
var docId = Long.parseLong(head);
@ -188,7 +187,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -188,7 +187,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = modules.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head){
@ -220,7 +219,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -220,7 +219,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
var attachment = new Attachment(doc.number()+".pdf",rendered.mimeType(),rendered.bytes());
var message = new Message(user,subject,content,null,List.of(attachment));
var envelope = new Envelope(message,new User(doc.customer().shortName(),new EmailAddress(email),doc.customer().language()));
modules.postBox().send(envelope);
postBox().send(envelope);
db.save(doc.set(SENT));
return ok(ex);
}
@ -245,8 +244,8 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -245,8 +244,8 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private Tuple<Document,Company> getDocument(long docId, UmbrellaUser user) throws UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
var company = modules.companyService().get(companyId);
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
return Tuple.of(doc,company);
}
@ -365,7 +364,7 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -365,7 +364,7 @@ public class DocumentApi extends BaseHandler implements DocumentService {
.filter(filter)
.findAny();
if (optDoc.isEmpty()) throw UmbrellaException.notFound("Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template);
Function<String,String> translate = text -> modules.translator().translate(user.language(),text);
Function<String,String> translate = text -> translator().translate(user.language(),text);
var pdfData = new HashMap<String,Object>();
pdfData.put(FIELD_DOCUMENT,document.renderToMap());
pdfData.put("translate",translate);
@ -419,8 +418,8 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -419,8 +418,8 @@ public class DocumentApi extends BaseHandler implements DocumentService {
var json = json(ex);
if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
long companyId = json.getLong(COMPANY);
var company = modules.companyService().get(companyId);
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company);
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company);
var docs = list(companyId);
var map = new HashMap<Long,Object>();
for (var entry : docs.entrySet()) map.put(entry.getKey(),entry.getValue().summary());
@ -466,8 +465,8 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -466,8 +465,8 @@ public class DocumentApi extends BaseHandler implements DocumentService {
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 = modules.companyService().get(companyId.longValue());
if (!modules.companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company);
var company = companyService().get(companyId.longValue());
if (!companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company);
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);
@ -513,8 +512,8 @@ public class DocumentApi extends BaseHandler implements DocumentService { @@ -513,8 +512,8 @@ public class DocumentApi extends BaseHandler implements DocumentService {
private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException {
var json = json(ex);
if (!(json.has(COMPANY) && json.get(COMPANY) instanceof Number companyId)) throw missingFieldException(COMPANY);
var company = modules.companyService().get(companyId.longValue());
if (!modules.companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are not a member of {0}",company.name());
var company = companyService().get(companyId.longValue());
if (!companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are not a member of {0}",company.name());
var templates = db.getCompanyTemplates(companyId.longValue());
return sendContent(ex,templates.stream().map(Template::toMap));
}

9
items/src/main/java/de/srsoftware/umbrella/items/ItemApi.java

@ -27,12 +27,11 @@ import java.util.Optional; @@ -27,12 +27,11 @@ import java.util.Optional;
public class ItemApi extends BaseHandler implements ItemService {
private final ItemDb itemDb;
private final ModuleRegistry registry;
public ItemApi(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
itemDb = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
@Override
@ -40,7 +39,7 @@ public class ItemApi extends BaseHandler implements ItemService { @@ -40,7 +39,7 @@ public class ItemApi extends BaseHandler implements ItemService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -61,8 +60,8 @@ public class ItemApi extends BaseHandler implements ItemService { @@ -61,8 +60,8 @@ public class ItemApi extends BaseHandler implements ItemService {
var json = json(ex);
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
var companyId = cid.longValue();
var company = registry.companyService().get(companyId);
if (!registry.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var items = list(companyId)
.stream()
.map(Item::toMap)

7
legacy/src/main/java/de/srsoftware/umbrella/legacy/CompanyLegacy.java

@ -20,11 +20,10 @@ import java.util.Map; @@ -20,11 +20,10 @@ import java.util.Map;
import java.util.Optional;
public class CompanyLegacy extends BaseHandler {
private final ModuleRegistry registry;
private final Configuration config;
public CompanyLegacy(ModuleRegistry registry, Configuration config) {
this.registry = registry;
super(registry);
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
}
@ -55,7 +54,7 @@ public class CompanyLegacy extends BaseHandler { @@ -55,7 +54,7 @@ public class CompanyLegacy extends BaseHandler {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
if (token.isEmpty()) token = nullable(params.get(TOKEN)).map(Object::toString).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
return switch (path.pop()){
@ -65,7 +64,7 @@ public class CompanyLegacy extends BaseHandler { @@ -65,7 +64,7 @@ public class CompanyLegacy extends BaseHandler {
}
private boolean postCompanyJson(HttpExchange ex, Map<String, Object> params, UmbrellaUser user) throws IOException {
var companies = registry.companyService().listCompaniesOf(user);
var companies = companyService().listCompaniesOf(user);
return sendContent(ex, mapValues(companies));
}

9
legacy/src/main/java/de/srsoftware/umbrella/legacy/NotesLegacy.java

@ -24,11 +24,10 @@ import java.util.Map; @@ -24,11 +24,10 @@ import java.util.Map;
import java.util.Optional;
public class NotesLegacy extends BaseHandler {
private final ModuleRegistry registry;
private final Configuration config;
public NotesLegacy(ModuleRegistry registry, Configuration config) {
this.registry = registry;
super(registry);
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
}
@ -59,7 +58,7 @@ public class NotesLegacy extends BaseHandler { @@ -59,7 +58,7 @@ public class NotesLegacy extends BaseHandler {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
if (token.isEmpty()) token = nullable(params.get(TOKEN)).map(Object::toString).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
return switch (path.pop()){
@ -74,9 +73,9 @@ public class NotesLegacy extends BaseHandler { @@ -74,9 +73,9 @@ public class NotesLegacy extends BaseHandler {
if (parts.length<2) throw invalidFieldException(URI,"URI of the form \"module:entry-id\"");
var module = parts[0];
var entryId = parts[1];
var notes = registry.noteService().getNotes(module,entryId);
var notes = noteService().getNotes(module,entryId);
var authors = new HashMap<Long, UmbrellaUser> ();
var users = registry.userService();
var users = userService();
for (var note : notes.values()) {
var userId = note.authorId();
authors.computeIfAbsent(userId,k -> users.loadUser(userId));

7
legacy/src/main/java/de/srsoftware/umbrella/legacy/ProjectLegacy.java

@ -20,11 +20,10 @@ import java.util.Map; @@ -20,11 +20,10 @@ import java.util.Map;
import java.util.Optional;
public class ProjectLegacy extends BaseHandler {
private final ModuleRegistry registry;
private final Configuration config;
public ProjectLegacy(ModuleRegistry registry, Configuration config) {
this.registry = registry;
super(registry);
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
}
@ -55,7 +54,7 @@ public class ProjectLegacy extends BaseHandler { @@ -55,7 +54,7 @@ public class ProjectLegacy extends BaseHandler {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
if (token.isEmpty()) token = nullable(params.get(TOKEN)).map(Object::toString).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
return switch (path.pop()){
@ -66,7 +65,7 @@ public class ProjectLegacy extends BaseHandler { @@ -66,7 +65,7 @@ public class ProjectLegacy extends BaseHandler {
private boolean postProjectJson(HttpExchange ex, Map<String, Object> params, UmbrellaUser user) throws IOException {
var includeUsers = "1".equals(params.get(USERS));
var projects = registry.projectService().listUserProjects(user.id(), false);
var projects = projectService().listUserProjects(user.id(), false);
return sendContent(ex, mapValues(projects));
}
}

72
legacy/src/main/java/de/srsoftware/umbrella/legacy/TaskLegacy.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.legacy;
import static de.srsoftware.tools.Optionals.nullable;
import static de.srsoftware.umbrella.core.Constants.TOKEN;
import static de.srsoftware.umbrella.core.Constants.USERS;
import static de.srsoftware.umbrella.core.Paths.JSON;
import static de.srsoftware.umbrella.core.Util.mapValues;
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.ModuleRegistry;
import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
public class TaskLegacy extends BaseHandler {
private final Configuration config;
public TaskLegacy(ModuleRegistry registry, Configuration config) {
super(registry);
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
}
@Override
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
return super.doDelete(path, ex);
}
@Override
public boolean doGet(Path path, HttpExchange ex) throws IOException {
if (path.empty()) return sendRedirect(ex, url(ex).replaceAll("/legacy/","/"));
return super.doGet(path, ex);
}
@Override
public boolean doOptions(Path path, HttpExchange ex) throws IOException {
return super.doOptions(path, ex);
}
@Override
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
return super.doPatch(path, ex);
}
@Override
public boolean doPost(Path path, HttpExchange ex) throws IOException{
var params = formData(ex);
Optional<Token> token = SessionToken.from(ex).map(Token::of);
if (token.isEmpty()) token = nullable(params.get(TOKEN)).map(Object::toString).map(Token::of);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
return switch (path.pop()){
case JSON -> postProjectJson(ex,params,user.get());
default -> super.doPost(path, ex);
};
}
private boolean postProjectJson(HttpExchange ex, Map<String, Object> params, UmbrellaUser user) throws IOException {
var includeUsers = "1".equals(params.get(USERS));
var projects = projectService().listUserProjects(user.id(), false);
return sendContent(ex, mapValues(projects));
}
}

17
legacy/src/main/java/de/srsoftware/umbrella/legacy/UserLegacy.java

@ -33,10 +33,9 @@ public class UserLegacy extends BaseHandler { @@ -33,10 +33,9 @@ public class UserLegacy extends BaseHandler {
private final Configuration config;
private final String messageUrl;
private final ModuleRegistry registry;
public UserLegacy(ModuleRegistry registry, Configuration config) {
this.registry = registry;
super(registry);
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
this.messageUrl = null;
}
@ -128,7 +127,7 @@ public class UserLegacy extends BaseHandler { @@ -128,7 +127,7 @@ public class UserLegacy extends BaseHandler {
throw new UmbrellaException(400,"Fetching related users not implemented, yet!");
}
Map<Long, UmbrellaUser> userMap = registry.userService().list(0, null, ids);
Map<Long, UmbrellaUser> userMap = userService().list(0, null, ids);
if (arrayPassed || userMap.size() != 1) {
var userData = new HashMap<Long, Map<String, Object>>();
for (var entry : userMap.entrySet()) userData.put(entry.getKey(),entry.getValue().toMap());
@ -180,7 +179,7 @@ public class UserLegacy extends BaseHandler { @@ -180,7 +179,7 @@ public class UserLegacy extends BaseHandler {
}
}
if (!recipients.isEmpty()){ // replace legacy user ids by user objects in receivers field
Map<Long, UmbrellaUser> resp = registry.userService().list(0, null, recipients);
Map<Long, UmbrellaUser> resp = userService().list(0, null, recipients);
data.put("receivers",resp.values().stream().map(UmbrellaUser::toMap).toList());
}
@ -203,7 +202,7 @@ public class UserLegacy extends BaseHandler { @@ -203,7 +202,7 @@ public class UserLegacy extends BaseHandler {
var optToken = SessionToken.from(ex).map(Token::of);
if (optToken.isPresent()) try{
var token = optToken.get();
registry.userService().dropSession(token);
userService().dropSession(token);
var expiredToken = new SessionToken(token.toString(),"/", Instant.now().minus(1, DAYS),true);
expiredToken.addTo(ex);
if (returnTo instanceof String location) return sendRedirect(ex,location);
@ -245,8 +244,8 @@ public class UserLegacy extends BaseHandler { @@ -245,8 +244,8 @@ public class UserLegacy extends BaseHandler {
};
protected Session requestSession(Token token) throws UmbrellaException {
var session = registry.userService().load(token);
session = registry.userService().extend(session);
var session = userService().load(token);
session = userService().extend(session);
return session;
}
@ -280,8 +279,8 @@ public class UserLegacy extends BaseHandler { @@ -280,8 +279,8 @@ public class UserLegacy extends BaseHandler {
var o = map.get(TOKEN);
if (!(o instanceof String token)) throw new UmbrellaException(500,"Request did not contain token!");
var session = registry.userService().load(Token.of(token));
var user = registry.userService().load(session);
var session = userService().load(Token.of(token));
var user = userService().load(session);
var userMap = user.toMap();
userMap.put(TOKEN,Map.of(TOKEN,token,EXPIRATION,session.expiration().getEpochSecond()));
return sendContent(ex,userMap);

5
markdown/src/main/java/de/srsoftware/umbrella/markdown/MarkdownApi.java

@ -17,10 +17,9 @@ import java.util.Optional; @@ -17,10 +17,9 @@ import java.util.Optional;
public class MarkdownApi extends BaseHandler implements MarkdownService {
private final ModuleRegistry registry;
public MarkdownApi(ModuleRegistry registry) {
this.registry = registry.add(this);
super(registry);
}
@Override
@ -28,7 +27,7 @@ public class MarkdownApi extends BaseHandler implements MarkdownService { @@ -28,7 +27,7 @@ public class MarkdownApi extends BaseHandler implements MarkdownService {
try {
addCors(ex);
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) throw UmbrellaException.forbidden("You must be logged in to use the markdown renderer!");
var rendered = Util.markdown(body(ex));

14
messages/src/main/java/de/srsoftware/umbrella/message/MessageApi.java

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.message;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.ModuleRegistry;
public class MessageApi extends BaseHandler {
private final ModuleRegistry registry;
public MessageApi(ModuleRegistry moduleRegistry) {
super();
this.registry = moduleRegistry;
}
}

13
notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java

@ -28,12 +28,11 @@ import java.util.stream.Collectors; @@ -28,12 +28,11 @@ import java.util.stream.Collectors;
public class NoteModule extends BaseHandler implements NoteService {
private final NotesDb notesDb;
private final ModuleRegistry registry;
public NoteModule(ModuleRegistry registry, Configuration config) {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
notesDb = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
@Override
@ -46,7 +45,7 @@ public class NoteModule extends BaseHandler implements NoteService { @@ -46,7 +45,7 @@ public class NoteModule extends BaseHandler implements NoteService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
if (head == null) throw unprocessable("Module missing in path.");
@ -73,7 +72,7 @@ public class NoteModule extends BaseHandler implements NoteService { @@ -73,7 +72,7 @@ public class NoteModule extends BaseHandler implements NoteService {
public boolean doGet(Path path, HttpExchange ex) throws IOException {
addCors(ex);
try {
var user = registry.userService().refreshSession(ex);
var user = userService().refreshSession(ex);
if (user.isEmpty()) return unauthorized(ex);
var module = path.pop();
return switch (module){
@ -105,7 +104,7 @@ public class NoteModule extends BaseHandler implements NoteService { @@ -105,7 +104,7 @@ public class NoteModule extends BaseHandler implements NoteService {
}
private Map<String, Object> addUsers(Map<Long, Note> notes) {
var authors = notes.values().stream().map(Note::authorId).distinct().map(registry.userService()::loadUser).collect(Collectors.toMap(UmbrellaUser::id,UmbrellaUser::toMap));
var authors = notes.values().stream().map(Note::authorId).distinct().map(userService()::loadUser).collect(Collectors.toMap(UmbrellaUser::id,UmbrellaUser::toMap));
return Map.of("notes",mapValues(notes),"authors",authors);
}
@ -114,7 +113,7 @@ public class NoteModule extends BaseHandler implements NoteService { @@ -114,7 +113,7 @@ public class NoteModule extends BaseHandler implements NoteService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
long noteId = Long.parseLong(head);
@ -137,7 +136,7 @@ public class NoteModule extends BaseHandler implements NoteService { @@ -137,7 +136,7 @@ public class NoteModule extends BaseHandler implements NoteService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var module = path.pop();
if (module == null) throw unprocessable("Module missing in path.");

25
project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java

@ -30,16 +30,15 @@ import org.json.JSONObject; @@ -30,16 +30,15 @@ import org.json.JSONObject;
public class ProjectModule extends BaseHandler implements ProjectService {
private final ProjectDb projects;
private final ModuleRegistry registy;
public ProjectModule(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
projects = new SqliteDb(connect(dbFile));
this.registy = registry.add(this);
}
private void addMember(Project project, long userId) {
var user = registy.userService().loadUser(userId);
var user = userService().loadUser(userId);
var member = new Member(user,READ_ONLY);
project.members().put(userId,member);
project.dirty(MEMBERS);
@ -50,7 +49,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -50,7 +49,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registy.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -74,7 +73,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -74,7 +73,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registy.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -97,7 +96,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -97,7 +96,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registy.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -129,7 +128,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -129,7 +128,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
var project = loadMembers(projects.load(projectId));
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name());
var map = project.toMap();
project.companyId().map(registy.companyService()::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data));
project.companyId().map(companyService()::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data));
return sendContent(ex,map);
}
@ -140,8 +139,8 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -140,8 +139,8 @@ public class ProjectModule extends BaseHandler implements ProjectService {
}
private boolean listCompanyProjects(HttpExchange ex, UmbrellaUser user, long companyId) throws IOException, UmbrellaException {
var company = registy.companyService().get(companyId);
if (!registy.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var projects = listCompanyProjects(companyId,false);
return sendContent(ex,mapValues(projects));
}
@ -170,7 +169,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -170,7 +169,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
for (var entry : projects.getMembers(project).entrySet()){
var userId = entry.getKey();
var permission = entry.getValue();
var user = userMap.computeIfAbsent(userId,k -> registy.userService().loadUser(userId));
var user = userMap.computeIfAbsent(userId,k -> userService().loadUser(userId));
project.members().put(userId,new Member(user,permission));
}
}
@ -194,7 +193,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -194,7 +193,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
if (member.permission() == OWNER) members.put(member.user().id(),new Member(member.user(),EDIT));
}
}
members.put(userId,new Member(registy.userService().loadUser(userId),permission));
members.put(userId,new Member(userService().loadUser(userId),permission));
project.dirty(MEMBERS);
}
}
@ -233,7 +232,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -233,7 +232,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
}
Long companyId = null;
if (json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number number){
if (!registy.companyService().membership(number.longValue(), user.id())) throw forbidden("You are not a member of company {0}!",number);
if (!companyService().membership(number.longValue(), user.id())) throw forbidden("You are not a member of company {0}!",number);
companyId = number.longValue();
}
var showClosed = false;
@ -246,7 +245,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -246,7 +245,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){
var tagList = arr.toList().stream().filter(elem -> elem instanceof String).map(String.class::cast).toList();
registy.tagService().save(PROJECT,prj.id(),null,tagList);
tagService().save(PROJECT,prj.id(),null,tagList);
}
return sendContent(ex,prj);

9
tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java

@ -25,13 +25,12 @@ import org.json.JSONArray; @@ -25,13 +25,12 @@ import org.json.JSONArray;
public class TagModule extends BaseHandler implements TagService {
private final SqliteDb tagDb;
private final ModuleRegistry registry;
public TagModule(ModuleRegistry registry, Configuration config) {
super(registry);
var tagDbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
var bmDbFile = config.get(de.srsoftware.umbrella.bookmarks.Constants.CONFIG_DATABASE).orElseThrow(() -> missingFieldException(de.srsoftware.umbrella.bookmarks.Constants.CONFIG_DATABASE));
tagDb = new SqliteDb(connect(tagDbFile),connect(bmDbFile));
this.registry = registry.add(this);
}
@Override
@ -44,7 +43,7 @@ public class TagModule extends BaseHandler implements TagService { @@ -44,7 +43,7 @@ public class TagModule extends BaseHandler implements TagService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var module = path.pop();
if (module == null) throw unprocessable("Module missing in path.");
@ -63,7 +62,7 @@ public class TagModule extends BaseHandler implements TagService { @@ -63,7 +62,7 @@ public class TagModule extends BaseHandler implements TagService {
public boolean doGet(Path path, HttpExchange ex) throws IOException {
addCors(ex);
try {
var user = registry.userService().refreshSession(ex);
var user = userService().refreshSession(ex);
if (user.isEmpty()) return unauthorized(ex);
var module = path.pop();
if (module == null) throw unprocessable("Module missing in path.");
@ -87,7 +86,7 @@ public class TagModule extends BaseHandler implements TagService { @@ -87,7 +86,7 @@ public class TagModule extends BaseHandler implements TagService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var module = path.pop();
if (module == null) throw unprocessable("Module missing in path.");

37
task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java

@ -35,16 +35,15 @@ import org.json.JSONObject; @@ -35,16 +35,15 @@ import org.json.JSONObject;
public class TaskModule extends BaseHandler implements TaskService {
private final TaskDb taskDb;
private final ModuleRegistry registry;
public TaskModule(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
taskDb = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
private void addMember(Task task, long userId) {
var user = registry.userService().loadUser(userId);
var user = userService().loadUser(userId);
var member = new Member(user,READ_ONLY);
task.members().put(userId,member);
task.dirty(MEMBERS);
@ -55,8 +54,8 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -55,8 +54,8 @@ public class TaskModule extends BaseHandler implements TaskService {
var member = task.members().get(user.id());
if (member == null || !member.mayWrite()) throw forbidden("You are not allowed to delete {0}",task.name());
taskDb.delete(task);
registry.noteService().deleteEntity(TASK,""+taskId);
registry.tagService().deleteEntity(TASK,taskId);
noteService().deleteEntity(TASK,""+taskId);
tagService().deleteEntity(TASK,taskId);
return sendContent(ex,Map.of(DELETED,taskId));
}
@ -65,7 +64,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -65,7 +64,7 @@ public class TaskModule extends BaseHandler implements TaskService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -85,7 +84,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -85,7 +84,7 @@ public class TaskModule extends BaseHandler implements TaskService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -107,7 +106,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -107,7 +106,7 @@ public class TaskModule extends BaseHandler implements TaskService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -128,7 +127,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -128,7 +127,7 @@ public class TaskModule extends BaseHandler implements TaskService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -152,9 +151,9 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -152,9 +151,9 @@ public class TaskModule extends BaseHandler implements TaskService {
var json = json(ex);
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
var companyId = cid.longValue();
var company = registry.companyService().get(companyId);
if (!registry.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var projectMap = registry.projectService().listCompanyProjects(companyId,false);
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var projectMap = projectService().listCompanyProjects(companyId,false);
var taskMap = taskDb.listTasks(projectMap.keySet());
var taskTree = new HashMap<Long,Map<String,Object>>();
taskMap.values().stream().filter(task -> !is0(task.estimatedTime())).forEach(task -> placeInTree(task,taskTree,taskMap));
@ -196,7 +195,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -196,7 +195,7 @@ public class TaskModule extends BaseHandler implements TaskService {
} catch (NumberFormatException e) {
throw invalidFieldException(LIMIT,"number");
}
Set<Long> projectIds = registry.projectService().listUserProjects(user.id(), true).keySet();
Set<Long> projectIds = projectService().listUserProjects(user.id(), true).keySet();
var list = taskDb.listUserTasks(user.id(), limit, offset, false).stream()
.filter(task -> projectIds.contains(task.projectId())) // drop tasks assigned to project we are not member of
.map(Task::toMap)
@ -206,7 +205,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -206,7 +205,7 @@ public class TaskModule extends BaseHandler implements TaskService {
@Override
public HashMap<Long, Task> listCompanyTasks(long companyId) throws UmbrellaException {
var projectList = registry.projectService().listCompanyProjects(companyId,false);
var projectList = projectService().listCompanyProjects(companyId,false);
return taskDb.listTasks(projectList.keySet());
}
@ -222,7 +221,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -222,7 +221,7 @@ public class TaskModule extends BaseHandler implements TaskService {
for (var entry : taskDb.getMembers(task).entrySet()){
var userId = entry.getKey();
var permission = entry.getValue();
var user = userMap.computeIfAbsent(userId,k -> registry.userService().loadUser(userId));
var user = userMap.computeIfAbsent(userId,k -> userService().loadUser(userId));
task.members().put(userId,new Member(user,permission));
}
}
@ -267,7 +266,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -267,7 +266,7 @@ public class TaskModule extends BaseHandler implements TaskService {
if (member.permission() == ASSIGNEE) members.put(member.user().id(),new Member(member.user(),EDIT));
}
}
members.put(userId,new Member(registry.userService().loadUser(userId),permission));
members.put(userId,new Member(userService().loadUser(userId),permission));
task.dirty(MEMBERS);
}
}
@ -301,8 +300,8 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -301,8 +300,8 @@ public class TaskModule extends BaseHandler implements TaskService {
if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingFieldException(PROJECT_ID);
if (!(json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberData)) throw missingFieldException(MEMBERS);
long projectId = pid.longValue();
var project = registry.projectService().load(projectId);
registry.projectService().loadMembers(List.of(project));
var project = projectService().load(projectId);
projectService().loadMembers(List.of(project));
var member = project.members().get(user.id());
if (member == null || member.permission() == READ_ONLY) throw forbidden("You are not allowed to create new tasks in this project");
for (var key : memberData.keySet()){
@ -331,7 +330,7 @@ public class TaskModule extends BaseHandler implements TaskService { @@ -331,7 +330,7 @@ public class TaskModule extends BaseHandler implements TaskService {
}
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){
var tagList = arr.toList().stream().filter(e -> e instanceof String).map(String.class::cast).toList();
registry.tagService().save(TASK,task.id(),null,tagList);
tagService().save(TASK,task.id(),null,tagList);
}
return sendContent(ex,loadMembers(task));
}

11
time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java

@ -35,14 +35,13 @@ public class TimeModule extends BaseHandler implements TimeService { @@ -35,14 +35,13 @@ public class TimeModule extends BaseHandler implements TimeService {
}
private final ModuleRegistry registry;
private final TimeDb timeDb;
public TimeModule(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
timeDb = new SqliteDb(connect(dbFile));
this.registry = registry.add(this);
}
@Override
@ -50,7 +49,7 @@ public class TimeModule extends BaseHandler implements TimeService { @@ -50,7 +49,7 @@ public class TimeModule extends BaseHandler implements TimeService {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = registry.userService().loadUser(token);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head) {
@ -106,11 +105,11 @@ public class TimeModule extends BaseHandler implements TimeService { @@ -106,11 +105,11 @@ public class TimeModule extends BaseHandler implements TimeService {
var json = json(ex);
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
var companyId = cid.longValue();
var company = registry.companyService().get(companyId);
if (!registry.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingFieldException(PROJECT_ID);
long projectId = pid.longValue();
Map<Long,Task> tasksOfProject = registry.taskService().listProjectTasks(projectId);
Map<Long,Task> tasksOfProject = taskService().listProjectTasks(projectId);
List<Map<String, Object>> times = timeDb.listTimes(tasksOfProject.keySet())
.stream().filter(not(Time::isClosed))

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

@ -69,7 +69,6 @@ public class UserModule extends BaseHandler implements UserService { @@ -69,7 +69,6 @@ public class UserModule extends BaseHandler implements UserService {
private static final System.Logger LOG = System.getLogger("User");
private final UserDb users;
private final LoginServiceDb logins;
private final ModuleRegistry registry;
private final HashMap<String, State> stateMap = new HashMap<>(); // map from state to OIDC provider name
private final HashMap<String,String> tokenMap = new HashMap<>();
@ -82,11 +81,11 @@ public class UserModule extends BaseHandler implements UserService { @@ -82,11 +81,11 @@ public class UserModule extends BaseHandler implements UserService {
}
public UserModule(ModuleRegistry registry, Configuration config) throws UmbrellaException {
super(registry);
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingConfigException(CONFIG_DATABASE));
// may be splitted in separate db files later
logins = new SqliteDB(connect(dbFile));
users = new SqliteDB(connect(dbFile));
this.registry = registry.add(this);
}
private boolean deleteOIDC(HttpExchange ex, UmbrellaUser user, Path path) throws IOException {
@ -504,7 +503,7 @@ public class UserModule extends BaseHandler implements UserService { @@ -504,7 +503,7 @@ public class UserModule extends BaseHandler implements UserService {
var fills = Map.of("url",url);
var message = new Message(user,subject,content,fills,null);
var envelope = new Envelope(message,user);
registry.postBox().send(envelope);
postBox().send(envelope);
} catch (UmbrellaException e){
return send(ex,e);
}

5
web/src/main/java/de/srsoftware/umbrella/web/WebHandler.java

@ -8,11 +8,16 @@ import static java.net.HttpURLConnection.HTTP_NOT_FOUND; @@ -8,11 +8,16 @@ import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.tools.Path;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.ModuleRegistry;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class WebHandler extends BaseHandler {
public WebHandler(ModuleRegistry registry){
super(registry);
}
@Override
public boolean doGet(Path path, HttpExchange ex) throws IOException {
LOG.log(DEBUG,"doGet({0},ex)",path);

Loading…
Cancel
Save