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:
Aaron Godin
2024-10-23 15:37:30 -05:00
committed by GitHub
parent 66c728d26b
commit d89235aa8c
3 changed files with 77 additions and 34 deletions
+29 -14
View File
@@ -1,31 +1,46 @@
package accesscontrol
import (
"bytes"
"encoding/base64"
"encoding/gob"
"fmt"
"hash/fnv"
"strings"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/apimachinery/identity"
)
func (s *SearchOptions) HashString() (string, error) {
if s == nil {
return "", nil
}
var buf bytes.Buffer
encoder := gob.NewEncoder(&buf)
if err := encoder.Encode(s); err != nil {
return "", err
}
h := fnv.New64a()
_, err := h.Write(buf.Bytes())
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil
}
func GetUserPermissionCacheKey(user identity.Requester) string {
return fmt.Sprintf("rbac-permissions-%s", user.GetCacheKey())
}
func GetSearchPermissionCacheKey(user identity.Requester, searchOptions SearchOptions) string {
key := fmt.Sprintf("rbac-permissions-%s", user.GetCacheKey())
if searchOptions.Action != "" {
key += fmt.Sprintf("-%s", searchOptions.Action)
func GetSearchPermissionCacheKey(log log.Logger, user identity.Requester, searchOptions SearchOptions) (string, error) {
searchHash, err := searchOptions.HashString()
if err != nil {
return "", err
}
if searchOptions.Scope != "" {
key += fmt.Sprintf("-%s", searchOptions.Scope)
}
if len(searchOptions.RolePrefixes) > 0 {
key += "-" + strings.Join(searchOptions.RolePrefixes, "-")
}
if searchOptions.ActionPrefix != "" {
key += fmt.Sprintf("-%s", searchOptions.ActionPrefix)
}
return key
key := fmt.Sprintf("rbac-permissions-%s-%s", user.GetCacheKey(), searchHash)
return key, nil
}
func GetUserDirectPermissionCacheKey(user identity.Requester) string {