Starting to see services being made
This commit is contained in:
parent
67a990de1f
commit
c31586573b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1609,6 +1609,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"data-encoding",
|
||||
"futures-util",
|
||||
"log",
|
||||
"ring",
|
||||
"serde",
|
||||
"sqlx",
|
||||
|
@ -16,4 +16,5 @@ sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "postgres"
|
||||
chrono = { version = "0.4", features = [ "serde" ] }
|
||||
ring = "0.16.20"
|
||||
data-encoding = "2.3.2"
|
||||
futures-util = "0.3"
|
||||
futures-util = "0.3"
|
||||
log = "0.4.19"
|
@ -32,3 +32,10 @@ pub async fn fetch_user_credentials(
|
||||
) -> Result<Vec<Credential>, Error> {
|
||||
sqlx::query_as(r#"SELECT user_id, credential_type as "credential_type: _", credential, validated, time_created, last_updated FROM credential WHERE user_id = $1 "#).bind(user_id).fetch_all(conn).await
|
||||
}
|
||||
|
||||
pub async fn get_credential(
|
||||
conn: &PgPool,
|
||||
credential: String,
|
||||
) -> Result<Option<Credential>, Error> {
|
||||
sqlx::query_as(r#"SELECT user_id, credential_type as "credential_type: _", credential, validated, time_created, last_updated FROM credential WHERE credential = $1"#).bind(credential).fetch_optional(conn).await
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub const ERROR_INVALID_PASSWORD: (&str, &str) = (
|
||||
|
||||
pub const ERROR_USER_ALREADY_EXISTS: (&str, &str) = (
|
||||
"ERROR.USER_ALREADY_EXISTS",
|
||||
"A user with that email already exists.",
|
||||
"A user with that credential already exists.",
|
||||
);
|
||||
|
||||
pub const ERROR_USER_DOES_NOT_EXIST: (&str, &str) = (
|
||||
@ -60,3 +60,8 @@ pub const ERROR_CREATING_TOKEN: (&str, &str) = (
|
||||
"ERROR.CREATING_TOKEN",
|
||||
"The server had an error creating the auth tokens.",
|
||||
);
|
||||
|
||||
pub const ERROR_TOO_MANY_CREDENTIALS: (&str, &str) = (
|
||||
"ERROR.TOO_MANY_CREDENTIALS",
|
||||
"Only up to 3 credentials are allowed. One of each type.",
|
||||
);
|
||||
|
@ -1,5 +1,76 @@
|
||||
use std::error::Error;
|
||||
use log::{error, log};
|
||||
use crate::dao::credential::get_credential;
|
||||
use crate::domain::credential::Credential;
|
||||
use crate::dto::users::UserRegisterPayload;
|
||||
use crate::resources::error_messages::{ERROR_TOO_MANY_CREDENTIALS, ERROR_USER_ALREADY_EXISTS, ErrorResource};
|
||||
use crate::validation::user_validator::validate_user_for_creation;
|
||||
|
||||
pub async fn register_user(db_conn: &sqlx::PgPool, user: UserRegisterPayload) -> Result<(), ()> {
|
||||
pub async fn register_user(db_conn: &sqlx::PgPool, user: UserRegisterPayload) -> Result<(), Vec<ErrorResource>> {
|
||||
let mut error_resources: Vec<ErrorResource> = Vec::new();
|
||||
// Validate user
|
||||
validate_user_for_creation(&user, &mut error_resources);
|
||||
// Find if user exists
|
||||
if user.credentials.len() > 3 {
|
||||
error_resources.push(ERROR_TOO_MANY_CREDENTIALS);
|
||||
|
||||
}
|
||||
for credential_dto in user.credentials.iter() {
|
||||
match get_credential(
|
||||
&db_conn,
|
||||
credential_dto.credential.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(credential_opt) => {
|
||||
match credential_opt {
|
||||
None => {}
|
||||
Some(_) => {
|
||||
error_resources.push(
|
||||
ERROR_USER_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
error_resources.push(("ERROR.DATABASE_ERROR", ""));
|
||||
}
|
||||
};
|
||||
}
|
||||
// If validation gave any errors blow up and send them back to the client
|
||||
if error_resources.len() > 0 {
|
||||
return Err(error_resources);
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
// Get salt and hashed password from hashing function then give the results to the user
|
||||
let hash_result = hasher::hash_password(&user_to_insert.password);
|
||||
user_to_insert.password = hash_result.hash;
|
||||
user_to_insert.salt = hash_result.salt;
|
||||
|
||||
// Insert user in DB
|
||||
match insert_user(&db_conn, &user_to_insert).await{
|
||||
Ok(resultrs) => {
|
||||
user_to_insert.id = resultrs.last_insert_id() as u32;
|
||||
},
|
||||
Err(error) => {
|
||||
println!("Error while inserting user in database from create_user method. Log: {}", error);
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}};
|
||||
|
||||
// Create token and send it back.
|
||||
let tokens: Vec<String> = hasher::generate_multiple_random_token_with_rng(2).await.expect("Error creating multiple random tokens.");
|
||||
let mut token_to_insert =
|
||||
Token::new(user_to_insert.id,
|
||||
tokens.get(0).expect("Error. Token doesn't exist in list.").to_string(),
|
||||
tokens.get(1).expect("Error. Token doesn't exist in list.").to_string()
|
||||
);
|
||||
|
||||
// Insert token in DB
|
||||
match insert_token(&db_conn, &token_to_insert).await{
|
||||
Ok(resultrs) => {token_to_insert.id = resultrs.last_insert_id() as u32},
|
||||
Err(_e) => {return HttpResponse::InternalServerError().finish()}
|
||||
}
|
||||
*/
|
||||
Ok(())
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ use tokio::task::JoinError;
|
||||
|
||||
const SALT_ROUNDS: u32 = 1000;
|
||||
|
||||
pub async fn generate_multiple_random_token_with_rng(amount: u8) -> Result<Vec<String>, JoinError> {
|
||||
pub(crate) 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();
|
||||
|
||||
@ -20,7 +22,7 @@ pub async fn generate_multiple_random_token_with_rng(amount: u8) -> Result<Vec<S
|
||||
let future_token = async move {
|
||||
let mut token_arr = [0u8; digest::SHA512_OUTPUT_LEN];
|
||||
match cloned_rng.fill(&mut token_arr) {
|
||||
Ok(()) => BASE64.encode(&token_arr), //TODO: Remove this panic, make your own error and fix this
|
||||
Ok(()) => BASE64.encode(&token_arr),
|
||||
Err(_e) => {
|
||||
panic!("Failed to generate random token for some reason.")
|
||||
}
|
||||
@ -42,7 +44,10 @@ pub async fn generate_multiple_random_token_with_rng(amount: u8) -> Result<Vec<S
|
||||
Ok(all_tokens_solved)
|
||||
}
|
||||
|
||||
pub fn hash_password_with_existing_salt(password: &String, input_salt: &String) -> HashResult {
|
||||
pub(crate) fn hash_password_with_existing_salt(
|
||||
password: &String,
|
||||
input_salt: &String,
|
||||
) -> HashResult {
|
||||
// Get output length from a sha512 hash
|
||||
const CREDENTIAL_LEN: usize = digest::SHA512_OUTPUT_LEN;
|
||||
let n_iter = NonZeroU32::new(SALT_ROUNDS).unwrap();
|
||||
@ -65,7 +70,7 @@ pub fn hash_password_with_existing_salt(password: &String, input_salt: &String)
|
||||
HashResult::new(BASE64.encode(&salt), BASE64.encode(&pbkdf2_hash))
|
||||
}
|
||||
|
||||
pub fn hash_password(password: &String) -> HashResult {
|
||||
pub(crate) fn hash_password(password: &String) -> HashResult {
|
||||
// Get output length from a sha512 hash
|
||||
const CREDENTIAL_LEN: usize = digest::SHA512_OUTPUT_LEN;
|
||||
let n_iter = NonZeroU32::new(SALT_ROUNDS).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user