2 use schema::user_::dsl::*;
4 use {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>
24 #[derive(Insertable, AsChangeset, Clone)]
28 pub fedi_name: String,
29 pub preferred_username: Option<String>,
30 pub password_encrypted: String,
33 pub email: Option<String>,
34 pub updated: Option<chrono::NaiveDateTime>
37 impl Crud<UserForm> for User_ {
38 fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
39 use schema::user_::dsl::*;
43 fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
44 diesel::delete(user_.find(user_id))
47 fn create(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
50 .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();
62 let password_hash = hash(&form.password_encrypted, DEFAULT_COST)
63 .expect("Couldn't hash password");
64 edited_user.password_encrypted = password_hash;
66 Self::create(&conn, &edited_user)
69 pub fn read_from_name(conn: &PgConnection, from_user_name: String) -> Result<Self, Error> {
70 user_.filter(name.eq(from_user_name))
75 #[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(),
100 encode(&Header::default(), &my_claims, Settings::get().jwt_secret.as_ref()).unwrap()
103 pub fn find_by_email_or_username(conn: &PgConnection, username_or_email: &str) -> Result<Self, Error> {
104 if is_email_regex(username_or_email) {
105 user_.filter(email.eq(username_or_email))
106 .first::<User_>(conn)
108 user_.filter(name.eq(username_or_email))
109 .first::<User_>(conn)
113 pub fn find_by_jwt(conn: &PgConnection, jwt: &str) -> Result<Self, Error> {
114 let claims: Claims = Claims::decode(&jwt).expect("Invalid token").claims;
115 Self::read(&conn, claims.id)
126 let conn = establish_connection();
128 let new_user = UserForm {
129 name: "thommy".into(),
130 fedi_name: "rrf".into(),
131 preferred_username: None,
132 password_encrypted: "nope".into(),
139 let inserted_user = User_::create(&conn, &new_user).unwrap();
141 let expected_user = User_ {
142 id: inserted_user.id,
143 name: "thommy".into(),
144 fedi_name: "rrf".into(),
145 preferred_username: None,
146 password_encrypted: "nope".into(),
151 published: inserted_user.published,
155 let read_user = User_::read(&conn, inserted_user.id).unwrap();
156 let updated_user = User_::update(&conn, inserted_user.id, &new_user).unwrap();
157 let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
159 assert_eq!(expected_user, read_user);
160 assert_eq!(expected_user, inserted_user);
161 assert_eq!(expected_user, updated_user);
162 assert_eq!(1, num_deleted);