Access control: Allow empty scope requirement lists (#33518)

This commit is contained in:
Emil Tullstedt
2021-04-29 13:22:13 +02:00
committed by GitHub
parent 017bcc73ba
commit 840828b5d2
2 changed files with 73 additions and 31 deletions

View File

@@ -26,6 +26,10 @@ func Evaluate(ctx context.Context, ac accesscontrol.AccessControl, user *models.
} }
func evaluateScope(dbScopes map[string]struct{}, targetScopes ...string) (bool, error) { func evaluateScope(dbScopes map[string]struct{}, targetScopes ...string) (bool, error) {
if len(targetScopes) == 0 {
return true, nil
}
for _, s := range targetScopes { for _, s := range targetScopes {
var match bool var match bool
for dbScope := range dbScopes { for dbScope := range dbScopes {

View File

@@ -3,9 +3,10 @@ package evaluator
import ( import (
"testing" "testing"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/accesscontrol"
) )
func TestExtractPermission(t *testing.T) { func TestExtractPermission(t *testing.T) {
@@ -29,37 +30,74 @@ func TestExtractPermission(t *testing.T) {
} }
func TestEvaluatePermissions(t *testing.T) { func TestEvaluatePermissions(t *testing.T) {
scopes := map[string]struct{}{ tests := []struct {
"teams:*/permissions:*": {}, Name string
"users:*": {}, HasScopes map[string]struct{}
"permissions:delegate": {}, NeedAnyScope []string
Valid bool
}{
{
Name: "Base",
HasScopes: map[string]struct{}{},
NeedAnyScope: []string{},
Valid: true,
},
{
Name: "No expected scope always returns true",
HasScopes: map[string]struct{}{
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
},
NeedAnyScope: []string{},
Valid: true,
},
{
Name: "Single scope from list",
HasScopes: map[string]struct{}{
"teams:1/permissions:delegate": {},
},
NeedAnyScope: []string{"teams:1/permissions:delegate"},
Valid: true,
},
{
Name: "Single scope from glob list",
HasScopes: map[string]struct{}{
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
},
NeedAnyScope: []string{"teams:1/permissions:delegate"},
Valid: true,
},
{
Name: "Either of two scopes from glob list",
HasScopes: map[string]struct{}{
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
},
NeedAnyScope: []string{"global:admin", "permissions:delegate"},
Valid: true,
},
{
Name: "No match found",
HasScopes: map[string]struct{}{
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
},
NeedAnyScope: []string{"teams1/permissions:delegate"},
Valid: false,
},
} }
ok, err := evaluateScope(scopes, "teams:1/permissions:delegate") for _, tc := range tests {
require.NoError(t, err) tc := tc
assert.True(t, ok) t.Run(tc.Name, func(t *testing.T) {
} ok, err := evaluateScope(tc.HasScopes, tc.NeedAnyScope...)
require.NoError(t, err)
func TestEvaluatePermissions_WhenAtLeastOneScopeIsMatched_ReturnsTrue(t *testing.T) { assert.Equal(t, tc.Valid, ok)
scopes := map[string]struct{}{ })
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
} }
ok, err := evaluateScope(scopes, "global:admin", "permissions:delegate")
require.NoError(t, err)
assert.True(t, ok)
}
func TestEvaluatePermissions_WhenNoMatchFound_ReturnsFalse(t *testing.T) {
scopes := map[string]struct{}{
"teams:*/permissions:*": {},
"users:*": {},
"permissions:delegate": {},
}
ok, err := evaluateScope(scopes, "teams1/permissions:delegate")
require.NoError(t, err)
assert.False(t, ok)
} }