Skip to content

Commit 1ff534f

Browse files
committed
chore: add organization id to custom_roles
1 parent 3617e39 commit 1ff534f

File tree

20 files changed

+192
-45
lines changed

20 files changed

+192
-45
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,11 +835,12 @@ func (q *querier) CleanTailnetTunnels(ctx context.Context) error {
835835
return q.db.CleanTailnetTunnels(ctx)
836836
}
837837

838-
func (q *querier) CustomRolesByName(ctx context.Context, lookupRoles []string) ([]database.CustomRole, error) {
838+
// TODO: Handle org scoped lookups
839+
func (q *querier) CustomRoles(ctx context.Context, arg database.CustomRolesParams) ([]database.CustomRole, error) {
839840
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAssignRole); err != nil {
840841
return nil, err
841842
}
842-
return q.db.CustomRolesByName(ctx, lookupRoles)
843+
return q.db.CustomRoles(ctx, arg)
843844
}
844845

845846
func (q *querier) DeleteAPIKeyByID(ctx context.Context, id string) error {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,8 +1167,8 @@ func (s *MethodTestSuite) TestUser() {
11671167
b := dbgen.User(s.T(), db, database.User{})
11681168
check.Args().Asserts(rbac.ResourceSystem, policy.ActionRead).Returns(slice.New(a.ID, b.ID))
11691169
}))
1170-
s.Run("CustomRolesByName", s.Subtest(func(db database.Store, check *expects) {
1171-
check.Args([]string{}).Asserts(rbac.ResourceAssignRole, policy.ActionRead).Returns([]database.CustomRole{})
1170+
s.Run("CustomRoles", s.Subtest(func(db database.Store, check *expects) {
1171+
check.Args(database.CustomRolesParams{}).Asserts(rbac.ResourceAssignRole, policy.ActionRead).Returns([]database.CustomRole{})
11721172
}))
11731173
s.Run("Blank/UpsertCustomRole", s.Subtest(func(db database.Store, check *expects) {
11741174
// Blank is no perms in the role

coderd/database/dbmem/dbmem.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,18 +1174,26 @@ func (*FakeQuerier) CleanTailnetTunnels(context.Context) error {
11741174
return ErrUnimplemented
11751175
}
11761176

1177-
func (q *FakeQuerier) CustomRolesByName(_ context.Context, lookupRoles []string) ([]database.CustomRole, error) {
1177+
func (q *FakeQuerier) CustomRoles(_ context.Context, arg database.CustomRolesParams) ([]database.CustomRole, error) {
11781178
q.mutex.Lock()
11791179
defer q.mutex.Unlock()
11801180

11811181
found := make([]database.CustomRole, 0)
11821182
for _, role := range q.data.customRoles {
1183-
if slices.ContainsFunc(lookupRoles, func(s string) bool {
1184-
return strings.EqualFold(s, role.Name)
1185-
}) {
1186-
role := role
1187-
found = append(found, role)
1183+
if len(arg.LookupRoles) > 0 {
1184+
if !slices.ContainsFunc(arg.LookupRoles, func(s string) bool {
1185+
return strings.EqualFold(s, role.Name)
1186+
}) {
1187+
continue
1188+
}
11881189
}
1190+
1191+
if arg.ExcludeOrgRoles && role.OrganizationID.Valid {
1192+
continue
1193+
}
1194+
1195+
role := role
1196+
found = append(found, role)
11891197
}
11901198

11911199
return found, nil

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ALTER TABLE custom_roles
2+
-- This column is nullable, meaning no organization scope
3+
DROP COLUMN organization_id;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE custom_roles
2+
-- This column is nullable, meaning no organization scope
3+
ADD COLUMN organization_id uuid;
4+
5+
COMMENT ON COLUMN custom_roles.organization_id IS 'Roles can optionally be scoped to an organization'

coderd/database/models.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 61 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/roles.sql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
-- name: CustomRolesByName :many
1+
-- name: CustomRoles :many
22
SELECT
33
*
44
FROM
55
custom_roles
66
WHERE
7+
true
8+
-- Lookup roles filter
9+
AND CASE WHEN array_length(@lookup_roles :: text[], 1) > 0 THEN
710
-- Case insensitive
811
name ILIKE ANY(@lookup_roles :: text [])
12+
ELSE true
13+
END
14+
-- Org scoping filter, to only fetch site wide roles
15+
AND CASE WHEN @exclude_org_roles :: boolean THEN
16+
organization_id IS null
17+
ELSE true
18+
END
919
;
1020

11-
1221
-- name: UpsertCustomRole :one
1322
INSERT INTO
1423
custom_roles (

coderd/httpapi/name.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func UsernameFrom(str string) string {
3838
}
3939

4040
// NameValid returns whether the input string is a valid name.
41-
// It is a generic validator for any name (user, workspace, template, etc.).
41+
// It is a generic validator for any name (user, workspace, template, role name, etc.).
4242
func NameValid(str string) error {
4343
if len(str) > 32 {
4444
return xerrors.New("must be <= 32 characters")

coderd/rbac/rolestore/rolestore.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ func Expand(ctx context.Context, db database.Store, names []string) (rbac.Roles,
7272
// If some roles are missing from the database, they are omitted from
7373
// the expansion. These roles are no-ops. Should we raise some kind of
7474
// warning when this happens?
75-
dbroles, err := db.CustomRolesByName(ctx, lookup)
75+
dbroles, err := db.CustomRoles(ctx, database.CustomRolesParams{
76+
LookupRoles: lookup,
77+
})
7678
if err != nil {
7779
return nil, xerrors.Errorf("fetch custom roles: %w", err)
7880
}

coderd/roles.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package coderd
33
import (
44
"net/http"
55

6+
"github.com/coder/coder/v2/coderd/database"
7+
"github.com/coder/coder/v2/coderd/database/db2sdk"
68
"github.com/coder/coder/v2/coderd/httpmw"
79
"github.com/coder/coder/v2/coderd/rbac/policy"
10+
"github.com/coder/coder/v2/coderd/rbac/rolestore"
811
"github.com/coder/coder/v2/codersdk"
912

1013
"github.com/coder/coder/v2/coderd/httpapi"
@@ -29,6 +32,22 @@ func (api *API) AssignableSiteRoles(rw http.ResponseWriter, r *http.Request) {
2932
}
3033

3134
roles := rbac.SiteRoles()
35+
customRoles, err := api.Database.CustomRoles(ctx, database.CustomRolesParams{
36+
// Only site wide custom roles to be included
37+
ExcludeOrgRoles: true,
38+
})
39+
if err != nil {
40+
httpapi.InternalServerError(rw, err)
41+
return
42+
}
43+
44+
for _, customRole := range customRoles {
45+
rbacRole, err := rolestore.ConvertDBRole(customRole)
46+
if err == nil {
47+
roles = append(roles, rbacRole)
48+
}
49+
}
50+
3251
httpapi.Write(ctx, rw, http.StatusOK, assignableRoles(actorRoles.Roles, roles))
3352
}
3453

@@ -66,10 +85,7 @@ func assignableRoles(actorRoles rbac.ExpandableRoles, roles []rbac.Role) []coder
6685
continue
6786
}
6887
assignable = append(assignable, codersdk.AssignableRoles{
69-
SlimRole: codersdk.SlimRole{
70-
Name: role.Name,
71-
DisplayName: role.DisplayName,
72-
},
88+
Role: db2sdk.Role(role),
7389
Assignable: rbac.CanAssignRole(actorRoles, role.Name),
7490
})
7591
}

coderd/roles_test.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/stretchr/testify/require"
99

1010
"github.com/coder/coder/v2/coderd/coderdtest"
11+
"github.com/coder/coder/v2/coderd/database/db2sdk"
1112
"github.com/coder/coder/v2/coderd/rbac"
1213
"github.com/coder/coder/v2/codersdk"
1314
"github.com/coder/coder/v2/testutil"
@@ -143,20 +144,17 @@ func TestListRoles(t *testing.T) {
143144
}
144145
}
145146

146-
func convertRole(roleName string) codersdk.SlimRole {
147+
func convertRole(roleName string) codersdk.Role {
147148
role, _ := rbac.RoleByName(roleName)
148-
return codersdk.SlimRole{
149-
DisplayName: role.DisplayName,
150-
Name: role.Name,
151-
}
149+
return db2sdk.Role(role)
152150
}
153151

154152
func convertRoles(assignableRoles map[string]bool) []codersdk.AssignableRoles {
155153
converted := make([]codersdk.AssignableRoles, 0, len(assignableRoles))
156154
for roleName, assignable := range assignableRoles {
157155
role := convertRole(roleName)
158156
converted = append(converted, codersdk.AssignableRoles{
159-
SlimRole: role,
157+
Role: role,
160158
Assignable: assignable,
161159
})
162160
}

codersdk/roles.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type SlimRole struct {
1919
}
2020

2121
type AssignableRoles struct {
22-
SlimRole
22+
Role
2323
Assignable bool `json:"assignable"`
2424
}
2525

0 commit comments

Comments
 (0)