From acf119a12c2385bb9c315ea449160ab71e8386a8 Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Fri, 8 Nov 2024 16:53:51 +0100 Subject: [PATCH] Zanzana: resource sets on folder grants read on all children (#96127) * resource sets on folder grants read on all children * remove comment * Add type for consistency --- pkg/services/authz/zanzana/common/tuple.go | 62 ++++++++++++--- .../authz/zanzana/schema/schema_folder.fga | 4 - .../authz/zanzana/schema/schema_resource.fga | 9 +-- .../authz/zanzana/server/server_test.go | 2 +- pkg/services/authz/zanzana/zanzana.go | 75 ++++++++++++------- 5 files changed, 105 insertions(+), 47 deletions(-) diff --git a/pkg/services/authz/zanzana/common/tuple.go b/pkg/services/authz/zanzana/common/tuple.go index fba017ce2fd..824a332871f 100644 --- a/pkg/services/authz/zanzana/common/tuple.go +++ b/pkg/services/authz/zanzana/common/tuple.go @@ -10,9 +10,41 @@ import ( ) const ( - TypeResource = "resource" - TypeFolder = "folder" - TypeNamespace = "namespace" + TypeUser string = "user" + TypeTeam string = "team" + TypeRole string = "role" + TypeFolder string = "folder" + TypeResource string = "resource" + TypeNamespace string = "namespace" +) + +const ( + RelationTeamMember string = "member" + RelationTeamAdmin string = "admin" + RelationParent string = "parent" + RelationAssignee string = "assignee" + + RelationSetView string = "view" + RelationSetEdit string = "edit" + RelationSetAdmin string = "admin" + + RelationRead string = "read" + RelationWrite string = "write" + 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 + RelationFolderResourceCreate string = "resource_" + RelationCreate + RelationFolderResourceDelete string = "resource_" + RelationDelete + RelationFolderResourcePermissionsRead string = "resource_" + RelationPermissionsRead + RelationFolderResourcePermissionsWrite string = "resource_" + RelationPermissionsWrite ) func FolderResourceRelation(relation string) string { @@ -55,12 +87,17 @@ func NewResourceTuple(subject, relation, group, resource, name string) *openfgav } } +func isFolderResourceRelationSet(relation string) bool { + return relation == RelationFolderResourceSetView || + relation == RelationFolderResourceSetEdit || + relation == RelationFolderResourceSetAdmin +} + func NewFolderResourceTuple(subject, relation, group, resource, folder string) *openfgav1.TupleKey { - return &openfgav1.TupleKey{ - User: subject, - Relation: FolderResourceRelation(relation), - Object: NewFolderIdent(folder), - Condition: &openfgav1.RelationshipCondition{ + relation = FolderResourceRelation(relation) + var condition *openfgav1.RelationshipCondition + if !isFolderResourceRelationSet(relation) { + condition = &openfgav1.RelationshipCondition{ Name: "folder_group_filter", Context: &structpb.Struct{ Fields: map[string]*structpb.Value{ @@ -69,7 +106,14 @@ func NewFolderResourceTuple(subject, relation, group, resource, folder string) * }), }, }, - }, + } + } + + return &openfgav1.TupleKey{ + User: subject, + Relation: relation, + Object: NewFolderIdent(folder), + Condition: condition, } } diff --git a/pkg/services/authz/zanzana/schema/schema_folder.fga b/pkg/services/authz/zanzana/schema/schema_folder.fga index e034dd99813..b66f20854cb 100644 --- a/pkg/services/authz/zanzana/schema/schema_folder.fga +++ b/pkg/services/authz/zanzana/schema/schema_folder.fga @@ -15,7 +15,3 @@ type folder define delete: [user, team#member, role#assignee] or edit or delete from parent define permissions_read: [user, team#member, role#assignee] or admin or permissions_read from parent define permissions_write: [user, team#member, role#assignee] or admin or permissions_write from parent - - - - diff --git a/pkg/services/authz/zanzana/schema/schema_resource.fga b/pkg/services/authz/zanzana/schema/schema_resource.fga index e6661536d5c..932e92181a1 100644 --- a/pkg/services/authz/zanzana/schema/schema_resource.fga +++ b/pkg/services/authz/zanzana/schema/schema_resource.fga @@ -2,9 +2,9 @@ module resource extend type folder relations - define resource_view: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_view from parent - define resource_edit: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_edit from parent - define resource_admin: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin from parent + define resource_view: [user, team#member, role#assignee] or resource_edit or resource_view from parent + define resource_edit: [user, team#member, role#assignee] or resource_admin or resource_edit from parent + define resource_admin: [user, team#member, role#assignee] or resource_admin from parent define resource_read: [user 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_create: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_create from parent @@ -13,7 +13,6 @@ extend type folder define resource_permissions_read: [user 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, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_write from parent - type resource relations define view: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or edit @@ -27,7 +26,6 @@ type resource define permissions_read: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or admin define permissions_write: [user 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 } @@ -35,4 +33,3 @@ condition group_filter(requested_group: string, group_resource: string) { condition folder_group_filter(requested_group: string, group_resources: list) { requested_group in group_resources } - diff --git a/pkg/services/authz/zanzana/server/server_test.go b/pkg/services/authz/zanzana/server/server_test.go index dcbe3d4cb17..4800f38541e 100644 --- a/pkg/services/authz/zanzana/server/server_test.go +++ b/pkg/services/authz/zanzana/server/server_test.go @@ -81,7 +81,7 @@ func setup(t *testing.T, testDB db.DB, cfg *setting.Cfg) *Server { common.NewNamespaceResourceTuple("user:7", "read", folderGroup, folderResource), common.NewFolderParentTuple("5", "4"), common.NewFolderParentTuple("6", "5"), - common.NewFolderResourceTuple("user:8", "read", dashboardGroup, dashboardResource, "5"), + common.NewFolderResourceTuple("user:8", "view", dashboardGroup, dashboardResource, "5"), }, }, }) diff --git a/pkg/services/authz/zanzana/zanzana.go b/pkg/services/authz/zanzana/zanzana.go index 8dbb3fcc320..cc95432fe03 100644 --- a/pkg/services/authz/zanzana/zanzana.go +++ b/pkg/services/authz/zanzana/zanzana.go @@ -10,40 +10,61 @@ import ( ) const ( - TypeUser string = "user" - TypeTeam string = "team" - TypeRole string = "role" - TypeFolder string = "folder" - TypeResource string = "resource" + TypeUser = common.TypeUser + TypeTeam = common.TypeTeam + TypeRole = common.TypeRole + TypeFolder = common.TypeFolder + TypeResource = common.TypeResource + TypeNamespace = common.TypeNamespace ) const ( - RelationTeamMember string = "member" - RelationTeamAdmin string = "admin" - RelationParent string = "parent" - RelationAssignee string = "assignee" - RelationOrg string = "org" + RelationTeamMember = common.RelationTeamMember + RelationTeamAdmin = common.RelationTeamAdmin + RelationParent = common.RelationParent + RelationAssignee = common.RelationAssignee - // FIXME action sets - RelationAdmin string = "admin" - RelationRead string = "read" - RelationWrite string = "write" - RelationCreate string = "create" - RelationDelete string = "delete" - RelationPermissionsRead string = "permissions_read" - RelationPermissionsWrite string = "permissions_write" + RelationSetView = common.RelationSetView + RelationSetEdit = common.RelationSetEdit + RelationSetAdmin = common.RelationSetAdmin - FolderResourceRelationAdmin string = "resource_admin" - FolderResourceRelationRead string = "resource_read" - FolderResourceRelationWrite string = "resource_write" - FolderResourceRelationCreate string = "resource_create" - FolderResourceRelationDelete string = "resource_delete" - FolderResourceRelationPermissionsRead string = "resource_permissions_read" - FolderResourceRelationPermissionsWrite string = "resource_permissions_write" + RelationRead = common.RelationRead + RelationWrite = common.RelationWrite + 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 + RelationFolderResourceCreate = common.RelationFolderResourceCreate + RelationFolderResourceDelete = common.RelationFolderResourceDelete + RelationFolderResourcePermissionsRead = common.RelationFolderResourcePermissionsRead + RelationFolderResourcePermissionsWrite = common.RelationFolderResourcePermissionsWrite ) -var ResourceRelations = []string{RelationRead, RelationWrite, RelationCreate, RelationDelete, RelationPermissionsRead, RelationPermissionsWrite} -var FolderRelations = append(ResourceRelations, FolderResourceRelationRead, FolderResourceRelationWrite, FolderResourceRelationCreate, FolderResourceRelationDelete, FolderResourceRelationPermissionsRead, FolderResourceRelationPermissionsWrite) +var ResourceRelations = []string{ + RelationRead, + RelationWrite, + RelationCreate, + RelationDelete, + RelationPermissionsRead, + RelationPermissionsWrite, +} + +var FolderRelations = append( + ResourceRelations, + RelationFolderResourceRead, + RelationFolderResourceWrite, + RelationFolderResourceCreate, + RelationFolderResourceDelete, + RelationFolderResourcePermissionsRead, + RelationFolderResourcePermissionsWrite, +) const ( KindDashboards string = "dashboards"