40ddb0a0f6
Сервер получает флаги --require-auth/--backend-url (по умолчанию выключено, поведение уже развёрнутых нод не меняется). Auth-кадр хендшейка расширен с "session_id:leg_id" до "session_id:leg_id:token"; при включённом --require-auth сервер валидирует токен через новый AuthValidator (BackendClient к netrunner-backend, с кешем на 60с). Muxer теперь ведёт монотонный учёт трафика сессии (переживает реконнект ног — раньше total_bytes мог занижаться после переподключения) и раз в ~30с отчитывается бэкенду; при превышении лимита сессия разрывается. Токен клиента прокидывается через EngineConfig/TunnelConfig до Tauri-плагина (desktop.rs + Android Kotlin-плагин). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
38 lines
1.9 KiB
Rust
38 lines
1.9 KiB
Rust
//! Абстракция проверки клиентского токена и учёта расхода трафика на
|
|
//! control-plane бэкенде. Ядро знает только этот трейт — конкретную реализацию
|
|
//! (HTTP-клиент к `netrunner-backend`) даёт связывающий бинарь (`netrunner-server`),
|
|
//! чтобы ядро не тянуло HTTP-клиент как обязательную зависимость.
|
|
//!
|
|
//! Включается/выключается на инстанс целиком через `--require-auth` (см.
|
|
//! `server/src/main.rs`): если сервер запущен без флага, [`ServerHandler`]
|
|
//! вообще не спрашивает валидатор, и поведение не отличается от того, что
|
|
//! было до этой фичи.
|
|
|
|
use async_trait::async_trait;
|
|
use netrunner_logger::AppError;
|
|
|
|
/// Результат успешной проверки токена клиента.
|
|
#[derive(Debug, Clone)]
|
|
pub struct UserQuota {
|
|
pub user_id: String,
|
|
/// `None` — безлимит.
|
|
pub limit_bytes: Option<u64>,
|
|
pub used_bytes: u64,
|
|
}
|
|
|
|
/// Ответ на отчёт о расходе трафика.
|
|
#[derive(Debug, Clone)]
|
|
pub struct UsageReport {
|
|
pub used_bytes: u64,
|
|
pub limit_bytes: Option<u64>,
|
|
pub over_limit: bool,
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait AuthValidator: Send + Sync {
|
|
/// Проверяет Bearer-токен клиента (JWT, выданный бэкендом при логине).
|
|
async fn validate(&self, token: &str) -> Result<UserQuota, AppError>;
|
|
/// Отчитывается о переданных байтах и синхронно узнаёт, не превышен ли лимит.
|
|
async fn report_usage(&self, user_id: &str, delta_bytes: u64) -> Result<UsageReport, AppError>;
|
|
}
|