RBAC: Split non-empty scopes into kind, attribute and identifier fields for better search performance (#71933)

* add a feature toggle

* add the fields for attribute, kind and identifier to permission

Co-authored-by: Kalle Persson <kalle.persson@grafana.com>

* set the new fields when new permissions are stored

* add migrations

Co-authored-by: Kalle Persson <kalle.persson@grafana.com>

* remove comments

* Update pkg/services/accesscontrol/migrator/migrator.go

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>

* feedback: put column migrations behind the feature toggle, added an index, changed how wildcard scopes are split

* PR feedback: add a comment and revert an accidentally changed file

* PR feedback: handle the case with : in resource identifier

* switch from checking feature toggle through cfg to checking it through featuremgmt

* don't put the column migrations behind a feature toggle after all - this breaks permission queries from db

---------

Co-authored-by: Kalle Persson <kalle.persson@grafana.com>
Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
Ieva
2023-07-21 15:23:01 +01:00
committed by GitHub
co-authored by Kalle Persson Gabriel MABILLE
parent 59eb2f68b7
commit cfa1a2c55f
23 changed files with 179 additions and 37 deletions
+30
View File
@@ -3,6 +3,7 @@ package accesscontrol
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -108,3 +109,32 @@ func TestSaveExternalServiceRoleCommand_Validate(t *testing.T) {
})
}
}
func TestPermission_ScopeSplit(t *testing.T) {
type testCase struct {
desc string
scope string
kind string
attribute string
identifier string
}
tests := []testCase{
{desc: "all fields should be empty for empty scope", scope: "", kind: "", attribute: "", identifier: ""},
{desc: "all fields should be set to * for wildcard", scope: "*", kind: "*", attribute: "*", identifier: "*"},
{desc: "kind should be specified and attribute and identifier should be * for a wildcard with kind prefix", scope: "dashboards:*", kind: "dashboards", attribute: "*", identifier: "*"},
{desc: "all fields should be set correctly", scope: "dashboards:uid:123", kind: "dashboards", attribute: "uid", identifier: "123"},
{desc: "can handle a case with : in the uid", scope: "datasources:uid:weird:name", kind: "datasources", attribute: "uid", identifier: "weird:name"},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
p := Permission{Scope: tt.scope}
kind, attribute, identifier := p.SplitScope()
assert.Equal(t, tt.kind, kind)
assert.Equal(t, tt.attribute, attribute)
assert.Equal(t, tt.identifier, identifier)
})
}
}