diff --git a/pkg/services/accesscontrol/filter.go b/pkg/services/accesscontrol/filter.go index 63958b77449..b8fb8675fbb 100644 --- a/pkg/services/accesscontrol/filter.go +++ b/pkg/services/accesscontrol/filter.go @@ -51,7 +51,7 @@ func Filter(user *models.SignedInUser, sqlID, prefix string, actions ...string) if len(ids) == 0 { return denyQuery, nil } - for _, id := range ids { + for id := range ids { result[id] += 1 } } @@ -84,14 +84,15 @@ func Filter(user *models.SignedInUser, sqlID, prefix string, actions ...string) return SQLFilter{query.String(), ids}, nil } -func parseScopes(prefix string, scopes []string) (ids []int64, hasWildcard bool) { +func parseScopes(prefix string, scopes []string) (ids map[int64]struct{}, hasWildcard bool) { + ids = make(map[int64]struct{}) for _, scope := range scopes { if strings.HasPrefix(scope, prefix) || scope == "*" { if id := strings.TrimPrefix(scope, prefix); id == "*" || id == ":*" || id == ":id:*" { return nil, true } if id, err := parseScopeID(scope); err == nil { - ids = append(ids, id) + ids[id] = struct{}{} } } } diff --git a/pkg/services/accesscontrol/filter_test.go b/pkg/services/accesscontrol/filter_test.go index 121e0226c85..ac5dc67adf2 100644 --- a/pkg/services/accesscontrol/filter_test.go +++ b/pkg/services/accesscontrol/filter_test.go @@ -129,6 +129,18 @@ func TestFilter_Datasources(t *testing.T) { expectedDataSources: []string{}, expectErr: false, }, + { + desc: "expect to not crash if duplicates in the scope", + sqlID: "data_source.id", + prefix: "datasources", + actions: []string{"datasources:read", "datasources:write"}, + permissions: map[string][]string{ + "datasources:read": {"datasources:id:3", "datasources:id:7", "datasources:id:8", "datasources:id:3", "datasources:id:8"}, + "datasources:write": {"datasources:id:3", "datasources:id:7"}, + }, + expectedDataSources: []string{"ds:3", "ds:7"}, + expectErr: false, + }, } // set sqlIDAcceptList before running tests