mirror of
https://github.com/MedzikUser/HomeDisk.git
synced 2024-08-14 21:46:53 +00:00
server (http): add error handler for several exceptions
This commit is contained in:
parent
36fba1dd1d
commit
5164a94a55
8 changed files with 71 additions and 18 deletions
|
@ -1,29 +1,28 @@
|
|||
use axum::{Extension, Json};
|
||||
use axum::{extract::rejection::JsonRejection, Extension, Json};
|
||||
use homedisk_database::{Database, Error, User};
|
||||
use homedisk_types::{
|
||||
auth::login::{Request, Response},
|
||||
config::types::Config,
|
||||
errors::{AuthError, ServerError},
|
||||
};
|
||||
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
||||
|
||||
use crate::middleware::{create_token, validate_json};
|
||||
|
||||
pub async fn handle(
|
||||
db: Extension<Database>,
|
||||
config: Extension<Config>,
|
||||
request: Json<Request>,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
let request = validate_json::<Request>(request)?;
|
||||
|
||||
let user = User::new(&request.username, &request.password);
|
||||
|
||||
let response = match db.find_user(&user.username, &user.password).await {
|
||||
Ok(res) => {
|
||||
let token = Token::new(
|
||||
config.jwt.secret.as_bytes(),
|
||||
Claims::new(res.id, config.jwt.expires),
|
||||
)
|
||||
.unwrap();
|
||||
let token = create_token(res, config.jwt.secret.as_bytes(), config.jwt.expires)?;
|
||||
|
||||
Response::LoggedIn {
|
||||
access_token: token.encoded,
|
||||
access_token: token,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
use axum::{Extension, Json};
|
||||
use axum::{extract::rejection::JsonRejection, Extension, Json};
|
||||
use homedisk_database::{Database, User};
|
||||
use homedisk_types::{
|
||||
auth::login::{Request, Response},
|
||||
config::types::Config,
|
||||
errors::{AuthError, ServerError},
|
||||
};
|
||||
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
||||
|
||||
use crate::middleware::{create_token, validate_json};
|
||||
|
||||
pub async fn handle(
|
||||
db: Extension<Database>,
|
||||
config: Extension<Config>,
|
||||
request: Json<Request>,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
let request = validate_json::<Request>(request)?;
|
||||
|
||||
let user = User::new(&request.username, &request.password);
|
||||
|
||||
let response = match db.create_user(&user).await {
|
||||
Ok(_) => {
|
||||
let token = Token::new(
|
||||
config.jwt.secret.as_bytes(),
|
||||
Claims::new(user.id, config.jwt.expires),
|
||||
)
|
||||
.unwrap();
|
||||
let token = create_token(user, config.jwt.secret.as_bytes(), config.jwt.expires)?;
|
||||
|
||||
Response::LoggedIn {
|
||||
access_token: token.encoded,
|
||||
access_token: token,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod auth;
|
||||
pub mod middleware;
|
||||
|
||||
mod error;
|
||||
|
||||
|
|
1
server/src/middleware/auth.rs
Normal file
1
server/src/middleware/auth.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
12
server/src/middleware/jwt.rs
Normal file
12
server/src/middleware/jwt.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use homedisk_database::User;
|
||||
use homedisk_types::errors::{AuthError, ServerError};
|
||||
use rust_utilities::crypto::jsonwebtoken::{Claims, Token};
|
||||
|
||||
pub fn create_token(user: User, secret: &[u8], expires: i64) -> Result<String, ServerError> {
|
||||
let token = Token::new(secret, Claims::new(user.id, expires));
|
||||
|
||||
match token {
|
||||
Ok(token) => Ok(token.encoded),
|
||||
Err(_) => Err(ServerError::AuthError(AuthError::TokenGenerate)),
|
||||
}
|
||||
}
|
5
server/src/middleware/mod.rs
Normal file
5
server/src/middleware/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod auth;
|
||||
mod jwt;
|
||||
mod validate_json;
|
||||
|
||||
pub use {auth::*, jwt::*, validate_json::*};
|
15
server/src/middleware/validate_json.rs
Normal file
15
server/src/middleware/validate_json.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use axum::{extract::rejection::JsonRejection, Json};
|
||||
use homedisk_types::errors::ServerError;
|
||||
|
||||
pub fn validate_json<Typ>(
|
||||
payload: Result<Json<Typ>, JsonRejection>,
|
||||
) -> Result<Json<Typ>, ServerError> {
|
||||
match payload {
|
||||
Ok(payload) => Ok(payload),
|
||||
Err(JsonRejection::MissingJsonContentType(_)) => Err(ServerError::MissingJsonContentType),
|
||||
Err(JsonRejection::JsonDataError(_)) => Err(ServerError::JsonDataError),
|
||||
Err(JsonRejection::JsonSyntaxError(_)) => Err(ServerError::JsonSyntaxError),
|
||||
Err(JsonRejection::BytesRejection(_)) => Err(ServerError::BytesRejection),
|
||||
Err(err) => Err(ServerError::Other(err.to_string())),
|
||||
}
|
||||
}
|
|
@ -12,6 +12,21 @@ pub enum ServerError {
|
|||
|
||||
#[error("too may requests, please slow down")]
|
||||
TooManyRequests,
|
||||
|
||||
#[error("missing json content type")]
|
||||
MissingJsonContentType,
|
||||
|
||||
#[error("error deserialize json")]
|
||||
JsonDataError,
|
||||
|
||||
#[error("json syntax error")]
|
||||
JsonSyntaxError,
|
||||
|
||||
#[error("failed to extract the request body")]
|
||||
BytesRejection,
|
||||
|
||||
#[error("unexcepted error")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
#[cfg(feature = "axum")]
|
||||
|
@ -27,6 +42,12 @@ impl axum::response::IntoResponse for ServerError {
|
|||
AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
AuthError::UnknowError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
},
|
||||
|
||||
Self::MissingJsonContentType => StatusCode::BAD_REQUEST,
|
||||
Self::JsonDataError => StatusCode::BAD_REQUEST,
|
||||
Self::JsonSyntaxError => StatusCode::BAD_REQUEST,
|
||||
Self::BytesRejection => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Self::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
};
|
||||
|
||||
let mut response = axum::Json(self).into_response();
|
||||
|
|
Loading…
Reference in a new issue