encrypt_config/
source.rs

1//! Source module for the encrypt-config crate.
2
3#[cfg(feature = "secret")]
4use crate::encrypt_utils::Encrypter;
5#[cfg(feature = "persist")]
6use serde::{de::DeserializeOwned, Serialize};
7#[cfg(feature = "persist")]
8use std::path::PathBuf;
9
10pub use rom_cache::Cacheable;
11
12/// Normal source trait.
13pub trait NormalSource: rom_cache::Cacheable {}
14
15/// Persist source trait.
16#[cfg(feature = "persist")]
17pub trait PersistSource: rom_cache::Cacheable + Serialize + DeserializeOwned {
18    /// Path for the persist source.
19    #[cfg(not(feature = "default_config_dir"))]
20    const PATH: &'static str;
21    /// Name for the persist source.
22    #[cfg(feature = "default_config_dir")]
23    const NAME: &'static str;
24
25    /// Path for the persist source.
26    fn path() -> PathBuf {
27        #[cfg(not(feature = "default_config_dir"))]
28        {
29            PathBuf::from(Self::PATH)
30        }
31        #[cfg(feature = "default_config_dir")]
32        {
33            dirs::config_dir()
34                .expect("Default config dir unknown in your OS.")
35                .join(Self::NAME)
36        }
37    }
38    /// Load the persist source.
39    fn load() -> std::io::Result<Self> {
40        let path = Self::path();
41        let file = std::fs::File::open(path)?;
42        Ok(serde_json::from_reader(file)?)
43    }
44    /// Save the persist source.
45    fn store(&self) -> std::io::Result<()> {
46        let path = Self::path();
47        let parent = path.parent().unwrap();
48        std::fs::create_dir_all(parent)?;
49        let file = std::fs::File::create(path)?;
50        serde_json::to_writer(file, self)?;
51        Ok(())
52    }
53}
54
55/// Secret source trait.
56#[cfg(feature = "secret")]
57pub trait SecretSource: rom_cache::Cacheable + Serialize + DeserializeOwned {
58    /// Path for the persist source.
59    #[cfg(not(feature = "default_config_dir"))]
60    const PATH: &'static str;
61    /// Name for the persist source.
62    #[cfg(feature = "default_config_dir")]
63    const NAME: &'static str;
64    /// Keyring entry for the secret source.
65    const KEYRING_ENTRY: &'static str;
66
67    /// Path for the persist source.
68    fn path() -> PathBuf {
69        #[cfg(not(feature = "default_config_dir"))]
70        {
71            PathBuf::from(Self::PATH)
72        }
73        #[cfg(feature = "default_config_dir")]
74        {
75            dirs::config_dir()
76                .expect("Default config dir unknown in your OS.")
77                .join(Self::NAME)
78        }
79    }
80    /// Load the secret source.
81    fn load() -> ::std::io::Result<Self> {
82        let path = Self::path();
83        let encrypter =
84            Encrypter::new(Self::KEYRING_ENTRY).map_err(|_| std::io::ErrorKind::InvalidData)?;
85        let file = std::fs::File::open(path)?;
86        let encrypted: Vec<u8> = std::io::Read::bytes(file).collect::<Result<_, _>>()?;
87        encrypter
88            .decrypt(&encrypted)
89            .map_err(|_| std::io::ErrorKind::InvalidData.into())
90    }
91    /// Save the secret source.
92    fn store(&self) -> ::std::io::Result<()> {
93        use std::io::Write as _;
94
95        let path = Self::path();
96        let parent = path.parent().unwrap();
97        std::fs::create_dir_all(parent)?;
98        let encrypter =
99            Encrypter::new(Self::KEYRING_ENTRY).map_err(|_| std::io::ErrorKind::InvalidData)?;
100        let encrypted = encrypter
101            .encrypt(self)
102            .map_err(|_| std::io::ErrorKind::InvalidData)?;
103        let mut file = std::fs::File::create(path)?;
104        file.write_all(&encrypted)?;
105        file.flush()?;
106        Ok(())
107    }
108}