mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Add rbac to templateversion+orgmember endpoints (#1713)
This commit is contained in:
@@ -3,6 +3,7 @@ package rbac
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
|
||||
@@ -135,6 +135,12 @@ var (
|
||||
Action: ActionRead,
|
||||
ResourceID: "*",
|
||||
},
|
||||
{
|
||||
// Can read available roles.
|
||||
ResourceType: ResourceOrgRoleAssignment.Type,
|
||||
ResourceID: "*",
|
||||
Action: ActionRead,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -217,6 +223,37 @@ func SiteRoles() []Role {
|
||||
return roles
|
||||
}
|
||||
|
||||
// ChangeRoleSet is a helper function that finds the difference of 2 sets of
|
||||
// roles. When setting a user's new roles, it is equivalent to adding and
|
||||
// removing roles. This set determines the changes, so that the appropriate
|
||||
// RBAC checks can be applied using "ActionCreate" and "ActionDelete" for
|
||||
// "added" and "removed" roles respectively.
|
||||
func ChangeRoleSet(from []string, to []string) (added []string, removed []string) {
|
||||
has := make(map[string]struct{})
|
||||
for _, exists := range from {
|
||||
has[exists] = struct{}{}
|
||||
}
|
||||
|
||||
for _, roleName := range to {
|
||||
// If the user already has the role assigned, we don't need to check the permission
|
||||
// to reassign it. Only run permission checks on the difference in the set of
|
||||
// roles.
|
||||
if _, ok := has[roleName]; ok {
|
||||
delete(has, roleName)
|
||||
continue
|
||||
}
|
||||
|
||||
added = append(added, roleName)
|
||||
}
|
||||
|
||||
// Remaining roles are the ones removed/deleted.
|
||||
for roleName := range has {
|
||||
removed = append(removed, roleName)
|
||||
}
|
||||
|
||||
return added, removed
|
||||
}
|
||||
|
||||
// roleName is a quick helper function to return
|
||||
// role_name:scopeID
|
||||
// If no scopeID is required, only 'role_name' is returned
|
||||
|
||||
@@ -93,3 +93,52 @@ func TestListRoles(t *testing.T) {
|
||||
},
|
||||
orgRoleNames)
|
||||
}
|
||||
|
||||
func TestChangeSet(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
Name string
|
||||
From []string
|
||||
To []string
|
||||
ExpAdd []string
|
||||
ExpRemove []string
|
||||
}{
|
||||
{
|
||||
Name: "Empty",
|
||||
},
|
||||
{
|
||||
Name: "Same",
|
||||
From: []string{"a", "b", "c"},
|
||||
To: []string{"a", "b", "c"},
|
||||
ExpAdd: []string{},
|
||||
ExpRemove: []string{},
|
||||
},
|
||||
{
|
||||
Name: "AllRemoved",
|
||||
From: []string{"a", "b", "c"},
|
||||
ExpRemove: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
Name: "AllAdded",
|
||||
To: []string{"a", "b", "c"},
|
||||
ExpAdd: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
Name: "AddAndRemove",
|
||||
From: []string{"a", "b", "c"},
|
||||
To: []string{"a", "b", "d", "e"},
|
||||
ExpAdd: []string{"d", "e"},
|
||||
ExpRemove: []string{"c"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range testCases {
|
||||
c := c
|
||||
t.Run(c.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
add, remove := rbac.ChangeRoleSet(c.From, c.To)
|
||||
require.ElementsMatch(t, c.ExpAdd, add, "expect added")
|
||||
require.ElementsMatch(t, c.ExpRemove, remove, "expect removed")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ var (
|
||||
Type: "workspace",
|
||||
}
|
||||
|
||||
// ResourceTemplate CRUD. Org owner only.
|
||||
// create/delete = Make or delete a new template
|
||||
// update = Update the template, make new template versions
|
||||
// read = read the template and all versions associated
|
||||
ResourceTemplate = Object{
|
||||
Type: "template",
|
||||
}
|
||||
@@ -41,6 +45,7 @@ var (
|
||||
// ResourceRoleAssignment might be expanded later to allow more granular permissions
|
||||
// to modifying roles. For now, this covers all possible roles, so having this permission
|
||||
// allows granting/deleting **ALL** roles.
|
||||
// Never has an owner or org.
|
||||
// create = Assign roles
|
||||
// update = ??
|
||||
// read = View available roles to assign
|
||||
@@ -49,6 +54,11 @@ var (
|
||||
Type: "assign_role",
|
||||
}
|
||||
|
||||
// ResourceOrgRoleAssignment is just like ResourceRoleAssignment but for organization roles.
|
||||
ResourceOrgRoleAssignment = Object{
|
||||
Type: "assign_org_role",
|
||||
}
|
||||
|
||||
// ResourceAPIKey is owned by a user.
|
||||
// create = Create a new api key for user
|
||||
// update = ??
|
||||
|
||||
Reference in New Issue
Block a user