Fix RBAC authorization logic to only return notifiers with matching roles

- Change IsAuthorized() to use deny-by-default when RBAC is enabled
- If ANY authorization rules are configured, only notifiers with explicit allowed_roles are accessible
- Notifiers without rules are denied access when RBAC is active
- If NO rules are configured, maintain open access for backward compatibility
- Add HasRules() helper method to check if RBAC is enabled

This fixes the issue where notifiers WITHOUT allowed_roles were being returned instead of
the notifiers WITH matching allowed_roles. Now when RBAC is configured:
- Only notifiers with explicit rules that match the user's roles are returned
- All other notifiers are hidden from the client

Example: If only email has allowed_roles=['admin'] and user has role 'admin':
- OLD: email ✓, stdout ✓ (WRONG - stdout should be hidden)
- NEW: email ✓, stdout ✗ (CORRECT - only email is returned)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-31 01:43:18 -07:00
parent 5eaf6fe6fb
commit 4e594d3a7d
+22 -11
View File
@@ -34,21 +34,32 @@ func (a *NotifierAuthz) IsAuthorized(auth *AuthContext, notificationType domain.
key := makeAuthzKey(notificationType, account)
allowedRoles, exists := a.rules[key]
// If no specific rule is registered, allow all authenticated users
if !exists {
return true
}
// Check if any of the user's roles is in the allowed roles
for _, userRole := range auth.Roles {
for _, allowedRole := range allowedRoles {
if userRole == allowedRole {
return true
// If RBAC is enabled (at least one rule exists), restrict access:
// - Notifiers with explicit rules: check if user has allowed roles
// - Notifiers without rules: deny access (must be explicitly allowed)
if a.HasRules() {
if !exists {
// RBAC is enabled but this notifier has no rule - deny access
return false
}
// Check if any of the user's roles is in the allowed roles
for _, userRole := range auth.Roles {
for _, allowedRole := range allowedRoles {
if userRole == allowedRole {
return true
}
}
}
return false
}
return false
// If no rules are registered at all, allow all authenticated users (open access)
return true
}
// HasRules returns true if any authorization rules have been registered
func (a *NotifierAuthz) HasRules() bool {
return len(a.rules) > 0
}
// GetAllowedRoles returns the allowed roles for a notifier