secure-env 0.2.2

Encrypted environment variables manager for your shell
Documentation
use secrecy::SecretString;
use secure_env::{crypto, store};
use std::collections::BTreeMap;

fn sample_sets() -> store::Sets {
    BTreeMap::from([
        (
            "db".to_string(),
            BTreeMap::from([
                ("HOST".to_string(), "localhost".to_string()),
                ("PORT".to_string(), "5432".to_string()),
            ]),
        ),
        (
            "app".to_string(),
            BTreeMap::from([
                ("API_KEY".to_string(), "s3cr3t!@#$%^&*()_+".to_string()),
                (
                    "GREETING".to_string(),
                    "hello 'world' with \"quotes\" and emoji 🚀".to_string(),
                ),
            ]),
        ),
    ])
}

#[test]
fn encrypt_then_decrypt_preserves_values() {
    let sets = sample_sets();
    let passphrase = SecretString::from("correct horse battery staple".to_owned());

    let toml = store::to_toml(&sets);
    let ciphertext = crypto::encrypt(toml.as_bytes(), passphrase.clone()).unwrap();
    let plaintext = crypto::decrypt(&ciphertext, passphrase).unwrap();

    assert_eq!(plaintext, toml.as_bytes());
    let decrypted = store::from_toml(&plaintext).unwrap();
    assert_eq!(decrypted, sets);
}

#[test]
fn wrong_passphrase_fails_to_decrypt() {
    let ciphertext = crypto::encrypt(
        b"secret data",
        SecretString::from("right passphrase".to_owned()),
    )
    .unwrap();

    assert!(crypto::decrypt(&ciphertext, SecretString::from("wrong passphrase".to_owned())).is_err());
}

#[test]
fn file_roundtrip_with_atomic_write() {
    let dir = tempfile::tempdir().unwrap();
    let path = dir.path().join("secure-env.enc");
    let passphrase = SecretString::from("file roundtrip passphrase".to_owned());

    let sets = sample_sets();
    let toml = store::to_toml(&sets);
    let ciphertext = crypto::encrypt(toml.as_bytes(), passphrase.clone()).unwrap();
    store::atomic_write(&path, &ciphertext).unwrap();

    let loaded = store::read_plain(&path, passphrase).unwrap().unwrap();
    assert_eq!(loaded, sets);
}