diff --git a/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java index 5efff18..7fef682 100644 --- a/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java +++ b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java @@ -18,7 +18,6 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Company; import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.UmbrellaUser; - import java.io.IOException; import java.util.Collection; import java.util.HashSet; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java index 83cd633..30778c2 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java @@ -42,6 +42,7 @@ public class Constants { public static final String KEY = "key"; public static final String LANGUAGE = "language"; public static final String LOGIN = "login"; + public static final String MEMBERS = "members"; public static final String MESSAGES = "messages"; public static final String NAME = "name"; public static final String MIME = "mime"; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/ProjectService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/ProjectService.java index 5ea0734..f228bd4 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/ProjectService.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/ProjectService.java @@ -6,7 +6,7 @@ import de.srsoftware.umbrella.core.model.Project; import java.util.Collection; public interface ProjectService { - public Collection listProjects(long companyId,boolean includeClosed) throws UmbrellaException; + public Collection listProjectsOfCompany(long companyId, boolean includeClosed) throws UmbrellaException; CompanyService companyService(); } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java index 65d5203..d7a82ab 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/UserService.java @@ -5,9 +5,12 @@ import com.sun.net.httpserver.HttpExchange; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.UmbrellaUser; +import java.util.Collection; +import java.util.Map; import java.util.Optional; public interface UserService { + Map list(Collection ids) throws UmbrellaException; UmbrellaUser loadUser(long userId) throws UmbrellaException; Optional loadUser(Optional sessionToken) throws UmbrellaException; Optional loadUser(HttpExchange ex) throws UmbrellaException; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Member.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Member.java new file mode 100644 index 0000000..416f410 --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Member.java @@ -0,0 +1,5 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.model; + + +public record Member(UmbrellaUser user, Permission permission){ } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java new file mode 100644 index 0000000..9c8dcce --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Permission.java @@ -0,0 +1,30 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.model; + +import static java.text.MessageFormat.format; + +import java.security.InvalidParameterException; + +public enum Permission { + OWNER(1), + EDIT(2), + ASSIGNEE(3), + READ_ONLY(4); + + private final int code; + + Permission(int code){ + this.code = code; + } + + public int code(){ + return code; + } + + public static Permission of(int code){ + for (var p : Permission.values()){ + if (p.code == code) return p; + } + throw new InvalidParameterException(format("{0} is not a valid permission code")); + } +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java index 589b9a2..549b7bd 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java @@ -6,9 +6,9 @@ import static de.srsoftware.umbrella.core.Constants.*; import de.srsoftware.tools.Mappable; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Map; +import java.util.*; -public record Project(long id, String name, String description, Status status, Long companyId, boolean showClosed) implements Mappable { +public record Project(long id, String name, String description, Status status, Long companyId, boolean showClosed, Collection members) implements Mappable { public enum Status{ Open(10), Started(20), @@ -39,18 +39,19 @@ public record Project(long id, String name, String description, Status status, L } public static Project of(ResultSet rs) throws SQLException { - return new Project(rs.getLong(ID),rs.getString(NAME),rs.getString(DESCRIPTION),Status.of(rs.getInt(STATUS)),rs.getLong(COMPANY_ID),rs.getBoolean(SHOW_CLOSED)); + return new Project(rs.getLong(ID),rs.getString(NAME),rs.getString(DESCRIPTION),Status.of(rs.getInt(STATUS)),rs.getLong(COMPANY_ID),rs.getBoolean(SHOW_CLOSED),new ArrayList<>()); } @Override public Map toMap() { - return Map.of( - ID,id, - NAME,name, - DESCRIPTION,description, - STATUS,Map.of(STATUS_CODE,status.code(), NAME,status.name()), - COMPANY_ID,companyId, - SHOW_CLOSED,showClosed - ); + var map = new HashMap(); + map.put(ID,id); + map.put(NAME,name); + map.put(DESCRIPTION,description); + map.put(STATUS,Map.of(STATUS_CODE,status.code(), NAME,status.name())); + map.put(COMPANY_ID,companyId); + map.put(SHOW_CLOSED,showClosed); + map.put(MEMBERS,members == null ? List.of() : members); + return map; } } diff --git a/documents/src/main/java/de/srsoftware/umbrella/documents/model/Position.java b/documents/src/main/java/de/srsoftware/umbrella/documents/model/Position.java index 2fd81be..988d6c4 100644 --- a/documents/src/main/java/de/srsoftware/umbrella/documents/model/Position.java +++ b/documents/src/main/java/de/srsoftware/umbrella/documents/model/Position.java @@ -5,7 +5,6 @@ package de.srsoftware.umbrella.documents.model; import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Util.markdown; import static de.srsoftware.umbrella.documents.Constants.*; -import static java.lang.System.Logger.Level.WARNING; import de.srsoftware.tools.Mappable; import java.util.*; diff --git a/frontend/src/routes/project/Create.svelte b/frontend/src/routes/project/Create.svelte index eed12f0..85ad468 100644 --- a/frontend/src/routes/project/Create.svelte +++ b/frontend/src/routes/project/Create.svelte @@ -8,6 +8,7 @@ let showSettings = $state(false); let ready = $derived(!!project.name.trim()) let error = $state(null); + const router = useTinyRouter(); let project = $state({ name:'', diff --git a/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java b/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java index acc8565..cbe2833 100644 --- a/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java +++ b/legacy/src/main/java/de/srsoftware/umbrella/legacy/LegacyApi.java @@ -27,7 +27,6 @@ import de.srsoftware.umbrella.user.api.UserDb; import java.io.IOException; import java.time.Instant; import java.util.*; -import java.util.stream.Collectors; import org.json.JSONObject; public class LegacyApi extends BaseHandler { @@ -129,22 +128,16 @@ public class LegacyApi extends BaseHandler { throw new UmbrellaException(400,"Fetching related users not implemented, yet!"); } - List userList = new ArrayList<>(); - if (ids.isEmpty()) { - userList = users.list(0, null); - } else { - for (var id : ids){ - try { - userList.add(users.load(id)); - } catch (UmbrellaException ignored) { - } - } - } - if (arrayPassed || userList.size() != 1) { - Map> userData = userList.stream().collect(Collectors.toMap(UmbrellaUser::id, UmbrellaUser::toMap)); + Map userMap = users.list(0, null, ids); + if (arrayPassed || userMap.size() != 1) { + var userData = new HashMap>(); + for (var entry : userMap.entrySet()) userData.put(entry.getKey(),entry.getValue().toMap()); return sendContent(ex,userData); } - return sendContent(ex, userList.getFirst().toMap()); + for (var entry : userMap.entrySet()){ + return sendContent(ex,entry.getValue()); + } + throw UmbrellaException.notFound("Failed to load user(s) for id(s): {0}",ids); } private boolean legacyNotify(HttpExchange ex) throws UmbrellaException, IOException { @@ -187,8 +180,8 @@ public class LegacyApi extends BaseHandler { } } if (!recipients.isEmpty()){ // replace legacy user ids by user objects in receivers field - List resp = users.list(0, null, recipients.toArray(new Long[0])); - data.put("receivers",resp.stream().map(UmbrellaUser::toMap).toList()); + Map resp = users.list(0, null, recipients); + data.put("receivers",resp.values().stream().map(UmbrellaUser::toMap).toList()); } if (!data.has(SENDER)) data.put(SENDER,user.toMap()); diff --git a/project/src/main/java/de/srsoftware/umbrella/project/ProjectDb.java b/project/src/main/java/de/srsoftware/umbrella/project/ProjectDb.java index 107cbee..a51cdc0 100644 --- a/project/src/main/java/de/srsoftware/umbrella/project/ProjectDb.java +++ b/project/src/main/java/de/srsoftware/umbrella/project/ProjectDb.java @@ -1,12 +1,13 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.project; +import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Project; -import java.util.Collection; +import java.util.Map; public interface ProjectDb { - Collection list(long companyId, boolean includeClosed) throws UmbrellaException; + Map list(long companyId, boolean includeClosed, UserService userService) throws UmbrellaException; - Project save(Project prj); + Project save(Project prj) throws UmbrellaException; } diff --git a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java index 038ac0b..ffec3df 100644 --- a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java +++ b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java @@ -5,6 +5,7 @@ import static de.srsoftware.umbrella.core.ConnectionProvider.connect; import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Paths.LIST; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; +import static de.srsoftware.umbrella.core.model.Permission.OWNER; import static de.srsoftware.umbrella.project.Constants.CONFIG_DATABASE; import static java.lang.Boolean.TRUE; import static java.util.Comparator.comparing; @@ -18,15 +19,10 @@ import de.srsoftware.umbrella.core.api.CompanyService; import de.srsoftware.umbrella.core.api.ProjectService; import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; -import de.srsoftware.umbrella.core.model.Project; -import de.srsoftware.umbrella.core.model.Token; -import de.srsoftware.umbrella.core.model.UmbrellaUser; -import org.json.JSONObject; - +import de.srsoftware.umbrella.core.model.*; import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.Optional; +import java.util.*; +import org.json.JSONObject; public class ProjectModule extends BaseHandler implements ProjectService { @@ -55,7 +51,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { if (user.isEmpty()) return unauthorized(ex); var head = path.pop(); return switch (head) { - case LIST -> listItems(ex,user.get()); + case LIST -> listProjects(ex,user.get()); case null -> postProject(ex,user.get()); default -> super.doGet(path,ex); }; @@ -64,21 +60,22 @@ public class ProjectModule extends BaseHandler implements ProjectService { } } - private boolean listItems(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { + private boolean listProjects(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { 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 = companies.get(companyId); if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name()); - var items = listProjects(companyId,false) + var projects = listProjectsOfCompany(companyId,false) .stream() .map(Project::toMap) .map(HashMap::new); - return sendContent(ex,items); + return sendContent(ex,projects); } - public Collection listProjects(long companyId, boolean includeClosed) throws UmbrellaException { - return projectDb.list(companyId, includeClosed).stream().sorted(comparing(Project::name)).toList(); + public Collection listProjectsOfCompany(long companyId, boolean includeClosed) throws UmbrellaException { + + return projectDb.list(companyId, includeClosed, users).values().stream().sorted(comparing(Project::name)).toList(); } private boolean postProject(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { @@ -94,8 +91,8 @@ public class ProjectModule extends BaseHandler implements ProjectService { if (json.has(SETTINGS) && json.get(SETTINGS) instanceof JSONObject settingsJson){ showClosed = settingsJson.has(SHOW_CLOSED) && settingsJson.get(SHOW_CLOSED) == TRUE; } - var prj = new Project(0,name,description,Project.Status.Open,companyId,showClosed); - projectDb.save(prj); - return notFound(ex); + var prj = new Project(0,name,description,Project.Status.Open,companyId,showClosed, List.of(new Member(user, OWNER))); + prj = projectDb.save(prj); + return sendContent(ex,prj); } } \ No newline at end of file diff --git a/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java b/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java index e115641..0d79667 100644 --- a/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java +++ b/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java @@ -1,8 +1,7 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.project; -import static de.srsoftware.tools.jdbc.Condition.equal; -import static de.srsoftware.tools.jdbc.Condition.lessThan; +import static de.srsoftware.tools.jdbc.Condition.*; import static de.srsoftware.tools.jdbc.Query.insertInto; import static de.srsoftware.tools.jdbc.Query.select; import static de.srsoftware.umbrella.core.Constants.*; @@ -15,17 +14,16 @@ import static java.lang.System.Logger.Level.ERROR; import static java.lang.System.Logger.Level.INFO; import static java.text.MessageFormat.format; -import de.srsoftware.tools.PasswordHasher; import de.srsoftware.tools.jdbc.Query; +import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; +import de.srsoftware.umbrella.core.model.Member; +import de.srsoftware.umbrella.core.model.Permission; import de.srsoftware.umbrella.core.model.Project; - -import java.security.NoSuchAlgorithmException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; +import java.util.HashMap; public class SqliteDb implements ProjectDb { private static final System.Logger LOG = System.getLogger("Sqlite4Project"); @@ -125,25 +123,67 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255) } @Override - public Collection list(long companyId, boolean includeClosed) throws UmbrellaException { + public HashMap list(long companyId, boolean includeClosed, UserService userService) throws UmbrellaException { try { - var items = new HashSet(); + var projects = new HashMap(); var query = select("*").from(TABLE_PROJECTS).where(COMPANY_ID, equal(companyId)); if (!includeClosed) query = query.where(STATUS,lessThan(Project.Status.Complete.code())); var rs = query.exec(db); - while (rs.next()) items.add(Project.of(rs)); + while (rs.next()){ + var project = Project.of(rs); + projects.put(project.id(),project); + } + rs.close(); + rs = select("*").from(TABLE_PROJECT_USERS).where(PROJECT_ID,in(projects.keySet())).exec(db); + var userIdMap = new HashMap>(); + while (rs.next()){ + var userId = rs.getLong(USER_ID); + var projectId = rs.getLong(PROJECT_ID); + var permission = Permission.of(rs.getInt(PERMISSIONS)); + HashMap userMap = userIdMap.computeIfAbsent(userId, k -> new HashMap<>()); + userMap.put(projectId,permission); + } rs.close(); - return items; + var userMap = userService.list(userIdMap.keySet()); + for (var entry : userIdMap.entrySet()){ + var userId = entry.getKey(); + var user = userMap.get(userId); + for (var inner : entry.getValue().entrySet()){ + var projectId = inner.getKey(); + var perm = inner.getValue(); + var project = projects.get(projectId); + project.members().add(new Member(user,perm)); + } + } + return projects; } catch (SQLException e) { throw new UmbrellaException(HTTP_SERVER_ERROR,"Failed to load items from database"); } } @Override - public Project save(Project prj) { + public Project save(Project prj) throws UmbrellaException { try { - insertInto(TABLE_PROJECTS); + if (prj.id() == 0) { + var stmt = insertInto(TABLE_PROJECTS, NAME, DESCRIPTION, STATUS, COMPANY_ID, SHOW_CLOSED).values(prj.name(), prj.description(), prj.status().code(), prj.companyId(), prj.showClosed()).execute(db); + var rs = stmt.getGeneratedKeys(); + var id = rs.next() ? rs.getLong(1) : null; + rs.close(); + if (id != null){ + if (!prj.members().isEmpty()) { + var query = insertInto(TABLE_PROJECT_USERS, PROJECT_ID, USER_ID, PERMISSIONS); + for (var member : prj.members()) + query.values(id, member.user().id(), member.permission().code()); + query.execute(db).close(); + } + return new Project(id, prj.name(), prj.description(),prj.status(),prj.companyId(),prj.showClosed(),prj.members()); + } + } else { + LOG.log(ERROR,"Updating project not implemented!"); + } + return null; + } catch (SQLException e) { + throw new UmbrellaException(HTTP_SERVER_ERROR,"Failed to insert project into database"); } - return null; } } diff --git a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java index 71d79e9..4d198e8 100644 --- a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java +++ b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java @@ -70,7 +70,7 @@ public class TaskModule extends BaseHandler implements TaskService { var companyId = cid.longValue(); var company = companies.get(companyId); if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name()); - var projects = this.projects.listProjects(companyId,false); + var projects = this.projects.listProjectsOfCompany(companyId,false); var taskList = taskDb.listTasks(projects.stream().map(Project::id).toList()); var map = taskList.stream().collect(toMap(Task::id, t -> t)); var tree = new HashMap>(); @@ -89,7 +89,7 @@ public class TaskModule extends BaseHandler implements TaskService { @Override public Collection listCompanyTasks(long companyId) throws UmbrellaException { - var projectList = projects.listProjects(companyId,false); + var projectList = projects.listProjectsOfCompany(companyId,false); return taskDb.listTasks(projectList.stream().map(Project::id).toList()); } diff --git a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java index 6e8bcda..62568b3 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java @@ -140,6 +140,11 @@ public class UserModule extends BaseHandler implements UserService { } } + @Override + public Map list(Collection ids) throws UmbrellaException { + return users.list(0,null,ids); + } + @Override public UmbrellaUser loadUser(long userId) throws UmbrellaException { return users.load(userId); @@ -191,7 +196,7 @@ public class UserModule extends BaseHandler implements UserService { if (user.isEmpty()) return unauthorized(ex); if (!(user.get() instanceof DbUser dbUser)) return unauthorized(ex); if (!(dbUser.id() == userId || dbUser.permissions().contains(LIST_USERS))) throw forbidden("You are not allowed to access that user!"); - return sendContent(ex,users.load(userId)); + return sendContent(ex,loadUser(userId)); } catch (UmbrellaException e) { return send(ex,e); } catch (NumberFormatException ignored) {} @@ -216,7 +221,7 @@ public class UserModule extends BaseHandler implements UserService { if (PASSWORD.equals(head)) return patchPassword(ex,requestingUser.get()); if (OIDC.equals(head)) return patchService(ex,path.pop(),requestingUser.get()); userId = Long.parseLong(head); - DbUser editedUser = (DbUser) users.load(userId); + DbUser editedUser = (DbUser) loadUser(userId); if (!(requestingUser.get() instanceof DbUser dbUser) || !(dbUser.id() == userId || dbUser.permissions().contains(UPDATE_USERS))) throw forbidden("You are not allowed to update user "+editedUser.name()); @@ -288,7 +293,7 @@ public class UserModule extends BaseHandler implements UserService { var assignment = new ForeignLogin(state.loginService.name(),oidcUserId,currentUser.id()); logins.save(assignment); } - var user = users.load(logins.getUserId(state.loginService.name(), oidcUserId)); + var user = loadUser(logins.getUserId(state.loginService.name(), oidcUserId)); var session = users.getSession(user); var returnTo = "/user"; if (state.config.has("returnTo")) returnTo = state.config.getString("returnTo"); @@ -384,7 +389,7 @@ public class UserModule extends BaseHandler implements UserService { private boolean getUserList(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { if (!(user instanceof DbUser dbUser && dbUser.permissions().contains(LIST_USERS))) throw forbidden("You are not allowed to list users!"); - var list = users.list(0, null).stream().map(UmbrellaUser::toMap).toList(); + var list = users.list(0, null,null).values().stream().map(UmbrellaUser::toMap).toList(); return sendContent(ex,list); } @@ -393,7 +398,7 @@ public class UserModule extends BaseHandler implements UserService { if (!(requestingUser.isPresent() && requestingUser.get() instanceof DbUser dbUser)) return unauthorized(ex); if (!dbUser.permissions().contains(PERMISSION.IMPERSONATE)) throw forbidden("You are not allowed to impersonate other users!"); if (targetId == null) return sendContent(ex,HTTP_UNPROCESSABLE,"user id missing"); - var targetUser = users.load(targetId); + var targetUser = loadUser(targetId); users.getSession(targetUser).cookie().addTo(ex); return sendContent(ex,targetUser.toMap()); } diff --git a/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java b/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java index 9f6d718..f49b430 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/api/UserDb.java @@ -8,7 +8,8 @@ import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.user.model.DbUser; import de.srsoftware.umbrella.user.model.Password; -import java.util.List; +import java.util.Collection; +import java.util.Map; public interface UserDb { @@ -25,7 +26,7 @@ public interface UserDb { Session extend(Session session) throws UmbrellaException; - List list(Integer start, Integer limit, Long ... ids) throws UmbrellaException; + Map list(Integer start, Integer limit, Collection ids) throws UmbrellaException; Session load(Token token) throws UmbrellaException; diff --git a/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java b/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java index 0a0b573..458965f 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/sqlite/SqliteDB.java @@ -295,15 +295,18 @@ CREATE TABLE IF NOT EXISTS {0} ( @Override - public List list(Integer start, Integer limit, Long ... ids) throws UmbrellaException { - var list = new ArrayList(); + public Map list(Integer start, Integer limit, Collection ids) throws UmbrellaException { + var list = new HashMap(); try { var query = select(ALL).from(TABLE_USERS); if (start != null && start > 0) query.skip(start); if (limit != null && limit > 0) query.limit(limit); - if (ids != null && ids.length>0) query.where(ID,in((Object[]) ids)); + if (ids != null && !ids.isEmpty()) query.where(ID,in(ids.toArray())); var rs = query.exec(db); - while (rs.next()) list.add(toUser(rs)); + while (rs.next()) { + var user = toUser(rs); + list.put(user.id(),user); + } rs.close(); } catch (SQLException e) { LOG.log(WARNING,"Failed to load user list from database!",e);