]> Untitled Git - lemmy.git/blob - crates/db_queries/src/source/password_reset_request.rs
Support plain `cargo test` and disable unused doctests for speed
[lemmy.git] / crates / db_queries / src / source / password_reset_request.rs
1 use crate::Crud;
2 use diesel::{dsl::*, result::Error, PgConnection, *};
3 use lemmy_db_schema::{schema::password_reset_request::dsl::*, source::password_reset_request::*};
4 use sha2::{Digest, Sha256};
5
6 impl Crud<PasswordResetRequestForm> for PasswordResetRequest {
7   fn read(conn: &PgConnection, password_reset_request_id: i32) -> Result<Self, Error> {
8     password_reset_request
9       .find(password_reset_request_id)
10       .first::<Self>(conn)
11   }
12   fn create(conn: &PgConnection, form: &PasswordResetRequestForm) -> Result<Self, Error> {
13     insert_into(password_reset_request)
14       .values(form)
15       .get_result::<Self>(conn)
16   }
17   fn update(
18     conn: &PgConnection,
19     password_reset_request_id: i32,
20     form: &PasswordResetRequestForm,
21   ) -> Result<Self, Error> {
22     diesel::update(password_reset_request.find(password_reset_request_id))
23       .set(form)
24       .get_result::<Self>(conn)
25   }
26 }
27
28 pub trait PasswordResetRequest_ {
29   fn create_token(
30     conn: &PgConnection,
31     from_user_id: i32,
32     token: &str,
33   ) -> Result<PasswordResetRequest, Error>;
34   fn read_from_token(conn: &PgConnection, token: &str) -> Result<PasswordResetRequest, Error>;
35 }
36
37 impl PasswordResetRequest_ for PasswordResetRequest {
38   fn create_token(
39     conn: &PgConnection,
40     from_user_id: i32,
41     token: &str,
42   ) -> Result<PasswordResetRequest, Error> {
43     let mut hasher = Sha256::new();
44     hasher.update(token);
45     let token_hash: String = bytes_to_hex(hasher.finalize().to_vec());
46
47     let form = PasswordResetRequestForm {
48       user_id: from_user_id,
49       token_encrypted: token_hash,
50     };
51
52     Self::create(&conn, &form)
53   }
54   fn read_from_token(conn: &PgConnection, token: &str) -> Result<PasswordResetRequest, Error> {
55     let mut hasher = Sha256::new();
56     hasher.update(token);
57     let token_hash: String = bytes_to_hex(hasher.finalize().to_vec());
58     password_reset_request
59       .filter(token_encrypted.eq(token_hash))
60       .filter(published.gt(now - 1.days()))
61       .first::<Self>(conn)
62   }
63 }
64
65 fn bytes_to_hex(bytes: Vec<u8>) -> String {
66   let mut str = String::new();
67   for byte in bytes {
68     str = format!("{}{:02x}", str, byte);
69   }
70   str
71 }
72
73 #[cfg(test)]
74 mod tests {
75   use crate::{
76     establish_unpooled_connection,
77     source::password_reset_request::PasswordResetRequest_,
78     Crud,
79     ListingType,
80     SortType,
81   };
82   use lemmy_db_schema::source::{password_reset_request::PasswordResetRequest, user::*};
83   use serial_test::serial;
84
85   #[test]
86   #[serial]
87   fn test_crud() {
88     let conn = establish_unpooled_connection();
89
90     let new_user = UserForm {
91       name: "thommy prw".into(),
92       preferred_username: None,
93       password_encrypted: "nope".into(),
94       email: None,
95       matrix_user_id: None,
96       avatar: None,
97       banner: None,
98       admin: false,
99       banned: Some(false),
100       published: None,
101       updated: None,
102       show_nsfw: false,
103       theme: "browser".into(),
104       default_sort_type: SortType::Hot as i16,
105       default_listing_type: ListingType::Subscribed as i16,
106       lang: "browser".into(),
107       show_avatars: true,
108       send_notifications_to_email: false,
109       actor_id: None,
110       bio: None,
111       local: true,
112       private_key: None,
113       public_key: None,
114       last_refreshed_at: None,
115       inbox_url: None,
116       shared_inbox_url: None,
117     };
118
119     let inserted_user = User_::create(&conn, &new_user).unwrap();
120
121     let token = "nope";
122     let token_encrypted_ = "ca3704aa0b06f5954c79ee837faa152d84d6b2d42838f0637a15eda8337dbdce";
123
124     let inserted_password_reset_request =
125       PasswordResetRequest::create_token(&conn, inserted_user.id, token).unwrap();
126
127     let expected_password_reset_request = PasswordResetRequest {
128       id: inserted_password_reset_request.id,
129       user_id: inserted_user.id,
130       token_encrypted: token_encrypted_.to_string(),
131       published: inserted_password_reset_request.published,
132     };
133
134     let read_password_reset_request = PasswordResetRequest::read_from_token(&conn, token).unwrap();
135     let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
136
137     assert_eq!(expected_password_reset_request, read_password_reset_request);
138     assert_eq!(
139       expected_password_reset_request,
140       inserted_password_reset_request
141     );
142     assert_eq!(1, num_deleted);
143   }
144 }