switched from using Mutexes with MySqlConnection to Arcs with MySqlPools
This commit is contained in:
parent
04d60bd3ef
commit
e8c169f325
3
sql/schema/user/find_with_id.sql
Normal file
3
sql/schema/user/find_with_id.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SELECT *
|
||||||
|
FROM user
|
||||||
|
WHERE user.id = ?
|
@ -1,8 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use sqlx::{MySqlConnection, Connection};
|
use sqlx::{MySqlPool};
|
||||||
|
|
||||||
pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Result<MySqlConnection, sqlx::Error>{
|
pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Result<MySqlPool, sqlx::Error>{
|
||||||
let db_user = match env_vars.get("DB_USER") {
|
let db_user = match env_vars.get("DB_USER") {
|
||||||
Some(str) => str,
|
Some(str) => str,
|
||||||
None => panic!("DB_USER env var not found")
|
None => panic!("DB_USER env var not found")
|
||||||
@ -20,9 +20,9 @@ pub async fn start_database_connection(env_vars: &HashMap<String, String>) -> Re
|
|||||||
None => panic!("DB_DATABASE_NAME env var not found")
|
None => panic!("DB_DATABASE_NAME env var not found")
|
||||||
};
|
};
|
||||||
let formatted_db_url = &format!("mysql://{db_user}:{db_pass}@{db_host}/{db_database_name}");
|
let formatted_db_url = &format!("mysql://{db_user}:{db_pass}@{db_host}/{db_database_name}");
|
||||||
sqlx::MySqlConnection::connect(&formatted_db_url).await
|
sqlx::MySqlPool::connect(&formatted_db_url).await
|
||||||
}
|
}
|
||||||
pub async fn run_all_migrations(conn: &mut MySqlConnection){
|
pub async fn run_all_migrations(conn: &MySqlPool){
|
||||||
match sqlx::migrate!("./migrations").run(conn).await {
|
match sqlx::migrate!("./migrations").run(conn).await {
|
||||||
Ok(()) => {println!("{}", "Successfully ran migrations.")},
|
Ok(()) => {println!("{}", "Successfully ran migrations.")},
|
||||||
Err(error) => {panic!("{error}")}
|
Err(error) => {panic!("{error}")}
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use sqlx::{MySqlConnection, mysql::MySqlQueryResult};
|
use sqlx::MySqlPool;
|
||||||
|
use sqlx::{mysql::MySqlQueryResult};
|
||||||
|
|
||||||
use crate::r#do::token::Token;
|
use crate::r#do::token::Token;
|
||||||
use crate::r#do::token::{AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS, REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS};
|
use crate::r#do::token::{AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS, REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS};
|
||||||
|
|
||||||
pub async fn insert_token(conn: &mut MySqlConnection, token: &Token) -> Result<MySqlQueryResult, sqlx::Error> {
|
pub async fn insert_token(conn: &MySqlPool, token: &Token) -> Result<MySqlQueryResult, sqlx::Error> {
|
||||||
sqlx::query_file!("sql/schema/token/insert.sql", token.user_id, token.auth_token, token.refresh_token).execute(conn).await
|
sqlx::query_file!("sql/schema/token/insert.sql", token.user_id, token.auth_token, token.refresh_token).execute(conn).await
|
||||||
}
|
}
|
||||||
pub async fn get_tokens_with_user_id(conn: &mut MySqlConnection, user_id: &i32) -> Result<Vec<Token>, sqlx::Error> {
|
pub async fn get_tokens_with_user_id(conn: &MySqlPool, user_id: &i32) -> Result<Vec<Token>, sqlx::Error> {
|
||||||
sqlx::query_file_as!(Token, "sql/schema/token/find_with_user_id.sql", user_id).fetch_all(conn).await
|
sqlx::query_file_as!(Token, "sql/schema/token/find_with_user_id.sql", user_id).fetch_all(conn).await
|
||||||
}
|
}
|
||||||
pub async fn update_token_with_id(conn: &mut MySqlConnection, token: &Token ) -> Result<MySqlQueryResult, sqlx::Error> {
|
pub async fn update_token_with_id(conn: &MySqlPool, token: &Token ) -> Result<MySqlQueryResult, sqlx::Error> {
|
||||||
sqlx::query_file!("sql/schema/token/update.sql", token.auth_token, token.refresh_token, token.id).execute(conn).await
|
sqlx::query_file!("sql/schema/token/update.sql", token.auth_token, token.refresh_token, token.id).execute(conn).await
|
||||||
}
|
}
|
||||||
pub async fn delete_expired_tokens(conn: &mut MySqlConnection) -> Result<MySqlQueryResult, sqlx::Error>{
|
pub async fn delete_expired_tokens(conn: &MySqlPool) -> Result<MySqlQueryResult, sqlx::Error>{
|
||||||
sqlx::query_file!("sql/schema/token/delete_expired_tokens.sql",
|
sqlx::query_file!("sql/schema/token/delete_expired_tokens.sql",
|
||||||
AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS, REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS)
|
AUTH_TOKEN_EXPIRATION_TIME_IN_DAYS, REFRESH_TOKEN_EXPIRATION_TIME_IN_DAYS)
|
||||||
.execute(conn).await
|
.execute(conn).await
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
use sqlx::{MySqlConnection, mysql::MySqlQueryResult};
|
use sqlx::{mysql::MySqlQueryResult, MySqlPool};
|
||||||
|
|
||||||
use crate::r#do::user::User;
|
use crate::r#do::user::User;
|
||||||
|
|
||||||
pub async fn insert_user(conn: &mut MySqlConnection, user_to_insert: &User) -> Result<MySqlQueryResult, sqlx::Error>{
|
pub async fn insert_user(conn: &MySqlPool, user_to_insert: &User) -> Result<MySqlQueryResult, sqlx::Error>{
|
||||||
sqlx::query_file!("sql/schema/user/insert.sql",
|
sqlx::query_file!("sql/schema/user/insert.sql",
|
||||||
user_to_insert.app, user_to_insert.email, user_to_insert.name, user_to_insert.password, user_to_insert.salt)
|
user_to_insert.app, user_to_insert.email, user_to_insert.name, user_to_insert.password, user_to_insert.salt)
|
||||||
.execute(conn).await
|
.execute(conn).await
|
||||||
}
|
}
|
||||||
pub async fn find_user_by_email(conn: &mut MySqlConnection, email: &String, app: &String) -> Result<User, sqlx::Error>{
|
pub async fn find_user_by_email(conn: &MySqlPool, email: &String, app: &String) -> Result<User, sqlx::Error>{
|
||||||
sqlx::query_file_as!(User, "sql/schema/user/find_with_email.sql", email, app).fetch_one(conn).await
|
sqlx::query_file_as!(User, "sql/schema/user/find_with_email.sql", email, app).fetch_one(conn).await
|
||||||
}
|
}
|
||||||
|
pub async fn _find_user_by_id(conn: &MySqlPool, id: &i32) -> Result<User, sqlx::Error> {
|
||||||
|
sqlx::query_file_as!(User, "sql/schema/user/find_with_id.sql", id).fetch_one(conn).await
|
||||||
|
}
|
||||||
//pub async fn _update_user(conn: &mut MySqlConnection, user_to_modify: &User) -> Result<(), sqlx::Error>{
|
//pub async fn _update_user(conn: &mut MySqlConnection, user_to_modify: &User) -> Result<(), sqlx::Error>{
|
||||||
// Ok(())
|
// Ok(())
|
||||||
//}
|
//}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use sqlx::MySqlConnection;
|
use sqlx::{MySqlPool};
|
||||||
|
|
||||||
pub struct SharedStateObj{
|
pub struct SharedStateObj{
|
||||||
pub db_conn: MySqlConnection,
|
pub db_conn: MySqlPool,
|
||||||
pub env_vars: HashMap<String, String>,
|
pub env_vars: HashMap<String, String>,
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::Mutex;
|
use std::sync::{Mutex, Arc};
|
||||||
use actix_web::{HttpServer, App, web};
|
use actix_web::{HttpServer, App, web};
|
||||||
use crate::r#do::shared_state::SharedStateObj;
|
use crate::r#do::shared_state::SharedStateObj;
|
||||||
use super::user_routes;
|
use super::user_routes;
|
||||||
@ -29,9 +29,8 @@ pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedSta
|
|||||||
|
|
||||||
|
|
||||||
// Extract variables to be put into shared app state & clone them
|
// Extract variables to be put into shared app state & clone them
|
||||||
let db_conn_state = web::Data::new(Mutex::new(state.db_conn));
|
let db_conn_state = web::Data::new(Arc::new(state.db_conn));
|
||||||
let env_vars_state = web::Data::new(Mutex::new(state.env_vars.clone()));
|
let env_vars_state = web::Data::new(Mutex::new(state.env_vars.clone()));
|
||||||
|
|
||||||
// Start server code that turns into a future to be executed below
|
// Start server code that turns into a future to be executed below
|
||||||
let server_future = HttpServer::new( move || {
|
let server_future = HttpServer::new( move || {
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use core::panic;
|
use core::panic;
|
||||||
use std::{sync::Mutex};
|
use std::{sync::{Arc}};
|
||||||
|
|
||||||
use actix_web::{web::{self, Data}, HttpResponse, post, patch, HttpRequest};
|
use actix_web::{web::{self, Data}, HttpResponse, post, patch, HttpRequest};
|
||||||
use chrono::{Utc};
|
use chrono::{Utc};
|
||||||
use sqlx::MySqlConnection;
|
use sqlx::{MySqlPool};
|
||||||
|
|
||||||
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};
|
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};
|
||||||
|
|
||||||
#[post("/user")]
|
#[post("/user")]
|
||||||
pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse {
|
pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn: Data<Arc<MySqlPool>>) -> HttpResponse {
|
||||||
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
||||||
|
|
||||||
// Get user object from json
|
// Get user object from json
|
||||||
@ -23,7 +23,7 @@ pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn:
|
|||||||
user_validator::validate_user_for_creation(incoming_user_obj, &mut message_resources);
|
user_validator::validate_user_for_creation(incoming_user_obj, &mut message_resources);
|
||||||
|
|
||||||
// Find if user exists
|
// Find if user exists
|
||||||
match find_user_by_email(&mut db_conn.lock().unwrap(), &user_to_insert.email, &user_to_insert.app).await{
|
match find_user_by_email(&db_conn, &user_to_insert.email, &user_to_insert.app).await{
|
||||||
Ok(_usr) => {
|
Ok(_usr) => {
|
||||||
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_USER_ALREADY_EXISTS));
|
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_USER_ALREADY_EXISTS));
|
||||||
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
||||||
@ -40,7 +40,7 @@ pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn:
|
|||||||
user_to_insert.salt = hash_result.salt;
|
user_to_insert.salt = hash_result.salt;
|
||||||
|
|
||||||
// Insert user in DB
|
// Insert user in DB
|
||||||
match insert_user(&mut db_conn.lock().unwrap(), &user_to_insert).await{
|
match insert_user(&db_conn, &user_to_insert).await{
|
||||||
Ok(resultrs) => {
|
Ok(resultrs) => {
|
||||||
user_to_insert.id = resultrs.last_insert_id() as i32;
|
user_to_insert.id = resultrs.last_insert_id() as i32;
|
||||||
},
|
},
|
||||||
@ -58,7 +58,7 @@ pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn:
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Insert token in DB
|
// Insert token in DB
|
||||||
match insert_token(&mut db_conn.lock().unwrap(), &token_to_insert).await{
|
match insert_token(&db_conn, &token_to_insert).await{
|
||||||
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as i32},
|
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as i32},
|
||||||
Err(e) => {panic!("{e}")}
|
Err(e) => {panic!("{e}")}
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[post("/user/auth/password")]
|
#[post("/user/auth/password")]
|
||||||
pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLoginDto>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse {
|
pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLoginDto>, db_conn: Data<Arc<MySqlPool>>) -> HttpResponse {
|
||||||
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
||||||
let incoming_user_obj = incoming_user.0;
|
let incoming_user_obj = incoming_user.0;
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLog
|
|||||||
if message_resources.len() > 0 { return HttpResponse::BadRequest().json(web::Json(message_resources)); }
|
if message_resources.len() > 0 { return HttpResponse::BadRequest().json(web::Json(message_resources)); }
|
||||||
|
|
||||||
// If user exists get it, if it doesn't blow up to the client
|
// If user exists get it, if it doesn't blow up to the client
|
||||||
let persisted_user = match find_user_by_email(&mut db_conn.lock().unwrap(), &incoming_user_obj.email, &incoming_user_obj.app).await {
|
let persisted_user = match find_user_by_email(&db_conn, &incoming_user_obj.email, &incoming_user_obj.app).await {
|
||||||
Ok(rs) => {rs},
|
Ok(rs) => {rs},
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_USER_DOES_NOT_EXIST));
|
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_USER_DOES_NOT_EXIST));
|
||||||
@ -104,7 +104,7 @@ pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLog
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Insert token in DB
|
// Insert token in DB
|
||||||
match insert_token(&mut db_conn.lock().unwrap(), &token_to_insert).await{
|
match insert_token(&db_conn, &token_to_insert).await{
|
||||||
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as i32},
|
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as i32},
|
||||||
Err(e) => {panic!("{e}")}
|
Err(e) => {panic!("{e}")}
|
||||||
};
|
};
|
||||||
@ -113,7 +113,7 @@ pub async fn authenticate_user_with_password(incoming_user: web::Json<UserForLog
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[post("/user/auth/token/{user_id}")]
|
#[post("/user/auth/token/{user_id}")]
|
||||||
pub async fn authenticate_user_with_auth_token(request: HttpRequest, user_id: web::Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse{
|
pub async fn authenticate_user_with_auth_token(request: HttpRequest, user_id: web::Path<i32>, db_conn: Data<Arc<MySqlPool>>) -> HttpResponse{
|
||||||
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
||||||
let headers = request.headers();
|
let headers = request.headers();
|
||||||
let auth_token = match headers.get("auth-token") {
|
let auth_token = match headers.get("auth-token") {
|
||||||
@ -130,11 +130,11 @@ pub async fn authenticate_user_with_auth_token(request: HttpRequest, user_id: we
|
|||||||
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
match token_dao::delete_expired_tokens(&mut db_conn.lock().unwrap()).await
|
match token_dao::delete_expired_tokens(&db_conn).await
|
||||||
{ Ok(_res) => {}, Err(_err) => {} };
|
{ Ok(_res) => {}, Err(_err) => {} };
|
||||||
|
|
||||||
let mut _persisted_token =
|
let mut _persisted_token =
|
||||||
match token_dao::get_tokens_with_user_id(&mut db_conn.lock().unwrap(), &user_id).await {
|
match token_dao::get_tokens_with_user_id(&db_conn, &user_id).await {
|
||||||
Ok(tokens) => {
|
Ok(tokens) => {
|
||||||
for token in tokens{
|
for token in tokens{
|
||||||
let now = Utc::now().naive_utc();
|
let now = Utc::now().naive_utc();
|
||||||
@ -161,7 +161,7 @@ pub async fn authenticate_user_with_auth_token(request: HttpRequest, user_id: we
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[patch("/user/refresh/{user_id}")]
|
#[patch("/user/refresh/{user_id}")]
|
||||||
pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse{
|
pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path<i32>, db_conn: Data<Arc<MySqlPool>>) -> HttpResponse{
|
||||||
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
let mut message_resources: Vec<MessageResourceDto> = Vec::new();
|
||||||
let headers = request.headers();
|
let headers = request.headers();
|
||||||
let refresh_token = match headers.get("refresh-token") {
|
let refresh_token = match headers.get("refresh-token") {
|
||||||
@ -178,11 +178,11 @@ pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path<i32>, d
|
|||||||
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
return HttpResponse::BadRequest().json(web::Json(message_resources));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
match token_dao::delete_expired_tokens(&mut db_conn.lock().unwrap()).await
|
match token_dao::delete_expired_tokens(&db_conn).await
|
||||||
{ Ok(_res) => {}, Err(_err) => {} };
|
{ Ok(_res) => {}, Err(_err) => {} };
|
||||||
|
|
||||||
let mut persisted_token =
|
let mut persisted_token =
|
||||||
match token_dao::get_tokens_with_user_id(&mut db_conn.lock().unwrap(), &user_id).await {
|
match token_dao::get_tokens_with_user_id(&db_conn, &user_id).await {
|
||||||
Ok(tokens) => {
|
Ok(tokens) => {
|
||||||
let mut matched_token: Option<Token> = None;
|
let mut matched_token: Option<Token> = None;
|
||||||
for token in tokens{
|
for token in tokens{
|
||||||
@ -209,7 +209,7 @@ pub async fn refresh_auth_token(request: HttpRequest, user_id: web::Path<i32>, d
|
|||||||
return HttpResponse::InternalServerError().json(web::Json(message_resources));
|
return HttpResponse::InternalServerError().json(web::Json(message_resources));
|
||||||
}};
|
}};
|
||||||
persisted_token.auth_token = generate_multiple_random_token_with_rng(1).await.expect("msg").get(0).expect("msg").to_string();
|
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 {
|
match update_token_with_id(&db_conn, &persisted_token).await {
|
||||||
Ok(_rs) => {
|
Ok(_rs) => {
|
||||||
return HttpResponse::Ok().json(web::Json(persisted_token));
|
return HttpResponse::Ok().json(web::Json(persisted_token));
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user