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:
Karl Persson
2022-05-02 09:29:30 +02:00
committed by GitHub
parent 9622e7457e
commit de50f39c12
18 changed files with 453 additions and 434 deletions
@@ -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)