Skip to content

Commit e54324d

Browse files
refactor: Add roles into the user response (#1347)
1 parent ad8d9dd commit e54324d

File tree

10 files changed

+74
-37
lines changed

10 files changed

+74
-37
lines changed

coderd/roles.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func (*api) assignableSiteRoles(rw http.ResponseWriter, _ *http.Request) {
1515
// TODO: @emyrk in the future, allow granular subsets of roles to be returned based on the
1616
// role of the user.
1717
roles := rbac.SiteRoles()
18-
httpapi.Write(rw, http.StatusOK, codersdk.ConvertRoles(roles))
18+
httpapi.Write(rw, http.StatusOK, convertRoles(roles))
1919
}
2020

2121
// assignableSiteRoles returns all site wide roles that can be assigned.
@@ -24,5 +24,20 @@ func (*api) assignableOrgRoles(rw http.ResponseWriter, r *http.Request) {
2424
// role of the user.
2525
organization := httpmw.OrganizationParam(r)
2626
roles := rbac.OrganizationRoles(organization.ID)
27-
httpapi.Write(rw, http.StatusOK, codersdk.ConvertRoles(roles))
27+
httpapi.Write(rw, http.StatusOK, convertRoles(roles))
28+
}
29+
30+
func convertRole(role rbac.Role) codersdk.Role {
31+
return codersdk.Role{
32+
DisplayName: role.DisplayName,
33+
Name: role.Name,
34+
}
35+
}
36+
37+
func convertRoles(roles []rbac.Role) []codersdk.Role {
38+
converted := make([]codersdk.Role, 0, len(roles))
39+
for _, role := range roles {
40+
converted = append(converted, convertRole(role))
41+
}
42+
return converted
2843
}

coderd/roles_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func TestListRoles(t *testing.T) {
8484
APICall: func() ([]codersdk.Role, error) {
8585
return orgAdmin.ListOrganizationRoles(ctx, admin.OrganizationID)
8686
},
87-
ExpectedRoles: codersdk.ConvertRoles(rbac.OrganizationRoles(admin.OrganizationID)),
87+
ExpectedRoles: convertRoles(rbac.OrganizationRoles(admin.OrganizationID)),
8888
},
8989
{
9090
Name: "OrgAdminListOtherOrg",
@@ -99,14 +99,14 @@ func TestListRoles(t *testing.T) {
9999
APICall: func() ([]codersdk.Role, error) {
100100
return client.ListSiteRoles(ctx)
101101
},
102-
ExpectedRoles: codersdk.ConvertRoles(rbac.SiteRoles()),
102+
ExpectedRoles: convertRoles(rbac.SiteRoles()),
103103
},
104104
{
105105
Name: "AdminListOrg",
106106
APICall: func() ([]codersdk.Role, error) {
107107
return client.ListOrganizationRoles(ctx, admin.OrganizationID)
108108
},
109-
ExpectedRoles: codersdk.ConvertRoles(rbac.OrganizationRoles(admin.OrganizationID)),
109+
ExpectedRoles: convertRoles(rbac.OrganizationRoles(admin.OrganizationID)),
110110
},
111111
}
112112

@@ -127,3 +127,18 @@ func TestListRoles(t *testing.T) {
127127
})
128128
}
129129
}
130+
131+
func convertRole(role rbac.Role) codersdk.Role {
132+
return codersdk.Role{
133+
DisplayName: role.DisplayName,
134+
Name: role.Name,
135+
}
136+
}
137+
138+
func convertRoles(roles []rbac.Role) []codersdk.Role {
139+
converted := make([]codersdk.Role, 0, len(roles))
140+
for _, role := range roles {
141+
converted = append(converted, convertRole(role))
142+
}
143+
return converted
144+
}

coderd/users.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,14 +807,22 @@ func (api *api) createUser(ctx context.Context, req codersdk.CreateUserRequest)
807807
}
808808

