2 use crate::schema::user_;
3 use crate::schema::user_::dsl::*;
4 use crate::{is_email_regex, Settings};
5 use bcrypt::{hash, DEFAULT_COST};
6 use jsonwebtoken::{decode, encode, Header, TokenData, Validation};
8 #[derive(Queryable, Identifiable, PartialEq, Debug)]
9 #[table_name = "user_"]
13 pub fedi_name: String,
14 pub preferred_username: Option<String>,
15 pub password_encrypted: String,
16 pub email: Option<String>,
17 pub icon: Option<Vec<u8>>,
20 pub published: chrono::NaiveDateTime,
21 pub updated: Option<chrono::NaiveDateTime>,
26 #[derive(Insertable, AsChangeset, Clone)]
27 #[table_name = "user_"]
30 pub fedi_name: String,
31 pub preferred_username: Option<String>,
32 pub password_encrypted: String,
35 pub email: Option<String>,
36 pub updated: Option<chrono::NaiveDateTime>,
41 impl Crud<UserForm> for User_ {
42 fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
43 use crate::schema::user_::dsl::*;
44 user_.find(user_id).first::<Self>(conn)
46 fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
47 diesel::delete(user_.find(user_id)).execute(conn)
49 fn create(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
50 insert_into(user_).values(form).get_result::<Self>(conn)
52 fn update(conn: &PgConnection, user_id: i32, form: &UserForm) -> Result<Self, Error> {
53 diesel::update(user_.find(user_id))
55 .get_result::<Self>(conn)
60 pub fn register(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
61 let mut edited_user = form.clone();
63 hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
64 edited_user.password_encrypted = password_hash;
66 Self::create(&conn, &edited_user)
68 pub fn read_from_name(conn: &PgConnection, from_user_name: String) -> Result<Self, Error> {
69 user_.filter(name.eq(from_user_name)).first::<Self>(conn)
73 #[derive(Debug, Serialize, Deserialize)]
83 pub fn decode(jwt: &str) -> Result<TokenData<Claims>, jsonwebtoken::errors::Error> {
86 ..Validation::default()
88 decode::<Claims>(&jwt, Settings::get().jwt_secret.as_ref(), &v)
94 pub fn jwt(&self) -> Jwt {
95 let my_claims = Claims {
97 username: self.name.to_owned(),
98 iss: self.fedi_name.to_owned(),
99 show_nsfw: self.show_nsfw,
100 theme: self.theme.to_owned(),
105 Settings::get().jwt_secret.as_ref(),
110 pub fn find_by_email_or_username(
112 username_or_email: &str,
113 ) -> Result<Self, Error> {
114 if is_email_regex(username_or_email) {
116 .filter(email.eq(username_or_email))
117 .first::<User_>(conn)
120 .filter(name.eq(username_or_email))
121 .first::<User_>(conn)
125 pub fn find_by_jwt(conn: &PgConnection, jwt: &str) -> Result<Self, Error> {
126 let claims: Claims = Claims::decode(&jwt).expect("Invalid token").claims;
127 Self::read(&conn, claims.id)
136 let conn = establish_connection();
138 let new_user = UserForm {
139 name: "thommy".into(),
140 fedi_name: "rrf".into(),
141 preferred_username: None,
142 password_encrypted: "nope".into(),
148 theme: "darkly".into(),
151 let inserted_user = User_::create(&conn, &new_user).unwrap();
153 let expected_user = User_ {
154 id: inserted_user.id,
155 name: "thommy".into(),
156 fedi_name: "rrf".into(),
157 preferred_username: None,
158 password_encrypted: "nope".into(),
163 published: inserted_user.published,
166 theme: "darkly".into(),
169 let read_user = User_::read(&conn, inserted_user.id).unwrap();
170 let updated_user = User_::update(&conn, inserted_user.id, &new_user).unwrap();
171 let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
173 assert_eq!(expected_user, read_user);
174 assert_eq!(expected_user, inserted_user);
175 assert_eq!(expected_user, updated_user);
176 assert_eq!(1, num_deleted);