#![allow(dead_code)]
use axum::{
extract::Request,
http::{header, StatusCode},
middleware::Next,
response::Response,
};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use chrono::{Duration, Utc};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String,
pub exp: i64,
pub iat: i64,
}
pub struct AuthManager {
secret: String,
enabled: bool,
}
impl AuthManager {
pub fn new(secret: String, enabled: bool) -> Self {
Self { secret, enabled }
}
pub fn generate_token(&self, user_id: &str, expiry_hours: i64) -> Result<String, jsonwebtoken::errors::Error> {
let now = Utc::now();
let exp = now + Duration::hours(expiry_hours);
let claims = Claims {
sub: user_id.to_string(),
exp: exp.timestamp(),
iat: now.timestamp(),
};
encode(&Header::default(), &claims, &EncodingKey::from_secret(self.secret.as_bytes()))
}
pub fn verify_token(&self, token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
decode::<Claims>(
token,
&DecodingKey::from_secret(self.secret.as_bytes()),
&Validation::default(),
).map(|data| data.claims)
}
}
pub async fn auth_middleware(
req: Request,
next: Next,
) -> Result<Response, StatusCode> {
let auth_header = req
.headers()
.get(header::AUTHORIZATION)
.and_then(|h| h.to_str().ok());
if let Some(auth_header) = auth_header
&& auth_header.starts_with("Bearer ") {
return Ok(next.run(req).await);
}
Err(StatusCode::UNAUTHORIZED)
}