mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: handle partially resolved scopes (#85323)
* RBAC: handle partially resolved scopes Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
parent
c6a489cfd8
commit
5dd98a0fd5
@ -2,6 +2,7 @@ package accesscontrol
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@ -84,14 +85,25 @@ func (p permissionEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttri
|
||||
return EvalPermission(p.Action), nil
|
||||
}
|
||||
|
||||
resolved := false
|
||||
scopes := make([]string, 0, len(p.Scopes))
|
||||
for _, scope := range p.Scopes {
|
||||
mutated, err := mutate(ctx, scope)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrResolverNotFound) {
|
||||
scopes = append(scopes, mutated...)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
resolved = true
|
||||
scopes = append(scopes, mutated...)
|
||||
}
|
||||
|
||||
if !resolved {
|
||||
return nil, ErrResolverNotFound
|
||||
}
|
||||
|
||||
return EvalPermission(p.Action, scopes...), nil
|
||||
}
|
||||
|
||||
@ -124,14 +136,24 @@ func (a allEvaluator) Evaluate(permissions map[string][]string) bool {
|
||||
}
|
||||
|
||||
func (a allEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) {
|
||||
resolved := false
|
||||
modified := make([]Evaluator, 0, len(a.allOf))
|
||||
for _, e := range a.allOf {
|
||||
i, err := e.MutateScopes(ctx, mutate)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrResolverNotFound) {
|
||||
modified = append(modified, e)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
resolved = true
|
||||
modified = append(modified, i)
|
||||
}
|
||||
|
||||
if !resolved {
|
||||
return nil, ErrResolverNotFound
|
||||
}
|
||||
return EvalAll(modified...), nil
|
||||
}
|
||||
|
||||
@ -174,14 +196,25 @@ func (a anyEvaluator) Evaluate(permissions map[string][]string) bool {
|
||||
}
|
||||
|
||||
func (a anyEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) {
|
||||
resolved := false
|
||||
modified := make([]Evaluator, 0, len(a.anyOf))
|
||||
for _, e := range a.anyOf {
|
||||
i, err := e.MutateScopes(ctx, mutate)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrResolverNotFound) {
|
||||
modified = append(modified, e)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
resolved = true
|
||||
modified = append(modified, i)
|
||||
}
|
||||
|
||||
if !resolved {
|
||||
return nil, ErrResolverNotFound
|
||||
}
|
||||
|
||||
return EvalAny(modified...), nil
|
||||
}
|
||||
|
||||
|
@ -410,3 +410,49 @@ func TestEval(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEval_MutateScopes(t *testing.T) {
|
||||
t.Run("should return error if none of the scopes was a resolved", func(t *testing.T) {
|
||||
eval := EvalAll(
|
||||
EvalPermission("action:1", "scope:uid:1"),
|
||||
EvalPermission("action:2", "scope:id:1"),
|
||||
)
|
||||
|
||||
calls := 0
|
||||
_, err := eval.MutateScopes(context.Background(), func(ctx context.Context, s string) ([]string, error) {
|
||||
calls += 1
|
||||
return nil, ErrResolverNotFound
|
||||
})
|
||||
|
||||
assert.Equal(t, 2, calls)
|
||||
assert.ErrorIs(t, err, ErrResolverNotFound)
|
||||
})
|
||||
|
||||
t.Run("should return if at least one scope was resolved", func(t *testing.T) {
|
||||
eval := EvalAll(
|
||||
EvalPermission("action:1", "scope:uid:1"),
|
||||
EvalPermission("action:2", "scope:id:1"),
|
||||
)
|
||||
|
||||
calls := 0
|
||||
resolved := 0
|
||||
eval, err := eval.MutateScopes(context.Background(), func(ctx context.Context, s string) ([]string, error) {
|
||||
calls += 1
|
||||
if s == "scope:id:1" {
|
||||
resolved += 1
|
||||
return []string{"scope:uid:2"}, nil
|
||||
}
|
||||
return nil, ErrResolverNotFound
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, calls)
|
||||
assert.Equal(t, 1, resolved)
|
||||
|
||||
hasAccess := eval.Evaluate(map[string][]string{
|
||||
"action:1": {"scope:uid:1"},
|
||||
"action:2": {"scope:uid:2"},
|
||||
})
|
||||
assert.True(t, hasAccess)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user