use async_trait::async_trait;
use axum::http::request::Parts;
use axum::response::{IntoResponse, Response};
use serde_json::json;
#[derive(Debug, Clone)]
pub enum GuardError {
Unauthorized(String),
Forbidden(String),
}
impl GuardError {
pub fn unauthorized(message: impl Into<String>) -> Self {
Self::Unauthorized(message.into())
}
pub fn forbidden(message: impl Into<String>) -> Self {
Self::Forbidden(message.into())
}
}
impl IntoResponse for GuardError {
fn into_response(self) -> Response {
let (status, message, error_label) = match &self {
GuardError::Unauthorized(m) => (
axum::http::StatusCode::UNAUTHORIZED,
m.clone(),
"Unauthorized",
),
GuardError::Forbidden(m) => (axum::http::StatusCode::FORBIDDEN, m.clone(), "Forbidden"),
};
let body = axum::Json(json!({
"statusCode": status.as_u16(),
"message": message,
"error": error_label,
}));
(status, body).into_response()
}
}
#[async_trait]
pub trait CanActivate: Default + Send + Sync + 'static {
async fn can_activate(&self, parts: &Parts) -> Result<(), GuardError>;
}