Zanzana: Update relation names (#97638)

* Update relation names to match k8s verbs

* Only check namespace if relation is valid

* Only list for valid relations
pull/97727/head
Karl Persson 5 months ago committed by GitHub
parent 4712883601
commit 718612aabf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      pkg/services/accesscontrol/dualwrite/reconciler.go
  2. 20
      pkg/services/authz/zanzana/common/info.go
  3. 80
      pkg/services/authz/zanzana/common/tuple.go
  4. 12
      pkg/services/authz/zanzana/schema/schema_core.fga
  5. 6
      pkg/services/authz/zanzana/schema/schema_folder.fga
  6. 12
      pkg/services/authz/zanzana/schema/schema_resource.fga
  7. 6
      pkg/services/authz/zanzana/server/server_capabilities.go
  8. 16
      pkg/services/authz/zanzana/server/server_capabilities_test.go
  9. 57
      pkg/services/authz/zanzana/server/server_check.go
  10. 57
      pkg/services/authz/zanzana/server/server_list.go
  11. 22
      pkg/services/authz/zanzana/server/server_test.go
  12. 18
      pkg/services/authz/zanzana/translations.go
  13. 17
      pkg/services/authz/zanzana/zanzana.go

@ -55,19 +55,19 @@ func NewZanzanaReconciler(cfg *setting.Cfg, client zanzana.Client, store db.DB,
newResourceReconciler(
"managed folder permissions",
managedPermissionsCollector(store, zanzana.KindFolders),
zanzanaCollector(zanzana.FolderRelations),
zanzanaCollector(zanzana.RelationsFolder),
client,
),
newResourceReconciler(
"managed dashboard permissions",
managedPermissionsCollector(store, zanzana.KindDashboards),
zanzanaCollector(zanzana.ResourceRelations),
zanzanaCollector(zanzana.RelationsResouce),
client,
),
newResourceReconciler(
"role permissions",
rolePermissionsCollector(store),
zanzanaCollector(zanzana.FolderRelations),
zanzanaCollector(zanzana.RelationsFolder),
client,
),
newResourceReconciler(

@ -11,11 +11,15 @@ type TypeInfo struct {
Relations []string
}
func (t TypeInfo) IsValidRelation(relation string) bool {
return isValidRelation(relation, t.Relations)
}
var typedResources = map[string]TypeInfo{
FormatGroupResource(
folderalpha1.FolderResourceInfo.GroupResource().Group,
folderalpha1.FolderResourceInfo.GroupResource().Resource,
): {Type: "folder", Relations: append(ResourceRelations, RelationCreate)},
): {Type: "folder", Relations: RelationsFolder},
}
func GetTypeInfo(group, resource string) (TypeInfo, bool) {
@ -24,19 +28,19 @@ func GetTypeInfo(group, resource string) (TypeInfo, bool) {
}
var VerbMapping = map[string]string{
utils.VerbGet: RelationRead,
utils.VerbList: RelationRead,
utils.VerbWatch: RelationRead,
utils.VerbGet: RelationGet,
utils.VerbList: RelationGet,
utils.VerbWatch: RelationGet,
utils.VerbCreate: RelationCreate,
utils.VerbUpdate: RelationWrite,
utils.VerbPatch: RelationWrite,
utils.VerbUpdate: RelationUpdate,
utils.VerbPatch: RelationUpdate,
utils.VerbDelete: RelationDelete,
utils.VerbDeleteCollection: RelationDelete,
}
var RelationToVerbMapping = map[string]string{
RelationRead: utils.VerbGet,
RelationGet: utils.VerbGet,
RelationCreate: utils.VerbCreate,
RelationWrite: utils.VerbUpdate,
RelationUpdate: utils.VerbUpdate,
RelationDelete: utils.VerbDelete,
}

@ -31,44 +31,74 @@ const (
RelationSetEdit string = "edit"
RelationSetAdmin string = "admin"
RelationRead string = "read"
RelationWrite string = "write"
RelationGet string = "get"
RelationUpdate string = "update"
RelationCreate string = "create"
RelationDelete string = "delete"
RelationPermissionsRead string = "permissions_read"
RelationPermissionsWrite string = "permissions_write"
RelationFolderResourceSetView string = "resource_" + RelationSetView
RelationFolderResourceSetEdit string = "resource_" + RelationSetEdit
RelationFolderResourceSetAdmin string = "resource_" + RelationSetAdmin
RelationFolderResourceRead string = "resource_" + RelationRead
RelationFolderResourceWrite string = "resource_" + RelationWrite
RelationFolderResourceGet string = "resource_" + RelationGet
RelationFolderResourceUpdate string = "resource_" + RelationUpdate
RelationFolderResourceCreate string = "resource_" + RelationCreate
RelationFolderResourceDelete string = "resource_" + RelationDelete
RelationFolderResourcePermissionsRead string = "resource_" + RelationPermissionsRead
RelationFolderResourcePermissionsWrite string = "resource_" + RelationPermissionsWrite
)
var ResourceRelations = []string{
RelationRead,
RelationWrite,
// RelationsNamespace are relations that can be added on type "namespace".
var RelationsNamespace = []string{
RelationGet,
RelationUpdate,
RelationCreate,
RelationDelete,
RelationPermissionsRead,
RelationPermissionsWrite,
}
var FolderRelations = append(
ResourceRelations,
RelationCreate,
RelationFolderResourceRead,
RelationFolderResourceWrite,
// RelationsResource are relations that can be added on type "resource".
var RelationsResource = []string{
RelationGet,
RelationUpdate,
RelationDelete,
}
// RelationsFolderResource are relations that can be added on type "folder" for child resources.
var RelationsFolderResource = []string{
RelationFolderResourceGet,
RelationFolderResourceUpdate,
RelationFolderResourceCreate,
RelationFolderResourceDelete,
RelationFolderResourcePermissionsRead,
RelationFolderResourcePermissionsWrite,
}
// RelationsFolder are relations that can be added on type "folder".
var RelationsFolder = append(
RelationsFolderResource,
RelationGet,
RelationUpdate,
RelationCreate,
RelationDelete,
)
func IsNamespaceRelation(relation string) bool {
return isValidRelation(relation, RelationsNamespace)
}
func IsFolderResourceRelation(relation string) bool {
return isValidRelation(relation, RelationsFolderResource)
}
func IsResourceRelation(relation string) bool {
return isValidRelation(relation, RelationsResource)
}
func isValidRelation(relation string, valid []string) bool {
for _, r := range valid {
if r == relation {
return true
}
}
return false
}
func FolderResourceRelation(relation string) string {
return fmt.Sprintf("%s_%s", TypeResource, relation)
}
@ -258,10 +288,18 @@ func AddRenderContext(req *openfgav1.CheckRequest) {
req.ContextualTuples.TupleKeys = append(req.ContextualTuples.TupleKeys, &openfgav1.TupleKey{
User: req.TupleKey.User,
Relation: "view",
Relation: RelationSetView,
Object: NewNamespaceResourceIdent(
dashboardalpha1.DashboardResourceInfo.GroupResource().Group,
dashboardalpha1.DashboardResourceInfo.GroupResource().Resource,
),
})
}
func NewResourceContext(group, resource string) *structpb.Struct {
return &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": structpb.NewStringValue(FormatGroupResource(group, resource)),
},
}
}

@ -12,12 +12,10 @@ type namespace
define edit: [user, service-account, team#member, role#assignee] or admin
define admin: [user, service-account, team#member, role#assignee]
define read: [user, service-account, render, team#member, role#assignee] or view
define get: [user, service-account, render, team#member, role#assignee] or view
define create: [user, service-account, team#member, role#assignee] or edit
define write: [user, service-account, team#member, role#assignee] or edit
define update: [user, service-account, team#member, role#assignee] or edit
define delete: [user, service-account, team#member, role#assignee] or edit
define permissions_read: [user, service-account, team#member, role#assignee] or admin
define permissions_write: [user, service-account, team#member, role#assignee] or admin
type role
relations
@ -29,8 +27,6 @@ type team
define admin: [user, service-account]
define member: [user, service-account] or admin
define read: [role#assignee] or member
define write: [role#assignee] or admin
define get: [role#assignee] or member
define update: [role#assignee] or admin
define delete: [role#assignee] or admin
define permissions_read: [role#assignee] or admin
define permissions_write: [role#assignee] or admin

@ -9,9 +9,7 @@ type folder
define edit: [user, service-account, team#member, role#assignee] or admin or edit from parent
define admin: [user, service-account, team#member, role#assignee] or admin from parent
define read: [user, service-account, team#member, role#assignee] or view or read from parent
define get: [user, service-account, team#member, role#assignee] or view or get from parent
define create: [user, service-account, team#member, role#assignee] or edit or create from parent
define write: [user, service-account, team#member, role#assignee] or edit or write from parent
define update: [user, service-account, team#member, role#assignee] or edit or update from parent
define delete: [user, service-account, team#member, role#assignee] or edit or delete from parent
define permissions_read: [user, service-account, team#member, role#assignee] or admin or permissions_read from parent
define permissions_write: [user, service-account, team#member, role#assignee] or admin or permissions_write from parent

@ -6,12 +6,10 @@ extend type folder
define resource_edit: [user, service-account, team#member, role#assignee] or resource_admin or resource_edit from parent
define resource_admin: [user, service-account, team#member, role#assignee] or resource_admin from parent
define resource_read: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_view or resource_read from parent
define resource_get: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_view or resource_get from parent
define resource_create: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_create from parent
define resource_write: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_write from parent
define resource_update: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_update from parent
define resource_delete: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_delete from parent
define resource_permissions_read: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_read from parent
define resource_permissions_write: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_write from parent
type resource
relations
@ -19,11 +17,9 @@ type resource
define edit: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
define admin: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter]
define read: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or view
define write: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
define get: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or view
define update: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
define delete: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
define permissions_read: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
define permissions_write: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
condition group_filter(requested_group: string, group_resource: string) {
requested_group == group_resource

@ -20,7 +20,7 @@ func (s *Server) Capabilities(ctx context.Context, r *authzextv1.CapabilitiesReq
}
func (s *Server) capabilitiesTyped(ctx context.Context, r *authzextv1.CapabilitiesRequest, info common.TypeInfo, store *storeInfo) (*authzextv1.CapabilitiesResponse, error) {
out := make([]string, 0, len(common.ResourceRelations))
out := make([]string, 0, len(common.RelationsResource))
for _, relation := range info.Relations {
res, err := s.checkNamespace(ctx, r.GetSubject(), relation, r.GetGroup(), r.GetResource(), store)
if err != nil {
@ -46,8 +46,8 @@ func (s *Server) capabilitiesTyped(ctx context.Context, r *authzextv1.Capabiliti
}
func (s *Server) capabilitiesGeneric(ctx context.Context, r *authzextv1.CapabilitiesRequest, store *storeInfo) (*authzextv1.CapabilitiesResponse, error) {
out := make([]string, 0, len(common.ResourceRelations))
for _, relation := range common.ResourceRelations {
out := make([]string, 0, len(common.RelationsResource))
for _, relation := range common.RelationsResource {
res, err := s.checkNamespace(ctx, r.GetSubject(), relation, r.GetGroup(), r.GetResource(), store)
if err != nil {
return nil, err

@ -26,42 +26,42 @@ func testCapabilities(t *testing.T, server *Server) {
t.Run("user:1 should only be able to read and write resource:dashboards.grafana.app/dashboards/1", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:1", dashboardGroup, dashboardResource, "1", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead, common.RelationWrite}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet, common.RelationUpdate}, res.GetCapabilities())
})
t.Run("user:2 should be able to read and write resource:dashboards.grafana.app/dashboards/1 through namespace", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:2", dashboardGroup, dashboardResource, "1", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead, common.RelationWrite}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet, common.RelationUpdate}, res.GetCapabilities())
})
t.Run("user:3 should be able to read resource:dashboards.grafana.app/dashboards/1 with set relation", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:3", dashboardGroup, dashboardResource, "1", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet}, res.GetCapabilities())
})
t.Run("user:4 should be able to read dashboards.grafana.app/dashboards in folder 1", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:4", dashboardGroup, dashboardResource, "1", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet}, res.GetCapabilities())
})
t.Run("user:5 should be able to read, write, create and delete resource:dashboards.grafana.app/dashboards/1 through folder with set relation", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:5", dashboardGroup, dashboardResource, "1", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead, common.RelationWrite, common.RelationDelete}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet, common.RelationUpdate, common.RelationDelete}, res.GetCapabilities())
})
t.Run("user:6 should be able to read folder 1 ", func(t *testing.T) {
t.Run("user:6 should be able to read folder 1", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:6", folderGroup, folderResource, "", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet}, res.GetCapabilities())
})
t.Run("user:7 should be able to read folder one through namespace access", func(t *testing.T) {
res, err := server.Capabilities(context.Background(), newReq("user:7", folderGroup, folderResource, "", "1"))
require.NoError(t, err)
assert.Equal(t, []string{common.RelationRead}, res.GetCapabilities())
assert.Equal(t, []string{common.RelationGet}, res.GetCapabilities())
})
}

@ -7,7 +7,6 @@ import (
authzv1 "github.com/grafana/authlib/authz/proto/v1"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"google.golang.org/protobuf/types/known/structpb"
"github.com/grafana/grafana/pkg/services/authz/zanzana/common"
)
@ -22,8 +21,6 @@ func (s *Server) Check(ctx context.Context, r *authzv1.CheckRequest) (*authzv1.C
}
relation := common.VerbMapping[r.GetVerb()]
// Check if subject has access through namespace
res, err := s.checkNamespace(ctx, r.GetSubject(), relation, r.GetGroup(), r.GetResource(), store)
if err != nil {
return nil, err
@ -39,9 +36,13 @@ func (s *Server) Check(ctx context.Context, r *authzv1.CheckRequest) (*authzv1.C
return s.checkGeneric(ctx, r.GetSubject(), relation, r.GetGroup(), r.GetResource(), r.GetName(), r.GetFolder(), store)
}
// checkTyped performes check on the root "namespace". If subject has access through the namespace they have access to
// checkTyped checks on the root "namespace". If subject has access through the namespace they have access to
// every resource for that "GroupResource".
func (s *Server) checkNamespace(ctx context.Context, subject, relation, group, resource string, store *storeInfo) (*authzv1.CheckResponse, error) {
if !common.IsNamespaceRelation(relation) {
return &authzv1.CheckResponse{Allowed: false}, nil
}
req := &openfgav1.CheckRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
@ -51,6 +52,7 @@ func (s *Server) checkNamespace(ctx context.Context, subject, relation, group, r
Object: common.NewNamespaceResourceIdent(group, resource),
},
}
if strings.HasPrefix(subject, fmt.Sprintf("%s:", common.TypeRenderService)) {
common.AddRenderContext(req)
}
@ -63,8 +65,12 @@ func (s *Server) checkNamespace(ctx context.Context, subject, relation, group, r
return &authzv1.CheckResponse{Allowed: res.GetAllowed()}, nil
}
// checkTyped performes checks on our typed resources e.g. folder.
// checkTyped checks on our typed resources e.g. folder.
func (s *Server) checkTyped(ctx context.Context, subject, relation, name string, info common.TypeInfo, store *storeInfo) (*authzv1.CheckResponse, error) {
if !info.IsValidRelation(relation) {
return &authzv1.CheckResponse{Allowed: false}, nil
}
// Check if subject has direct access to resource
res, err := s.openfga.Check(ctx, &openfgav1.CheckRequest{
StoreId: store.ID,
@ -86,27 +92,26 @@ func (s *Server) checkTyped(ctx context.Context, subject, relation, name string,
return &authzv1.CheckResponse{Allowed: false}, nil
}
// checkGeneric check our generic "resource" type.
// checkGeneric check our generic "resource" type. It checks:
// 1. If subject has access as a sub resource for a folder.
// 2. If subject has direct access to resource.
func (s *Server) checkGeneric(ctx context.Context, subject, relation, group, resource, name, folder string, store *storeInfo) (*authzv1.CheckResponse, error) {
groupResource := structpb.NewStringValue(common.FormatGroupResource(group, resource))
var (
resourceCtx = common.NewResourceContext(group, resource)
folderRelation = common.FolderResourceRelation(relation)
)
// Create relation can only exist on namespace or folder level.
// So we skip direct resource access check.
if relation != common.RelationCreate {
// Check if subject has direct access to resource
if folder != "" && common.IsFolderResourceRelation(folderRelation) {
// Check if subject has access as a sub resource for the folder
res, err := s.openfga.Check(ctx, &openfgav1.CheckRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
TupleKey: &openfgav1.CheckRequestTupleKey{
User: subject,
Relation: relation,
Object: common.NewResourceIdent(group, resource, name),
},
Context: &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": groupResource,
},
Relation: common.FolderResourceRelation(relation),
Object: common.NewFolderIdent(folder),
},
Context: resourceCtx,
})
if err != nil {
@ -114,28 +119,24 @@ func (s *Server) checkGeneric(ctx context.Context, subject, relation, group, res
}
if res.GetAllowed() {
return &authzv1.CheckResponse{Allowed: true}, nil
return &authzv1.CheckResponse{Allowed: res.GetAllowed()}, nil
}
}
if folder == "" {
if !common.IsResourceRelation(relation) {
return &authzv1.CheckResponse{Allowed: false}, nil
}
// Check if subject has access as a sub resource for the folder
// Check if subject has direct access to resource
res, err := s.openfga.Check(ctx, &openfgav1.CheckRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
TupleKey: &openfgav1.CheckRequestTupleKey{
User: subject,
Relation: common.FolderResourceRelation(relation),
Object: common.NewFolderIdent(folder),
},
Context: &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": groupResource,
},
Relation: relation,
Object: common.NewResourceIdent(group, resource, name),
},
Context: resourceCtx,
})
if err != nil {

@ -6,7 +6,6 @@ import (
"strings"
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"google.golang.org/protobuf/types/known/structpb"
authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
"github.com/grafana/grafana/pkg/services/authz/zanzana/common"
@ -23,15 +22,7 @@ func (s *Server) List(ctx context.Context, r *authzextv1.ListRequest) (*authzext
relation := common.VerbMapping[r.GetVerb()]
res, err := s.checkNamespace(
ctx,
r.GetSubject(),
relation,
r.GetGroup(),
r.GetResource(),
store,
)
res, err := s.checkNamespace(ctx, r.GetSubject(), relation, r.GetGroup(), r.GetResource(), store)
if err != nil {
return nil, err
}
@ -55,8 +46,12 @@ func (s *Server) listObjects(ctx context.Context, req *openfgav1.ListObjectsRequ
}
func (s *Server) listTyped(ctx context.Context, subject, relation string, info common.TypeInfo, store *storeInfo) (*authzextv1.ListResponse, error) {
if !info.IsValidRelation(relation) {
return &authzextv1.ListResponse{}, nil
}
// List all resources user has access too
listRes, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
res, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
Type: info.Type,
@ -68,50 +63,56 @@ func (s *Server) listTyped(ctx context.Context, subject, relation string, info c
}
return &authzextv1.ListResponse{
Items: typedObjects(info.Type, listRes.GetObjects()),
Items: typedObjects(info.Type, res.GetObjects()),
}, nil
}
func (s *Server) listGeneric(ctx context.Context, subject, relation, group, resource string, store *storeInfo) (*authzextv1.ListResponse, error) {
groupResource := structpb.NewStringValue(common.FormatGroupResource(group, resource))
var (
resourceCtx = common.NewResourceContext(group, resource)
folderRelation = common.FolderResourceRelation(relation)
)
// 1. List all folders subject has access to resource type in
folders, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
var folders []string
if common.IsFolderResourceRelation(folderRelation) {
res, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
Type: common.TypeFolder,
Relation: common.FolderResourceRelation(relation),
Relation: folderRelation,
User: subject,
Context: &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": groupResource,
},
},
Context: resourceCtx,
})
if err != nil {
return nil, err
}
folders = res.GetObjects()
}
// 2. List all resource directly assigned to subject
direct, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
var resources []string
if common.IsResourceRelation(relation) {
res, err := s.listObjects(ctx, &openfgav1.ListObjectsRequest{
StoreId: store.ID,
AuthorizationModelId: store.ModelID,
Type: common.TypeResource,
Relation: relation,
User: subject,
Context: &structpb.Struct{
Fields: map[string]*structpb.Value{
"requested_group": groupResource,
},
},
Context: resourceCtx,
})
if err != nil {
return nil, err
}
resources = res.GetObjects()
}
return &authzextv1.ListResponse{
Folders: folderObject(folders.GetObjects()),
Items: directObjects(group, resource, direct.GetObjects()),
Folders: folderObject(folders),
Items: directObjects(group, resource, resources),
}, nil
}

@ -80,19 +80,19 @@ func setup(t *testing.T, testDB db.DB, cfg *setting.Cfg) *Server {
AuthorizationModelId: storeInf.ModelID,
Writes: &openfgav1.WriteRequestWrites{
TupleKeys: []*openfgav1.TupleKey{
common.NewResourceTuple("user:1", "read", dashboardGroup, dashboardResource, "1"),
common.NewResourceTuple("user:1", "write", dashboardGroup, dashboardResource, "1"),
common.NewNamespaceResourceTuple("user:2", "read", dashboardGroup, dashboardResource),
common.NewNamespaceResourceTuple("user:2", "write", dashboardGroup, dashboardResource),
common.NewResourceTuple("user:3", "view", dashboardGroup, dashboardResource, "1"),
common.NewFolderResourceTuple("user:4", "read", dashboardGroup, dashboardResource, "1"),
common.NewFolderResourceTuple("user:4", "read", dashboardGroup, dashboardResource, "3"),
common.NewFolderResourceTuple("user:5", "edit", dashboardGroup, dashboardResource, "1"),
common.NewFolderTuple("user:6", "read", "1"),
common.NewNamespaceResourceTuple("user:7", "read", folderGroup, folderResource),
common.NewResourceTuple("user:1", common.RelationGet, dashboardGroup, dashboardResource, "1"),
common.NewResourceTuple("user:1", common.RelationUpdate, dashboardGroup, dashboardResource, "1"),
common.NewNamespaceResourceTuple("user:2", common.RelationGet, dashboardGroup, dashboardResource),
common.NewNamespaceResourceTuple("user:2", common.RelationUpdate, dashboardGroup, dashboardResource),
common.NewResourceTuple("user:3", common.RelationSetView, dashboardGroup, dashboardResource, "1"),
common.NewFolderResourceTuple("user:4", common.RelationGet, dashboardGroup, dashboardResource, "1"),
common.NewFolderResourceTuple("user:4", common.RelationGet, dashboardGroup, dashboardResource, "3"),
common.NewFolderResourceTuple("user:5", common.RelationSetEdit, dashboardGroup, dashboardResource, "1"),
common.NewFolderTuple("user:6", common.RelationGet, "1"),
common.NewNamespaceResourceTuple("user:7", common.RelationGet, folderGroup, folderResource),
common.NewFolderParentTuple("5", "4"),
common.NewFolderParentTuple("6", "5"),
common.NewFolderResourceTuple("user:8", "edit", dashboardGroup, dashboardResource, "5"),
common.NewFolderResourceTuple("user:8", common.RelationSetEdit, dashboardGroup, dashboardResource, "5"),
common.NewFolderResourceTuple("user:9", "create", dashboardGroup, dashboardResource, "5"),
},
},

@ -56,18 +56,14 @@ var resourceTranslations = map[string]resourceTranslation{
group: folderGroup,
resource: folderResource,
mapping: map[string]actionMappig{
"folders:read": newMapping(RelationRead),
"folders:write": newMapping(RelationWrite),
"folders:read": newMapping(RelationGet),
"folders:write": newMapping(RelationUpdate),
"folders:create": newMapping(RelationCreate),
"folders:delete": newMapping(RelationDelete),
"folders.permissions:read": newMapping(RelationPermissionsRead),
"folders.permissions:write": newMapping(RelationPermissionsWrite),
"dashboards:read": newScopedMapping(RelationRead, dashboardGroup, dashboardResource),
"dashboards:write": newScopedMapping(RelationWrite, dashboardGroup, dashboardResource),
"dashboards:read": newScopedMapping(RelationGet, dashboardGroup, dashboardResource),
"dashboards:write": newScopedMapping(RelationUpdate, dashboardGroup, dashboardResource),
"dashboards:create": newScopedMapping(RelationCreate, dashboardGroup, dashboardResource),
"dashboards:delete": newScopedMapping(RelationDelete, dashboardGroup, dashboardResource),
"dashboards.permissions:read": newScopedMapping(RelationPermissionsRead, dashboardGroup, dashboardResource),
"dashboards.permissions:write": newScopedMapping(RelationPermissionsWrite, dashboardGroup, dashboardResource),
},
},
KindDashboards: {
@ -75,12 +71,10 @@ var resourceTranslations = map[string]resourceTranslation{
group: dashboardGroup,
resource: dashboardResource,
mapping: map[string]actionMappig{
"dashboards:read": newMapping(RelationRead),
"dashboards:write": newMapping(RelationWrite),
"dashboards:read": newMapping(RelationGet),
"dashboards:write": newMapping(RelationUpdate),
"dashboards:create": newMapping(RelationCreate),
"dashboards:delete": newMapping(RelationDelete),
"dashboards.permissions:read": newMapping(RelationPermissionsRead),
"dashboards.permissions:write": newMapping(RelationPermissionsWrite),
},
},
}

@ -31,28 +31,25 @@ const (
RelationSetEdit = common.RelationSetEdit
RelationSetAdmin = common.RelationSetAdmin
RelationRead = common.RelationRead
RelationWrite = common.RelationWrite
RelationGet = common.RelationGet
RelationUpdate = common.RelationUpdate
RelationCreate = common.RelationCreate
RelationDelete = common.RelationDelete
RelationPermissionsRead = common.RelationPermissionsRead
RelationPermissionsWrite = common.RelationPermissionsWrite
RelationFolderResourceSetView = common.RelationFolderResourceSetView
RelationFolderResourceSetEdit = common.RelationFolderResourceSetEdit
RelationFolderResourceSetAdmin = common.RelationFolderResourceSetAdmin
RelationFolderResourceRead = common.RelationFolderResourceRead
RelationFolderResourceWrite = common.RelationFolderResourceWrite
RelationFolderResourceRead = common.RelationFolderResourceGet
RelationFolderResourceWrite = common.RelationFolderResourceUpdate
RelationFolderResourceCreate = common.RelationFolderResourceCreate
RelationFolderResourceDelete = common.RelationFolderResourceDelete
RelationFolderResourcePermissionsRead = common.RelationFolderResourcePermissionsRead
RelationFolderResourcePermissionsWrite = common.RelationFolderResourcePermissionsWrite
)
var (
FolderRelations = common.FolderRelations
ResourceRelations = common.ResourceRelations
RelationsFolder = common.RelationsFolder
RelationsFolderResource = common.RelationsFolder
RelationsResouce = common.RelationsResource
)
const (

Loading…
Cancel
Save