Skip to main content

sentinelpass_protocol/
paths.rs

1//! Platform path helpers for the IPC socket and token file.
2
3use std::path::PathBuf;
4
5/// Directory holding user-level config files (IPC token, grants).
6///
7/// Mirrors `sentinelpass_core::platform::get_config_dir`; duplicated here so
8/// protocol clients do not need the core crate.
9pub fn get_config_dir() -> PathBuf {
10    let base = dirs::config_dir()
11        .or_else(dirs::data_dir)
12        .or_else(|| dirs::home_dir().map(|h| h.join(".config")))
13        .unwrap_or_else(|| PathBuf::from("."));
14
15    base.join("PasswordManager")
16}
17
18/// Get the default IPC socket path for the platform
19pub fn default_ipc_socket_path() -> PathBuf {
20    if cfg!(target_os = "windows") {
21        // Windows: Use named pipes with per-user ACLs
22        // Default to named pipe format; custom tcp://... paths still work as legacy fallback
23        PathBuf::from(r"\\.\pipe\SentinelPass")
24    } else {
25        // Unix: Use Unix domain socket
26        let runtime_dir = std::env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/tmp".to_string());
27
28        PathBuf::from(runtime_dir).join("sentinelpass.sock")
29    }
30}
31
32/// Get the default IPC auth token path for the platform
33pub fn default_ipc_token_path() -> PathBuf {
34    get_config_dir().join("ipc.token")
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[cfg(unix)]
42    #[test]
43    fn test_default_socket_path_unix() {
44        let path = default_ipc_socket_path();
45        assert!(path.to_string_lossy().ends_with("sentinelpass.sock"));
46    }
47
48    #[cfg(windows)]
49    #[test]
50    fn test_default_socket_path_windows() {
51        let path = default_ipc_socket_path();
52        assert!(path.to_string_lossy().contains("\\\\.\\pipe\\"));
53    }
54
55    #[test]
56    fn test_socket_path_with_xdg_runtime_dir() {
57        let custom_runtime = "/tmp/custom_runtime";
58        std::env::set_var("XDG_RUNTIME_DIR", custom_runtime);
59
60        let path = default_ipc_socket_path();
61
62        #[cfg(unix)]
63        {
64            let path_str = path.to_string_lossy();
65            assert!(path_str.contains(custom_runtime));
66        }
67
68        #[cfg(windows)]
69        {
70            // On Windows, just verify the function runs without error
71            let _ = path;
72        }
73
74        std::env::remove_var("XDG_RUNTIME_DIR");
75    }
76}