fix: syncOidcRoles uses direct roles only, always overwrites
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 1m0s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 35s

- Expose getDirectRolesForUser on RbacService interface so syncOidcRoles
  compares against directly-assigned roles only, not group-inherited ones
- Remove early-return that preserved existing roles when OIDC returned
  none — now always applies defaultRoles as fallback
- Update CLAUDE.md and SERVER-CAPABILITIES.md to reflect changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-07 10:56:40 +02:00
parent ca1b549f10
commit 07f3c2584c
5 changed files with 8 additions and 18 deletions

View File

@@ -239,7 +239,8 @@ public class RbacServiceImpl implements RbacService {
return max;
}
private List<RoleSummary> getDirectRolesForUser(String userId) {
@Override
public List<RoleSummary> getDirectRolesForUser(String userId) {
return jdbc.query("""
SELECT r.id, r.name, r.system FROM user_roles ur
JOIN roles r ON r.id = ur.role_id WHERE ur.user_id = ?

View File

@@ -174,18 +174,6 @@ public class OidcAuthController {
}
private void syncOidcRoles(String userId, List<String> oidcRoles, OidcConfig config) {
// If OIDC returned no roles and user already has local roles, preserve them
if (oidcRoles.isEmpty()) {
Set<UUID> current = rbacService.getEffectiveRolesForUser(userId).stream()
.filter(r -> SystemRole.isSystem(r.id()))
.map(RoleSummary::id)
.collect(Collectors.toSet());
if (!current.isEmpty()) {
log.info("syncOidcRoles: userId={}, no OIDC roles, preserving existing roles: {}", userId, current);
return;
}
}
List<String> roleNames = !oidcRoles.isEmpty() ? oidcRoles : config.defaultRoles();
log.info("syncOidcRoles: userId={}, oidcRoles={}, defaultRoles={}, using={}",
userId, oidcRoles, config.defaultRoles(), roleNames);
@@ -199,8 +187,8 @@ public class OidcAuthController {
}
}
// Current system roles (excludes group-inherited roles)
Set<UUID> current = rbacService.getEffectiveRolesForUser(userId).stream()
// Only compare against directly-assigned roles (not group-inherited)
Set<UUID> current = rbacService.getDirectRolesForUser(userId).stream()
.filter(r -> SystemRole.isSystem(r.id()))
.map(RoleSummary::id)
.collect(Collectors.toSet());