Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitba4c3ce

Browse files
feat: add filter by status on GET /users (#1206)
1 parent82364d1 commitba4c3ce

File tree

7 files changed

+116
-37
lines changed

7 files changed

+116
-37
lines changed

‎coderd/database/databasefake/databasefake.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ func (q *fakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams
212212
users=tmp
213213
}
214214

215+
ifparams.Status!="" {
216+
usersFilteredByStatus:=make([]database.User,0,len(users))
217+
fori,user:=rangeusers {
218+
ifparams.Status==string(user.Status) {
219+
usersFilteredByStatus=append(usersFilteredByStatus,users[i])
220+
}
221+
}
222+
users=usersFilteredByStatus
223+
}
224+
215225
ifparams.OffsetOpt>0 {
216226
ifint(params.OffsetOpt)>len(users)-1 {
217227
return []database.User{},nil
@@ -225,6 +235,7 @@ func (q *fakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams
225235
}
226236
users=users[:params.LimitOpt]
227237
}
238+
228239
tmp:=make([]database.User,len(users))
229240
copy(tmp,users)
230241

‎coderd/database/queries.sql.go

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

‎coderd/database/queries/users.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,25 @@ WHERE
7676
)
7777
ELSE true
7878
END
79+
-- Start filters
80+
-- Filter by name, email or username
7981
AND CASE
8082
WHEN @search ::text!='' THEN (
8183
emailLIKE concat('%', @search,'%')
8284
OR usernameLIKE concat('%', @search,'%')
85+
)
86+
ELSE true
87+
END
88+
-- Filter by status
89+
AND CASE
90+
-- @status needs to be a text because it can be empty, If it was
91+
-- user_status enum, it would not.
92+
WHEN @status ::text!='' THEN (
93+
status= @status :: user_status
8394
)
8495
ELSE true
8596
END
97+
-- End of filters
8698
ORDER BY
8799
-- Deterministic and consistent ordering of all users, even if they share
88100
-- a timestamp. This is to ensure consistent pagination.

‎coderd/users.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
9090

9191
func (api*api)users(rw http.ResponseWriter,r*http.Request) {
9292
var (
93-
afterArg=r.URL.Query().Get("after_user")
94-
limitArg=r.URL.Query().Get("limit")
95-
offsetArg=r.URL.Query().Get("offset")
96-
searchName=r.URL.Query().Get("search")
93+
afterArg=r.URL.Query().Get("after_user")
94+
limitArg=r.URL.Query().Get("limit")
95+
offsetArg=r.URL.Query().Get("offset")
96+
searchName=r.URL.Query().Get("search")
97+
statusFilter=r.URL.Query().Get("status")
9798
)
9899

99100
// createdAfter is a user uuid.
@@ -136,6 +137,7 @@ func (api *api) users(rw http.ResponseWriter, r *http.Request) {
136137
OffsetOpt:int32(offset),
137138
LimitOpt:int32(pageLimit),
138139
Search:searchName,
140+
Status:statusFilter,
139141
})
140142
iferr!=nil {
141143
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{

‎coderd/users_test.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,19 +330,54 @@ func TestUserByName(t *testing.T) {
330330

331331
funcTestGetUsers(t*testing.T) {
332332
t.Parallel()
333-
client:=coderdtest.New(t,nil)
334-
user:=coderdtest.CreateFirstUser(t,client)
335-
client.CreateUser(context.Background(), codersdk.CreateUserRequest{
336-
Email:"alice@email.com",
337-
Username:"alice",
338-
Password:"password",
339-
OrganizationID:user.OrganizationID,
333+
t.Run("AllUsers",func(t*testing.T) {
334+
t.Parallel()
335+
client:=coderdtest.New(t,nil)
336+
user:=coderdtest.CreateFirstUser(t,client)
337+
client.CreateUser(context.Background(), codersdk.CreateUserRequest{
338+
Email:"alice@email.com",
339+
Username:"alice",
340+
Password:"password",
341+
OrganizationID:user.OrganizationID,
342+
})
343+
// No params is all users
344+
users,err:=client.Users(context.Background(), codersdk.UsersRequest{})
345+
require.NoError(t,err)
346+
require.Len(t,users,2)
347+
require.Len(t,users[0].OrganizationIDs,1)
348+
})
349+
t.Run("ActiveUsers",func(t*testing.T) {
350+
t.Parallel()
351+
client:=coderdtest.New(t,nil)
352+
first:=coderdtest.CreateFirstUser(t,client)
353+
active:=make([]codersdk.User,0)
354+
alice,err:=client.CreateUser(context.Background(), codersdk.CreateUserRequest{
355+
Email:"alice@email.com",
356+
Username:"alice",
357+
Password:"password",
358+
OrganizationID:first.OrganizationID,
359+
})
360+
require.NoError(t,err)
361+
active=append(active,alice)
362+
363+
bruno,err:=client.CreateUser(context.Background(), codersdk.CreateUserRequest{
364+
Email:"bruno@email.com",
365+
Username:"bruno",
366+
Password:"password",
367+
OrganizationID:first.OrganizationID,
368+
})
369+
require.NoError(t,err)
370+
active=append(active,bruno)
371+
372+
_,err=client.SuspendUser(context.Background(),first.UserID)
373+
require.NoError(t,err)
374+
375+
users,err:=client.Users(context.Background(), codersdk.UsersRequest{
376+
Status:string(codersdk.UserStatusActive),
377+
})
378+
require.NoError(t,err)
379+
require.ElementsMatch(t,active,users)
340380
})
341-
// No params is all users
342-
users,err:=client.Users(context.Background(), codersdk.UsersRequest{})
343-
require.NoError(t,err)
344-
require.Len(t,users,2)
345-
require.Len(t,users[0].OrganizationIDs,1)
346381
}
347382

348383
funcTestOrganizationsByUser(t*testing.T) {

‎codersdk/users.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ import (
1414
// Me is used as a replacement for your own ID.
1515
varMe=uuid.Nil
1616

17+
typeUserStatusstring
18+
19+
const (
20+
UserStatusActiveUserStatus="active"
21+
UserStatusSuspendedUserStatus="suspended"
22+
)
23+
1724
typeUsersRequeststruct {
1825
AfterUser uuid.UUID`json:"after_user"`
1926
Searchstring`json:"search"`
@@ -26,15 +33,10 @@ type UsersRequest struct {
2633
// To get the next page, use offset=<limit>*<page_number>.
2734
// Offset is 0 indexed, so the first record sits at offset 0.
2835
Offsetint`json:"offset"`
36+
// Filter users by status
37+
Statusstring`json:"status"`
2938
}
3039

31-
typeUserStatusstring
32-
33-
const (
34-
UserStatusActiveUserStatus="active"
35-
UserStatusSuspendedUserStatus="suspended"
36-
)
37-
3840
// User represents a user in Coder.
3941
typeUserstruct {
4042
ID uuid.UUID`json:"id" validate:"required"`
@@ -165,6 +167,7 @@ func (c *Client) SuspendUser(ctx context.Context, userID uuid.UUID) (User, error
165167
ifres.StatusCode!=http.StatusOK {
166168
returnUser{},readBodyAsError(res)
167169
}
170+
168171
varuserUser
169172
returnuser,json.NewDecoder(res.Body).Decode(&user)
170173
}
@@ -243,6 +246,7 @@ func (c *Client) Users(ctx context.Context, req UsersRequest) ([]User, error) {
243246
}
244247
q.Set("offset",strconv.Itoa(req.Offset))
245248
q.Set("search",req.Search)
249+
q.Set("status",req.Status)
246250
r.URL.RawQuery=q.Encode()
247251
})
248252
iferr!=nil {

‎site/src/api/typesGenerated.ts

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

15-
// From codersdk/users.go:94:6
15+
// From codersdk/users.go:96:6
1616
exportinterfaceAuthMethods{
1717
readonlypassword:boolean
1818
readonlygithub:boolean
@@ -30,21 +30,21 @@ export interface BuildInfoResponse {
3030
readonlyversion:string
3131
}
3232

33-
// From codersdk/users.go:48:6
33+
// From codersdk/users.go:50:6
3434
exportinterfaceCreateFirstUserRequest{
3535
readonlyemail:string
3636
readonlyusername:string
3737
readonlypassword:string
3838
readonlyorganization:string
3939
}
4040

41-
// From codersdk/users.go:56:6
41+
// From codersdk/users.go:58:6
4242
exportinterfaceCreateFirstUserResponse{
4343
readonlyuser_id:string
4444
readonlyorganization_id:string
4545
}
4646

47-
// From codersdk/users.go:89:6
47+
// From codersdk/users.go:91:6
4848
exportinterfaceCreateOrganizationRequest{
4949
readonlyname:string
5050
}
@@ -77,7 +77,7 @@ export interface CreateTemplateVersionRequest {
7777
readonlyparameter_values:CreateParameterRequest[]
7878
}
7979

80-
// From codersdk/users.go:61:6
80+
// From codersdk/users.go:63:6
8181
exportinterfaceCreateUserRequest{
8282
readonlyemail:string
8383
readonlyusername:string
@@ -100,7 +100,7 @@ export interface CreateWorkspaceRequest {
100100
readonlyparameter_values:CreateParameterRequest[]
101101
}
102102

103-
// From codersdk/users.go:85:6
103+
// From codersdk/users.go:87:6
104104
exportinterfaceGenerateAPIKeyResponse{
105105
readonlykey:string
106106
}
@@ -118,13 +118,13 @@ export interface GoogleInstanceIdentityToken {
118118
readonlyjson_web_token:string
119119
}
120120

121-
// From codersdk/users.go:74:6
121+
// From codersdk/users.go:76:6
122122
exportinterfaceLoginWithPasswordRequest{
123123
readonlyemail:string
124124
readonlypassword:string
125125
}
126126

127-
// From codersdk/users.go:80:6
127+
// From codersdk/users.go:82:6
128128
exportinterfaceLoginWithPasswordResponse{
129129
readonlysession_token:string
130130
}
@@ -245,7 +245,7 @@ export interface UpdateActiveTemplateVersion {
245245
readonlyid:string
246246
}
247247

248-
// From codersdk/users.go:68:6
248+
// From codersdk/users.go:70:6
249249
exportinterfaceUpdateUserProfileRequest{
250250
readonlyemail:string
251251
readonlyusername:string
@@ -266,7 +266,7 @@ export interface UploadResponse {
266266
readonlyhash:string
267267
}
268268

269-
// From codersdk/users.go:39:6
269+
// From codersdk/users.go:41:6
270270
exportinterfaceUser{
271271
readonlyid:string
272272
readonlyemail:string
@@ -276,12 +276,13 @@ export interface User {
276276
readonlyorganization_ids:string[]
277277
}
278278

279-
// From codersdk/users.go:17:6
279+
// From codersdk/users.go:24:6
280280
exportinterfaceUsersRequest{
281281
readonlyafter_user:string
282282
readonlysearch:string
283283
readonlylimit:number
284284
readonlyoffset:number
285+
readonlystatus:string
285286
}
286287

287288
// From codersdk/workspaces.go:18:6
@@ -378,7 +379,7 @@ export type ParameterScope = "organization" | "template" | "user" | "workspace"
378379
// From codersdk/provisionerdaemons.go:26:6
379380
exporttypeProvisionerJobStatus="canceled"|"canceling"|"failed"|"pending"|"running"|"succeeded"
380381

381-
// From codersdk/users.go:31:6
382+
// From codersdk/users.go:17:6
382383
exporttypeUserStatus="active"|"suspended"
383384

384385
// From codersdk/workspaceresources.go:15:6

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp