Added refresh token endpoint

This commit is contained in:
franklinblanco 2022-07-07 01:14:01 -04:00
parent 2112836fa6
commit 19fdedc49e
5 changed files with 70 additions and 4 deletions

View File

@ -0,0 +1,3 @@
UPDATE token
SET last_updated = NOW(), auth_token = ?, refresh_token = ?
WHERE id = ?

View File

@ -8,3 +8,6 @@ pub async fn insert_token(conn: &mut MySqlConnection, token: &Token) -> Result<M
pub async fn get_token_with_user_id(conn: &mut MySqlConnection, user_id: &i32) -> Result<Token, sqlx::Error> { pub async fn get_token_with_user_id(conn: &mut MySqlConnection, user_id: &i32) -> Result<Token, sqlx::Error> {
sqlx::query_file_as!(Token, "sql/schema/token/find_with_user_id.sql", user_id).fetch_one(conn).await sqlx::query_file_as!(Token, "sql/schema/token/find_with_user_id.sql", user_id).fetch_one(conn).await
} }
pub async fn update_token_with_id(conn: &mut MySqlConnection, token: &Token ) -> Result<MySqlQueryResult, sqlx::Error> {
sqlx::query_file_as!(Token, "sql/schema/token/update.sql", token.auth_token, token.refresh_token, token.id).execute(conn).await
}

View File

@ -11,4 +11,10 @@ pub const ERROR_USER_ALREADY_EXISTS: (&str, &str) = ("ERROR.USER_ALREADY_EXISTS"
pub const ERROR_USER_DOES_NOT_EXIST: (&str, &str) = ("ERROR.USER_DOES_NOT_EXIST", "User with this email does not exist."); pub const ERROR_USER_DOES_NOT_EXIST: (&str, &str) = ("ERROR.USER_DOES_NOT_EXIST", "User with this email does not exist.");
pub const ERROR_PASSWORD_INCORRECT: (&str, &str) = ("ERROR.PASSWORD_INCORRECT", "THe password you have entered is incorrect."); pub const ERROR_PASSWORD_INCORRECT: (&str, &str) = ("ERROR.PASSWORD_INCORRECT", "The password you have entered is incorrect.");
pub const ERROR_INVALID_TOKEN: (&str, &str) = ("ERROR.INVALID_TOKEN", "The token you have supplied is not formattable.");
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.");

View File

@ -40,6 +40,7 @@ pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedSta
.app_data(env_vars_state.clone()) .app_data(env_vars_state.clone())
.service(user_routes::create_user) .service(user_routes::create_user)
.service(user_routes::authenticate_user_with_password) .service(user_routes::authenticate_user_with_password)
.service(user_routes::refresh_auth_token)
//.service(user_routes::get_user_from_db) //.service(user_routes::get_user_from_db)
}) })
.bind((host_addr, host_port))? .bind((host_addr, host_port))?

View File

@ -1,10 +1,10 @@
use core::panic; use core::panic;
use std::sync::Mutex; use std::{sync::Mutex};
use actix_web::{web::{self, Data}, HttpResponse, post}; use actix_web::{web::{self, Data}, HttpResponse, post, patch, HttpRequest};
use sqlx::MySqlConnection; use sqlx::MySqlConnection;
use crate::{r#do::user::User, dao::{user_dao::{insert_user, find_user_by_email}, token_dao::insert_token}, 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}}; 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}};
/*#[get("/u&ser/{id}")] /*#[get("/u&ser/{id}")]
pub async fn get_user_from_db(id: Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse { pub async fn get_user_from_db(id: Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse {
@ -118,3 +118,56 @@ pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLog
HttpResponse::Ok().json(token_to_insert) HttpResponse::Ok().json(token_to_insert)
} }
pub async fn _authenticate_user_with_auth_token(){}
//TODO: Change auth token in db when this is used.
#[patch("/user/refresh/{user_id}")]
pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse{
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
let headers = request.headers();
let refresh_token = match headers.get("refresh-token") {
Some(token) => {
match token.to_str(){
Ok(value) => {value},
Err(e) => {
println!("{}", e);
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_INVALID_TOKEN));
return HttpResponse::BadRequest().json(web::Json(message_resources));
}}},
None => {
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_MISSING_TOKEN));
return HttpResponse::BadRequest().json(web::Json(message_resources));
}};
let mut persisted_token =
match token_dao::get_token_with_user_id(&mut db_conn.lock().unwrap(), &user_id).await {
Ok(token) => {token},
Err(err) if matches!(err, sqlx::Error::RowNotFound) => {
println!("{}", err);
return HttpResponse::NotFound().json(web::Json(message_resources));
}
Err(err) => {
println!("{}", err);
return HttpResponse::InternalServerError().json(web::Json(message_resources));
}};
match persisted_token.refresh_token == refresh_token{
true => {
persisted_token.auth_token = generate_multiple_random_token_with_rng(1).await.expect("msg").get(0).expect("msg").to_string();
match update_token_with_id(&mut db_conn.lock().unwrap(), &persisted_token).await {
Ok(_rs) => {
return HttpResponse::Ok().json(web::Json(persisted_token));
},
Err(err) => {
println!("{}", err);
return HttpResponse::InternalServerError().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));
}};
}