From 82974170e9266793b23de1fd3ace8cd38ded0f4d Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 15 Mar 2026 12:35:42 +0100 Subject: [PATCH] fix: make Permission enum complete and grant all permissions to admin group Three related issues: - READ_ALL was stored in the DB but missing from the Permission enum - ADMIN_USER, ADMIN_TAG and ADMIN_PERMISSION were in the enum and used in controllers but never granted to any user, making those endpoints permanently inaccessible - No runtime signal when a DB permission string drifts from the enum Changes: - Add READ_ALL to Permission enum - Grant all six permissions to the Administrators group in DataInitializer - Warn in CustomUserDetailsService when a DB permission string has no matching Permission enum value Co-Authored-By: Claude Sonnet 4.6 --- .../familienarchiv/config/DataInitializer.java | 2 +- .../familienarchiv/security/Permission.java | 2 +- .../service/CustomUserDetailsService.java | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java b/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java index f4ff4a79..902a8ab6 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java @@ -49,7 +49,7 @@ public class DataInitializer { // 1. Admin Gruppe erstellen UserGroup adminGroup = UserGroup.builder() .name("Administrators") - .permissions(Set.of("ADMIN", "READ_ALL", "WRITE_ALL")) + .permissions(Set.of("ADMIN", "READ_ALL", "WRITE_ALL", "ADMIN_USER", "ADMIN_TAG", "ADMIN_PERMISSION")) .build(); groupRepository.save(adminGroup); diff --git a/backend/src/main/java/org/raddatz/familienarchiv/security/Permission.java b/backend/src/main/java/org/raddatz/familienarchiv/security/Permission.java index f859263d..25120a2b 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/security/Permission.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/security/Permission.java @@ -1,7 +1,7 @@ package org.raddatz.familienarchiv.security; public enum Permission { - //Every authenticated user has read rights + READ_ALL, WRITE_ALL, ADMIN, ADMIN_USER, diff --git a/backend/src/main/java/org/raddatz/familienarchiv/service/CustomUserDetailsService.java b/backend/src/main/java/org/raddatz/familienarchiv/service/CustomUserDetailsService.java index f2fd734c..e9dd489f 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/service/CustomUserDetailsService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/service/CustomUserDetailsService.java @@ -1,9 +1,11 @@ package org.raddatz.familienarchiv.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.raddatz.familienarchiv.model.AppUser; import org.raddatz.familienarchiv.repository.AppUserRepository; +import org.raddatz.familienarchiv.security.Permission; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; @@ -11,12 +13,19 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import java.util.Arrays; +import java.util.Set; import java.util.stream.Collectors; @Service @RequiredArgsConstructor +@Slf4j public class CustomUserDetailsService implements UserDetailsService { + private static final Set KNOWN_PERMISSIONS = Arrays.stream(Permission.values()) + .map(Enum::name) + .collect(Collectors.toSet()); + private final AppUserRepository userRepository; @Override @@ -24,9 +33,14 @@ public class CustomUserDetailsService implements UserDetailsService { AppUser appUser = userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User nicht gefunden: " + username)); - // Wir sammeln alle Permissions aus allen Gruppen des Users + // Collect all permissions from all groups; warn about any that don't match a known Permission enum value var authorities = appUser.getGroups().stream() .flatMap(group -> group.getPermissions().stream()) + .peek(p -> { + if (!KNOWN_PERMISSIONS.contains(p)) { + log.warn("Unknown permission '{}' found in database for user '{}' — it will be granted but never matched by @RequirePermission", p, appUser.getUsername()); + } + }) .map(SimpleGrantedAuthority::new) .collect(Collectors.toSet());