@@ -51,7 +51,7 @@ impl<W: std::io::Write> HeaderContext<W> {
5151 Some ( "redirect" ) => self . redirect ( & data) . map ( PageContext :: Close ) ,
5252 Some ( "json" ) => self . json ( & data) . map ( PageContext :: Close ) ,
5353 Some ( "cookie" ) => self . add_cookie ( & data) . map ( PageContext :: Header ) ,
54- Some ( "authentication" ) => self . authentication ( & data) . await ,
54+ Some ( "authentication" ) => self . authentication ( data) . await ,
5555 _ => self . start_body ( data) . await ,
5656 }
5757 }
@@ -167,27 +167,19 @@ impl<W: std::io::Write> HeaderContext<W> {
167167 Ok ( self . response . body ( json_response) )
168168 }
169169
170- async fn authentication ( mut self , data : & JsonValue ) -> anyhow:: Result < PageContext < W > > {
171- let password_hash = get_object_str ( data, "password_hash" ) ;
172- let password = get_object_str ( data, "password" ) ;
170+ async fn authentication ( mut self , mut data : JsonValue ) -> anyhow:: Result < PageContext < W > > {
171+ let password_hash = take_object_str ( & mut data, "password_hash" ) ;
172+ let password = take_object_str ( & mut data, "password" ) ;
173173 if let ( Some ( password) , Some ( password_hash) ) = ( password, password_hash) {
174- log:: debug!(
175- "Authenticating user with password_hash = {:?}" ,
176- password_hash
177- ) ;
178- let verif_result =
179- tokio:: task:: block_in_place ( move || verify_password_sync ( password_hash, password) ) ?;
180- match verif_result {
174+ log:: debug!( "Authentication with password_hash = {:?}" , password_hash) ;
175+ match verify_password_async ( password_hash, password) . await ? {
181176 Ok ( ( ) ) => return Ok ( PageContext :: Header ( self ) ) ,
182- Err ( e) => log:: info!( "User authentication failed : {}" , e) ,
177+ Err ( e) => log:: info!( "Password didn't match : {}" , e) ,
183178 }
184179 }
185- log:: debug!(
186- "Authentication failed with password_hash = {:?}" ,
187- password_hash
188- ) ;
180+ log:: debug!( "Authentication failed" ) ;
189181 // The authentication failed
190- if let Some ( link) = get_object_str ( data, "link" ) {
182+ if let Some ( link) = get_object_str ( & data, "link" ) {
191183 self . response . status ( StatusCode :: FOUND ) ;
192184 self . response . insert_header ( ( header:: LOCATION , link) ) ;
193185 self . has_status = true ;
@@ -218,14 +210,17 @@ impl<W: std::io::Write> HeaderContext<W> {
218210 }
219211}
220212
221- fn verify_password_sync (
222- password_hash : & str ,
223- password : & str ,
213+ async fn verify_password_async (
214+ password_hash : String ,
215+ password : String ,
224216) -> Result < Result < ( ) , password_hash:: Error > , anyhow:: Error > {
225- let hash = password_hash:: PasswordHash :: new ( password_hash)
226- . map_err ( |e| anyhow:: anyhow!( "invalid value for the password_hash property: {}" , e) ) ?;
227- let phfs = & [ & argon2:: Argon2 :: default ( ) as & dyn password_hash:: PasswordVerifier ] ;
228- Ok ( hash. verify_password ( phfs, password) )
217+ tokio:: task:: spawn_blocking ( move || {
218+ let hash = password_hash:: PasswordHash :: new ( & password_hash)
219+ . map_err ( |e| anyhow:: anyhow!( "invalid value for the password_hash property: {}" , e) ) ?;
220+ let phfs = & [ & argon2:: Argon2 :: default ( ) as & dyn password_hash:: PasswordVerifier ] ;
221+ Ok ( hash. verify_password ( phfs, password) )
222+ } )
223+ . await ?
229224}
230225
231226fn get_backtrace ( error : & anyhow:: Error ) -> Vec < String > {
@@ -244,6 +239,13 @@ fn get_object_str<'a>(json: &'a JsonValue, key: &str) -> Option<&'a str> {
244239 . and_then ( JsonValue :: as_str)
245240}
246241
242+ fn take_object_str ( json : & mut JsonValue , key : & str ) -> Option < String > {
243+ match json. get_mut ( key) ?. take ( ) {
244+ JsonValue :: String ( s) => Some ( s) ,
245+ _ => None ,
246+ }
247+ }
248+
247249#[ allow( clippy:: module_name_repetitions) ]
248250pub struct RenderContext < W : std:: io:: Write > {
249251 app_state : Arc < AppState > ,
0 commit comments