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