#![doc = include_str!("README.md")]
mod crypto;
mod json;
mod kube;
mod map;
use std::path::Path;
use anyhow::Result;
pub use crypto::{Key, KeyPair};
pub use json::SecretsFile;
pub use kube::SecretsManifest;
pub use map::SecretsMap;
const NEW_LINE: &str = "\n";
const CARRIAGE_RETURN: &str = "\r";
pub fn compact() -> Result<impl Fn(String) -> Result<String>> {
Ok(|s: String| {
if s.contains(NEW_LINE) || s.contains(CARRIAGE_RETURN) {
return Ok(s
.trim()
.replace(NEW_LINE, r"\n")
.replace(CARRIAGE_RETURN, r"\r")
.to_string());
}
Ok(s)
})
}
pub fn encrypt(secrets_file: &SecretsFile) -> Result<impl Fn(String) -> Result<String>> {
let public_key = secrets_file.public_key().unwrap();
let ephemeral_key = KeyPair::generate()?;
let encryptor = ephemeral_key.encryptor(public_key)?;
Ok(move |s: String| {
if crypto::Message::is_valid(&s) {
return Ok(s);
}
encryptor.encrypt(s)
})
}
pub fn decrypt(secrets_file: &SecretsFile, private_key: Key) -> Result<impl Fn(String) -> Result<String>> {
let public_key = secrets_file.public_key().unwrap();
let decryptor = KeyPair::new(public_key, private_key).decryptor();
Ok(move |s: String| {
if !crypto::Message::is_valid(&s) {
return Ok(s);
}
decryptor.decrypt(s)
})
}
pub fn load_private_key(secrets_file: &SecretsFile, keydir: &str) -> Result<Key> {
let public_key = secrets_file.public_key().unwrap();
Key::from_file(Path::new(keydir).join(public_key.to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compact_transform() -> Result<()> {
let cases = [
("\n\n\n\r\r\n", ""),
("some\nstring", r"some\nstring"),
("some\r\nstring", r"some\r\nstring"),
];
let tf = compact()?;
cases.into_iter().try_for_each(|(given, want)| -> Result<()> {
assert_eq!(want, tf(given.to_string())?);
Ok(())
})
}
}