diff --git a/core/src/helpers/auth.rs b/core/src/helpers/auth.rs index 7ad06a5..f6466b0 100644 --- a/core/src/helpers/auth.rs +++ b/core/src/helpers/auth.rs @@ -1,3 +1,4 @@ +use actix_web::http::StatusCode; use actix_web::web::Data; use actix_web::HttpRequest; use jsonwebtoken::{decode, DecodingKey, TokenData, Validation}; @@ -6,6 +7,7 @@ use crate::app_state::AppState; use crate::enums::app_message::AppMessage::{UnAuthorized, WarningMessage}; use crate::enums::auth_permission::AuthPermission; use crate::helpers::request::RequestHelper; +use crate::helpers::responder::{JsonResponse, JsonResponseEmptyMessage}; use crate::results::{AppResult, HttpResult}; use crate::services::auth_service::TokenClaims; use crate::services::role_service::RoleService; @@ -65,3 +67,13 @@ pub(crate) fn decode_auth_token( &Validation::default(), ) } + +pub(crate) fn make_unauthorized_message(msg: &str) -> JsonResponse { + JsonResponse { + code: 401, + success: false, + status: StatusCode::UNAUTHORIZED.to_string(), + message: Some(msg.to_string()), + data: JsonResponseEmptyMessage {}, + } +} diff --git a/core/src/helpers/responder.rs b/core/src/helpers/responder.rs index 778e159..801d638 100644 --- a/core/src/helpers/responder.rs +++ b/core/src/helpers/responder.rs @@ -1,16 +1,26 @@ use actix_web::http::StatusCode; use actix_web::HttpResponse; use serde::Serialize; +use std::fmt::{Display, Formatter}; use crate::helpers::db_pagination::PageData; -#[derive(Serialize)] +#[derive(Debug, Serialize)] +pub(crate) struct JsonResponseEmptyMessage {} + +#[derive(Debug, Serialize)] pub struct JsonResponse { - code: u16, - success: bool, - status: String, - message: Option, - data: T, + pub(crate) code: u16, + pub(crate) success: bool, + pub(crate) status: String, + pub(crate) message: Option, + pub(crate) data: T, +} + +impl Display for JsonResponse { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(serde_json::to_string(self).unwrap().as_str()) + } } #[derive(Serialize)] @@ -22,9 +32,6 @@ pub struct PaginationResponse { pub(crate) data: Vec, } -#[derive(Serialize)] -pub struct JsonMessageResponse {} - pub fn json(data: T, status: StatusCode) -> HttpResponse { HttpResponse::build(status).json(data) } @@ -77,11 +84,15 @@ pub fn json_error_message(message: &str) -> HttpResponse { } pub fn json_error_message_status(message: &str, status: StatusCode) -> HttpResponse { - json_error(JsonMessageResponse {}, status, Some(message.to_string())) + json_error( + JsonResponseEmptyMessage {}, + status, + Some(message.to_string()), + ) } pub fn json_success_message(message: &str) -> HttpResponse { - json_success(JsonMessageResponse {}, Some(message.to_string())) + json_success(JsonResponseEmptyMessage {}, Some(message.to_string())) } #[allow(dead_code)] diff --git a/core/src/http/middlewares/auth_middleware.rs b/core/src/http/middlewares/auth_middleware.rs index debc534..1a868a5 100644 --- a/core/src/http/middlewares/auth_middleware.rs +++ b/core/src/http/middlewares/auth_middleware.rs @@ -8,12 +8,11 @@ use actix_web::{ }; use futures_util::future::LocalBoxFuture; use log::error; -use serde::Serialize; use uuid::Uuid; use crate::app_state::AppState; use crate::enums::auth_role::AuthRole; -use crate::helpers::auth::decode_auth_token; +use crate::helpers::auth::{decode_auth_token, make_unauthorized_message}; use crate::helpers::uuid::UniqueIdentifier; use crate::models::user::User; use crate::repositories::personal_access_token_repository::PersonaAccessTokenRepository; @@ -21,13 +20,6 @@ use crate::repositories::user_repository::UserRepository; use crate::repositories::user_role_repository::UserRoleRepository; use crate::results::http_result::ErroneousOptionResponse; -#[derive(Debug, Serialize)] -struct ErrorResponse<'a> { - success: bool, - status: i32, - message: &'a str, -} - #[derive(Clone)] pub struct AuthMiddleware { pub roles: Vec, @@ -93,11 +85,9 @@ where if token.is_none() { //You are not logged in, please provide token let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "you are not logged in, please provide token", - }) + .json(make_unauthorized_message( + "you are not logged in, please provide token", + )) .map_into_right_body(); let (req, _pl) = request.into_parts(); @@ -117,11 +107,7 @@ where if decoded.is_err() { let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "invalid authentication token", - }) + .json(make_unauthorized_message("invalid authentication token")) .map_into_right_body(); let (req, _pl) = request.into_parts(); @@ -138,17 +124,13 @@ where true => match PersonaAccessTokenRepository.find_by_token(app.database(), raw_token) { Ok(pat) => { if !pat.is_usable() { - let message = Box::leak(Box::new(format!( + let msg = Box::leak(Box::new(format!( "personal access token has expired on {:?}", pat.expired_at ))); let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message, - }) + .json(make_unauthorized_message(msg)) .map_into_right_body(); let (req, _pl) = request.into_parts(); @@ -160,11 +142,9 @@ where Err(err) => { error!("pat error: {:?}", err); let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "failed to authenticate personal access token", - }) + .json(make_unauthorized_message( + "failed to authenticate personal access token", + )) .map_into_right_body(); let (req, _pl) = request.into_parts(); @@ -175,11 +155,9 @@ where if user_lookup.is_error_or_empty() { let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "Invalid auth token, user not found", - }) + .json(make_unauthorized_message( + "Invalid auth token, user not found", + )) .map_into_right_body(); let (req, _pl) = request.into_parts(); @@ -193,11 +171,9 @@ where UserRoleRepository.list_role_names_by_user_id(app.database(), user.user_id); if roles_result.is_error_or_empty() { let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "Something went wrong trying to authenticate you", - }) + .json(make_unauthorized_message( + "Something went wrong trying to authenticate you", + )) .map_into_right_body(); error!( @@ -220,11 +196,9 @@ where if !has_access { let response = HttpResponse::Unauthorized() - .json(ErrorResponse { - success: false, - status: 401, - message: "You are not authorised to access requested resource(s)", - }) + .json(make_unauthorized_message( + "You are not authorised to access requested resource(s)", + )) .map_into_right_body(); let (req, _pl) = request.into_parts(); diff --git a/core/src/http/middlewares/manual_auth_middleware.rs b/core/src/http/middlewares/manual_auth_middleware.rs index 144fc98..ccb6ef2 100644 --- a/core/src/http/middlewares/manual_auth_middleware.rs +++ b/core/src/http/middlewares/manual_auth_middleware.rs @@ -1,4 +1,3 @@ -use std::fmt; use std::future::{ready, Ready}; use actix_web::error::ErrorUnauthorized; @@ -6,31 +5,17 @@ use actix_web::web::Data; use actix_web::{dev::Payload, Error as ActixWebError}; use actix_web::{http, FromRequest, HttpMessage, HttpRequest}; use log::error; -use serde::Serialize; use uuid::Uuid; use crate::app_state::AppState; use crate::enums::app_message::AppMessage; -use crate::helpers::auth::decode_auth_token; +use crate::helpers::auth::{decode_auth_token, make_unauthorized_message}; use crate::helpers::uuid::UniqueIdentifier; use crate::models::user::User; use crate::repositories::personal_access_token_repository::PersonaAccessTokenRepository; use crate::repositories::user_repository::UserRepository; use crate::results::http_result::ErroneousOptionResponse; -#[derive(Debug, Serialize)] -struct ErrorResponse<'a> { - success: bool, - status: i32, - message: &'a str, -} - -impl fmt::Display for ErrorResponse<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", serde_json::to_string(&self).unwrap()) - } -} - pub struct ManualAuthMiddleware { pub user_id: Uuid, } @@ -49,7 +34,7 @@ impl FromRequest for ManualAuthMiddleware { }); if token.is_none() { - return ready(Err(ErrorUnauthorized(make_unauthorized_response( + return ready(Err(ErrorUnauthorized(make_unauthorized_message( "You are not logged in, please provide token", )))); } @@ -69,7 +54,7 @@ impl FromRequest for ManualAuthMiddleware { let claims = match decoded { Ok(c) => c.claims, Err(_) => { - return ready(Err(ErrorUnauthorized(make_unauthorized_response( + return ready(Err(ErrorUnauthorized(make_unauthorized_message( "Invalid auth token", )))); } @@ -85,7 +70,7 @@ impl FromRequest for ManualAuthMiddleware { "personal access token has expired on {:?}", pat.expired_at ))); - return ready(Err(ErrorUnauthorized(make_unauthorized_response(message)))); + return ready(Err(ErrorUnauthorized(make_unauthorized_message(message)))); } UserRepository.find_by_id(app.database(), pat.user_id) @@ -96,7 +81,7 @@ impl FromRequest for ManualAuthMiddleware { _ => error!("pat error: {:?}", error), } - return ready(Err(ErrorUnauthorized(make_unauthorized_response( + return ready(Err(ErrorUnauthorized(make_unauthorized_message( "failed to authenticate personal access token", )))); } @@ -104,7 +89,7 @@ impl FromRequest for ManualAuthMiddleware { }; if user_lookup.is_error_or_empty() { - return ready(Err(ErrorUnauthorized(make_unauthorized_response( + return ready(Err(ErrorUnauthorized(make_unauthorized_message( "Invalid auth token, user not found", )))); } @@ -118,11 +103,3 @@ impl FromRequest for ManualAuthMiddleware { ready(Ok(ManualAuthMiddleware { user_id })) } } - -fn make_unauthorized_response(message: &str) -> ErrorResponse { - ErrorResponse { - success: false, - status: 401, - message, - } -}