1 use crate::schema::user_;
2 use crate::schema::user_::dsl::*;
4 use crate::{Settings, is_email_regex};
5 use jsonwebtoken::{encode, decode, Header, Validation, TokenData};
6 use bcrypt::{DEFAULT_COST, hash};
8 #[derive(Queryable, Identifiable, PartialEq, Debug)]
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>,
25 #[derive(Insertable, AsChangeset, Clone)]
29 pub fedi_name: String,
30 pub preferred_username: Option<String>,
31 pub password_encrypted: String,
34 pub email: Option<String>,
35 pub updated: Option<chrono::NaiveDateTime>,
39 impl Crud<UserForm> for User_ {
40 fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
41 use crate::schema::user_::dsl::*;
45 fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
46 diesel::delete(user_.find(user_id))
49 fn create(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
52 .get_result::<Self>(conn)
54 fn update(conn: &PgConnection, user_id: i32, form: &UserForm) -> Result<Self, Error> {
55 diesel::update(user_.find(user_id))
57 .get_result::<Self>(conn)
62 pub fn register(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
63 let mut edited_user = form.clone();
64 let password_hash = hash(&form.password_encrypted, DEFAULT_COST)
65 .expect("Couldn't hash password");
66 edited_user.password_encrypted = password_hash;
68 Self::create(&conn, &edited_user)
71 pub fn read_from_name(conn: &PgConnection, from_user_name: String) -> Result<Self, Error> {
72 user_.filter(name.eq(from_user_name))
77 #[derive(Debug, Serialize, Deserialize)]
86 pub fn decode(jwt: &str) -> Result<TokenData<Claims>, jsonwebtoken::errors::Error> {
89 ..Validation::default()
91 decode::<Claims>(&jwt, Settings::get().jwt_secret.as_ref(), &v)
97 pub fn jwt(&self) -> Jwt {
98 let my_claims = Claims {
100 username: self.name.to_owned(),
101 iss: self.fedi_name.to_owned(),
102 show_nsfw: self.show_nsfw,
104 encode(&Header::default(), &my_claims, Settings::get().jwt_secret.as_ref()).unwrap()
107 pub fn find_by_email_or_username(conn: &PgConnection, username_or_email: &str) -> Result<Self, Error> {
108 if is_email_regex(username_or_email) {
109 user_.filter(email.eq(username_or_email))
110 .first::<User_>(conn)
112 user_.filter(name.eq(username_or_email))
113 .first::<User_>(conn)
117 pub fn find_by_jwt(conn: &PgConnection, jwt: &str) -> Result<Self, Error> {
118 let claims: Claims = Claims::decode(&jwt).expect("Invalid token").claims;
119 Self::read(&conn, claims.id)
130 let conn = establish_connection();
132 let new_user = UserForm {
133 name: "thommy".into(),
134 fedi_name: "rrf".into(),
135 preferred_username: None,
136 password_encrypted: "nope".into(),
144 let inserted_user = User_::create(&conn, &new_user).unwrap();
146 let expected_user = User_ {
147 id: inserted_user.id,
148 name: "thommy".into(),
149 fedi_name: "rrf".into(),
150 preferred_username: None,
151 password_encrypted: "nope".into(),
156 published: inserted_user.published,
161 let read_user = User_::read(&conn, inserted_user.id).unwrap();
162 let updated_user = User_::update(&conn, inserted_user.id, &new_user).unwrap();
163 let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
165 assert_eq!(expected_user, read_user);
166 assert_eq!(expected_user, inserted_user);
167 assert_eq!(expected_user, updated_user);
168 assert_eq!(1, num_deleted);