@@ -36,6 +36,9 @@ pub enum RouteError {
36
36
#[ error( "Password is too weak" ) ]
37
37
PasswordTooWeak ,
38
38
39
+ #[ error( "Password auth is disabled" ) ]
40
+ PasswordAuthDisabled ,
41
+
39
42
#[ error( "Password hashing failed" ) ]
40
43
Password ( #[ source] anyhow:: Error ) ,
41
44
@@ -50,6 +53,7 @@ impl IntoResponse for RouteError {
50
53
let error = ErrorResponse :: from_error ( & self ) ;
51
54
let status = match self {
52
55
Self :: Internal ( _) | Self :: Password ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
56
+ Self :: PasswordAuthDisabled => StatusCode :: FORBIDDEN ,
53
57
Self :: PasswordTooWeak => StatusCode :: BAD_REQUEST ,
54
58
Self :: NotFound ( _) => StatusCode :: NOT_FOUND ,
55
59
} ;
@@ -83,6 +87,11 @@ pub fn doc(operation: TransformOperation) -> TransformOperation {
83
87
let response = ErrorResponse :: from_error ( & RouteError :: PasswordTooWeak ) ;
84
88
t. description ( "Password is too weak" ) . example ( response)
85
89
} )
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
+ } )
86
95
. response_with :: < 404 , RouteError , _ > ( |t| {
87
96
let response = ErrorResponse :: from_error ( & RouteError :: NotFound ( Ulid :: nil ( ) ) ) ;
88
97
t. description ( "User was not found" ) . example ( response)
@@ -99,6 +108,10 @@ pub async fn handler(
99
108
id : UlidPathParam ,
100
109
Json ( params) : Json < Request > ,
101
110
) -> Result < StatusCode , RouteError > {
111
+ if !password_manager. is_enabled ( ) {
112
+ return Err ( RouteError :: PasswordAuthDisabled ) ;
113
+ }
114
+
102
115
let user = repo
103
116
. user ( )
104
117
. lookup ( * id)
@@ -137,7 +150,10 @@ mod tests {
137
150
use sqlx:: PgPool ;
138
151
use zeroize:: Zeroizing ;
139
152
140
- use crate :: test_utils:: { setup, RequestBuilderExt , ResponseExt , TestState } ;
153
+ use crate :: {
154
+ passwords:: PasswordManager ,
155
+ test_utils:: { setup, RequestBuilderExt , ResponseExt , TestState } ,
156
+ } ;
141
157
142
158
#[ sqlx:: test( migrator = "mas_storage_pg::MIGRATOR" ) ]
143
159
async fn test_set_password ( pool : PgPool ) {
@@ -267,4 +283,26 @@ mod tests {
267
283
"User ID 01040G2081040G2081040G2081 not found"
268
284
) ;
269
285
}
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 ( format ! (
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
+ }
270
308
}
0 commit comments