Preferences: Add read-only APIServer for preferences and dashboard stars (#106109)
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
// +enum
|
||||
type ResourceOwner string
|
||||
|
||||
const (
|
||||
// Used when there is a single resource for a given org|stack
|
||||
NamespaceResourceOwner ResourceOwner = "namespace"
|
||||
// Resource with a 1:1 user mapping
|
||||
UserResourceOwner ResourceOwner = "user"
|
||||
// Resource with a 1:1 team mapping
|
||||
TeamResourceOwner ResourceOwner = "team"
|
||||
// The name does not match user, team or namespace
|
||||
UnknownResourceOwner ResourceOwner = ""
|
||||
)
|
||||
|
||||
type OwnerReference struct {
|
||||
Owner ResourceOwner // the resource owner
|
||||
Name string // the team|user name
|
||||
}
|
||||
|
||||
func (o OwnerReference) AsName() string {
|
||||
if o.Name == "" || o.Owner == NamespaceResourceOwner {
|
||||
return string(o.Owner)
|
||||
}
|
||||
return string(o.Owner) + ":" + o.Name
|
||||
}
|
||||
|
||||
func ParseOwnerFromName(name string) (OwnerReference, bool) {
|
||||
before, after, found := strings.Cut(name, ":")
|
||||
if found && len(after) > 0 {
|
||||
switch before {
|
||||
case "user":
|
||||
return OwnerReference{Owner: UserResourceOwner, Name: after}, true
|
||||
case "team":
|
||||
return OwnerReference{Owner: TeamResourceOwner, Name: after}, true
|
||||
}
|
||||
} else if name == "namespace" {
|
||||
return OwnerReference{Owner: NamespaceResourceOwner}, true
|
||||
}
|
||||
return OwnerReference{}, false
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/registry/apis/preferences/utils"
|
||||
)
|
||||
|
||||
func TestLegacyAuthorizer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
output utils.OwnerReference
|
||||
found bool
|
||||
}{
|
||||
{
|
||||
name: "invalid",
|
||||
input: "xxx:yyy",
|
||||
output: utils.OwnerReference{},
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
name: "with user",
|
||||
input: "user:a",
|
||||
output: utils.OwnerReference{Owner: utils.UserResourceOwner, Name: "a"},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "missing user",
|
||||
input: "user:",
|
||||
output: utils.OwnerReference{},
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
name: "with team",
|
||||
input: "team:b",
|
||||
output: utils.OwnerReference{Owner: utils.TeamResourceOwner, Name: "b"},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "missing team",
|
||||
input: "team:",
|
||||
output: utils.OwnerReference{},
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
name: "for namespace",
|
||||
input: "namespace",
|
||||
output: utils.OwnerReference{Owner: utils.NamespaceResourceOwner},
|
||||
found: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
output, found := utils.ParseOwnerFromName(tt.input)
|
||||
require.Equal(t, tt.output, output)
|
||||
require.Equal(t, tt.found, found)
|
||||
if tt.found {
|
||||
require.Equal(t, tt.input, output.AsName())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user