Skip to main content

trellis_auth/
session_store.rs

1use 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
34/// Persist an admin session to the CLI config directory.
35pub 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
40/// Load the current admin session from disk.
41pub 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
52/// Remove the stored admin session and related local credential files.
53pub 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}