Create user endpoint perfected and finished
This commit is contained in:
parent
a71402aad0
commit
964e655e1c
@ -13,4 +13,5 @@ sqlx = { version = "0.5", features = [ "runtime-tokio-rustls", "mysql", "chrono"
|
||||
actix-web = "4"
|
||||
chrono = { version = "0.4", features = [ "serde" ] }
|
||||
ring = "0.16.20"
|
||||
data-encoding = "2.3.2"
|
||||
data-encoding = "2.3.2"
|
||||
futures-util = "0.3"
|
@ -4,6 +4,6 @@ CREATE TABLE IF NOT EXISTS user (
|
||||
last_updated TIMESTAMP NOT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
salt VARCHAR(255) NOT NULL
|
||||
password TEXT NOT NULL,
|
||||
salt TEXT NOT NULL
|
||||
)
|
@ -3,6 +3,6 @@ CREATE TABLE IF NOT EXISTS token (
|
||||
user_id INT NOT NULL,
|
||||
time_created TIMESTAMP NOT NULL,
|
||||
last_updated TIMESTAMP NOT NULL,
|
||||
auth_token VARCHAR(255) NOT NULL,
|
||||
refresh_token VARCHAR(255) NOT NULL
|
||||
auth_token TEXT NOT NULL,
|
||||
refresh_token TEXT NOT NULL
|
||||
)
|
@ -3,6 +3,6 @@ CREATE TABLE IF NOT EXISTS token (
|
||||
user_id INT NOT NULL,
|
||||
time_created TIMESTAMP NOT NULL,
|
||||
last_updated TIMESTAMP NOT NULL,
|
||||
auth_token VARCHAR(255) NOT NULL,
|
||||
refresh_token VARCHAR(255) NOT NULL
|
||||
auth_token TEXT NOT NULL,
|
||||
refresh_token TEXT NOT NULL
|
||||
)
|
@ -4,6 +4,6 @@ CREATE TABLE IF NOT EXISTS user (
|
||||
last_updated TIMESTAMP NOT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
salt VARCHAR(255) NOT NULL
|
||||
)
|
@ -1,2 +1,3 @@
|
||||
pub mod main_dao;
|
||||
pub mod user_dao;
|
||||
pub mod user_dao;
|
||||
pub mod token_dao;
|
7
src/dao/token_dao.rs
Normal file
7
src/dao/token_dao.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use sqlx::{MySqlConnection, mysql::MySqlQueryResult};
|
||||
|
||||
use crate::r#do::token::Token;
|
||||
|
||||
pub async fn insert_token(conn: &mut MySqlConnection, 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
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod shared_state;
|
||||
pub mod user;
|
||||
pub mod user;
|
||||
pub mod token;
|
24
src/do/token.rs
Normal file
24
src/do/token.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Serialize, Deserialize};
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Token {
|
||||
pub id: i32,
|
||||
pub user_id: i32,
|
||||
pub time_created: Option<NaiveDateTime>,
|
||||
pub last_updated: Option<NaiveDateTime>,
|
||||
pub auth_token: String,
|
||||
pub refresh_token: String
|
||||
}
|
||||
|
||||
impl Token{
|
||||
pub fn new(user_id: i32, auth_token: String, refresh_token: String) -> Token{
|
||||
Token {
|
||||
id: 0,
|
||||
user_id,
|
||||
time_created: None,
|
||||
last_updated: None,
|
||||
auth_token,
|
||||
refresh_token
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
use std::{sync::Mutex};
|
||||
use actix_web::{HttpServer, App, web};
|
||||
use crate::r#do::shared_state::SharedStateObj;
|
||||
|
||||
use crate::{r#do::shared_state::SharedStateObj};
|
||||
use super::user_routes;
|
||||
|
||||
// This function is to be used in case code is meant to be run after server startup
|
||||
pub fn after_startup_fn(){
|
||||
pub fn after_startup_fn() {
|
||||
println!("{}", "Started server.");
|
||||
}
|
||||
|
||||
@ -47,6 +46,6 @@ pub async fn start_all_routes(after_startup_fn_call: &dyn Fn(), state: SharedSta
|
||||
|
||||
// Actual server start and after startup call
|
||||
let (server_start_result, _after_startup_value) =
|
||||
tokio::join!(server_future, async {after_startup_fn_call();});
|
||||
tokio::join!(server_future, async {after_startup_fn_call});
|
||||
return server_start_result; // Return server
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use actix_web::{web::{self, Data}, HttpResponse, post};
|
||||
use sqlx::{MySqlConnection};
|
||||
use sqlx::MySqlConnection;
|
||||
|
||||
use crate::{r#do::user::User, dao::user_dao::{insert_user}, dto::{user_dtos::UserForCreationDto, message_resources_dtos::MessageResourceDto}, validation::user_validator, util::hasher};
|
||||
use crate::{r#do::user::User, dao::{user_dao::{insert_user}, token_dao::insert_token}, dto::{user_dtos::UserForCreationDto, message_resources_dtos::MessageResourceDto}, validation::user_validator, util::hasher, r#do::token::Token};
|
||||
|
||||
/*#[get("/user/{id}")]
|
||||
pub async fn get_user_from_db(id: Path<i32>, db_conn: Data<Mutex<MySqlConnection>>) -> HttpResponse {
|
||||
@ -38,13 +38,27 @@ pub async fn create_user(incoming_user: web::Json<UserForCreationDto>, db_conn:
|
||||
|
||||
// Try to insert user in DB
|
||||
match insert_user(&mut db_conn.lock().unwrap(), &user_to_insert).await{
|
||||
Ok(_resultrs) => {},
|
||||
Ok(resultrs) => {
|
||||
user_to_insert.id = resultrs.last_insert_id() as i32;
|
||||
},
|
||||
Err(error) => {
|
||||
println!("Error while inserting user in database from create_user method. Log: {}", error);
|
||||
return HttpResponse::InternalServerError().json(web::Json(()))
|
||||
}};
|
||||
// TODO: Create token and send it back.
|
||||
|
||||
// Create token and send it back.
|
||||
let tokens: Vec<String> = hasher::generate_multiple_random_token_with_rng(2).await.expect("msg");
|
||||
let mut token_to_insert =
|
||||
Token::new(user_to_insert.id,
|
||||
tokens.get(0).expect("msg").to_string(),
|
||||
tokens.get(1).expect("msg").to_string()
|
||||
);
|
||||
|
||||
match insert_token(&mut db_conn.lock().unwrap(), &token_to_insert).await{
|
||||
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as i32},
|
||||
Err(e) => {panic!("{e}")}
|
||||
}
|
||||
|
||||
// All good? Send an OK!
|
||||
HttpResponse::Ok().body(())
|
||||
HttpResponse::Ok().json(web::Json(token_to_insert))
|
||||
}
|
@ -1,9 +1,35 @@
|
||||
use std::{num::NonZeroU32};
|
||||
use std::num::NonZeroU32;
|
||||
use data_encoding::HEXUPPER;
|
||||
use ring::{digest, rand::{SecureRandom, SystemRandom}, pbkdf2, error::Unspecified};
|
||||
use tokio::task::JoinError;
|
||||
|
||||
use crate::dto::hash_dtos::HashResult;
|
||||
|
||||
pub async fn generate_multiple_random_token_with_rng(amount: u8) -> Result<Vec<String>, JoinError> {
|
||||
// Get a new instance of a Random Number Generator
|
||||
let rng = SystemRandom::new();
|
||||
|
||||
let mut tokens = Vec::with_capacity(amount.into());
|
||||
|
||||
for _i in 0 .. amount {
|
||||
let cloned_rng = rng.clone();
|
||||
let future_token = async move {
|
||||
let mut token_arr = [0u8; digest::SHA512_OUTPUT_LEN];
|
||||
match cloned_rng.fill(&mut token_arr){
|
||||
Ok(()) => {HEXUPPER.encode(&token_arr)},
|
||||
Err(_e) => { panic!("Failed to generate random token for some reason.") }
|
||||
}};
|
||||
tokens.push(tokio::spawn(future_token));
|
||||
}
|
||||
|
||||
let all_tokens = futures_util::future::join_all(tokens).await;
|
||||
let all_tokens_solved: Vec<String> = all_tokens.into_iter().map(|result| match result {
|
||||
Ok(string) => {string},
|
||||
Err(_e) => {"".to_string()}
|
||||
}).rev().collect();
|
||||
|
||||
Ok(all_tokens_solved)
|
||||
}
|
||||
|
||||
pub fn hash_password(password: &String) -> HashResult{
|
||||
// Get output length from a sha512 hash
|
||||
|
@ -19,13 +19,13 @@ fn validate_user_password(password: &String) -> bool {
|
||||
}
|
||||
// User dto SHOULD die here.
|
||||
pub fn validate_user_for_creation(user: UserForCreationDto, message_resources: &mut Vec<MessageResourceDto>){
|
||||
if validate_user_email(&user.email) {
|
||||
if !validate_user_email(&user.email) {
|
||||
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_INVALID_EMAIL));
|
||||
}
|
||||
if validate_user_name(&user.name) {
|
||||
if !validate_user_name(&user.name) {
|
||||
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_INVALID_NAME));
|
||||
}
|
||||
if validate_user_password(&user.password) {
|
||||
if !validate_user_password(&user.password) {
|
||||
message_resources.push(MessageResourceDto::new_from_error_message(ERROR_INVALID_PASSWORD));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user