Skip to content

Commit d3dfab5

Browse files
committed
Improve OpenAPI documentation for PUT /api/v1/me/tokens endpoint
1 parent 937e383 commit d3dfab5

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

src/controllers/token.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,24 @@ pub struct NewApiTokenRequest {
8989
api_token: NewApiToken,
9090
}
9191

92+
#[derive(Debug, Serialize, utoipa::ToSchema)]
93+
pub struct CreateResponse {
94+
api_token: EncodableApiTokenWithToken,
95+
}
96+
9297
/// Create a new API token.
9398
#[utoipa::path(
9499
put,
95100
path = "/api/v1/me/tokens",
96101
security(("cookie" = [])),
97102
tag = "api_tokens",
98-
responses((status = 200, description = "Successful Response")),
103+
responses((status = 200, description = "Successful Response", body = inline(CreateResponse))),
99104
)]
100105
pub async fn create_api_token(
101106
app: AppState,
102107
parts: Parts,
103108
Json(new): Json<NewApiTokenRequest>,
104-
) -> AppResult<ErasedJson> {
109+
) -> AppResult<Json<CreateResponse>> {
105110
if new.api_token.name.is_empty() {
106111
return Err(bad_request("name must have a value"));
107112
}
@@ -186,7 +191,7 @@ pub async fn create_api_token(
186191
plaintext: plaintext.expose_secret().to_string(),
187192
};
188193

189-
Ok(json!({ "api_token": api_token }))
194+
Ok(Json(CreateResponse { api_token }))
190195
}
191196

192197
/// Find API token by id.

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,26 @@ expression: response.json()
497497
],
498498
"type": "object"
499499
},
500+
"EncodableApiTokenWithToken": {
501+
"allOf": [
502+
{
503+
"$ref": "#/components/schemas/ApiToken"
504+
},
505+
{
506+
"properties": {
507+
"token": {
508+
"description": "The plaintext API token.\n\nOnly available when the token is created.",
509+
"example": "a1b2c3d4e5f6g7h8i9j0",
510+
"type": "string"
511+
}
512+
},
513+
"required": [
514+
"token"
515+
],
516+
"type": "object"
517+
}
518+
]
519+
},
500520
"EncodableDependency": {
501521
"properties": {
502522
"crate_id": {
@@ -3667,6 +3687,21 @@ expression: response.json()
36673687
"operationId": "create_api_token",
36683688
"responses": {
36693689
"200": {
3690+
"content": {
3691+
"application/json": {
3692+
"schema": {
3693+
"properties": {
3694+
"api_token": {
3695+
"$ref": "#/components/schemas/EncodableApiTokenWithToken"
3696+
}
3697+
},
3698+
"required": [
3699+
"api_token"
3700+
],
3701+
"type": "object"
3702+
}
3703+
}
3704+
},
36703705
"description": "Successful Response"
36713706
}
36723707
},

src/views.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -628,14 +628,16 @@ impl From<Team> for EncodableTeam {
628628
}
629629
}
630630

631-
/// The serialization format for the `ApiToken` model with its token value.
632-
/// This should only be used when initially creating a new token to minimize
633-
/// the chance of token leaks.
634-
#[derive(Serialize, Debug)]
631+
#[derive(Serialize, Debug, utoipa::ToSchema)]
635632
pub struct EncodableApiTokenWithToken {
636633
#[serde(flatten)]
637634
pub token: ApiToken,
635+
636+
/// The plaintext API token.
637+
///
638+
/// Only available when the token is created.
638639
#[serde(rename = "token")]
640+
#[schema(example = "a1b2c3d4e5f6g7h8i9j0")]
639641
pub plaintext: String,
640642
}
641643

0 commit comments

Comments
 (0)