use serde::{Deserialize, Serialize};
use std::time::Duration;
use crate::utils::get_env_with_prefix;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SessionBackend {
InMemory,
#[cfg(feature = "sessions")]
Cookie,
}
impl Default for SessionBackend {
fn default() -> Self {
Self::InMemory
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SessionConfig {
#[serde(default)]
pub backend: SessionBackend,
#[serde(default = "default_ttl_seconds")]
pub default_ttl_seconds: u64,
#[serde(default = "default_cookie_name")]
pub cookie_name: String,
#[serde(default)]
pub cookie_domain: Option<String>,
#[serde(default = "default_cookie_path")]
pub cookie_path: String,
#[serde(default = "default_secure")]
pub cookie_secure: bool,
#[serde(default = "default_http_only")]
pub cookie_http_only: bool,
#[serde(default)]
pub encryption_key: Option<String>,
}
impl Default for SessionConfig {
fn default() -> Self {
Self {
backend: SessionBackend::default(),
default_ttl_seconds: default_ttl_seconds(),
cookie_name: default_cookie_name(),
cookie_domain: None,
cookie_path: default_cookie_path(),
cookie_secure: default_secure(),
cookie_http_only: default_http_only(),
encryption_key: None,
}
}
}
impl SessionConfig {
pub fn from_env() -> Self {
let mut config = Self::default();
if let Some(backend) = get_env_with_prefix("SESSION_BACKEND") {
config.backend = match backend.to_lowercase().as_str() {
"cookie" => {
#[cfg(feature = "sessions")]
{
SessionBackend::Cookie
}
#[cfg(not(feature = "sessions"))]
{
tracing::warn!("Cookie sessions requested but sessions feature not enabled, using in-memory");
SessionBackend::InMemory
}
}
_ => SessionBackend::InMemory,
};
}
if let Some(ttl) = get_env_with_prefix("SESSION_TTL_SECONDS") {
if let Ok(seconds) = ttl.parse() {
config.default_ttl_seconds = seconds;
}
}
if let Some(name) = get_env_with_prefix("SESSION_COOKIE_NAME") {
config.cookie_name = name;
}
if let Some(domain) = get_env_with_prefix("SESSION_COOKIE_DOMAIN") {
config.cookie_domain = Some(domain);
}
if let Some(path) = get_env_with_prefix("SESSION_COOKIE_PATH") {
config.cookie_path = path;
}
if let Some(secure) = get_env_with_prefix("SESSION_COOKIE_SECURE") {
config.cookie_secure = secure.parse().unwrap_or(true);
}
if let Some(http_only) = get_env_with_prefix("SESSION_COOKIE_HTTP_ONLY") {
config.cookie_http_only = http_only.parse().unwrap_or(true);
}
if let Some(key) = get_env_with_prefix("SESSION_ENCRYPTION_KEY") {
config.encryption_key = Some(key);
}
config
}
pub fn default_ttl(&self) -> Duration {
Duration::from_secs(self.default_ttl_seconds)
}
}
fn default_ttl_seconds() -> u64 {
3600 * 24 }
fn default_cookie_name() -> String {
"tideway_session".to_string()
}
fn default_cookie_path() -> String {
"/".to_string()
}
fn default_secure() -> bool {
true
}
fn default_http_only() -> bool {
true
}