diff --git a/src/auth/jwt.rs b/src/auth/jwt.rs index 4b8923f..83e7a1e 100644 --- a/src/auth/jwt.rs +++ b/src/auth/jwt.rs @@ -1,5 +1,5 @@ use chrono::Utc; -use diesel::{insert_into, prelude::*, PgConnection}; +use diesel::{prelude::*, PgConnection}; use hmac::{Hmac, NewMac}; use jwt::SignWithKey; use rand::{thread_rng, Rng}; @@ -7,10 +7,8 @@ use serde::{Deserialize, Serialize}; use sha2::Sha256; use crate::{ - db::{ - tokens::{NewRefreshToken, RefreshToken}, - users::User, - }, + db, + db::{tokens::NewRefreshToken, users::User}, errors::{RbError, RbResult}, schema::{refresh_tokens::dsl as refresh_tokens, users::dsl as users}, }; @@ -61,14 +59,14 @@ pub fn generate_jwt_token(conn: &PgConnection, user: &User) -> RbResult RbResult(conn) - .map_err(|_| RbError::AuthInvalidRefreshToken)?; + let (token_entry, user) = + db::tokens::find_with_user(conn, &token_bytes).ok_or(RbError::AuthInvalidRefreshToken)?; // If we see that the token has already been used before, we block the user. if token_entry.last_used_at.is_some() { diff --git a/src/auth/pass.rs b/src/auth/pass.rs index c8d5b96..1c0f04e 100644 --- a/src/auth/pass.rs +++ b/src/auth/pass.rs @@ -1,9 +1,9 @@ use argon2::verify_encoded; -use diesel::{insert_into, prelude::*, PgConnection}; +use diesel::{prelude::*, PgConnection}; use rand::{thread_rng, Rng}; use crate::{ - db::users::{NewUser, User}, + db::users::User, errors::{RbError, RbResult}, schema::users::dsl as users, }; diff --git a/src/db/tokens.rs b/src/db/tokens.rs index cfe5904..7ca6b1d 100644 --- a/src/db/tokens.rs +++ b/src/db/tokens.rs @@ -1,7 +1,10 @@ -use diesel::{Insertable, Queryable}; +use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use uuid::Uuid; -use crate::schema::refresh_tokens; +use crate::{ + errors::{RbError, RbResult}, + schema::{refresh_tokens, refresh_tokens::dsl::*}, +}; #[derive(Queryable)] pub struct RefreshToken @@ -20,3 +23,36 @@ pub struct NewRefreshToken pub user_id: Uuid, pub expires_at: chrono::NaiveDateTime, } + +pub fn all(conn: &PgConnection) -> RbResult> +{ + refresh_tokens + .load::(conn) + .map_err(|_| RbError::DbError("Couldn't get all refresh tokens.")) +} + +pub fn create(conn: &PgConnection, new_refresh_token: &NewRefreshToken) -> RbResult<()> +{ + insert_into(refresh_tokens) + .values(new_refresh_token) + .execute(conn) + .map_err(|_| RbError::Custom("Couldn't insert refresh token."))?; + + // TODO check for conflict? + + Ok(()) +} + +pub fn find_with_user( + conn: &PgConnection, + token_val: &[u8], +) -> Option<(RefreshToken, super::users::User)> +{ + // TODO actually check for errors here + refresh_tokens + .inner_join(crate::schema::users::dsl::users) + .filter(token.eq(token_val)) + .first::<(RefreshToken, super::users::User)>(conn) + .map_err(|_| RbError::Custom("Couldn't get refresh token & user.")) + .ok() +}