IAM: fix GetSearchPermissionCacheKey uniqueness (#95192)
* fix: Change users permissions search to use a consistent key without collisions * Move HashString to cacheutils * Change error handling logic for what to do with a cache key * Add a test that confirms search cache key consistency
This commit is contained in:
@@ -4,13 +4,17 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
var testLogger = log.New("test")
|
||||
|
||||
func TestPermissionCacheKey(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
@@ -75,23 +79,18 @@ func TestPermissionCacheKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetSearchPermissionCacheKey(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
keyInputs := []struct {
|
||||
signedInUser *user.SignedInUser
|
||||
searchOptions SearchOptions
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "should return correct key for user with no options",
|
||||
signedInUser: &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
},
|
||||
searchOptions: SearchOptions{},
|
||||
expected: "rbac-permissions-1-user-1",
|
||||
},
|
||||
{
|
||||
name: "should return correct key for user with action",
|
||||
signedInUser: &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
@@ -99,10 +98,8 @@ func TestGetSearchPermissionCacheKey(t *testing.T) {
|
||||
searchOptions: SearchOptions{
|
||||
Action: "datasources:read",
|
||||
},
|
||||
expected: "rbac-permissions-1-user-1-datasources:read",
|
||||
},
|
||||
{
|
||||
name: "should return correct key for user with scope",
|
||||
signedInUser: &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
@@ -110,10 +107,8 @@ func TestGetSearchPermissionCacheKey(t *testing.T) {
|
||||
searchOptions: SearchOptions{
|
||||
Scope: "datasources:*",
|
||||
},
|
||||
expected: "rbac-permissions-1-user-1-datasources:*",
|
||||
},
|
||||
{
|
||||
name: "should return correct key for user with action and scope",
|
||||
signedInUser: &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
@@ -122,10 +117,8 @@ func TestGetSearchPermissionCacheKey(t *testing.T) {
|
||||
Action: "datasources:read",
|
||||
Scope: "datasources:*",
|
||||
},
|
||||
expected: "rbac-permissions-1-user-1-datasources:read-datasources:*",
|
||||
},
|
||||
{
|
||||
name: "should return correct key for user with role prefixes",
|
||||
signedInUser: &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
@@ -133,13 +126,40 @@ func TestGetSearchPermissionCacheKey(t *testing.T) {
|
||||
searchOptions: SearchOptions{
|
||||
RolePrefixes: []string{"foo", "bar"},
|
||||
},
|
||||
expected: "rbac-permissions-1-user-1-foo-bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Equal(t, tc.expected, GetSearchPermissionCacheKey(tc.signedInUser, tc.searchOptions))
|
||||
})
|
||||
cacheKeys := make([]string, 0, len(keyInputs))
|
||||
|
||||
for _, i := range keyInputs {
|
||||
key, err := GetSearchPermissionCacheKey(testLogger, i.signedInUser, i.searchOptions)
|
||||
require.NoError(t, err)
|
||||
cacheKeys = append(cacheKeys, key)
|
||||
}
|
||||
|
||||
uniqueCheck := make(map[string]bool)
|
||||
for _, str := range cacheKeys {
|
||||
require.False(t, uniqueCheck[str], "Found duplicate string: %s", str)
|
||||
uniqueCheck[str] = true
|
||||
}
|
||||
|
||||
assert.Equal(t, len(cacheKeys), len(uniqueCheck), "The slice contains duplicate strings")
|
||||
|
||||
t.Run("the cache key is consistent", func(t *testing.T) {
|
||||
user := &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
UserID: 1,
|
||||
}
|
||||
key1, err := GetSearchPermissionCacheKey(testLogger, user, SearchOptions{
|
||||
ActionPrefix: "foobar",
|
||||
RolePrefixes: []string{"foo", "bar"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
key2, err := GetSearchPermissionCacheKey(testLogger, user, SearchOptions{
|
||||
ActionPrefix: "foobar",
|
||||
RolePrefixes: []string{"foo", "bar"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, key1, key2, "expected search cache keys to be consistent")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user