mirror of
https://github.com/grafana/grafana.git
synced 2026-08-18 17:15:08 -05:00
Access Control: Refactor scope resolvers with support to resolve into several scopes (#48202)
* Refactor Scope resolver to support resolving into several scopes * Change permission evaluator to match at least one of passed scopes
This commit is contained in:
@@ -33,11 +33,11 @@ func ProvideService(features featuremgmt.FeatureToggles,
|
||||
|
||||
func ProvideOSSAccessControl(features featuremgmt.FeatureToggles, provider accesscontrol.PermissionsProvider) *OSSAccessControlService {
|
||||
s := &OSSAccessControlService{
|
||||
features: features,
|
||||
provider: provider,
|
||||
log: log.New("accesscontrol"),
|
||||
scopeResolver: accesscontrol.NewScopeResolver(),
|
||||
roles: accesscontrol.BuildMacroRoleDefinitions(),
|
||||
features: features,
|
||||
provider: provider,
|
||||
log: log.New("accesscontrol"),
|
||||
scopeResolvers: accesscontrol.NewScopeResolvers(),
|
||||
roles: accesscontrol.BuildMacroRoleDefinitions(),
|
||||
}
|
||||
|
||||
return s
|
||||
@@ -45,12 +45,12 @@ func ProvideOSSAccessControl(features featuremgmt.FeatureToggles, provider acces
|
||||
|
||||
// OSSAccessControlService is the service implementing role based access control.
|
||||
type OSSAccessControlService struct {
|
||||
log log.Logger
|
||||
features featuremgmt.FeatureToggles
|
||||
scopeResolver accesscontrol.ScopeResolver
|
||||
provider accesscontrol.PermissionsProvider
|
||||
registrations accesscontrol.RegistrationList
|
||||
roles map[string]*accesscontrol.RoleDTO
|
||||
log log.Logger
|
||||
features featuremgmt.FeatureToggles
|
||||
scopeResolvers accesscontrol.ScopeResolvers
|
||||
provider accesscontrol.PermissionsProvider
|
||||
registrations accesscontrol.RegistrationList
|
||||
roles map[string]*accesscontrol.RoleDTO
|
||||
}
|
||||
|
||||
func (ac *OSSAccessControlService) IsDisabled() bool {
|
||||
@@ -92,7 +92,7 @@ func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.Si
|
||||
user.Permissions[user.OrgId] = accesscontrol.GroupScopesByAction(permissions)
|
||||
}
|
||||
|
||||
attributeMutator := ac.scopeResolver.GetResolveAttributeScopeMutator(user.OrgId)
|
||||
attributeMutator := ac.scopeResolvers.GetScopeAttributeMutator(user.OrgId)
|
||||
resolvedEvaluator, err := evaluator.MutateScopes(ctx, attributeMutator)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -124,7 +124,7 @@ func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user
|
||||
|
||||
permissions = append(permissions, dbPermissions...)
|
||||
resolved := make([]*accesscontrol.Permission, 0, len(permissions))
|
||||
keywordMutator := ac.scopeResolver.GetResolveKeywordScopeMutator(user)
|
||||
keywordMutator := ac.scopeResolvers.GetScopeKeywordMutator(user)
|
||||
for _, p := range permissions {
|
||||
// if the permission has a keyword in its scope it will be resolved
|
||||
p.Scope, err = keywordMutator(ctx, p.Scope)
|
||||
@@ -217,8 +217,8 @@ func (ac *OSSAccessControlService) DeclareFixedRoles(registrations ...accesscont
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAttributeScopeResolver allows the caller to register scope resolvers for a
|
||||
// RegisterScopeAttributeResolver allows the caller to register scope resolvers for a
|
||||
// specific scope prefix (ex: datasources:name:)
|
||||
func (ac *OSSAccessControlService) RegisterAttributeScopeResolver(scopePrefix string, resolver accesscontrol.AttributeScopeResolveFunc) {
|
||||
ac.scopeResolver.AddAttributeResolver(scopePrefix, resolver)
|
||||
func (ac *OSSAccessControlService) RegisterScopeAttributeResolver(scopePrefix string, resolver accesscontrol.ScopeAttributeResolver) {
|
||||
ac.scopeResolvers.AddScopeAttributeResolver(scopePrefix, resolver)
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ func setupTestEnv(t testing.TB) *OSSAccessControlService {
|
||||
t.Helper()
|
||||
|
||||
ac := &OSSAccessControlService{
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagAccesscontrol),
|
||||
log: log.New("accesscontrol"),
|
||||
registrations: accesscontrol.RegistrationList{},
|
||||
scopeResolver: accesscontrol.NewScopeResolver(),
|
||||
provider: database.ProvideService(sqlstore.InitTestDB(t)),
|
||||
roles: accesscontrol.BuildMacroRoleDefinitions(),
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagAccesscontrol),
|
||||
log: log.New("accesscontrol"),
|
||||
registrations: accesscontrol.RegistrationList{},
|
||||
scopeResolvers: accesscontrol.NewScopeResolvers(),
|
||||
provider: database.ProvideService(sqlstore.InitTestDB(t)),
|
||||
roles: accesscontrol.BuildMacroRoleDefinitions(),
|
||||
}
|
||||
require.NoError(t, ac.RegisterFixedRoles(context.Background()))
|
||||
return ac
|
||||
@@ -439,12 +439,12 @@ func TestOSSAccessControlService_Evaluate(t *testing.T) {
|
||||
},
|
||||
Grants: []string{"Viewer"},
|
||||
}
|
||||
userLoginScopeSolver := func(ctx context.Context, orgID int64, initialScope string) (string, error) {
|
||||
userLoginScopeSolver := accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, initialScope string) ([]string, error) {
|
||||
if initialScope == "users:login:testUser" {
|
||||
return "users:id:2", nil
|
||||
return []string{"users:id:2"}, nil
|
||||
}
|
||||
return initialScope, nil
|
||||
}
|
||||
return []string{initialScope}, nil
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -475,7 +475,7 @@ func TestOSSAccessControlService_Evaluate(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Setup
|
||||
ac := setupTestEnv(t)
|
||||
ac.RegisterAttributeScopeResolver("users:login:", userLoginScopeSolver)
|
||||
ac.RegisterScopeAttributeResolver("users:login:", userLoginScopeSolver)
|
||||
|
||||
registration.Role.Permissions = []accesscontrol.Permission{tt.rawPerm}
|
||||
err := ac.DeclareFixedRoles(registration)
|
||||
|
||||
Reference in New Issue
Block a user