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 <noreply@anthropic.com>
This commit is contained in:
@@ -49,7 +49,7 @@ public class DataInitializer {
|
|||||||
// 1. Admin Gruppe erstellen
|
// 1. Admin Gruppe erstellen
|
||||||
UserGroup adminGroup = UserGroup.builder()
|
UserGroup adminGroup = UserGroup.builder()
|
||||||
.name("Administrators")
|
.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();
|
.build();
|
||||||
groupRepository.save(adminGroup);
|
groupRepository.save(adminGroup);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.raddatz.familienarchiv.security;
|
package org.raddatz.familienarchiv.security;
|
||||||
|
|
||||||
public enum Permission {
|
public enum Permission {
|
||||||
//Every authenticated user has read rights
|
READ_ALL,
|
||||||
WRITE_ALL,
|
WRITE_ALL,
|
||||||
ADMIN,
|
ADMIN,
|
||||||
ADMIN_USER,
|
ADMIN_USER,
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.raddatz.familienarchiv.service;
|
package org.raddatz.familienarchiv.service;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.raddatz.familienarchiv.model.AppUser;
|
import org.raddatz.familienarchiv.model.AppUser;
|
||||||
import org.raddatz.familienarchiv.repository.AppUserRepository;
|
import org.raddatz.familienarchiv.repository.AppUserRepository;
|
||||||
|
import org.raddatz.familienarchiv.security.Permission;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
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.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class CustomUserDetailsService implements UserDetailsService {
|
public class CustomUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
|
private static final Set<String> KNOWN_PERMISSIONS = Arrays.stream(Permission.values())
|
||||||
|
.map(Enum::name)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
private final AppUserRepository userRepository;
|
private final AppUserRepository userRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -24,9 +33,14 @@ public class CustomUserDetailsService implements UserDetailsService {
|
|||||||
AppUser appUser = userRepository.findByUsername(username)
|
AppUser appUser = userRepository.findByUsername(username)
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("User nicht gefunden: " + 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()
|
var authorities = appUser.getGroups().stream()
|
||||||
.flatMap(group -> group.getPermissions().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)
|
.map(SimpleGrantedAuthority::new)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user