chore: implement databased backend for custom roles (#13295)

Includes db schema and dbauthz layer for upserting custom roles. Unit test in `customroles_test.go` verify against escalating permissions through this feature.
This commit is contained in:
Steven Masley
2024-05-16 13:11:26 -05:00
committed by GitHub
parent 194be12133
commit cf91eff7cf
21 changed files with 854 additions and 19 deletions
+2 -1
View File
@@ -37,7 +37,8 @@ var (
// ResourceAssignRole
// Valid Actions
// - "ActionAssign" :: ability to assign roles
// - "ActionDelete" :: ability to delete roles
// - "ActionCreate" :: ability to create/delete/edit custom roles
// - "ActionDelete" :: ability to unassign roles
// - "ActionRead" :: view what roles are assignable
ResourceAssignRole = Object{
Type: "assign_role",
+2 -1
View File
@@ -209,7 +209,8 @@ var RBACPermissions = map[string]PermissionDefinition{
Actions: map[Action]ActionDefinition{
ActionAssign: actDef("ability to assign roles"),
ActionRead: actDef("view what roles are assignable"),
ActionDelete: actDef("ability to delete roles"),
ActionDelete: actDef("ability to unassign roles"),
ActionCreate: actDef("ability to create/delete/edit custom roles"),
},
},
"assign_org_role": {
+22 -14
View File
@@ -20,6 +20,10 @@ const (
templateAdmin string = "template-admin"
userAdmin string = "user-admin"
auditor string = "auditor"
// customSiteRole is a placeholder for all custom site roles.
// This is used for what roles can assign other roles.
// TODO: Make this more dynamic to allow other roles to grant.
customSiteRole string = "custom-site-role"
orgAdmin string = "organization-admin"
orgMember string = "organization-member"
@@ -52,6 +56,8 @@ func RoleOwner() string {
return roleName(owner, "")
}
func CustomSiteRole() string { return roleName(customSiteRole, "") }
func RoleTemplateAdmin() string {
return roleName(templateAdmin, "")
}
@@ -320,22 +326,24 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
// map[actor_role][assign_role]<can_assign>
var assignRoles = map[string]map[string]bool{
"system": {
owner: true,
auditor: true,
member: true,
orgAdmin: true,
orgMember: true,
templateAdmin: true,
userAdmin: true,
owner: true,
auditor: true,
member: true,
orgAdmin: true,
orgMember: true,
templateAdmin: true,
userAdmin: true,
customSiteRole: true,
},
owner: {
owner: true,
auditor: true,
member: true,
orgAdmin: true,
orgMember: true,
templateAdmin: true,
userAdmin: true,
owner: true,
auditor: true,
member: true,
orgAdmin: true,
orgMember: true,
templateAdmin: true,
userAdmin: true,
customSiteRole: true,
},
userAdmin: {
member: true,
+10 -1
View File
@@ -248,6 +248,15 @@ func TestRolePermissions(t *testing.T) {
false: {otherOrgAdmin, otherOrgMember, memberMe, userAdmin},
},
},
{
Name: "CreateCustomRole",
Actions: []policy.Action{policy.ActionCreate},
Resource: rbac.ResourceAssignRole,
AuthorizeMap: map[bool][]authSubject{
true: {owner},
false: {userAdmin, orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin},
},
},
{
Name: "RoleAssignment",
Actions: []policy.Action{policy.ActionAssign, policy.ActionDelete},
@@ -380,7 +389,7 @@ func TestRolePermissions(t *testing.T) {
},
// Some admin style resources
{
Name: "Licences",
Name: "Licenses",
Actions: []policy.Action{policy.ActionCreate, policy.ActionRead, policy.ActionDelete},
Resource: rbac.ResourceLicense,
AuthorizeMap: map[bool][]authSubject{
+37
View File
@@ -0,0 +1,37 @@
package rolestore
import (
"encoding/json"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/rbac"
)
func ConvertDBRole(dbRole database.CustomRole) (rbac.Role, error) {
role := rbac.Role{
Name: dbRole.Name,
DisplayName: dbRole.DisplayName,
Site: nil,
Org: nil,
User: nil,
}
err := json.Unmarshal(dbRole.SitePermissions, &role.Site)
if err != nil {
return role, xerrors.Errorf("unmarshal site permissions: %w", err)
}
err = json.Unmarshal(dbRole.OrgPermissions, &role.Org)
if err != nil {
return role, xerrors.Errorf("unmarshal org permissions: %w", err)
}
err = json.Unmarshal(dbRole.UserPermissions, &role.User)
if err != nil {
return role, xerrors.Errorf("unmarshal user permissions: %w", err)
}
return role, nil
}