mirror of
https://github.com/DefectingCat/phthonus
synced 2025-07-15 16:41:32 +00:00
feat: add user registry
add hash password
This commit is contained in:
1
frameworks/Rust/axum/Cargo.lock
generated
1
frameworks/Rust/axum/Cargo.lock
generated
@ -958,6 +958,7 @@ dependencies = [
|
||||
"dotenvy",
|
||||
"jsonwebtoken",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
|
@ -18,6 +18,7 @@ thiserror = "2.0.0"
|
||||
dotenvy = "0.15.7"
|
||||
argon2 = "0.5.3"
|
||||
rand = "0.8.5"
|
||||
regex = "1.11.1"
|
||||
serde = { version = "1.0.214", features = ["derive", "serde_derive"] }
|
||||
serde_json = { version = "1.0.132" }
|
||||
serde_repr = "0.1.19"
|
||||
|
@ -15,6 +15,8 @@ pub enum AppError {
|
||||
#[error("{0}")]
|
||||
Any(#[from] anyhow::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
ValidationError(#[from] validator::ValidationErrors),
|
||||
// axum
|
||||
#[error(transparent)]
|
||||
AxumFormRejection(#[from] FormRejection),
|
||||
@ -80,11 +82,14 @@ impl IntoResponse for AppError {
|
||||
ParameterIncorrect,
|
||||
self.to_string(),
|
||||
),
|
||||
// route
|
||||
// AppError::AuthorizeFailed(err) => {
|
||||
// (StatusCode::UNAUTHORIZED, AuthorizeFailed, err.to_string())
|
||||
// }
|
||||
// AppError::UserConflict(err) => (StatusCode::CONFLICT, UserConflict, err.to_string()),
|
||||
AppError::ValidationError(_) => {
|
||||
let message = format!("Input validation error: [{self}]").replace('\n', ", ");
|
||||
(StatusCode::BAD_REQUEST, ParameterIncorrect, message)
|
||||
} // route
|
||||
// AppError::AuthorizeFailed(err) => {
|
||||
// (StatusCode::UNAUTHORIZED, AuthorizeFailed, err.to_string())
|
||||
// }
|
||||
// AppError::UserConflict(err) => (StatusCode::CONFLICT, UserConflict, err.to_string()),
|
||||
};
|
||||
let body = Json(json!({
|
||||
"code": code,
|
||||
|
@ -1,12 +1,22 @@
|
||||
use crate::utils::password::hash;
|
||||
use axum::{routing::post, Json, Router};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::utils::validator::EMAIL_REGEX;
|
||||
|
||||
use super::{RouteResponse, RouteResult};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Validate)]
|
||||
pub struct UserResigtry {
|
||||
#[validate(length(min = 1, message = "Can not be empty"))]
|
||||
pub username: String,
|
||||
#[validate(regex(
|
||||
path = *EMAIL_REGEX,
|
||||
message = "邮箱格式不正确"
|
||||
))]
|
||||
pub email: String,
|
||||
#[validate(length(min = 6, max = 100, message = "Can not be empty"))]
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
@ -14,13 +24,23 @@ pub struct UserResigtry {
|
||||
pub struct UserResigtryRes {
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
pub password: String,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
pub async fn registry(Json(user_param): Json<UserResigtry>) -> RouteResult<UserResigtryRes> {
|
||||
let UserResigtry {
|
||||
email,
|
||||
password,
|
||||
username,
|
||||
} = user_param;
|
||||
|
||||
let hashed = hash(password).await?;
|
||||
|
||||
let data = UserResigtryRes {
|
||||
username: "xfy".to_string(),
|
||||
email: "i@rua.plus".to_string(),
|
||||
username,
|
||||
email,
|
||||
password: hashed,
|
||||
token: "abc".to_string(),
|
||||
};
|
||||
let res = RouteResponse {
|
||||
|
@ -3,6 +3,7 @@ use tracing_subscriber::{fmt, prelude::*, registry, EnvFilter};
|
||||
|
||||
pub mod jwt;
|
||||
pub mod password;
|
||||
pub mod validator;
|
||||
|
||||
/// Initializes the logger for tracing.
|
||||
pub fn init_logger() {
|
||||
|
57
frameworks/Rust/axum/src/utils/validator.rs
Normal file
57
frameworks/Rust/axum/src/utils/validator.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use axum::{
|
||||
async_trait,
|
||||
extract::{
|
||||
rejection::{FormRejection, JsonRejection},
|
||||
FromRequest, Request,
|
||||
},
|
||||
Form, Json,
|
||||
};
|
||||
use regex::Regex;
|
||||
use serde::de::DeserializeOwned;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::error::AppError;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct ValidatedForm<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
impl<T, S> FromRequest<S> for ValidatedForm<T>
|
||||
where
|
||||
T: DeserializeOwned + Validate,
|
||||
S: Send + Sync,
|
||||
Form<T>: FromRequest<S, Rejection = FormRejection>,
|
||||
{
|
||||
type Rejection = AppError;
|
||||
|
||||
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
||||
let Form(value) = Form::<T>::from_request(req, state).await?;
|
||||
value.validate()?;
|
||||
Ok(ValidatedForm(value))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct ValidatedJson<T>(pub T);
|
||||
|
||||
#[async_trait]
|
||||
impl<T, S> FromRequest<S> for ValidatedJson<T>
|
||||
where
|
||||
T: DeserializeOwned + Validate,
|
||||
S: Send + Sync,
|
||||
Json<T>: FromRequest<S, Rejection = JsonRejection>,
|
||||
{
|
||||
type Rejection = AppError;
|
||||
|
||||
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
||||
let Json(value) = Json::<T>::from_request(req, state).await?;
|
||||
value.validate()?;
|
||||
Ok(ValidatedJson(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub static EMAIL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$").expect("Regex is valid")
|
||||
});
|
Reference in New Issue
Block a user