lmrc-cli 0.3.16

CLI tool for scaffolding LMRC Stack infrastructure projects
Documentation
//! Authentication middleware for request validation

use axum::{
    extract::{Request, State},
    middleware::Next,
    response::Response,
};
use crate::{state::AppState, error::AppError};
use super::models::CurrentUser;

/// Middleware to validate session and extract current user
/// This works with the gateway's session management
pub async fn auth_middleware(
    State(_state): State<AppState>,
    mut request: Request,
    next: Next,
) -> Result<Response, AppError> {
    // The gateway handles session validation
    // It should pass user info via headers

    // Extract user ID from header (set by gateway)
    let user_id = request
        .headers()
        .get("X-User-Id")
        .and_then(|h| h.to_str().ok())
        .and_then(|s| s.parse::<i64>().ok())
        .ok_or_else(|| AppError::Unauthorized("Missing or invalid user ID".to_string()))?;

    let email = request
        .headers()
        .get("X-User-Email")
        .and_then(|h| h.to_str().ok())
        .unwrap_or("unknown@lmrc.local")
        .to_string();

    let role = request
        .headers()
        .get("X-User-Role")
        .and_then(|h| h.to_str().ok())
        .unwrap_or("user")
        .to_string();

    // Create current user and add to request extensions
    let current_user = CurrentUser {
        id: user_id,
        email,
        role,
    };

    request.extensions_mut().insert(current_user);

    Ok(next.run(request).await)
}

/// Middleware to require admin role
pub async fn admin_middleware(
    request: Request,
    next: Next,
) -> Result<Response, AppError> {
    // Get current user from extensions
    let user = request
        .extensions()
        .get::<CurrentUser>()
        .ok_or_else(|| AppError::Unauthorized("Authentication required".to_string()))?;

    // Check if user is admin
    if user.role != "admin" {
        return Err(AppError::Forbidden("Admin access required".to_string()));
    }

    Ok(next.run(request).await)
}