11mod authenticate_flow;
22mod get_user_flow;
3+ pub mod password;
4+ pub mod repository;
35
46use std:: sync:: Arc ;
57
@@ -8,7 +10,6 @@ use bon::Builder;
810use nutype:: nutype;
911use secrecy:: SecretString ;
1012use snafu:: prelude:: * ;
11- use strum_macros:: Display ;
1213
1314use domain:: user;
1415
@@ -19,62 +20,26 @@ type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
1920#[ derive( Debug , Snafu ) ]
2021pub enum Error {
2122 #[ snafu( display( "{source}" ) ) ]
22- Repository { source : RepositoryError } ,
23+ Repository { source : repository :: Error } ,
2324 #[ snafu( display( "auth password hashing failed: {source}" ) ) ]
24- HashPassword { source : PasswordHashError } ,
25+ HashPassword { source : password :: HashError } ,
2526 #[ snafu( display( "stored password hash parsing failed: {source}" ) ) ]
26- ParseStoredPasswordHash { source : PasswordHashError } ,
27+ ParseStoredPasswordHash { source : password :: HashError } ,
2728 #[ snafu( display( "invalid authenticated user id: {source}" ) ) ]
2829 InvalidAuthenticatedUserId { source : uuid:: Error } ,
2930}
3031
31- #[ derive( Clone , Copy , Debug , Display ) ]
32- pub enum RepositoryOperation {
33- #[ strum( serialize = "find auth record by email" ) ]
34- FindByEmail ,
35- #[ strum( serialize = "find auth record by id" ) ]
36- FindById ,
37- }
38-
39- #[ derive( Debug , Snafu ) ]
40- pub enum RepositoryError {
41- #[ snafu( display( "auth repository query failed while {operation}: {source}" ) ) ]
42- Query {
43- operation : RepositoryOperation ,
44- source : BoxError ,
45- } ,
46- #[ snafu( display( "failed to decode auth username: {source}" ) ) ]
47- DecodeUsername { source : user:: UsernameError } ,
48- #[ snafu( display( "failed to decode auth email: {source}" ) ) ]
49- DecodeEmail { source : user:: EmailError } ,
50- }
51-
52- #[ derive( Debug ) ]
53- pub struct PasswordHashError ( BoxError ) ;
54-
55- impl core:: fmt:: Display for PasswordHashError {
56- fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
57- write ! ( f, "{}" , self . 0 )
58- }
59- }
60-
61- impl std:: error:: Error for PasswordHashError {
62- fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
63- Some ( & * self . 0 )
64- }
65- }
66-
6732fn box_error ( source : impl std:: error:: Error + Send + Sync + ' static ) -> BoxError {
6833 Box :: new ( source)
6934}
7035
7136impl Error {
7237 pub fn query_repository (
73- operation : RepositoryOperation ,
38+ operation : repository :: Operation ,
7439 source : impl std:: error:: Error + Send + Sync + ' static ,
7540 ) -> Self {
7641 Self :: Repository {
77- source : RepositoryError :: Query {
42+ source : repository :: Error :: Query {
7843 operation,
7944 source : box_error ( source) ,
8045 } ,
@@ -83,27 +48,27 @@ impl Error {
8348
8449 pub fn decode_username ( source : user:: UsernameError ) -> Self {
8550 Self :: Repository {
86- source : RepositoryError :: DecodeUsername { source } ,
51+ source : repository :: Error :: DecodeUsername { source } ,
8752 }
8853 }
8954
9055 pub fn decode_email ( source : user:: EmailError ) -> Self {
9156 Self :: Repository {
92- source : RepositoryError :: DecodeEmail { source } ,
57+ source : repository :: Error :: DecodeEmail { source } ,
9358 }
9459 }
9560
9661 pub fn hash_password ( source : impl std:: error:: Error + Send + Sync + ' static ) -> Self {
9762 Self :: HashPassword {
98- source : PasswordHashError ( box_error ( source) ) ,
63+ source : password :: HashError ( box_error ( source) ) ,
9964 }
10065 }
10166
10267 pub fn parse_stored_password_hash (
10368 source : impl std:: error:: Error + Send + Sync + ' static ,
10469 ) -> Self {
10570 Self :: ParseStoredPasswordHash {
106- source : PasswordHashError ( box_error ( source) ) ,
71+ source : password :: HashError ( box_error ( source) ) ,
10772 }
10873 }
10974}
@@ -127,7 +92,7 @@ pub struct Record {
12792 pub id : user:: Id ,
12893 pub username : user:: Username ,
12994 pub email : user:: Email ,
130- pub password_hash : PasswordHash ,
95+ pub password_hash : password :: Hash ,
13196 pub session_hash : SessionHash ,
13297}
13398
@@ -190,19 +155,14 @@ pub trait Repository: Send + Sync {
190155 async fn find_by_id ( & self , user_id : & user:: Id ) -> Result < Option < Record > > ;
191156}
192157
193- pub trait PasswordHasher : Send + Sync {
194- fn hash ( & self , password : & str ) -> Result < PasswordHash > ;
195- fn verify ( & self , password : & str , password_hash : & PasswordHash ) -> Result < bool > ;
196- }
197-
198158#[ derive( Clone ) ]
199159pub struct ProviderImpl {
200160 repo : Arc < dyn Repository > ,
201- hasher : Arc < dyn PasswordHasher > ,
161+ hasher : Arc < dyn password :: Hasher > ,
202162}
203163
204164impl ProviderImpl {
205- pub fn new ( repo : Arc < dyn Repository > , hasher : Arc < dyn PasswordHasher > ) -> Self {
165+ pub fn new ( repo : Arc < dyn Repository > , hasher : Arc < dyn password :: Hasher > ) -> Self {
206166 Self { repo, hasher }
207167 }
208168}
@@ -227,9 +187,6 @@ impl Provider for ProviderImpl {
227187 }
228188}
229189
230- #[ nutype( sanitize( trim) , derive( Clone , Debug , PartialEq , Display ) ) ]
231- pub struct PasswordHash ( String ) ;
232-
233190#[ nutype( sanitize( trim) , derive( Clone , Debug , PartialEq , Display ) ) ]
234191pub struct SessionHash ( String ) ;
235192
@@ -249,7 +206,7 @@ mod tests {
249206 #[ test]
250207 fn repository_error_preserves_source ( ) {
251208 let error = Error :: query_repository (
252- RepositoryOperation :: FindByEmail ,
209+ repository :: Operation :: FindByEmail ,
253210 std:: io:: Error :: other ( "db unavailable" ) ,
254211 ) ;
255212
@@ -311,8 +268,8 @@ mod tests {
311268 user:: Id :: from_uuid ( uuid:: Uuid :: new_v4 ( ) )
312269 }
313270
314- fn test_password_hash ( ) -> PasswordHash {
315- PasswordHash :: new ( "hash" )
271+ fn test_password_hash ( ) -> password :: Hash {
272+ password :: Hash :: new ( "hash" )
316273 }
317274
318275 fn test_session_hash ( ) -> SessionHash {
@@ -338,12 +295,12 @@ mod tests {
338295 ok : bool ,
339296 }
340297
341- impl PasswordHasher for TestHasher {
342- fn hash ( & self , _password : & str ) -> Result < PasswordHash > {
298+ impl password :: Hasher for TestHasher {
299+ fn hash ( & self , _password : & str ) -> Result < password :: Hash > {
343300 Ok ( test_password_hash ( ) )
344301 }
345302
346- fn verify ( & self , _password : & str , _password_hash : & PasswordHash ) -> Result < bool > {
303+ fn verify ( & self , _password : & str , _password_hash : & password :: Hash ) -> Result < bool > {
347304 Ok ( self . ok )
348305 }
349306 }
0 commit comments