Skip to content

Commit c61b64b

Browse files
authored
feat: add hidden enterprise cmd command to list roles (#13303)
* feat: add hidden enterprise cmd command to list roles This includes custom roles, and has a json ouput option for more granular permissions
1 parent 8e78b94 commit c61b64b

28 files changed

+662
-86
lines changed

coderd/apidoc/docs.go

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz.go

+3-2
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,8 @@ func (s *MethodTestSuite) TestUser() {
11771177
b := dbgen.User(s.T(), db, database.User{})
11781178
check.Args().Asserts(rbac.ResourceSystem, policy.ActionRead).Returns(slice.New(a.ID, b.ID))
11791179
}))
1180-
s.Run("CustomRolesByName", s.Subtest(func(db database.Store, check *expects) {
1181-
check.Args([]string{}).Asserts(rbac.ResourceAssignRole, policy.ActionRead).Returns([]database.CustomRole{})
1180+
s.Run("CustomRoles", s.Subtest(func(db database.Store, check *expects) {
1181+
check.Args(database.CustomRolesParams{}).Asserts(rbac.ResourceAssignRole, policy.ActionRead).Returns([]database.CustomRole{})
11821182
}))
11831183
s.Run("Blank/UpsertCustomRole", s.Subtest(func(db database.Store, check *expects) {
11841184
// Blank is no perms in the role

coderd/database/dbmem/dbmem.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -1175,18 +1175,26 @@ func (*FakeQuerier) CleanTailnetTunnels(context.Context) error {
11751175
return ErrUnimplemented
11761176
}
11771177

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

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

11921200
return found, nil

coderd/database/dbmetrics/dbmetrics.go

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
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;
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

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

+22-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/roles.sql

+11-2
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

+1-1
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

+5-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ 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+
ExcludeOrgRoles: false,
78+
})
7679
if err != nil {
7780
return nil, xerrors.Errorf("fetch custom roles: %w", err)
7881
}
@@ -81,7 +84,7 @@ func Expand(ctx context.Context, db database.Store, names []string) (rbac.Roles,
8184
for _, dbrole := range dbroles {
8285
converted, err := ConvertDBRole(dbrole)
8386
if err != nil {
84-
return nil, xerrors.Errorf("convert db role %q: %w", dbrole, err)
87+
return nil, xerrors.Errorf("convert db role %q: %w", dbrole.Name, err)
8588
}
8689
roles = append(roles, converted)
8790
cache.Store(dbrole.Name, converted)

0 commit comments

Comments
 (0)