Alerting: Verify receiver permission read on rule create/update (#94286)

* Alerting: Verify receiver permission read on rule create/update
This commit is contained in:
Matthew Jacobson
2024-10-04 23:52:38 +03:00
committed by GitHub
parent 27c7e33217
commit 099055e8a5
5 changed files with 149 additions and 40 deletions
+30 -1
View File
@@ -2,6 +2,7 @@ package accesscontrol
import (
"fmt"
"slices"
"golang.org/x/net/context"
@@ -23,11 +24,17 @@ const (
type RuleService struct {
genericService
notificationSettingsAuth notificationSettingsAuth
}
type notificationSettingsAuth interface {
AuthorizeRead(context.Context, identity.Requester, *models.NotificationSettings) error
}
func NewRuleService(ac accesscontrol.AccessControl) *RuleService {
return &RuleService{
genericService{ac: ac},
genericService: genericService{ac: ac},
notificationSettingsAuth: NewReceiverAccess[*models.NotificationSettings](ac, true),
}
}
@@ -196,6 +203,10 @@ func (r *RuleService) AuthorizeRuleChanges(ctx context.Context, user identity.Re
}); err != nil {
return err
}
if err := r.authorizeNotificationSettings(ctx, user, rule); err != nil {
return err
}
}
if !existingGroup {
// create a new group, check that user has "read" access to that new group. Otherwise, it will not be able to read it back.
@@ -237,6 +248,24 @@ func (r *RuleService) AuthorizeRuleChanges(ctx context.Context, user identity.Re
}
updateAuthorized = true
}
if !slices.EqualFunc(rule.Existing.NotificationSettings, rule.New.NotificationSettings, func(settings models.NotificationSettings, settings2 models.NotificationSettings) bool {
return settings.Equals(&settings2)
}) {
if err := r.authorizeNotificationSettings(ctx, user, rule.New); err != nil {
return err
}
}
}
return nil
}
// authorizeNotificationSettings checks if the user has access to all receivers that are used by the rule's notification settings.
func (r *RuleService) authorizeNotificationSettings(ctx context.Context, user identity.Requester, rule *models.AlertRule) error {
for _, ns := range rule.NotificationSettings {
if err := r.notificationSettingsAuth.AuthorizeRead(ctx, user, &ns); err != nil {
return err
}
}
return nil
}