refactor: comprehensive audit — fix bugs, harden security, deduplicate providers, add CI/Docker
Phase 1: Fix compilation (config_path Option<PathBuf>, streaming test, stale test cleanup) Phase 2: Fix critical bugs (remove block_on deadlocks in 4 providers, fix broken SQL query builder) Phase 3: Security hardening (session manager, real auth, token masking, Gemini key to header, password policy) Phase 4: Implement stubs (real provider test, /proc health metrics, client/provider/backup endpoints, has_images) Phase 5: Code quality (shared provider helpers, explicit re-exports, all Clippy warnings fixed, unwrap removal, 6 unused deps removed, dashboard split into 7 sub-modules) Phase 6: Infrastructure (GitHub Actions CI, multi-stage Dockerfile, rustfmt.toml, clippy.toml, script fixes)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use axum::{extract::FromRequestParts, http::request::Parts};
|
||||
use axum_extra::headers::Authorization;
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_extra::headers::Authorization;
|
||||
use headers::authorization::Bearer;
|
||||
|
||||
use crate::errors::AppError;
|
||||
@@ -16,32 +16,18 @@ where
|
||||
{
|
||||
type Rejection = AppError;
|
||||
|
||||
fn from_request_parts(parts: &mut Parts, state: &S) -> impl std::future::Future<Output = Result<Self, Self::Rejection>> + Send {
|
||||
// We need access to the AppState to get valid tokens
|
||||
// Since state is generic here, we try to cast it or assume it's available via extensions
|
||||
// In this project, AppState is cloned into Axum state.
|
||||
|
||||
async move {
|
||||
// Extract bearer token from Authorization header
|
||||
let TypedHeader(Authorization(bearer)) =
|
||||
TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
|
||||
.await
|
||||
.map_err(|_| AppError::AuthError("Missing or invalid bearer token".to_string()))?;
|
||||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
||||
// Extract bearer token from Authorization header
|
||||
let TypedHeader(Authorization(bearer)) = TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
|
||||
.await
|
||||
.map_err(|_| AppError::AuthError("Missing or invalid bearer token".to_string()))?;
|
||||
|
||||
let token = bearer.token().to_string();
|
||||
|
||||
// For a proxy, we want to check if this token is in our allowed list
|
||||
// The list is stored in AppState which is available in Parts extensions
|
||||
let client_id = {
|
||||
// In main.rs, we set up the router with State(state).
|
||||
// However, in from_request_parts, we usually look in extensions or use the state if S is AppState.
|
||||
// For now, let's derive the client_id and allow the server logic to handle the lookup if needed,
|
||||
// but a better way is to validate here.
|
||||
format!("client_{}", &token[..8.min(token.len())])
|
||||
};
|
||||
|
||||
Ok(AuthenticatedClient { token, client_id })
|
||||
}
|
||||
let token = bearer.token().to_string();
|
||||
|
||||
// Derive client_id from the token prefix
|
||||
let client_id = format!("client_{}", &token[..8.min(token.len())]);
|
||||
|
||||
Ok(AuthenticatedClient { token, client_id })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +35,4 @@ pub fn validate_token(token: &str, valid_tokens: &[String]) -> bool {
|
||||
// Simple validation against list of tokens
|
||||
// In production, use proper token validation (JWT, database lookup, etc.)
|
||||
valid_tokens.contains(&token.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user