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

Commit aec9653

Browse files
committed
admin: better error when password auth is disabled
1 parent 9551f55 commit aec9653

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

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

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub enum RouteError {
3636
#[error("Password is too weak")]
3737
PasswordTooWeak,
3838

39+
#[error("Password auth is disabled")]
40+
PasswordAuthDisabled,
41+
3942
#[error("Password hashing failed")]
4043
Password(#[source] anyhow::Error),
4144

@@ -50,6 +53,7 @@ impl IntoResponse for RouteError {
5053
let error = ErrorResponse::from_error(&self);
5154
let status = match self {
5255
Self::Internal(_) | Self::Password(_) => StatusCode::INTERNAL_SERVER_ERROR,
56+
Self::PasswordAuthDisabled => StatusCode::FORBIDDEN,
5357
Self::PasswordTooWeak => StatusCode::BAD_REQUEST,
5458
Self::NotFound(_) => StatusCode::NOT_FOUND,
5559
};
@@ -83,6 +87,11 @@ pub fn doc(operation: TransformOperation) -> TransformOperation {
8387
let response = ErrorResponse::from_error(&RouteError::PasswordTooWeak);
8488
t.description("Password is too weak").example(response)
8589
})
90+
.response_with::<403, RouteError, _>(|t| {
91+
let response = ErrorResponse::from_error(&RouteError::PasswordAuthDisabled);
92+
t.description("Password auth is disabled in the server configuration")
93+
.example(response)
94+
})
8695
.response_with::<404, RouteError, _>(|t| {
8796
let response = ErrorResponse::from_error(&RouteError::NotFound(Ulid::nil()));
8897
t.description("User was not found").example(response)
@@ -99,6 +108,10 @@ pub async fn handler(
99108
id: UlidPathParam,
100109
Json(params): Json<Request>,
101110
) -> Result<StatusCode, RouteError> {
111+
if !password_manager.is_enabled() {
112+
return Err(RouteError::PasswordAuthDisabled);
113+
}
114+
102115
let user = repo
103116
.user()
104117
.lookup(*id)
@@ -137,7 +150,10 @@ mod tests {
137150
use sqlx::PgPool;
138151
use zeroize::Zeroizing;
139152

140-
use crate::test_utils::{setup, RequestBuilderExt, ResponseExt, TestState};
153+
use crate::{
154+
passwords::PasswordManager,
155+
test_utils::{setup, RequestBuilderExt, ResponseExt, TestState},
156+
};
141157

142158
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
143159
async fn test_set_password(pool: PgPool) {
@@ -267,4 +283,26 @@ mod tests {
267283
"User ID 01040G2081040G2081040G2081 not found"
268284
);
269285
}
286+
287+
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
288+
async fn test_disabled(pool: PgPool) {
289+
setup();
290+
let mut state = TestState::from_pool(pool).await.unwrap();
291+
state.password_manager = PasswordManager::disabled();
292+
let token = state.token_with_scope("urn:mas:admin").await;
293+
294+
let request = Request::post(
295+
"/api/admin/v1/users/01040G2081040G2081040G2081/set-password"
296+
)
297+
.bearer(&token)
298+
.json(serde_json::json!({
299+
"password": "hunter2",
300+
}));
301+
302+
let response = state.request(request).await;
303+
response.assert_status(StatusCode::FORBIDDEN);
304+
305+
let body: serde_json::Value = response.json();
306+
assert_eq!(body["errors"][0]["title"], "Password auth is disabled");
307+
}
270308
}

docs/api/spec.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,23 @@
367367
}
368368
}
369369
},
370+
"403": {
371+
"description": "Password auth is disabled in the server configuration",
372+
"content": {
373+
"application/json": {
374+
"schema": {
375+
"$ref": "#/components/schemas/ErrorResponse"
376+
},
377+
"example": {
378+
"errors": [
379+
{
380+
"title": "Password auth is disabled"
381+
}
382+
]
383+
}
384+
}
385+
}
386+
},
370387
"404": {
371388
"description": "User was not found",
372389
"content": {

0 commit comments

Comments
 (0)