diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcAuthController.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcAuthController.java index 1f1c89c7..2bff1b17 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcAuthController.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcAuthController.java @@ -156,7 +156,7 @@ public class OidcAuthController { userId, provider, oidcUser.email(), oidcUser.name(), Instant.now())); // Apply claim mapping rules to assign managed roles/groups from JWT claims - applyClaimMappings(userId, oidcUser.allClaims()); + applyClaimMappings(userId, oidcUser.allClaims(), config.get()); List roles = rbacService.getSystemRoleNames(userId); @@ -180,37 +180,50 @@ public class OidcAuthController { } } - private void applyClaimMappings(String userId, Map claims) { + private void applyClaimMappings(String userId, Map claims, OidcConfig oidcConfig) { List rules = claimMappingRepository.findAll(); - if (rules.isEmpty()) { - log.debug("No claim mapping rules configured, skipping for user {}", userId); - return; - } rbacService.clearManagedAssignments(userId); - List results = claimMappingService.evaluate(rules, claims); - for (var result : results) { - ClaimMappingRule rule = result.rule(); - switch (rule.action()) { - case "assignRole" -> { - UUID roleId = SystemRole.BY_NAME.get(SystemRole.normalizeScope(rule.target())); - if (roleId == null) { - log.warn("Claim mapping target role '{}' not found, skipping", rule.target()); - continue; + List results = List.of(); + if (!rules.isEmpty()) { + results = claimMappingService.evaluate(rules, claims); + for (var result : results) { + ClaimMappingRule rule = result.rule(); + switch (rule.action()) { + case "assignRole" -> { + UUID roleId = SystemRole.BY_NAME.get(SystemRole.normalizeScope(rule.target())); + if (roleId == null) { + log.warn("Claim mapping target role '{}' not found, skipping", rule.target()); + continue; + } + rbacService.assignManagedRole(userId, roleId, rule.id()); + log.debug("Managed role {} assigned to {} via mapping {}", rule.target(), userId, rule.id()); + } + case "addToGroup" -> { + var groups = groupRepository.findAll(); + var group = groups.stream().filter(g -> g.name().equalsIgnoreCase(rule.target())).findFirst(); + if (group.isEmpty()) { + log.warn("Claim mapping target group '{}' not found, skipping", rule.target()); + continue; + } + rbacService.addUserToManagedGroup(userId, group.get().id(), rule.id()); + log.debug("Managed group {} assigned to {} via mapping {}", rule.target(), userId, rule.id()); } - rbacService.assignManagedRole(userId, roleId, rule.id()); - log.debug("Managed role {} assigned to {} via mapping {}", rule.target(), userId, rule.id()); } - case "addToGroup" -> { - var groups = groupRepository.findAll(); - var group = groups.stream().filter(g -> g.name().equalsIgnoreCase(rule.target())).findFirst(); - if (group.isEmpty()) { - log.warn("Claim mapping target group '{}' not found, skipping", rule.target()); - continue; + } + } + + // Fallback: if no mapping rules matched, assign defaultRoles from OIDC config + if (results.isEmpty()) { + List defaultRoles = oidcConfig.defaultRoles(); + if (defaultRoles != null && !defaultRoles.isEmpty()) { + for (String roleName : defaultRoles) { + UUID roleId = SystemRole.BY_NAME.get(SystemRole.normalizeScope(roleName)); + if (roleId != null) { + rbacService.assignRoleToUser(userId, roleId); + log.debug("Default role {} assigned to {} (no claim mapping matched)", roleName, userId); } - rbacService.addUserToManagedGroup(userId, group.get().id(), rule.id()); - log.debug("Managed group {} assigned to {} via mapping {}", rule.target(), userId, rule.id()); } } }