Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit 57504d4

Browse files
committed
admin: add operation IDs on user operations & other improvements
This also documents better the user list operation parameters
1 parent f1bf85e commit 57504d4

File tree

4 files changed

+67
-40
lines changed

4 files changed

+67
-40
lines changed

crates/handlers/src/admin/v1/users/by_username.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub struct UsernamePathParam {
5858

5959
pub fn doc(operation: TransformOperation) -> TransformOperation {
6060
operation
61+
.id("getUserByUsername")
6162
.summary("Get a user by its username (localpart)")
6263
.tag("user")
6364
.response_with::<200, Json<SingleResponse<User>>, _>(|t| {

crates/handlers/src/admin/v1/users/get.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ impl IntoResponse for RouteError {
5252

5353
pub fn doc(operation: TransformOperation) -> TransformOperation {
5454
operation
55+
.id("getUser")
5556
.summary("Get a user")
5657
.tag("user")
5758
.response_with::<200, Json<SingleResponse<User>>, _>(|t| {

crates/handlers/src/admin/v1/users/list.rs

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,44 +34,57 @@ use crate::{
3434
impl_from_error_for_route,
3535
};
3636

37-
#[derive(Deserialize, JsonSchema)]
37+
#[derive(Deserialize, JsonSchema, Clone, Copy)]
3838
#[serde(rename_all = "snake_case")]
3939
enum UserStatus {
40-
/// The user is active
4140
Active,
42-
43-
/// The user is locked
4441
Locked,
4542
}
4643

44+
impl std::fmt::Display for UserStatus {
45+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46+
match self {
47+
Self::Active => write!(f, "active"),
48+
Self::Locked => write!(f, "locked"),
49+
}
50+
}
51+
}
52+
4753
#[derive(FromRequestParts, Deserialize, JsonSchema, OperationIo)]
54+
#[serde(rename = "UserFilter")]
4855
#[aide(input_with = "Query<FilterParams>")]
4956
#[from_request(via(Query), rejection(RouteError))]
5057
pub struct FilterParams {
58+
/// Retrieve users with (or without) the `can_request_admin` flag set
5159
#[serde(rename = "filter[can_request_admin]")]
5260
can_request_admin: Option<bool>,
5361

62+
/// Retrieve the items with the given status
63+
///
64+
/// Defaults to retrieve all users, including locked ones.
65+
///
66+
/// * `active`: Only retrieve active users
67+
///
68+
/// * `locked`: Only retrieve locked users
5469
#[serde(rename = "filter[status]")]
5570
status: Option<UserStatus>,
5671
}
5772

58-
impl<'a> From<&'a FilterParams> for UserFilter<'a> {
59-
fn from(val: &'a FilterParams) -> Self {
60-
let filter = UserFilter::default();
61-
62-
let filter = match val.can_request_admin {
63-
Some(true) => filter.can_request_admin_only(),
64-
Some(false) => filter.cannot_request_admin_only(),
65-
None => filter,
66-
};
67-
68-
let filter = match val.status {
69-
Some(UserStatus::Active) => filter.active_only(),
70-
Some(UserStatus::Locked) => filter.locked_only(),
71-
None => filter,
72-
};
73-
74-
filter
73+
impl std::fmt::Display for FilterParams {
74+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75+
let mut sep = '?';
76+
77+
if let Some(can_request_admin) = self.can_request_admin {
78+
write!(f, "{sep}filter[can_request_admin]={can_request_admin}")?;
79+
sep = '&';
80+
}
81+
if let Some(status) = self.status {
82+
write!(f, "{sep}filter[status]={status}")?;
83+
sep = '&';
84+
}
85+
86+
let _ = sep;
87+
Ok(())
7588
}
7689
}
7790

@@ -100,6 +113,7 @@ impl IntoResponse for RouteError {
100113

101114
pub fn doc(operation: TransformOperation) -> TransformOperation {
102115
operation
116+
.id("listUsers")
103117
.summary("List users")
104118
.tag("user")
105119
.response_with::<200, Json<PaginatedResponse<User>>, _>(|t| {
@@ -120,9 +134,22 @@ pub fn doc(operation: TransformOperation) -> TransformOperation {
120134
pub async fn handler(
121135
CallContext { mut repo, .. }: CallContext,
122136
Pagination(pagination): Pagination,
123-
filter: FilterParams,
137+
params: FilterParams,
124138
) -> Result<Json<PaginatedResponse<User>>, RouteError> {
125-
let filter = UserFilter::from(&filter);
139+
let base = format!("{path}{params}", path = User::PATH);
140+
let filter = UserFilter::default();
141+
142+
let filter = match params.can_request_admin {
143+
Some(true) => filter.can_request_admin_only(),
144+
Some(false) => filter.cannot_request_admin_only(),
145+
None => filter,
146+
};
147+
148+
let filter = match params.status {
149+
Some(UserStatus::Active) => filter.active_only(),
150+
Some(UserStatus::Locked) => filter.locked_only(),
151+
None => filter,
152+
};
126153

127154
let page = repo.user().list(filter, pagination).await?;
128155
let count = repo.user().count(filter).await?;
@@ -131,6 +158,6 @@ pub async fn handler(
131158
page.map(User::from),
132159
pagination,
133160
count,
134-
User::PATH,
161+
&base,
135162
)))
136163
}

docs/api/spec.json

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"user"
2323
],
2424
"summary": "List users",
25+
"operationId": "listUsers",
2526
"parameters": [
2627
{
2728
"in": "query",
@@ -74,7 +75,9 @@
7475
{
7576
"in": "query",
7677
"name": "filter[can_request_admin]",
78+
"description": "Retrieve users with (or without) the `can_request_admin` flag set",
7779
"schema": {
80+
"description": "Retrieve users with (or without) the `can_request_admin` flag set",
7881
"type": "boolean",
7982
"nullable": true
8083
},
@@ -83,7 +86,9 @@
8386
{
8487
"in": "query",
8588
"name": "filter[status]",
89+
"description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users",
8690
"schema": {
91+
"description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users",
8792
"$ref": "#/components/schemas/UserStatus",
8893
"nullable": true
8994
},
@@ -162,6 +167,7 @@
162167
"user"
163168
],
164169
"summary": "Get a user",
170+
"operationId": "getUser",
165171
"parameters": [
166172
{
167173
"in": "path",
@@ -229,6 +235,7 @@
229235
"user"
230236
],
231237
"summary": "Get a user by its username (localpart)",
238+
"operationId": "getUserByUsername",
232239
"parameters": [
233240
{
234241
"in": "path",
@@ -355,35 +362,26 @@
355362
"type": "string",
356363
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
357364
},
358-
"FilterParams": {
365+
"UserFilter": {
359366
"type": "object",
360367
"properties": {
361368
"filter[can_request_admin]": {
369+
"description": "Retrieve users with (or without) the `can_request_admin` flag set",
362370
"type": "boolean",
363371
"nullable": true
364372
},
365373
"filter[status]": {
374+
"description": "Retrieve the items with the given status\n\nDefaults to retrieve all users, including locked ones.\n\n* `active`: Only retrieve active users\n\n* `locked`: Only retrieve locked users",
366375
"$ref": "#/components/schemas/UserStatus",
367376
"nullable": true
368377
}
369378
}
370379
},
371380
"UserStatus": {
372-
"oneOf": [
373-
{
374-
"description": "The user is active",
375-
"type": "string",
376-
"enum": [
377-
"active"
378-
]
379-
},
380-
{
381-
"description": "The user is locked",
382-
"type": "string",
383-
"enum": [
384-
"locked"
385-
]
386-
}
381+
"type": "string",
382+
"enum": [
383+
"active",
384+
"locked"
387385
]
388386
},
389387
"PaginatedResponse_for_User": {

0 commit comments

Comments
 (0)