implemented dynamic theme loading, working on user edit

This commit is contained in:
2025-07-01 22:24:23 +02:00
parent 691c317a57
commit 684e0b00dd
12 changed files with 178 additions and 61 deletions

View File

@@ -8,6 +8,8 @@ import static de.srsoftware.umbrella.core.ResponseCode.*;
import static de.srsoftware.umbrella.user.Constants.*;
import static de.srsoftware.umbrella.user.Paths.LOGIN;
import static de.srsoftware.umbrella.user.Paths.WHOAMI;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.UPDATE_USERS;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.WARNING;
import static java.time.temporal.ChronoUnit.DAYS;
@@ -75,6 +77,38 @@ public class UserModule extends PathHandler {
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
addCors(ex);
var sessionToken = SessionToken.from(ex);
if (sessionToken.isEmpty()) return sendEmptyResponse(UNAUTHORIZED,ex);
UmbrellaUser requestingUser;
try {
Session session = users.load(Token.of(sessionToken.get()));
requestingUser = users.load(session);
} catch (UmbrellaException e) {
return sendContent(ex,e.statusCode(),e.getMessage());
}
var head = path.pop();
long userId;
try {
if (head == null || head.isBlank()) return sendContent(ex,UNPROCESSABLE,"User id missing!");
userId = Long.parseLong(head);
} catch (NumberFormatException e) {
return sendContent(ex,UNPROCESSABLE,"Invalid user id: "+head);
}
DbUser editedUser;
try {
editedUser = (DbUser) users.load(userId);
} catch (UmbrellaException e) {
return sendContent(ex,e.statusCode(),e.getMessage());
}
if (requestingUser.id() != userId && (!(requestingUser instanceof DbUser dbUser) || !dbUser.permissions().contains(UPDATE_USERS))){
return sendContent(ex,FORBIDDEN,"You are not allowed to update user "+editedUser.name());
}
JSONObject json;
try {
json = json(ex);
@@ -82,14 +116,10 @@ public class UserModule extends PathHandler {
LOG.log(WARNING,"Request does not contain valid JSON",e);
return sendContent(ex,BAD_REQUEST,"Body contains no JSON data");
}
var head = path.pop();
try {
if (head == null || head.isBlank()) return sendContent(ex,UNPROCESSABLE,"User id missing!");
long userId = Long.parseLong(head);
var user = (DbUser) users.load(userId);
return update(ex, user,json);
} catch (NumberFormatException e) {
return sendContent(ex,UNPROCESSABLE,"Invalid user id: "+head);
return update(ex, editedUser,json);
} catch (UmbrellaException e) {
return sendContent(ex,e.statusCode(),e.getMessage());
}
@@ -153,12 +183,12 @@ public class UserModule extends PathHandler {
private boolean update(HttpExchange ex, DbUser user, JSONObject json) throws UmbrellaException, IOException {
var id = user.id();
var name = json.has("user.name") && json.get("user.name") instanceof String s && !s.isBlank() ? s : user.name();
var email = json.has("user.email") && json.get("user.email") instanceof String e && !e.isBlank() ? e : user.email();
var pass = json.has("user.password") && json.get("user.password") instanceof String p && !p.isBlank() ? Password.of(BAD_HASHER.hash(p,null)) : user.hashedPassword();
var theme = json.has("user.theme") && json.get("user.theme") instanceof String t && !t.isBlank() ? t : user.theme();
var lang = json.has("user.language") && json.get("user.language") instanceof String l && !l.isBlank() ? l : user.language();
var saved = users.save(new DbUser(id,name,email,pass,theme,lang, Set.of(),null));
var name = json.has(NAME) && json.get(NAME) instanceof String s && !s.isBlank() ? s : user.name();
var email = json.has(EMAIL) && json.get(EMAIL) instanceof String e && !e.isBlank() ? e : user.email();
var pass = json.has(PASSWORD) && json.get(PASSWORD) instanceof String p && !p.isBlank() ? Password.of(BAD_HASHER.hash(p,null)) : user.hashedPassword();
var theme = json.has(THEME) && json.get(THEME) instanceof String t && !t.isBlank() ? t : user.theme();
var lang = json.has(LANGUAGE) && json.get(LANGUAGE) instanceof String l && !l.isBlank() ? l : user.language();
var saved = users.save(new DbUser(id,name,email,pass,theme,lang, user.permissions(),null));
return sendContent(ex,OK,saved);
}
}

View File

@@ -5,16 +5,24 @@ package de.srsoftware.umbrella.user.model;
import java.util.Map;
import java.util.Set;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.*;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.IMPERSONATE;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.LIST_USERS;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.MANAGE_LOGIN_SERVICES;
public class DbUser extends UmbrellaUser {
public enum PERMISSION {
CREATE_USERS,
UPDATE_USERS,
DELETE_USERS,
LIST_USERS,
IMPERSONATE,
MANAGE_LOGIN_SERVICES
}
public static Set<PERMISSION> ADMIN_PERMISSIONS = Set.of(CREATE_USERS, UPDATE_USERS, DELETE_USERS, IMPERSONATE, MANAGE_LOGIN_SERVICES,LIST_USERS);
private final Set<PERMISSION> permissions;
private final Password hashedPass;
private final Long lastLogoff;

View File

@@ -6,7 +6,7 @@ import static de.srsoftware.tools.jdbc.Query.*;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.user.Constants.*;
import static de.srsoftware.umbrella.user.model.DbUser.PERMISSION.*;
import static de.srsoftware.umbrella.user.model.DbUser.ADMIN_PERMISSIONS;
import static java.lang.System.Logger.Level.*;
import static java.text.MessageFormat.format;
@@ -471,7 +471,7 @@ CREATE TABLE IF NOT EXISTS {0} (
private DbUser toUser(ResultSet rs) throws SQLException {
long id = rs.getLong(ID);
Set<DbUser.PERMISSION> perms = id == 1 ? Set.of(CREATE_USERS,DELETE_USERS,IMPERSONATE, MANAGE_LOGIN_SERVICES,LIST_USERS) : Set.of();
Set<DbUser.PERMISSION> perms = id == 1 ? ADMIN_PERMISSIONS : Set.of();
return new DbUser(
id,
rs.getString(LOGIN),