Files
RustBox/src/session_store/mod.rs
T
Mateusz Gruszczyński dacdf9c27d
RustBox CI / rustbox (push) Canceled after 0s
v0.2.8
2026-11-01 20:40:40 +01:00

82 lines
2.7 KiB
Rust

pub mod crypto;
pub mod database;
pub mod redis_store;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::config::AppConfig;
#[derive(Debug, Clone, Serialize)]
pub struct SessionPersistenceDiagnostics {
pub backend: String,
pub status: String,
pub active_sessions: usize,
pub unique_users: usize,
pub unique_browsers: usize,
pub latest_accessed_unix: Option<u64>,
pub truncated: bool,
pub engine_version: Option<String>,
pub connected_clients: Option<u64>,
pub blocked_clients: Option<u64>,
pub used_memory_bytes: Option<u64>,
pub server_uptime_secs: Option<u64>,
pub role: Option<String>,
pub master_link_status: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersistedSession {
pub token: String,
pub account_id: String,
pub browser_id: String,
pub email: String,
pub password_ciphertext: String,
pub user_hash: String,
pub imap_host: String,
pub imap_port: u16,
pub imap_tls: bool,
pub imap_tls_verify: bool,
pub smtp_host: String,
pub smtp_port: u16,
pub smtp_tls: bool,
pub smtp_tls_verify: bool,
pub timeout_secs: u64,
pub created_at_unix: u64,
pub last_accessed_unix: u64,
pub user_agent: String,
}
impl PersistedSession {
pub fn expired_at(&self, now_unix: u64) -> bool {
now_unix.saturating_sub(self.last_accessed_unix) > self.timeout_secs
}
}
#[async_trait]
pub trait SessionPersistence: Send + Sync {
async fn save(&self, session: &PersistedSession) -> Result<(), String>;
async fn load_token(&self, token: &str) -> Result<Option<PersistedSession>, String>;
async fn load_browser(&self, browser_id: &str) -> Result<Vec<PersistedSession>, String>;
async fn load_user(&self, user_hash: &str) -> Result<Vec<PersistedSession>, String>;
async fn browser_exists(&self, browser_id: &str) -> Result<bool, String>;
async fn delete_account(&self, account_id: &str) -> Result<bool, String>;
async fn delete_browser(&self, browser_id: &str) -> Result<(), String>;
async fn purge_expired(&self, now_unix: u64) -> Result<u64, String>;
async fn diagnostics(&self, now_unix: u64) -> Result<SessionPersistenceDiagnostics, String>;
}
pub async fn from_config(
config: &AppConfig,
) -> Result<std::sync::Arc<dyn SessionPersistence>, String> {
match config.session_backend.as_str() {
"database" => Ok(std::sync::Arc::new(
database::DatabaseSessionStore::connect(config).await?,
)),
"redis" => Ok(std::sync::Arc::new(
redis_store::RedisSessionStore::connect(config).await?,
)),
other => Err(format!("unsupported session backend: {other}")),
}
}