@@ -3,12 +3,13 @@ use async_trait::async_trait;
3
3
use axum_login:: { AuthnBackend , UserId } ;
4
4
use chrono:: Utc ;
5
5
use entity:: users:: { ActiveModel , Column , Entity , Model } ;
6
+ use entity:: Id ;
6
7
use log:: * ;
7
8
use password_auth:: { generate_hash, verify_password} ;
8
9
use sea_orm:: { entity:: prelude:: * , DatabaseConnection , Set } ;
9
10
use serde:: Deserialize ;
10
11
use std:: sync:: Arc ;
11
- use utoipa:: ToSchema ;
12
+ use utoipa:: { IntoParams , ToSchema } ;
12
13
13
14
pub async fn create ( db : & DatabaseConnection , user_model : Model ) -> Result < Model , Error > {
14
15
debug ! (
@@ -36,7 +37,7 @@ pub async fn create(db: &DatabaseConnection, user_model: Model) -> Result<Model,
36
37
37
38
pub async fn find_by_email ( db : & DatabaseConnection , email : & str ) -> Result < Option < Model > , Error > {
38
39
let user: Option < Model > = Entity :: find ( )
39
- . filter ( Column :: Email . contains ( email) )
40
+ . filter ( Column :: Email . eq ( email) )
40
41
. one ( db)
41
42
. await ?;
42
43
@@ -45,6 +46,13 @@ pub async fn find_by_email(db: &DatabaseConnection, email: &str) -> Result<Optio
45
46
Ok ( user)
46
47
}
47
48
49
+ pub async fn find_by_id ( db : & DatabaseConnection , id : Id ) -> Result < Model , Error > {
50
+ Entity :: find_by_id ( id) . one ( db) . await ?. ok_or_else ( || Error {
51
+ source : None ,
52
+ error_kind : EntityApiErrorKind :: RecordNotFound ,
53
+ } )
54
+ }
55
+
48
56
async fn authenticate_user ( creds : Credentials , user : Model ) -> Result < Option < Model > , Error > {
49
57
match verify_password ( creds. password , & user. password ) {
50
58
Ok ( _) => Ok ( Some ( user) ) ,
@@ -60,7 +68,7 @@ pub struct Backend {
60
68
db : Arc < DatabaseConnection > ,
61
69
}
62
70
63
- #[ derive( Debug , Clone , ToSchema , Deserialize ) ]
71
+ #[ derive( Debug , Clone , ToSchema , IntoParams , Deserialize ) ]
64
72
#[ schema( as = entity_api:: user:: Credentials ) ] // OpenAPI schema
65
73
pub struct Credentials {
66
74
pub email : String ,
@@ -112,3 +120,55 @@ impl AuthnBackend for Backend {
112
120
}
113
121
114
122
pub type AuthSession = axum_login:: AuthSession < Backend > ;
123
+
124
+ #[ cfg( test) ]
125
+ // We need to gate seaORM's mock feature behind conditional compilation because
126
+ // the feature removes the Clone trait implementation from seaORM's DatabaseConnection.
127
+ // see https://github.com/SeaQL/sea-orm/issues/830
128
+ #[ cfg( feature = "mock" ) ]
129
+ mod test {
130
+ use super :: * ;
131
+ use entity:: Id ;
132
+ use sea_orm:: { DatabaseBackend , MockDatabase , Transaction } ;
133
+
134
+ #[ tokio:: test]
135
+ async fn find_by_email_returns_a_single_record ( ) -> Result < ( ) , Error > {
136
+ let db = MockDatabase :: new ( DatabaseBackend :: Postgres ) . into_connection ( ) ;
137
+
138
+ let user_email = "test@test.com" ;
139
+ let _ = find_by_email ( & db, user_email) . await ;
140
+
141
+ assert_eq ! (
142
+ db. into_transaction_log( ) ,
143
+ [ Transaction :: from_sql_and_values(
144
+ DatabaseBackend :: Postgres ,
145
+ r#"SELECT "users"."id", "users"."email", "users"."first_name", "users"."last_name", "users"."display_name", "users"."password", "users"."github_username", "users"."github_profile_url", "users"."created_at", "users"."updated_at" FROM "refactor_platform"."users" WHERE "users"."email" = $1 LIMIT $2"# ,
146
+ [ user_email. into( ) , sea_orm:: Value :: BigUnsigned ( Some ( 1 ) ) ]
147
+ ) ]
148
+ ) ;
149
+
150
+ Ok ( ( ) )
151
+ }
152
+
153
+ #[ tokio:: test]
154
+ async fn find_by_id_returns_a_single_record ( ) -> Result < ( ) , Error > {
155
+ let db = MockDatabase :: new ( DatabaseBackend :: Postgres ) . into_connection ( ) ;
156
+
157
+ let coaching_session_id = Id :: new_v4 ( ) ;
158
+ let _ = find_by_id ( & db, coaching_session_id) . await ;
159
+
160
+ assert_eq ! (
161
+ db. into_transaction_log( ) ,
162
+ [ Transaction :: from_sql_and_values(
163
+ DatabaseBackend :: Postgres ,
164
+ r#"SELECT "users"."id", "users"."email", "users"."first_name", "users"."last_name", "users"."display_name", "users"."password", "users"."github_username", "users"."github_profile_url", "users"."created_at", "users"."updated_at" FROM "refactor_platform"."users" WHERE "users"."id" = $1 LIMIT $2"# ,
165
+ [
166
+ coaching_session_id. into( ) ,
167
+ sea_orm:: Value :: BigUnsigned ( Some ( 1 ) )
168
+ ]
169
+ ) ]
170
+ ) ;
171
+
172
+ Ok ( ( ) )
173
+ }
174
+ }
0 commit comments