diff options
Diffstat (limited to 'src/session.rs')
| -rw-r--r-- | src/session.rs | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/session.rs b/src/session.rs new file mode 100644 index 0000000..acb0409 --- /dev/null +++ b/src/session.rs @@ -0,0 +1,161 @@ +use anyhow::{Context, Result}; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; + +use crate::models::UserInfo; + +/// Session data stored to disk +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SessionData { + pub server_url: String, + pub token: String, + pub user: UserInfo, + pub remember_server: bool, + pub remember_username: bool, + pub saved_username: Option<String>, + #[serde(default)] + pub default_printer_id: Option<i64>, + /// Remember last-used printer (may differ from default_printer_id if user overrides per-print) + #[serde(default)] + pub last_printer_id: Option<i64>, +} + +/// Manages user session and credentials +pub struct SessionManager { + config_path: PathBuf, + current_session: Option<SessionData>, +} + +impl SessionManager { + /// Create a new session manager + pub fn new() -> Self { + let config_dir = dirs::config_dir() + .unwrap_or_else(|| PathBuf::from(".")) + .join("beepzone"); + + // Ensure config directory exists + let _ = fs::create_dir_all(&config_dir); + + let config_path = config_dir.join("session.json"); + + let mut manager = Self { + config_path, + current_session: None, + }; + + // Try to load existing session + let _ = manager.load_session(); + + manager + } + + /// Save a new session + pub fn save_session(&mut self, session: SessionData) -> Result<()> { + self.current_session = Some(session.clone()); + + let json = serde_json::to_string_pretty(&session).context("Failed to serialize session")?; + + fs::write(&self.config_path, json).context("Failed to write session file")?; + + log::info!("Session saved to {:?}", self.config_path); + Ok(()) + } + + /// Load session from disk + pub fn load_session(&mut self) -> Result<()> { + if !self.config_path.exists() { + return Ok(()); + } + + let json = fs::read_to_string(&self.config_path).context("Failed to read session file")?; + + let session: SessionData = + serde_json::from_str(&json).context("Failed to parse session file")?; + + self.current_session = Some(session); + log::info!("Session loaded from {:?}", self.config_path); + Ok(()) + } + + /// Clear the current session + pub fn clear_session(&mut self) -> Result<()> { + self.current_session = None; + + if self.config_path.exists() { + fs::remove_file(&self.config_path).context("Failed to remove session file")?; + log::info!("Session file removed"); + } + + Ok(()) + } + + /// Get the current session + pub fn get_session(&self) -> Option<&SessionData> { + self.current_session.as_ref() + } + + /// Check if there's a valid session + #[allow(dead_code)] + pub fn has_session(&self) -> bool { + self.current_session.is_some() + } + + /// Get the saved server URL (if remember_server is enabled) + pub fn get_saved_server_url(&self) -> Option<String> { + self.current_session + .as_ref() + .filter(|s| s.remember_server) + .map(|s| s.server_url.clone()) + } + + /// Get the saved username (if remember_username is enabled) + pub fn get_saved_username(&self) -> Option<String> { + self.current_session + .as_ref() + .and_then(|s| s.saved_username.clone()) + } + + /// Update session with new token (for token refresh) + #[allow(dead_code)] + pub fn update_token(&mut self, new_token: String) -> Result<()> { + if let Some(session) = &mut self.current_session { + let mut updated_session = session.clone(); + updated_session.token = new_token; + self.save_session(updated_session)?; + } + Ok(()) + } + + /// Update default printer ID + pub fn update_default_printer(&mut self, printer_id: Option<i64>) -> Result<()> { + if let Some(session) = &mut self.current_session { + let mut updated_session = session.clone(); + updated_session.default_printer_id = printer_id; + self.save_session(updated_session)?; + } + Ok(()) + } + + /// Get default printer ID + pub fn get_default_printer_id(&self) -> Option<i64> { + self.current_session + .as_ref() + .and_then(|s| s.default_printer_id) + } + + /// Get last-used printer ID for printing + pub fn get_last_print_preferences(&self) -> Option<i64> { + if let Some(session) = &self.current_session { + session.last_printer_id + } else { + None + } + } +} + +impl Default for SessionManager { + fn default() -> Self { + Self::new() + } +} |
