mirror of
https://github.com/grafana/grafana.git
synced 2024-11-28 19:54:10 -06:00
Alerting: Move interface Namespaced from accesscontrol to models package (#89439)
move Namespaced interface from accesscontrol to models
This commit is contained in:
parent
5d328983a1
commit
92f10b73a8
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
)
|
||||
@ -22,8 +21,8 @@ type FakeRuleService struct {
|
||||
AuthorizeDatasourceAccessForRuleGroupFunc func(context.Context, identity.Requester, models.RulesGroup) error
|
||||
HasAccessToRuleGroupFunc func(context.Context, identity.Requester, models.RulesGroup) (bool, error)
|
||||
AuthorizeAccessToRuleGroupFunc func(context.Context, identity.Requester, models.RulesGroup) error
|
||||
HasAccessInFolderFunc func(context.Context, identity.Requester, accesscontrol.Namespaced) (bool, error)
|
||||
AuthorizeAccessInFolderFunc func(context.Context, identity.Requester, accesscontrol.Namespaced) error
|
||||
HasAccessInFolderFunc func(context.Context, identity.Requester, models.Namespaced) (bool, error)
|
||||
AuthorizeAccessInFolderFunc func(context.Context, identity.Requester, models.Namespaced) error
|
||||
AuthorizeRuleChangesFunc func(context.Context, identity.Requester, *store.GroupDelta) error
|
||||
|
||||
Calls []Call
|
||||
@ -77,7 +76,7 @@ func (s *FakeRuleService) AuthorizeAccessToRuleGroup(ctx context.Context, user i
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FakeRuleService) HasAccessInFolder(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) (bool, error) {
|
||||
func (s *FakeRuleService) HasAccessInFolder(ctx context.Context, user identity.Requester, namespaced models.Namespaced) (bool, error) {
|
||||
s.Calls = append(s.Calls, Call{"HasAccessInFolder", []interface{}{ctx, user, namespaced}})
|
||||
if s.HasAccessInFolderFunc != nil {
|
||||
return s.HasAccessInFolderFunc(ctx, user, namespaced)
|
||||
@ -85,7 +84,7 @@ func (s *FakeRuleService) HasAccessInFolder(ctx context.Context, user identity.R
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (s *FakeRuleService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error {
|
||||
func (s *FakeRuleService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error {
|
||||
s.Calls = append(s.Calls, Call{"AuthorizeAccessInFolder", []interface{}{ctx, user, namespaced}})
|
||||
if s.AuthorizeAccessInFolderFunc != nil {
|
||||
return s.AuthorizeAccessInFolderFunc(ctx, user, namespaced)
|
||||
|
@ -31,10 +31,6 @@ func NewRuleService(ac accesscontrol.AccessControl) *RuleService {
|
||||
}
|
||||
}
|
||||
|
||||
type Namespaced interface {
|
||||
GetNamespaceUID() string
|
||||
}
|
||||
|
||||
// getReadFolderAccessEvaluator constructs accesscontrol.Evaluator that checks all permissions required to read rules in specific folder
|
||||
func getReadFolderAccessEvaluator(folderUID string) accesscontrol.Evaluator {
|
||||
return accesscontrol.EvalAll(
|
||||
@ -130,7 +126,7 @@ func (r *RuleService) AuthorizeAccessToRuleGroup(ctx context.Context, user ident
|
||||
// - ("folders:read") read the folder
|
||||
// - ("alert.rules:read") read alert rules in the folder
|
||||
// Returns false if the requester does not have enough permissions, and error if something went wrong during the permission evaluation.
|
||||
func (r *RuleService) HasAccessInFolder(ctx context.Context, user identity.Requester, rule Namespaced) (bool, error) {
|
||||
func (r *RuleService) HasAccessInFolder(ctx context.Context, user identity.Requester, rule models.Namespaced) (bool, error) {
|
||||
eval := accesscontrol.EvalAll(getReadFolderAccessEvaluator(rule.GetNamespaceUID()))
|
||||
return r.HasAccess(ctx, user, eval)
|
||||
}
|
||||
@ -140,7 +136,7 @@ func (r *RuleService) HasAccessInFolder(ctx context.Context, user identity.Reque
|
||||
// - ("folders:read") read the folder
|
||||
// - ("alert.rules:read") read alert rules in the folder
|
||||
// Returns error if at least one permission is missing or if something went wrong during the permission evaluation
|
||||
func (r *RuleService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, rule Namespaced) error {
|
||||
func (r *RuleService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, rule models.Namespaced) error {
|
||||
eval := accesscontrol.EvalAll(getReadFolderAccessEvaluator(rule.GetNamespaceUID()))
|
||||
return r.HasAccessOrError(ctx, user, eval, func() string {
|
||||
return fmt.Sprintf("access rules in folder '%s'", rule.GetNamespaceUID())
|
||||
|
@ -45,7 +45,7 @@ type RuleAccessControlService interface {
|
||||
AuthorizeRuleChanges(ctx context.Context, user identity.Requester, change *store.GroupDelta) error
|
||||
AuthorizeDatasourceAccessForRule(ctx context.Context, user identity.Requester, rule *models.AlertRule) error
|
||||
AuthorizeDatasourceAccessForRuleGroup(ctx context.Context, user identity.Requester, rules models.RulesGroup) error
|
||||
AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error
|
||||
AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error
|
||||
}
|
||||
|
||||
// API handlers.
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||
@ -147,7 +146,7 @@ func (f fakeRuleAccessControlService) AuthorizeAccessToRuleGroup(ctx context.Con
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f fakeRuleAccessControlService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error {
|
||||
func (f fakeRuleAccessControlService) AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,11 @@ type AlertRule struct {
|
||||
NotificationSettings []NotificationSettings `xorm:"notification_settings"` // we use slice to workaround xorm mapping that does not serialize a struct to JSON unless it's a slice
|
||||
}
|
||||
|
||||
// Namespaced describes a class of resources that are stored in a specific namespace.
|
||||
type Namespaced interface {
|
||||
GetNamespaceUID() string
|
||||
}
|
||||
|
||||
// AlertRuleWithOptionals This is to avoid having to pass in additional arguments deep in the call stack. Alert rule
|
||||
// object is created in an early validation step without knowledge about current alert rule fields or if they need to be
|
||||
// overridden. This is done in a later step and, in that step, we did not have knowledge about if a field was optional
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
@ -24,7 +23,7 @@ type SilenceService struct {
|
||||
}
|
||||
|
||||
type RuleAccessControlService interface {
|
||||
HasAccessInFolder(ctx context.Context, user identity.Requester, rule accesscontrol.Namespaced) (bool, error)
|
||||
HasAccessInFolder(ctx context.Context, user identity.Requester, rule models.Namespaced) (bool, error)
|
||||
}
|
||||
|
||||
// SilenceAccessControlService provides access control for silences.
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@ -61,7 +60,7 @@ func TestWithRuleMetadata(t *testing.T) {
|
||||
user := ac.BackgroundUser("test", 1, org.RoleNone, nil)
|
||||
t.Run("Attach rule metadata to silences", func(t *testing.T) {
|
||||
ruleAuthz := fakes.FakeRuleService{}
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence accesscontrol.Namespaced) (bool, error) {
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence models.Namespaced) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -95,7 +94,7 @@ func TestWithRuleMetadata(t *testing.T) {
|
||||
})
|
||||
t.Run("Don't attach full rule metadata if no access or global", func(t *testing.T) {
|
||||
ruleAuthz := fakes.FakeRuleService{}
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence accesscontrol.Namespaced) (bool, error) {
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence models.Namespaced) (bool, error) {
|
||||
return silence.GetNamespaceUID() == "folder1", nil
|
||||
}
|
||||
|
||||
@ -134,7 +133,7 @@ func TestWithRuleMetadata(t *testing.T) {
|
||||
})
|
||||
t.Run("Don't check same namespace access more than once", func(t *testing.T) {
|
||||
ruleAuthz := fakes.FakeRuleService{}
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence accesscontrol.Namespaced) (bool, error) {
|
||||
ruleAuthz.HasAccessInFolderFunc = func(ctx context.Context, user identity.Requester, silence models.Namespaced) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -159,7 +158,7 @@ func TestWithRuleMetadata(t *testing.T) {
|
||||
require.NoError(t, svc.WithRuleMetadata(context.Background(), user, silencesWithMetadata...))
|
||||
assert.Lenf(t, ruleAuthz.Calls, 1, "HasAccessInFolder should be called only once per namespace")
|
||||
assert.Equal(t, "HasAccessInFolder", ruleAuthz.Calls[0].MethodName)
|
||||
assert.Equal(t, "folder1", ruleAuthz.Calls[0].Arguments[2].(accesscontrol.Namespaced).GetNamespaceUID())
|
||||
assert.Equal(t, "folder1", ruleAuthz.Calls[0].Arguments[2].(models.Namespaced).GetNamespaceUID())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
)
|
||||
@ -13,7 +12,7 @@ import (
|
||||
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
|
||||
AuthorizeAccessInFolder(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error
|
||||
AuthorizeRuleChanges(ctx context.Context, user identity.Requester, change *store.GroupDelta) error
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
accesscontrol2 "github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
@ -200,7 +199,7 @@ func TestAuthorizeAccessToRule(t *testing.T) {
|
||||
rs.HasAccessFunc = func(ctx context.Context, user identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
rs.AuthorizeAccessInFolderFunc = func(ctx context.Context, requester identity.Requester, namespaced accesscontrol2.Namespaced) error {
|
||||
rs.AuthorizeAccessInFolderFunc = func(ctx context.Context, requester identity.Requester, namespaced models.Namespaced) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -231,7 +230,7 @@ func TestAuthorizeAccessToRule(t *testing.T) {
|
||||
return false, nil
|
||||
}
|
||||
expected = errors.New("test2")
|
||||
rs.AuthorizeAccessInFolderFunc = func(ctx context.Context, requester identity.Requester, rule accesscontrol2.Namespaced) error {
|
||||
rs.AuthorizeAccessInFolderFunc = func(ctx context.Context, requester identity.Requester, rule models.Namespaced) error {
|
||||
return expected
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ func TestGetAlertRule(t *testing.T) {
|
||||
service, _, _, ac := initServiceWithData(t)
|
||||
|
||||
expected := errors.New("test")
|
||||
ac.AuthorizeAccessInFolderFunc = func(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error {
|
||||
ac.AuthorizeAccessInFolderFunc = func(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error {
|
||||
assert.Equal(t, u, user)
|
||||
assert.EqualValues(t, rule, namespaced)
|
||||
return expected
|
||||
@ -1034,7 +1034,7 @@ func TestGetAlertRule(t *testing.T) {
|
||||
assert.Equal(t, "AuthorizeRuleRead", ac.Calls[0].Method)
|
||||
|
||||
ac.Calls = nil
|
||||
ac.AuthorizeAccessInFolderFunc = func(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error {
|
||||
ac.AuthorizeAccessInFolderFunc = func(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
@ -161,7 +160,7 @@ type fakeRuleAccessControlService struct {
|
||||
mu sync.Mutex
|
||||
Calls []call
|
||||
AuthorizeAccessToRuleGroupFunc func(ctx context.Context, user identity.Requester, rules models.RulesGroup) error
|
||||
AuthorizeAccessInFolderFunc func(ctx context.Context, user identity.Requester, namespaced accesscontrol.Namespaced) error
|
||||
AuthorizeAccessInFolderFunc func(ctx context.Context, user identity.Requester, namespaced models.Namespaced) error
|
||||
AuthorizeRuleChangesFunc func(ctx context.Context, user identity.Requester, change *store.GroupDelta) error
|
||||
CanReadAllRulesFunc func(ctx context.Context, user identity.Requester) (bool, error)
|
||||
CanWriteAllRulesFunc func(ctx context.Context, user identity.Requester) (bool, error)
|
||||
|
Loading…
Reference in New Issue
Block a user