2025-04-01 10:38:02 +09:00

150 lines
3.2 KiB
Go

package common
import (
"google.golang.org/protobuf/types/known/structpb"
authzv1 "github.com/grafana/authlib/authz/proto/v1"
folderalpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
)
type typeInfo struct {
Type string
Relations []string
}
var typedResources = map[string]typeInfo{
FormatGroupResource(
folderalpha1.FolderResourceInfo.GroupResource().Group,
folderalpha1.FolderResourceInfo.GroupResource().Resource,
"",
): {Type: "folder", Relations: RelationsFolder},
}
func getTypeInfo(group, resource string) (typeInfo, bool) {
info, ok := typedResources[FormatGroupResource(group, resource, "")]
return info, ok
}
func NewResourceInfoFromCheck(r *authzv1.CheckRequest) ResourceInfo {
typ, relations := getTypeAndRelations(r.GetGroup(), r.GetResource())
return newResource(
typ,
r.GetGroup(),
r.GetResource(),
r.GetName(),
r.GetFolder(),
r.GetSubresource(),
relations,
)
}
func NewResourceInfoFromBatchItem(i *authzextv1.BatchCheckItem) ResourceInfo {
typ, relations := getTypeAndRelations(i.GetGroup(), i.GetResource())
return newResource(
typ,
i.GetGroup(),
i.GetResource(),
i.GetName(),
i.GetFolder(),
i.GetSubresource(),
relations,
)
}
func NewResourceInfoFromList(r *authzv1.ListRequest) ResourceInfo {
typ, relations := getTypeAndRelations(r.GetGroup(), r.GetResource())
return newResource(
typ,
r.GetGroup(),
r.GetResource(),
"",
"",
r.GetSubresource(),
relations,
)
}
func getTypeAndRelations(group, resource string) (string, []string) {
if info, ok := getTypeInfo(group, resource); ok {
return info.Type, info.Relations
}
return TypeResource, RelationsResource
}
func newResource(
typ, group, resource, name, folder, subresource string, relations []string,
) ResourceInfo {
return ResourceInfo{
typ: typ,
group: group,
resource: resource,
name: name,
folder: folder,
subresource: subresource,
relations: relations,
}
}
type ResourceInfo struct {
typ string
group string
resource string
name string
folder string
subresource string
relations []string
}
func (r ResourceInfo) GroupResource() string {
return FormatGroupResource(r.group, r.resource, r.subresource)
}
func (r ResourceInfo) GroupResourceIdent() string {
return NewGroupResourceIdent(r.group, r.resource, r.subresource)
}
func (r ResourceInfo) ResourceIdent() string {
if r.name == "" {
return ""
}
if r.IsGeneric() {
return NewResourceIdent(r.group, r.resource, r.subresource, r.name)
}
return NewTypedIdent(r.typ, r.name)
}
func (r ResourceInfo) FolderIdent() string {
if r.folder == "" {
return ""
}
return NewFolderIdent(r.folder)
}
func (r ResourceInfo) IsGeneric() bool {
return r.typ == TypeResource
}
func (r ResourceInfo) Type() string {
return r.typ
}
func (r ResourceInfo) Context() *structpb.Struct {
if !r.IsGeneric() {
return nil
}
return &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": structpb.NewStringValue(r.GroupResource()),
},
}
}
func (r ResourceInfo) IsValidRelation(relation string) bool {
return isValidRelation(relation, r.relations)
}