From a74db60399c4fdcb3d1175af2c735e6aa49a1561 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Fri, 21 Feb 2025 21:15:26 +0000 Subject: [PATCH 1/2] what --- coderd/rbac/roles.go | 24 ++++++++----- coderd/rbac/roles_test.go | 34 +++++++++---------- .../management/OrganizationSidebarView.tsx | 8 ++--- .../management/organizationPermissions.tsx | 1 - 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/coderd/rbac/roles.go b/coderd/rbac/roles.go index e1399aded95d0..7c733016430fe 100644 --- a/coderd/rbac/roles.go +++ b/coderd/rbac/roles.go @@ -283,10 +283,11 @@ func ReloadBuiltinRoles(opts *RoleOptions) { Permissions(map[string][]policy.Action{ // Reduced permission set on dormant workspaces. No build, ssh, or exec ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop}, - // Users cannot do create/update/delete on themselves, but they // can read their own details. ResourceUser.Type: {policy.ActionRead, policy.ActionReadPersonal, policy.ActionUpdatePersonal}, + // Can read their own organization member record + ResourceOrganizationMember.Type: {policy.ActionRead}, // Users can create provisioner daemons scoped to themselves. ResourceProvisionerDaemon.Type: {policy.ActionRead, policy.ActionCreate, policy.ActionRead, policy.ActionUpdate}, })..., @@ -423,12 +424,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) { ResourceAssignOrgRole.Type: {policy.ActionRead}, }), }, - User: []Permission{ - { - ResourceType: ResourceOrganizationMember.Type, - Action: policy.ActionRead, - }, - }, + User: []Permission{}, } }, orgAuditor: func(organizationID uuid.UUID) Role { @@ -439,6 +435,12 @@ func ReloadBuiltinRoles(opts *RoleOptions) { Org: map[string][]Permission{ organizationID.String(): Permissions(map[string][]policy.Action{ ResourceAuditLog.Type: {policy.ActionRead}, + // Allow auditors to see the resources that audit logs reflect. + ResourceTemplate.Type: {policy.ActionRead, policy.ActionViewInsights}, + ResourceGroup.Type: {policy.ActionRead}, + ResourceGroupMember.Type: {policy.ActionRead}, + ResourceOrganization.Type: {policy.ActionRead}, + ResourceOrganizationMember.Type: {policy.ActionRead}, }), }, User: []Permission{}, @@ -458,6 +460,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) { organizationID.String(): Permissions(map[string][]policy.Action{ // Assign, remove, and read roles in the organization. ResourceAssignOrgRole.Type: {policy.ActionAssign, policy.ActionDelete, policy.ActionRead}, + ResourceOrganization.Type: {policy.ActionRead}, ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate, policy.ActionDelete}, ResourceGroup.Type: ResourceGroup.AvailableActions(), ResourceGroupMember.Type: ResourceGroupMember.AvailableActions(), @@ -479,10 +482,15 @@ func ReloadBuiltinRoles(opts *RoleOptions) { ResourceFile.Type: {policy.ActionCreate, policy.ActionRead}, ResourceWorkspace.Type: {policy.ActionRead}, // Assigning template perms requires this permission. + ResourceOrganization.Type: {policy.ActionRead}, ResourceOrganizationMember.Type: {policy.ActionRead}, ResourceGroup.Type: {policy.ActionRead}, ResourceGroupMember.Type: {policy.ActionRead}, - ResourceProvisionerJobs.Type: {policy.ActionRead}, + // Since templates have to correlate with provisioners, + // the ability to create templates and provisioners has + // a lot of overlap. + ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate, policy.ActionDelete}, + ResourceProvisionerJobs.Type: {policy.ActionRead}, }), }, User: []Permission{}, diff --git a/coderd/rbac/roles_test.go b/coderd/rbac/roles_test.go index cb43b1b1751d6..6c658fef350e8 100644 --- a/coderd/rbac/roles_test.go +++ b/coderd/rbac/roles_test.go @@ -217,20 +217,20 @@ func TestRolePermissions(t *testing.T) { }, { Name: "Templates", - Actions: []policy.Action{policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete, policy.ActionViewInsights}, + Actions: []policy.Action{policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete}, Resource: rbac.ResourceTemplate.WithID(templateID).InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ true: {owner, orgAdmin, templateAdmin, orgTemplateAdmin}, - false: {setOtherOrg, orgAuditor, orgUserAdmin, memberMe, orgMemberMe, userAdmin}, + false: {setOtherOrg, orgUserAdmin, orgAuditor, memberMe, orgMemberMe, userAdmin}, }, }, { Name: "ReadTemplates", - Actions: []policy.Action{policy.ActionRead}, + Actions: []policy.Action{policy.ActionRead, policy.ActionViewInsights}, Resource: rbac.ResourceTemplate.InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin, templateAdmin, orgTemplateAdmin}, - false: {setOtherOrg, orgAuditor, orgUserAdmin, memberMe, userAdmin, orgMemberMe}, + true: {owner, orgAuditor, orgAdmin, templateAdmin, orgTemplateAdmin}, + false: {setOtherOrg, orgUserAdmin, memberMe, userAdmin, orgMemberMe}, }, }, { @@ -377,8 +377,8 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionRead}, Resource: rbac.ResourceOrganizationMember.WithID(currentUser).InOrg(orgID).WithOwner(currentUser.String()), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin, userAdmin, orgMemberMe, templateAdmin, orgUserAdmin, orgTemplateAdmin}, - false: {memberMe, setOtherOrg, orgAuditor}, + true: {owner, orgAuditor, orgAdmin, userAdmin, orgMemberMe, templateAdmin, orgUserAdmin, orgTemplateAdmin}, + false: {memberMe, setOtherOrg}, }, }, { @@ -404,7 +404,7 @@ func TestRolePermissions(t *testing.T) { }), AuthorizeMap: map[bool][]hasAuthSubjects{ true: {owner, orgAdmin, userAdmin, orgUserAdmin}, - false: {setOtherOrg, memberMe, orgMemberMe, templateAdmin, orgTemplateAdmin, orgAuditor, groupMemberMe}, + false: {setOtherOrg, memberMe, orgMemberMe, templateAdmin, orgTemplateAdmin, groupMemberMe, orgAuditor}, }, }, { @@ -416,8 +416,8 @@ func TestRolePermissions(t *testing.T) { }, }), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, groupMemberMe}, - false: {setOtherOrg, memberMe, orgMemberMe, orgAuditor}, + true: {owner, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, groupMemberMe, orgAuditor}, + false: {setOtherOrg, memberMe, orgMemberMe}, }, }, { @@ -425,8 +425,8 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionRead}, Resource: rbac.ResourceGroupMember.WithID(currentUser).InOrg(orgID).WithOwner(currentUser.String()), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgMemberMe, groupMemberMe}, - false: {setOtherOrg, memberMe, orgAuditor}, + true: {owner, orgAuditor, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgMemberMe, groupMemberMe}, + false: {setOtherOrg, memberMe}, }, }, { @@ -434,8 +434,8 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionRead}, Resource: rbac.ResourceGroupMember.WithID(adminID).InOrg(orgID).WithOwner(adminID.String()), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin}, - false: {setOtherOrg, memberMe, orgAuditor, orgMemberMe, groupMemberMe}, + true: {owner, orgAuditor, orgAdmin, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin}, + false: {setOtherOrg, memberMe, orgMemberMe, groupMemberMe}, }, }, { @@ -534,8 +534,8 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete}, Resource: rbac.ResourceProvisionerDaemon.InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, templateAdmin, orgAdmin}, - false: {setOtherOrg, orgTemplateAdmin, orgUserAdmin, memberMe, orgMemberMe, userAdmin, orgAuditor}, + true: {owner, templateAdmin, orgAdmin, orgTemplateAdmin}, + false: {setOtherOrg, orgAuditor, orgUserAdmin, memberMe, orgMemberMe, userAdmin}, }, }, { @@ -543,7 +543,7 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionRead}, Resource: rbac.ResourceProvisionerDaemon.InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, templateAdmin, setOrgNotMe, orgMemberMe}, + true: {owner, templateAdmin, setOrgNotMe, orgAuditor, orgMemberMe}, false: {setOtherOrg, memberMe, userAdmin}, }, }, diff --git a/site/src/modules/management/OrganizationSidebarView.tsx b/site/src/modules/management/OrganizationSidebarView.tsx index 7f3b697766563..71a37659ab14d 100644 --- a/site/src/modules/management/OrganizationSidebarView.tsx +++ b/site/src/modules/management/OrganizationSidebarView.tsx @@ -167,11 +167,9 @@ const OrganizationSettingsNavigation: FC< return ( <>
- {orgPermissions.viewMembers && ( - - Members - - )} + + Members + {orgPermissions.viewGroups && ( Date: Fri, 21 Feb 2025 21:22:29 +0000 Subject: [PATCH 2/2] fix tests --- coderd/rbac/roles_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coderd/rbac/roles_test.go b/coderd/rbac/roles_test.go index 6c658fef350e8..1ac2c4c9e0796 100644 --- a/coderd/rbac/roles_test.go +++ b/coderd/rbac/roles_test.go @@ -543,7 +543,7 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionRead}, Resource: rbac.ResourceProvisionerDaemon.InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, templateAdmin, setOrgNotMe, orgAuditor, orgMemberMe}, + true: {owner, templateAdmin, setOrgNotMe, orgMemberMe}, false: {setOtherOrg, memberMe, userAdmin}, }, }, @@ -552,8 +552,8 @@ func TestRolePermissions(t *testing.T) { Actions: []policy.Action{policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete}, Resource: rbac.ResourceProvisionerDaemon.WithOwner(currentUser.String()).InOrg(orgID), AuthorizeMap: map[bool][]hasAuthSubjects{ - true: {owner, templateAdmin, orgMemberMe, orgAdmin}, - false: {setOtherOrg, memberMe, userAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor}, + true: {owner, templateAdmin, orgTemplateAdmin, orgMemberMe, orgAdmin}, + false: {setOtherOrg, memberMe, userAdmin, orgUserAdmin, orgAuditor}, }, }, {