Replaced refresh tokens with hashed string, refactored logic

This commit is contained in:
Benjamin Sherriff
2024-01-30 11:10:57 -05:00
parent d74e8e181b
commit 40a45275d6
6 changed files with 161 additions and 244 deletions

View File

@@ -1,5 +1,6 @@
use std::{future::{ready, Ready}, env};
use actix_web::{FromRequest, Error as ActixError, HttpRequest, dev::Payload, http};
use argon2::{password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString, Error as HashError}, Argon2, PasswordHash};
use diesel::prelude::*;
use log::error;
use redis::Commands;
@@ -8,7 +9,7 @@ use siren::ServiceError;
use crate::storage::{schema::users, connection};
use super::{hash_password, verify_token};
use super::AccessToken;
#[derive(Debug, Serialize, Deserialize)]
pub struct RegisterUser {
@@ -35,6 +36,16 @@ impl RegisterUser {
}
}
fn hash_password(password: &[u8]) -> Result<String, HashError> {
let salt = SaltString::generate(&mut OsRng);
Ok(Argon2::default().hash_password(password, &salt)?.to_string())
}
pub fn verify_password(hash: &str, password: &[u8]) -> Result<(), HashError> {
let parsed_hash = PasswordHash::new(hash)?;
Ok(Argon2::default().verify_password(password, &parsed_hash)?)
}
#[derive(Debug, Serialize, Deserialize)]
pub struct LoginRequest {
pub email: String,
@@ -131,7 +142,7 @@ impl FromRequest for JwtAuth {
type Error = ActixError;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let access_token = match req
let access_token_string = match req
.cookie("access_token")
.map(|c| c.value().to_string())
.or_else(|| {
@@ -148,18 +159,18 @@ impl FromRequest for JwtAuth {
let keys_dir = env::var("KEYS_DIR_PATH").expect("KEYS_DIR_PATH must be set");
let public_key = std::fs::read_to_string(format!("{}/access_public_key.pem", keys_dir)).expect("Failed to read access public key");
let access_token_details = match verify_token(&access_token, &public_key) {
let access_token = match AccessToken::decode(&access_token_string, &public_key) {
Ok(token_details) => token_details,
Err(err) => {
error!("Failed to verify access token: {}", err);
return ready(Err(ActixError::from(ServiceError {
status: 401,
message: format!("Failed to verify access token: {}", err)
message: format!("Access token is invaid: {}", err)
})))
}
};
let access_token_uuid = uuid::Uuid::parse_str(&access_token_details.token_uuid.to_string()).unwrap();
let access_token_uuid = uuid::Uuid::parse_str(&access_token.token_uuid.to_string()).unwrap();
let mut conn = match crate::storage::redis_connection() {
Ok(conn) => conn,
@@ -172,11 +183,11 @@ impl FromRequest for JwtAuth {
}
};
let user_email = match conn.get::<_, String>(access_token_uuid.clone().to_string()) {
Ok(result) => result,
Ok(result) => serde_json::from_str::<AccessToken>(&result).unwrap().email,
Err(_) => {
return ready(Err(ActixError::from(ServiceError {
status: 401,
message: format!("Access token was not found")
message: format!("Access token is invalid")
})))
}
};
@@ -187,7 +198,7 @@ impl FromRequest for JwtAuth {
}
Err(_) => return ready(Err(ActixError::from(ServiceError {
status: 401,
message: format!("User was not found")
message: format!("User does not exist")
})))
}
}