server (http): add error handler for several exceptions

This commit is contained in:
MedzikUser 2022-04-23 21:21:04 +02:00
parent 36fba1dd1d
commit 5164a94a55
No known key found for this signature in database
GPG Key ID: A5FAC1E185C112DB
8 changed files with 71 additions and 18 deletions

View File

@ -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,
}
}

View File

@ -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,
}
}

View File

@ -1,4 +1,5 @@
pub mod auth;
pub mod middleware;
mod error;

View File

@ -0,0 +1 @@

View 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)),
}
}

View File

@ -0,0 +1,5 @@
mod auth;
mod jwt;
mod validate_json;
pub use {auth::*, jwt::*, validate_json::*};

View 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())),
}
}

View File

@ -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();