]> Untitled Git - lemmy.git/blob - lemmy_db_queries/src/source/password_reset_request.rs
Merge pull request #1328 from LemmyNet/move_views_to_diesel
[lemmy.git] / lemmy_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
84   #[test]
85   fn test_crud() {
86     let conn = establish_unpooled_connection();
87
88     let new_user = UserForm {
89       name: "thommy prw".into(),
90       preferred_username: None,
91       password_encrypted: "nope".into(),
92       email: None,
93       matrix_user_id: None,
94       avatar: None,
95       banner: None,
96       admin: false,
97       banned: Some(false),
98       published: None,
99       updated: None,
100       show_nsfw: false,
101       theme: "browser".into(),
102       default_sort_type: SortType::Hot as i16,
103       default_listing_type: ListingType::Subscribed as i16,
104       lang: "browser".into(),
105       show_avatars: true,
106       send_notifications_to_email: false,
107       actor_id: None,
108       bio: None,
109       local: true,
110       private_key: None,
111       public_key: None,
112       last_refreshed_at: None,
113     };
114
115     let inserted_user = User_::create(&conn, &new_user).unwrap();
116
117     let token = "nope";
118     let token_encrypted_ = "ca3704aa0b06f5954c79ee837faa152d84d6b2d42838f0637a15eda8337dbdce";
119
120     let inserted_password_reset_request =
121       PasswordResetRequest::create_token(&conn, inserted_user.id, token).unwrap();
122
123     let expected_password_reset_request = PasswordResetRequest {
124       id: inserted_password_reset_request.id,
125       user_id: inserted_user.id,
126       token_encrypted: token_encrypted_.to_string(),
127       published: inserted_password_reset_request.published,
128     };
129
130     let read_password_reset_request = PasswordResetRequest::read_from_token(&conn, token).unwrap();
131     let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
132
133     assert_eq!(expected_password_reset_request, read_password_reset_request);
134     assert_eq!(
135       expected_password_reset_request,
136       inserted_password_reset_request
137     );
138     assert_eq!(1, num_deleted);
139   }
140 }