Replaced refresh tokens with hashed string, refactored logic
This commit is contained in:
@@ -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")
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user