trellis_auth/
session_store.rs1use std::env;
2use std::fs;
3use std::path::{Path, PathBuf};
4
5use crate::{AdminSessionState, TrellisAuthError};
6
7fn cli_config_dir() -> PathBuf {
8 if let Ok(dir) = env::var("XDG_CONFIG_HOME") {
9 return PathBuf::from(dir).join("trellis");
10 }
11 if let Ok(home) = env::var("HOME") {
12 return PathBuf::from(home).join(".config/trellis");
13 }
14 PathBuf::from(".trellis")
15}
16
17fn admin_session_state_path() -> PathBuf {
18 cli_config_dir().join("admin-session.json")
19}
20
21fn write_private_file(path: &Path, contents: &str) -> Result<(), TrellisAuthError> {
22 if let Some(parent) = path.parent() {
23 fs::create_dir_all(parent)?;
24 }
25 fs::write(path, contents)?;
26 #[cfg(unix)]
27 {
28 use std::os::unix::fs::PermissionsExt;
29 fs::set_permissions(path, fs::Permissions::from_mode(0o600))?;
30 }
31 Ok(())
32}
33
34pub fn save_admin_session(state: &AdminSessionState) -> Result<(), TrellisAuthError> {
36 let state_json = serde_json::to_string_pretty(state)?;
37 write_private_file(&admin_session_state_path(), &state_json)
38}
39
40pub fn load_admin_session() -> Result<AdminSessionState, TrellisAuthError> {
42 let path = admin_session_state_path();
43 if !path.exists() {
44 return Err(TrellisAuthError::AuthFlowFailed(
45 "no stored admin session; run `trellis auth login`".to_string(),
46 ));
47 }
48 let state = fs::read_to_string(path)?;
49 Ok(serde_json::from_str(&state)?)
50}
51
52pub fn clear_admin_session() -> Result<bool, TrellisAuthError> {
54 let mut removed = false;
55 for path in [
56 admin_session_state_path(),
57 cli_config_dir().join("admin-sentinel.creds"),
58 ] {
59 if path.exists() {
60 fs::remove_file(path)?;
61 removed = true;
62 }
63 }
64 Ok(removed)
65}