Files
GopherGate/src/dashboard/mod.rs
T
hobokenchicken 54c45cbfca
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled
feat(auth): add DB-based token authentication for dashboard-created clients
Add client_tokens table with auto-generated sk-{hex} tokens so clients
created in the dashboard get working API keys. Auth flow: DB token lookup
first, then env token fallback, then permissive mode. Includes token
management CRUD endpoints and copy-once reveal modal in the frontend.
2026-03-02 15:14:12 -05:00

114 lines
3.6 KiB
Rust

// Dashboard module for LLM Proxy Gateway
mod auth;
mod clients;
mod models;
mod providers;
pub mod sessions;
mod system;
mod usage;
mod websocket;
use axum::{
Router,
routing::{delete, get, post, put},
};
use serde::Serialize;
use crate::state::AppState;
use sessions::SessionManager;
// Dashboard state
#[derive(Clone)]
struct DashboardState {
app_state: AppState,
session_manager: SessionManager,
}
// API Response types
#[derive(Serialize)]
struct ApiResponse<T> {
success: bool,
data: Option<T>,
error: Option<String>,
}
impl<T> ApiResponse<T> {
fn success(data: T) -> Self {
Self {
success: true,
data: Some(data),
error: None,
}
}
fn error(error: String) -> Self {
Self {
success: false,
data: None,
error: Some(error),
}
}
}
// Dashboard routes
pub fn router(state: AppState) -> Router {
let session_manager = SessionManager::new(24); // 24-hour session TTL
let dashboard_state = DashboardState {
app_state: state,
session_manager,
};
Router::new()
// Static file serving
.fallback_service(tower_http::services::ServeDir::new("static"))
// WebSocket endpoint
.route("/ws", get(websocket::handle_websocket))
// API endpoints
.route("/api/auth/login", post(auth::handle_login))
.route("/api/auth/status", get(auth::handle_auth_status))
.route("/api/auth/change-password", post(auth::handle_change_password))
.route("/api/usage/summary", get(usage::handle_usage_summary))
.route("/api/usage/time-series", get(usage::handle_time_series))
.route("/api/usage/clients", get(usage::handle_clients_usage))
.route("/api/usage/providers", get(usage::handle_providers_usage))
.route("/api/usage/detailed", get(usage::handle_detailed_usage))
.route("/api/analytics/breakdown", get(usage::handle_analytics_breakdown))
.route("/api/models", get(models::handle_get_models))
.route("/api/models/{id}", put(models::handle_update_model))
.route(
"/api/clients",
get(clients::handle_get_clients).post(clients::handle_create_client),
)
.route(
"/api/clients/{id}",
get(clients::handle_get_client)
.put(clients::handle_update_client)
.delete(clients::handle_delete_client),
)
.route("/api/clients/{id}/usage", get(clients::handle_client_usage))
.route(
"/api/clients/{id}/tokens",
get(clients::handle_get_client_tokens).post(clients::handle_create_client_token),
)
.route(
"/api/clients/{id}/tokens/{token_id}",
delete(clients::handle_delete_client_token),
)
.route("/api/providers", get(providers::handle_get_providers))
.route(
"/api/providers/{name}",
get(providers::handle_get_provider).put(providers::handle_update_provider),
)
.route("/api/providers/{name}/test", post(providers::handle_test_provider))
.route("/api/system/health", get(system::handle_system_health))
.route("/api/system/metrics", get(system::handle_system_metrics))
.route("/api/system/logs", get(system::handle_system_logs))
.route("/api/system/backup", post(system::handle_system_backup))
.route(
"/api/system/settings",
get(system::handle_get_settings).post(system::handle_update_settings),
)
.with_state(dashboard_state)
}