Added user register
This commit is contained in:
@@ -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)
|
||||
|
||||
48
src/users.rs
48
src/users.rs
@@ -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(®ister_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, ®ister_info.username, ®ister_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)?;
|
||||
|
||||
Reference in New Issue
Block a user