@@ -32,7 +32,8 @@ use zeroize::Zeroizing;
32
32
use super :: { MatrixError , MatrixJsonBody } ;
33
33
use crate :: {
34
34
BoundActivityTracker , Limiter , METER , RequesterFingerprint , impl_from_error_for_route,
35
- passwords:: PasswordManager , rate_limit:: PasswordCheckLimitedError ,
35
+ passwords:: { PasswordManager , PasswordVerificationResult } ,
36
+ rate_limit:: PasswordCheckLimitedError ,
36
37
} ;
37
38
38
39
static LOGIN_COUNTER : LazyLock < Counter < u64 > > = LazyLock :: new ( || {
@@ -193,7 +194,7 @@ pub enum RouteError {
193
194
NoPassword ,
194
195
195
196
#[ error( "password verification failed" ) ]
196
- PasswordVerificationFailed ( # [ source ] anyhow :: Error ) ,
197
+ PasswordMismatch ,
197
198
198
199
#[ error( "request rate limited" ) ]
199
200
RateLimited ( #[ from] PasswordCheckLimitedError ) ,
@@ -210,6 +211,12 @@ pub enum RouteError {
210
211
211
212
impl_from_error_for_route ! ( mas_storage:: RepositoryError ) ;
212
213
214
+ impl From < anyhow:: Error > for RouteError {
215
+ fn from ( err : anyhow:: Error ) -> Self {
216
+ Self :: Internal ( err. into ( ) )
217
+ }
218
+ }
219
+
213
220
impl IntoResponse for RouteError {
214
221
fn into_response ( self ) -> axum:: response:: Response {
215
222
let sentry_event_id =
@@ -241,13 +248,11 @@ impl IntoResponse for RouteError {
241
248
error : "Missing property 'identifier" ,
242
249
status : StatusCode :: BAD_REQUEST ,
243
250
} ,
244
- Self :: UserNotFound | Self :: NoPassword | Self :: PasswordVerificationFailed ( _) => {
245
- MatrixError {
246
- errcode : "M_FORBIDDEN" ,
247
- error : "Invalid username/password" ,
248
- status : StatusCode :: FORBIDDEN ,
249
- }
250
- }
251
+ Self :: UserNotFound | Self :: NoPassword | Self :: PasswordMismatch => MatrixError {
252
+ errcode : "M_FORBIDDEN" ,
253
+ error : "Invalid username/password" ,
254
+ status : StatusCode :: FORBIDDEN ,
255
+ } ,
251
256
Self :: LoginTookTooLong => MatrixError {
252
257
errcode : "M_FORBIDDEN" ,
253
258
error : "Login token expired" ,
@@ -576,28 +581,32 @@ async fn user_password_login(
576
581
// Verify the password
577
582
let password = Zeroizing :: new ( password) ;
578
583
579
- let new_password_hash = password_manager
584
+ match password_manager
580
585
. verify_and_upgrade (
581
586
& mut rng,
582
587
user_password. version ,
583
588
password,
584
589
user_password. hashed_password . clone ( ) ,
585
590
)
586
- . await
587
- . map_err ( RouteError :: PasswordVerificationFailed ) ?;
588
-
589
- if let Some ( ( version, hashed_password) ) = new_password_hash {
590
- // Save the upgraded password if needed
591
- repo. user_password ( )
592
- . add (
593
- & mut rng,
594
- clock,
595
- & user,
596
- version,
597
- hashed_password,
598
- Some ( & user_password) ,
599
- )
600
- . await ?;
591
+ . await ?
592
+ {
593
+ PasswordVerificationResult :: Success ( Some ( ( version, hashed_password) ) ) => {
594
+ // Save the upgraded password if needed
595
+ repo. user_password ( )
596
+ . add (
597
+ & mut rng,
598
+ clock,
599
+ & user,
600
+ version,
601
+ hashed_password,
602
+ Some ( & user_password) ,
603
+ )
604
+ . await ?;
605
+ }
606
+ PasswordVerificationResult :: Success ( None ) => { }
607
+ PasswordVerificationResult :: Failure => {
608
+ return Err ( RouteError :: PasswordMismatch ) ;
609
+ }
601
610
}
602
611
603
612
// We're about to create a device, let's explicitly acquire a lock, so that
0 commit comments