Access control: Update evaluator to authorize when at least one of the scopes is a match (#33393)

This commit is contained in:
Vardan Torosyan
2021-04-27 18:22:18 +02:00
committed by GitHub
parent 43bfa2801c
commit 5bf6d7dad8
4 changed files with 87 additions and 20 deletions
@@ -9,18 +9,24 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
// Evaluate evaluates access to the given resource, using provided AccessControl instance
func Evaluate(ctx context.Context, ac accesscontrol.AccessControl, user *models.SignedInUser, permission string, scope ...string) (bool, error) {
res, err := ac.GetUserPermissions(ctx, user)
// Evaluate evaluates access to the given resource, using provided AccessControl instance.
// Scopes are evaluated with an `OR` relationship.
func Evaluate(ctx context.Context, ac accesscontrol.AccessControl, user *models.SignedInUser, action string, scope ...string) (bool, error) {
userPermissions, err := ac.GetUserPermissions(ctx, user)
if err != nil {
return false, err
}
ok, dbScopes := extractPermission(res, permission)
ok, dbScopes := extractScopes(userPermissions, action)
if !ok {
return false, nil
}
for _, s := range scope {
return evaluateScope(dbScopes, scope...)
}
func evaluateScope(dbScopes map[string]struct{}, targetScopes ...string) (bool, error) {
for _, s := range targetScopes {
var match bool
for dbScope := range dbScopes {
rule, err := glob.Compile(dbScope, ':', '/')
@@ -30,19 +36,15 @@ func Evaluate(ctx context.Context, ac accesscontrol.AccessControl, user *models.
match = rule.Match(s)
if match {
break
return true, nil
}
}
if !match {
return false, nil
}
}
return true, nil
return false, nil
}
func extractPermission(permissions []*accesscontrol.Permission, permission string) (bool, map[string]struct{}) {
func extractScopes(permissions []*accesscontrol.Permission, targetAction string) (bool, map[string]struct{}) {
scopes := map[string]struct{}{}
ok := false
@@ -50,7 +52,7 @@ func extractPermission(permissions []*accesscontrol.Permission, permission strin
if p == nil {
continue
}
if p.Action == permission {
if p.Action == targetAction {
ok = true
scopes[p.Scope] = struct{}{}
}