From ba2594b84c992fb0a7c5890543d9877e662f2c86 Mon Sep 17 00:00:00 2001 From: franklinblanco Date: Thu, 7 Jul 2022 19:00:38 -0400 Subject: [PATCH] Added token expiration --- src/resources/error_messages.rs | 4 +++- src/routes/main_router.rs | 1 + src/routes/user_routes.rs | 34 +++++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/resources/error_messages.rs b/src/resources/error_messages.rs index 1630c3d..47e7f4a 100644 --- a/src/resources/error_messages.rs +++ b/src/resources/error_messages.rs @@ -17,4 +17,6 @@ pub const ERROR_INVALID_TOKEN: (&str, &str) = ("ERROR.INVALID_TOKEN", "The token pub const ERROR_INCORRECT_TOKEN: (&str, &str) = ("ERROR.INCORRECT_TOKEN", "The token you have supplied does not belong to this user."); -pub const ERROR_MISSING_TOKEN: (&str, &str) = ("ERROR.MISSING_TOKEN", "No token supplied."); \ No newline at end of file +pub const ERROR_MISSING_TOKEN: (&str, &str) = ("ERROR.MISSING_TOKEN", "No token supplied."); + +pub const ERROR_EXPIRED_TOKEN: (&str, &str) = ("ERROR.EXPIRED_TOKEN", "The token you have supplied is expired."); \ No newline at end of file diff --git a/src/routes/main_router.rs b/src/routes/main_router.rs index 702224f..6a983db 100644 --- a/src/routes/main_router.rs +++ b/src/routes/main_router.rs @@ -41,6 +41,7 @@ pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedSta .service(user_routes::create_user) .service(user_routes::authenticate_user_with_password) .service(user_routes::refresh_auth_token) + .service(user_routes::authenticate_user_with_auth_token) //.service(user_routes::get_user_from_db) }) .bind((host_addr, host_port))? diff --git a/src/routes/user_routes.rs b/src/routes/user_routes.rs index ed5c098..632538b 100644 --- a/src/routes/user_routes.rs +++ b/src/routes/user_routes.rs @@ -2,9 +2,10 @@ use core::panic; use std::{sync::Mutex}; use actix_web::{web::{self, Data}, HttpResponse, post, patch, HttpRequest}; +use chrono::{Utc}; use sqlx::MySqlConnection; -use crate::{r#do::user::User, dao::{user_dao::{insert_user, find_user_by_email}, token_dao::{insert_token, self, update_token_with_id}}, dto::{user_dtos::{UserForCreationDto, UserForLoginDto}, message_resources_dtos::MessageResourceDto}, validation::user_validator, util::hasher::{self, generate_multiple_random_token_with_rng}, r#do::token::Token, resources::error_messages::{ERROR_USER_ALREADY_EXISTS, ERROR_USER_DOES_NOT_EXIST, ERROR_PASSWORD_INCORRECT, ERROR_INVALID_TOKEN, ERROR_MISSING_TOKEN, ERROR_INCORRECT_TOKEN}}; +use crate::{r#do::user::User, dao::{user_dao::{insert_user, find_user_by_email}, token_dao::{insert_token, self, update_token_with_id}}, dto::{user_dtos::{UserForCreationDto, UserForLoginDto}, message_resources_dtos::MessageResourceDto}, validation::user_validator, util::hasher::{self, generate_multiple_random_token_with_rng}, r#do::token::Token, resources::error_messages::{ERROR_USER_ALREADY_EXISTS, ERROR_USER_DOES_NOT_EXIST, ERROR_PASSWORD_INCORRECT, ERROR_INVALID_TOKEN, ERROR_MISSING_TOKEN, ERROR_INCORRECT_TOKEN, ERROR_EXPIRED_TOKEN}, r#do::token::AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS, r#do::token::REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS}; /*#[get("/u&ser/{id}")] pub async fn get_user_from_db(id: Path, db_conn: Data>) -> HttpResponse { @@ -119,9 +120,8 @@ pub async fn authenticate_user_with_password(incoming_user: web::Json, db_conn: Data>) -> HttpResponse{ +#[post("/user/auth/token/{user_id}")] +pub async fn authenticate_user_with_auth_token(request: HttpRequest, user_id: web::Path, db_conn: Data>) -> HttpResponse{ let mut message_resources: Vec = Vec::new(); let headers = request.headers(); let auth_token = match headers.get("auth-token") { @@ -145,7 +145,16 @@ pub async fn _authenticate_user_with_auth_token(request: HttpRequest, user_id: w match token_dao::get_tokens_with_user_id(&mut db_conn.lock().unwrap(), &user_id).await { Ok(tokens) => { for token in tokens{ - if token.auth_token == auth_token{ return HttpResponse::Ok().finish(); } + let now = Utc::now().naive_utc(); + match token.auth_token == auth_token{ + true if token.last_updated.unwrap().signed_duration_since(now).num_days() < + AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS.into() => { return HttpResponse::Ok().finish(); }, + true => { + message_resources.push(MessageResourceDto::new_from_error_message(ERROR_EXPIRED_TOKEN)); + return HttpResponse::Unauthorized().json(web::Json(message_resources)); + }, + false => {} + } }; message_resources.push(MessageResourceDto::new_from_error_message(ERROR_INCORRECT_TOKEN)); return HttpResponse::Unauthorized().json(web::Json(message_resources)); @@ -185,8 +194,15 @@ pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path, d Ok(tokens) => { let mut matched_token: Option = None; for token in tokens{ - if token.refresh_token == refresh_token{ - matched_token = Some(token); + let now = Utc::now().naive_utc(); + match token.refresh_token == refresh_token{ + true if token.last_updated.unwrap().signed_duration_since(now).num_days() < + REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS.into() => { matched_token = Some(token) }, + true => { + message_resources.push(MessageResourceDto::new_from_error_message(ERROR_EXPIRED_TOKEN)); + return HttpResponse::Unauthorized().json(web::Json(message_resources)); + }, + false => {} } }; match matched_token { @@ -213,4 +229,6 @@ pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path, d println!("{}", err); return HttpResponse::InternalServerError().json(web::Json(message_resources)); }}; -} \ No newline at end of file +} + +