1use crate::tools::get_home;
2use anyhow::{Result, anyhow};
3use std::{
4 fs,
5 path::{Path, PathBuf},
6 time::{Duration, SystemTime},
7};
8
9pub fn get(key: &str) -> Result<String> {
13 let cache = get_cache_path(key)?;
14 if cache.exists() {
15 let metadata = fs::metadata(&cache);
16 let last_modified = metadata.map_or_else(
17 |_| SystemTime::now(),
18 |meta| meta.modified().unwrap_or_else(|_| SystemTime::now()),
19 );
20
21 let duration_since_modified = SystemTime::now()
23 .duration_since(last_modified)
24 .unwrap_or(Duration::from_secs(0));
25
26 if duration_since_modified > Duration::from_secs(30 * 24 * 60 * 60) {
28 Err(anyhow!("cache expired"))
29 } else {
30 Ok(fs::read_to_string(cache)?)
31 }
32 } else {
33 Err(anyhow!("cache not found"))
34 }
35}
36
37pub fn put(key: &str, response: &str) -> Result<()> {
41 let cache = get_cache_path(key)?;
42 if let Some(parent_dir) = std::path::Path::new(&cache).parent() {
44 fs::create_dir_all(parent_dir)?;
45 }
46 Ok(fs::write(cache, response)?)
47}
48
49fn get_cache_path(key: &str) -> Result<PathBuf> {
53 let ssh_vault = get_ssh_vault_path()?;
54 Ok(ssh_vault.join("keys").join(key))
55}
56
57fn get_ssh_vault_path() -> Result<PathBuf> {
61 let home = get_home()?;
62 Ok(Path::new(&home).join(".ssh").join("vault"))
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use std::fs;
69
70 #[test]
71 fn test_get_cache_path() -> Result<(), Box<dyn std::error::Error>> {
72 let cache = get_cache_path("test")?;
73 assert!(!cache.is_dir());
74 assert_eq!(
75 cache.to_str(),
76 get_home()?
77 .join(".ssh")
78 .join("vault")
79 .join("keys")
80 .join("test")
81 .to_str()
82 );
83 Ok(())
84 }
85
86 #[test]
87 fn test_get_ssh_vault_path() -> Result<(), Box<dyn std::error::Error>> {
88 let ssh_vault = get_ssh_vault_path()?;
89 assert!(!ssh_vault.is_file());
90 assert_eq!(
91 ssh_vault.to_str(),
92 get_home()?.join(".ssh").join("vault").to_str()
93 );
94 Ok(())
95 }
96
97 #[test]
98 fn test_put() -> Result<(), Box<dyn std::error::Error>> {
99 let cache = get_cache_path("test-2")?;
100 put("test-2", "test")?;
101
102 assert!(cache.is_file());
103 assert!(!cache.is_dir());
104 assert!(cache.exists());
105 assert_eq!(
106 cache.to_str(),
107 get_home()?
108 .join(".ssh")
109 .join("vault")
110 .join("keys")
111 .join("test-2")
112 .to_str()
113 );
114 fs::remove_file(cache)?;
115 Ok(())
116 }
117
118 #[test]
119 fn test_get() -> Result<(), Box<dyn std::error::Error>> {
120 let cache = get_cache_path("test-3")?;
121 put("test-3", "test")?;
122 let response = get("test-3")?;
123 assert_eq!(response, "test");
124 fs::remove_file(cache)?;
125 Ok(())
126 }
127}