809809
func convertUser(user database.User, organizationIDs []uuid.UUID) codersdk.User {
810-
return codersdk.User{
810+
convertedUser := codersdk.User{
811811
ID: user.ID,
812812
Email: user.Email,
813813
CreatedAt: user.CreatedAt,
814814
Username: user.Username,
815815
Status: codersdk.UserStatus(user.Status),
816816
OrganizationIDs: organizationIDs,
817+
Roles: make([]codersdk.Role, 0),
817818
}
819+
820+
for _, roleName := range user.RBACRoles {
821+
rbacRole, _ := rbac.RoleByName(roleName)
822+
convertedUser.Roles = append(convertedUser.Roles, convertRole(rbacRole))
823+
}
824+
825+
return convertedUser
818826
}
819827

820828
func convertUsers(users []database.User, organizationIDsByUserID map[uuid.UUID][]uuid.UUID) []codersdk.User {

codersdk/roles.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"net/http"
88

9-
"github.com/coder/coder/coderd/rbac"
109
"github.com/google/uuid"
1110
)
1211

@@ -44,14 +43,3 @@ func (c *Client) ListOrganizationRoles(ctx context.Context, org uuid.UUID) ([]Ro
4443
var roles []Role
4544
return roles, json.NewDecoder(res.Body).Decode(&roles)
4645
}
47-
48-
func ConvertRoles(roles []rbac.Role) []Role {
49-
converted := make([]Role, 0, len(roles))
50-
for _, role := range roles {
51-
converted = append(converted, Role{
52-
DisplayName: role.DisplayName,
53-
Name: role.Name,
54-
})
55-
}
56-
return converted
57-
}

codersdk/users.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type User struct {
4545
Username string `json:"username" validate:"required"`
4646
Status UserStatus `json:"status"`
4747
OrganizationIDs []uuid.UUID `json:"organization_ids"`
48+
Roles []Role `json:"roles"`
4849
}
4950

5051
type CreateFirstUserRequest struct {
@@ -216,17 +217,17 @@ func (c *Client) UpdateUserRoles(ctx context.Context, userID uuid.UUID, req Upda
216217

217218
// UpdateOrganizationMemberRoles grants the userID the specified roles in an org.
218219
// Include ALL roles the user has.
219-
func (c *Client) UpdateOrganizationMemberRoles(ctx context.Context, organizationID, userID uuid.UUID, req UpdateRoles) (User, error) {
220+
func (c *Client) UpdateOrganizationMemberRoles(ctx context.Context, organizationID, userID uuid.UUID, req UpdateRoles) (OrganizationMember, error) {
220221
res, err := c.request(ctx, http.MethodPut, fmt.Sprintf("/api/v2/organizations/%s/members/%s/roles", organizationID, uuidOrMe(userID)), req)
221222
if err != nil {
222-
return User{}, err
223+
return OrganizationMember{}, err
223224
}
224225
defer res.Body.Close()
225226
if res.StatusCode != http.StatusOK {
226-
return User{}, readBodyAsError(res)
227+
return OrganizationMember{}, readBodyAsError(res)
227228
}
228-
var user User
229-
return user, json.NewDecoder(res.Body).Decode(&user)
229+
var member OrganizationMember
230+
return member, json.NewDecoder(res.Body).Decode(&member)
230231
}
231232

232233
// GetUserRoles returns all roles the user has

site/src/api/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface UserResponse {
2424
readonly created_at: string
2525
readonly status: "active" | "suspended"
2626
readonly organization_ids: string[]
27+
readonly roles: { name: string; display_name: string }[]
2728
}
2829

2930
/**

site/src/api/typesGenerated.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface AgentGitSSHKey {
1212
readonly private_key: string
1313
}
1414

15-
// From codersdk/users.go:109:6
15+
// From codersdk/users.go:110:6
1616
export interface AuthMethods {
1717
readonly password: boolean
1818
readonly github: boolean
@@ -30,21 +30,21 @@ export interface BuildInfoResponse {
3030
readonly version: string
3131
}
3232

33-
// From codersdk/users.go:50:6
33+
// From codersdk/users.go:51:6
3434
export interface CreateFirstUserRequest {
3535
readonly email: string
3636
readonly username: string
3737
readonly password: string
3838
readonly organization: string
3939
}
4040

41-
// From codersdk/users.go:58:6
41+
// From codersdk/users.go:59:6
4242
export interface CreateFirstUserResponse {
4343
readonly user_id: string
4444
readonly organization_id: string
4545
}
4646

47-
// From codersdk/users.go:104:6
47+
// From codersdk/users.go:105:6
4848
export interface CreateOrganizationRequest {
4949
readonly name: string
5050
}
@@ -77,7 +77,7 @@ export interface CreateTemplateVersionRequest {
7777
readonly parameter_values: CreateParameterRequest[]
7878
}
7979

80-
// From codersdk/users.go:63:6
80+
// From codersdk/users.go:64:6
8181
export interface CreateUserRequest {
8282
readonly email: string
8383
readonly username: string
@@ -101,7 +101,7 @@ export interface CreateWorkspaceRequest {
101101
readonly parameter_values: CreateParameterRequest[]
102102
}
103103

104-
// From codersdk/users.go:100:6
104+
// From codersdk/users.go:101:6
105105
export interface GenerateAPIKeyResponse {
106106
readonly key: string
107107
}
@@ -119,13 +119,13 @@ export interface GoogleInstanceIdentityToken {
119119
readonly json_web_token: string
120120
}
121121

122-
// From codersdk/users.go:89:6
122+
// From codersdk/users.go:90:6
123123
export interface LoginWithPasswordRequest {
124124
readonly email: string
125125
readonly password: string
126126
}
127127

128-
// From codersdk/users.go:95:6
128+
// From codersdk/users.go:96:6
129129
export interface LoginWithPasswordResponse {
130130
readonly session_token: string
131131
}
@@ -195,6 +195,12 @@ export interface ProvisionerJobLog {
195195
readonly output: string
196196
}
197197

198+
// From codersdk/roles.go:13:6
199+
export interface Role {
200+
readonly name: string
201+
readonly display_name: string
202+
}
203+
198204
// From codersdk/templates.go:17:6
199205
export interface Template {
200206
readonly id: string
@@ -255,17 +261,17 @@ export interface UpdateActiveTemplateVersion {
255261
readonly id: string
256262
}
257263

258-
// From codersdk/users.go:79:6
264+
// From codersdk/users.go:80:6
259265
export interface UpdateRoles {
260266
readonly roles: string[]
261267
}
262268

263-
// From codersdk/users.go:75:6
269+
// From codersdk/users.go:76:6
264270
export interface UpdateUserPasswordRequest {
265271
readonly password: string
266272
}
267273

268-
// From codersdk/users.go:70:6
274+
// From codersdk/users.go:71:6
269275
export interface UpdateUserProfileRequest {
270276
readonly email: string
271277
readonly username: string
@@ -294,9 +300,10 @@ export interface User {
294300
readonly username: string
295301
readonly status: UserStatus
296302
readonly organization_ids: string[]
303+
readonly roles: Role[]
297304
}
298305

299-
// From codersdk/users.go:83:6
306+
// From codersdk/users.go:84:6
300307
export interface UserRoles {
301308
readonly roles: string[]
302309
readonly organization_roles: Record<string, string[]>

site/src/components/ResetPasswordDialog/ResetPasswordDialog.stories.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Story } from "@storybook/react"
22
import React from "react"
33
import { MockUser } from "../../testHelpers"
4-
import { generateRandomString } from "../../util/random"
54
import { ResetPasswordDialog, ResetPasswordDialogProps } from "./ResetPasswordDialog"
65

76
export default {
@@ -19,5 +18,5 @@ export const Example = Template.bind({})
1918
Example.args = {
2019
open: true,
2120
user: MockUser,
22-
newPassword: generateRandomString(12),
21+
newPassword: "somerandomstringhere",
2322
}

site/src/pages/PreferencesPages/AccountPage/AccountPage.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe("AccountPage", () => {
3737
created_at: new Date().toString(),
3838
status: "active",
3939
organization_ids: ["123"],
40+
roles: [],
4041
...data,
4142
}),
4243
)

site/src/testHelpers/entities.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const MockUser: UserResponse = {
2828
created_at: "",
2929
status: "active",
3030
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
31+
roles: [],
3132
}
3233

3334
export const MockUser2: UserResponse = {
@@ -37,6 +38,7 @@ export const MockUser2: UserResponse = {
3738
created_at: "",
3839
status: "active",
3940
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
41+
roles: [],
4042
}
4143

4244
export const MockOrganization: Organization = {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy