keeper_secrets_manager_core/
cache.rs1use crate::custom_error::KSMRError;
14use serde::{Deserialize, Serialize};
15use std::fs::{File, OpenOptions};
16use std::io::{Read, Write};
17use std::path::{Path, PathBuf};
18use std::{env, fs};
19
20const DEFAULT_FILE_PATH: &str = "ksm_cache.bin";
21
22#[derive(Clone, Debug)]
23pub enum KSMCache {
24 File(FileCache),
25 Memory(MemoryCache),
26 None,
27}
28
29impl KSMCache {
30 pub fn is_none(&self) -> bool {
31 matches!(self, KSMCache::None)
37 }
38}
39
40#[derive(Debug)]
41pub struct KSMRCache {
42 cache: KSMCache,
43}
44
45impl KSMCache {
46 pub fn save_cached_value(&mut self, data: &[u8]) -> Result<(), KSMRError> {
47 match self {
48 KSMCache::File(file_cache) => file_cache.save_cached_value(data),
49 KSMCache::Memory(memory_cache) => memory_cache.save_cached_value(data),
50 KSMCache::None => Err(KSMRError::CacheSaveError(
51 "No cache available for saving data.".to_string(),
52 )),
53 }
54 }
55
56 pub fn get_cached_value(&self) -> Result<Vec<u8>, KSMRError> {
57 match self {
58 KSMCache::File(file_cache) => file_cache.get_cached_value(),
59 KSMCache::Memory(memory_cache) => memory_cache.get_cached_value(),
60 KSMCache::None => Err(KSMRError::CacheRetrieveError(
61 "No cache available for retrieving data.".to_string(),
62 )),
63 }
64 }
65
66 pub fn purge(&mut self) -> Result<(), KSMRError> {
67 match self {
68 KSMCache::File(file_cache) => file_cache.purge(),
69 KSMCache::Memory(memory_cache) => memory_cache.purge(),
70 KSMCache::None => Ok(()), }
72 }
73}
74
75impl KSMRCache {
76 pub fn new_file_cache(file_path: Option<&str>) -> Result<Self, KSMRError> {
77 let file_cache = FileCache::new(file_path.unwrap_or(DEFAULT_FILE_PATH))?;
78 Ok(Self {
79 cache: KSMCache::File(file_cache),
80 })
81 }
82
83 pub fn new_memory_cache() -> Result<Self, KSMRError> {
85 Ok(Self {
86 cache: KSMCache::Memory(MemoryCache::new()),
87 })
88 }
89
90 pub fn new_none() -> Self {
91 Self {
92 cache: KSMCache::None,
93 }
94 }
95
96 pub fn save_cached_value(&mut self, data: &[u8]) -> Result<(), KSMRError> {
97 match &mut self.cache {
98 KSMCache::File(file_cache) => file_cache.save_cached_value(data),
99 KSMCache::Memory(memory_cache) => memory_cache.save_cached_value(data),
100 KSMCache::None => Err(KSMRError::CacheSaveError(
101 "No cache available for saving data.".to_string(),
102 )),
103 }
104 }
105
106 pub fn get_cached_value(&self) -> Result<Vec<u8>, KSMRError> {
107 match &self.cache {
108 KSMCache::File(file_cache) => file_cache.get_cached_value(),
109 KSMCache::Memory(memory_cache) => memory_cache.get_cached_value(),
110 KSMCache::None => Err(KSMRError::CacheRetrieveError(
111 "No cache available for retrieving data.".to_string(),
112 )),
113 }
114 }
115
116 pub fn purge(&mut self) -> Result<(), KSMRError> {
117 match &mut self.cache {
118 KSMCache::File(file_cache) => file_cache.purge(),
119 KSMCache::Memory(memory_cache) => memory_cache.purge(),
120 KSMCache::None => Ok(()), }
122 }
123}
124
125impl From<KSMRCache> for KSMCache {
126 fn from(ksmr_cache: KSMRCache) -> Self {
127 ksmr_cache.cache
128 }
129}
130
131impl From<KSMCache> for KSMRCache {
132 fn from(ksm_cache: KSMCache) -> Self {
133 KSMRCache { cache: ksm_cache }
134 }
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct FileCache {
140 file_path: String,
141}
142
143impl FileCache {
144 pub fn new(file_path: &str) -> Result<Self, KSMRError> {
145 let mut path = file_path.trim().to_string();
146
147 if path.is_empty() {
148 path = DEFAULT_FILE_PATH.to_string();
149 }
150
151 if !Path::new(&path).is_absolute() {
152 if let Ok(ksm_cache_dir) = env::var("KSM_CACHE_DIR") {
153 let ksm_cache_dir = ksm_cache_dir.trim();
154 if !ksm_cache_dir.is_empty() {
155 path = PathBuf::from(ksm_cache_dir)
156 .join(&path)
157 .to_string_lossy()
158 .to_string();
159 }
160 }
161 }
162 let mut file_opened = match File::open(path.clone()) {
163 Ok(resp) => resp,
164 Err(err) => {
165 if err.to_string().contains("No such file or directory")
166 || err
167 .to_string()
168 .contains("The system cannot find the file specified")
169 {
170 let file = OpenOptions::new()
171 .read(true) .write(true) .create(true) .truncate(true).open(file_path).map_err(|err| KSMRError::CacheSaveError(format!("Error creating cache file in location mentioned {} and exited with error {}.", file_path,err))).unwrap();
176 file
177 } else {
178 panic!("{}", err);
179 }
180 }
181 };
182
183 file_opened.flush().unwrap();
184
185 Ok(FileCache { file_path: path })
186 }
187
188 pub fn save_cached_value(&self, data: &[u8]) -> Result<(), KSMRError> {
189 let data = if data.is_empty() { &[] } else { data };
190 let mut file =
191 File::create(&self.file_path).map_err(|e| KSMRError::CacheSaveError(e.to_string()))?;
192 file.write_all(data)
193 .map_err(|e| KSMRError::CacheSaveError(e.to_string()))?;
194 Ok(())
195 }
196
197 pub fn get_cached_value(&self) -> Result<Vec<u8>, KSMRError> {
198 let mut file = File::open(&self.file_path)
199 .map_err(|e| KSMRError::CacheRetrieveError(e.to_string()))?;
200 let mut data = Vec::new();
201 file.read_to_end(&mut data)
202 .map_err(|e| KSMRError::CacheRetrieveError(e.to_string()))?;
203 Ok(data)
204 }
205
206 pub fn purge(&self) -> Result<(), KSMRError> {
207 if Path::new(&self.file_path).exists() {
208 fs::remove_file(&self.file_path)
209 .map_err(|e| KSMRError::CachePurgeError(e.to_string()))?;
210 }
211 Ok(())
212 }
213}
214
215#[derive(Debug, Clone, Default, Serialize, Deserialize)]
217pub struct MemoryCache {
218 data: Vec<u8>,
219}
220
221impl MemoryCache {
222 pub fn new() -> Self {
223 Self { data: Vec::new() }
224 }
225
226 pub fn save_cached_value(&mut self, data: &[u8]) -> Result<(), KSMRError> {
227 self.data.clear();
228 self.data.extend_from_slice(data);
229 Ok(())
230 }
231
232 pub fn get_cached_value(&self) -> Result<Vec<u8>, KSMRError> {
233 Ok(self.data.clone())
234 }
235
236 pub fn purge(&mut self) -> Result<(), KSMRError> {
237 self.data.clear();
238 Ok(())
239 }
240}