grafana/pkg/services/ngalert/provisioning/accesscontrol.go

98 lines
4.3 KiB
Go
Raw Normal View History

package provisioning
import (
"context"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/auth/identity"
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/store"
)
type RuleAccessControlService interface {
HasAccess(ctx context.Context, user identity.Requester, evaluator ac.Evaluator) (bool, error)
AuthorizeAccessToRuleGroup(ctx context.Context, user identity.Requester, rules models.RulesGroup) error
AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error
AuthorizeRuleChanges(ctx context.Context, user identity.Requester, change *store.GroupDelta) error
}
func newRuleAccessControlService(ac RuleAccessControlService) *provisioningRuleAccessControl {
return &provisioningRuleAccessControl{
RuleAccessControlService: ac,
}
}
type provisioningRuleAccessControl struct {
RuleAccessControlService
}
var _ ruleAccessControlService = &provisioningRuleAccessControl{}
// AuthorizeRuleRead authorizes the read access to a rule for a user.
// It first checks if the user has permission to read all rules. If yes, it bypasses the authorization.
// If not, it calls the RuleAccessControlService to authorize access to the rule.
// It returns an error if the authorization fails or if there is an error during permission check.
func (p *provisioningRuleAccessControl) AuthorizeRuleRead(ctx context.Context, user identity.Requester, rule *models.AlertRule) error {
can, err := p.CanReadAllRules(ctx, user)
if err != nil {
return err
}
if !can {
return p.RuleAccessControlService.AuthorizeAccessInFolder(ctx, user, rule)
}
return nil
}
// AuthorizeRuleGroupRead authorizes the read access to a group of rules for a user.
// It first checks if the user has permission to read all rules. If yes, it bypasses the authorization.
// If not, it calls the RuleAccessControlService to authorize access to the rule group.
// It returns an error if the authorization fails or if there is an error during permission check.
func (p *provisioningRuleAccessControl) AuthorizeRuleGroupRead(ctx context.Context, user identity.Requester, rules models.RulesGroup) error {
can, err := p.CanReadAllRules(ctx, user)
if err != nil {
return err
}
if !can {
return p.RuleAccessControlService.AuthorizeAccessToRuleGroup(ctx, user, rules)
}
return nil
}
// AuthorizeRuleGroupWrite authorizes the write access to a group of rules for a user.
// It first checks if the user has permission to write all rules. If yes, it bypasses the authorization.
// If not, it calls the RuleAccessControlService to authorize the rule changes.
// It returns an error if the authorization fails or if there is an error during permission check.
func (p *provisioningRuleAccessControl) AuthorizeRuleGroupWrite(ctx context.Context, user identity.Requester, change *store.GroupDelta) error {
can, err := p.CanWriteAllRules(ctx, user)
if err != nil {
return err
}
if !can {
return p.RuleAccessControlService.AuthorizeRuleChanges(ctx, user, change)
}
return nil
}
// CanReadAllRules checks if the user has permission to read all rules.
// It evaluates if the user has either "alert.provisioning:read" or "alert.provisioning.secrets:read" permissions.
// It returns true if the user has the required permissions, otherwise it returns false.
func (p *provisioningRuleAccessControl) CanReadAllRules(ctx context.Context, user identity.Requester) (bool, error) {
return p.HasAccess(ctx, user, ac.EvalAny(
ac.EvalPermission(ac.ActionAlertingProvisioningRead),
ac.EvalPermission(ac.ActionAlertingProvisioningReadSecrets),
ac.EvalPermission(ac.ActionAlertingRulesProvisioningRead),
))
}
// CanWriteAllRules is a method that checks if a user has permission to write all rules.
// It calls the HasAccess method with the provided action "alert.provisioning:write".
// It returns true if the user has permission, false otherwise.
// It returns an error if there is a problem checking the permission.
func (p *provisioningRuleAccessControl) CanWriteAllRules(ctx context.Context, user identity.Requester) (bool, error) {
return p.HasAccess(ctx, user, ac.EvalAny(
ac.EvalPermission(ac.ActionAlertingProvisioningWrite),
ac.EvalPermission(ac.ActionAlertingRulesProvisioningWrite),
))
}