Added user register

This commit is contained in:
2025-04-16 17:28:21 +02:00
parent c9dce27582
commit cef0b320d8
2 changed files with 45 additions and 4 deletions

View File

@@ -44,6 +44,7 @@ async fn main() -> std::io::Result<()> {
)
.service(login)
.service(logout)
.service(register)
.service(get_case)
.service(get_cases)
.service(get_item)

View File

@@ -28,20 +28,21 @@ use crate::AppState;
use actix_web::cookie::Cookie;
use actix_web::cookie::time::Duration;
use actix_web::web::{Data, Json};
use actix_web::{HttpRequest, HttpResponse, Responder, post};
use argon2::Argon2;
use argon2::password_hash::{PasswordHash, PasswordVerifier};
use actix_web::{App, HttpRequest, HttpResponse, Responder, post};
use argon2::{Argon2, PasswordHasher};
use argon2::password_hash::{PasswordHash, PasswordVerifier, SaltString};
use argon2::password_hash::rand_core::OsRng;
use jsonwebtoken::{Algorithm, EncodingKey, Header, encode, get_current_timestamp};
use rand::Rng;
use rand::distr::Alphanumeric;
use serde::{Deserialize, Deserializer};
use serde_json::{json, to_string};
use sqlx::sqlite::SqliteQueryResult;
use sqlx::{Pool, Sqlite, query, query_as};
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::fs::File;
use std::io::Read;
use sqlx::sqlite::SqliteQueryResult;
#[derive(Debug)]
struct Password {
@@ -94,6 +95,23 @@ impl User {
}
}
}
async fn create(database: &Pool<Sqlite>, hash: PasswordHash<'_>, username: &Username, email: &String) -> Result<User, sqlx::Error> {
let mut uuid = uuid::Uuid::new_v4().to_string();
while let Ok(Some(_)) = query!("SELECT id FROM users WHERE 'uuid' = ?1", uuid).fetch_optional(database).await {
uuid = uuid::Uuid::new_v4().to_string();
}
let hash_string = hash.to_string();
query_as!(User,
"INSERT INTO users ('uuid', 'username', 'email', 'hash') VALUES (?1, ?2, ?3, ?4) RETURNING *",
uuid,
username.value,
email,
hash_string
)
.fetch_one(database)
.await
}
}
struct PasswordError;
@@ -245,6 +263,28 @@ async fn logout(
}
}
#[derive(Deserialize, Debug)]
struct RegisterInfo {
username: Username,
password: Password,
email: String,
}
#[post("/register")]
async fn register(
app_state: Data<AppState>,
register_info: Json<RegisterInfo>,
) -> Result<impl Responder, Box<dyn Error>> {
if let Ok(Some(_)) = User::fetch_optional(&app_state.database, None, None, Some(&register_info.username)).await {
return Ok(HttpResponse::InternalServerError().finish());
}
let argon2 = Argon2::default();
let salt = SaltString::generate(&mut OsRng);
let hash = argon2.hash_password(register_info.password.value.as_bytes(), &salt)?;
User::create(&app_state.database, hash, &register_info.username, &register_info.email).await?;
Ok(HttpResponse::Ok().finish())
}
fn validate_authentication(user: &User, password: &Password) -> Result<bool, Box<dyn Error>> {
let argon2 = Argon2::default();
let hash = PasswordHash::new(&user.hash)?;