encrypted-json-kv 0.2.1

Easily store encrypted JSON blobs
Documentation
/********************************************************************************
 *   Encrypted KV store for json blobs based on sled                            *
 *   Copyright (C) 2020 Famedly GmbH                                            *
 *                                                                              *
 *   This program is free software: you can redistribute it and/or modify       *
 *   it under the terms of the GNU Affero General Public License as             *
 *   published by the Free Software Foundation, either version 3 of the         *
 *   License, or (at your option) any later version.                            *
 *                                                                              *
 *   This program is distributed in the hope that it will be useful,            *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               *
 *   GNU Affero General Public License for more details.                        *
 *                                                                              *
 *   You should have received a copy of the GNU Affero General Public License   *
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.     *
 ********************************************************************************/
use thiserror::Error;

use crate::{
    Database,
    DatabaseError,
    DatabaseOpenError,
    DatabaseSetPassphraseError,
    EncryptedValue,
    EncryptionError,

    crypto::derive_key,
};

#[derive(Error, Debug)]
pub enum TestError {
    #[error("something database")]
    Database(#[from] DatabaseError),
    #[error("something database init")]
    DatabaseOpen(#[from] DatabaseOpenError),
    #[error("something database passphrase change")]
    DatabaseSetPassphrase(#[from] DatabaseSetPassphraseError),
    #[error("something crypto")]
    Encryption(#[from] EncryptionError),
    #[error("something io")]
    Io(#[from] std::io::Error),
}

#[test]
fn test_database_temporary() -> Result<(), TestError> {
    let data = serde_json::json!({"test": true});
    let db = Database::temporary()?;
    assert!(db.get("test")?.is_none());
    db.insert("test", &data)?;
    assert_eq!(db.get("test")?.unwrap(), data);
    Ok(())
}

#[test]
fn test_new_database() -> Result<(), TestError> {
    let data = serde_json::json!({"test": true});
    let path = std::path::PathBuf::from("/tmp/encrypted-json-kv-rs-testdata");
    match std::fs::remove_dir_all(&path) {
        Ok(_) => (),
        Err(error) => match error.kind() {
            std::io::ErrorKind::NotFound => (),
            _ => Err(error)?,
        }
    };
    let db = Database::new(path, b"hello world")?;
    assert!(db.get("test")?.is_none());
    db.insert("test", &data)?;
    assert_eq!(db.get("test")?.unwrap(), data);
    db.set_passphrase(b"goodbye world")?;
    assert_eq!(db.get("test")?.unwrap(), data);
    Ok(())
}

#[test]
fn test_crypto() {
    let data = serde_json::json!({"test": true});
    let salt = sodiumoxide::crypto::pwhash::gen_salt();
    let key = derive_key(b"ohai!", salt);
    let ciphertext = EncryptedValue::encrypt(&data, &key);
    let string = dbg!(serde_json::to_string(&ciphertext).unwrap());
    let ciphertext: EncryptedValue = serde_json::from_str(&string).unwrap();
    let plaintext = ciphertext.decrypt(&key).unwrap();
    assert_eq!(data, plaintext);
}