diff options
author | Katharina Fey <kookie@spacekookie.de> | 2018-05-07 02:31:44 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2018-05-07 02:31:44 +0200 |
commit | 6cebea193fb72f31f7a6eeb20eb53405367eb419 (patch) | |
tree | 62232d0d5f07f2c709c795b4d975512c953c88ed /lockchain-core | |
parent | c5f7d995dfcc0b4225e767428960449fa09ac206 (diff) |
Moving some stuff around and documenting the common lockchain-core code
Diffstat (limited to '')
-rw-r--r-- | lockchain-core/src/errors.rs | 27 | ||||
-rw-r--r-- | lockchain-core/src/lib.rs | 29 | ||||
-rw-r--r-- | lockchain-core/src/record.rs | 100 | ||||
-rw-r--r-- | lockchain-core/src/vault.rs | 60 | ||||
-rw-r--r-- | src/api/mod.rs (renamed from lockchain-core/src/api/mod.rs) | 0 | ||||
-rw-r--r-- | src/api/rest.rs (renamed from lockchain-core/src/api/rest.rs) | 0 | ||||
-rw-r--r-- | src/security/crypto.rs (renamed from lockchain-core/src/security/crypto.rs) | 0 | ||||
-rw-r--r-- | src/security/keys.rs (renamed from lockchain-core/src/security/keys.rs) | 0 | ||||
-rw-r--r-- | src/security/mod.rs (renamed from lockchain-core/src/security/mod.rs) | 0 | ||||
-rw-r--r-- | src/security/utils.rs (renamed from lockchain-core/src/security/utils.rs) | 0 | ||||
-rw-r--r-- | src/version.rs (renamed from lockchain-core/src/version.rs) | 0 |
11 files changed, 58 insertions, 158 deletions
diff --git a/lockchain-core/src/errors.rs b/lockchain-core/src/errors.rs new file mode 100644 index 0000000..7b59f66 --- /dev/null +++ b/lockchain-core/src/errors.rs @@ -0,0 +1,27 @@ +//! Common lockchain error handling +//! +//! When working with a lockchain vault or record set +//! there are a lot of things that can go wrong. +//! +//! This module handles any generic failure condition +//! and logic to escallate from one to the next, e.g. +//! turning a `VaultAlreadyExists` failure to +//! a `FailedInitialise`. + + +/// A collection of common error codes that can be +/// returned by lockchain API functions +pub struct Error { + VaultAlreadyExists, + InvalidPath, + InvalidName, + InvalidCryptoLayer, + FailedCrypto, + FailedSelfTest, + FailedLoading, + FailedInitalise, + FailedCreation, + UnknownFailure, + #[hidden_docs] + __NonExhaustive, +}
\ No newline at end of file diff --git a/lockchain-core/src/lib.rs b/lockchain-core/src/lib.rs index 76a08c5..e69de29 100644 --- a/lockchain-core/src/lib.rs +++ b/lockchain-core/src/lib.rs @@ -1,29 +0,0 @@ -//! Lockchain library core -//! -//! **Documentation TBD** -//! -//! In short: this crate handles handling of lockchain vaults. A vault -//! is a collection of secret records that can be searched in an efficient -//! manner, without ever having to keep the entire set in memory -//! in unencrypted form. -//! -//! This is primarily used in the lockchain password manager. - -extern crate serde; -extern crate serde_json; -#[macro_use] -extern crate serde_derive; -extern crate miscreant; -extern crate base64; -extern crate blake2; -extern crate chrono; -extern crate rand; - -pub mod version; -pub mod record; -pub mod vault; -pub mod security; - -// Export some commonly used types -pub use vault::{Vault, ErrorType}; -pub use record::Payload;
\ No newline at end of file diff --git a/lockchain-core/src/record.rs b/lockchain-core/src/record.rs index 5f721c0..5280406 100644 --- a/lockchain-core/src/record.rs +++ b/lockchain-core/src/record.rs @@ -1,14 +1,24 @@ -//! Lockchain record handling module +//! Common record representation inside of vaults. //! -//! A record is a set of key-value store values with a header +//! A record is a collection of data stored in a vault. It's +//! structured into a publicly known, unencrypted header and +//! a securely saved, encrypted body. +//! +//! While the `lockchain-server` never has access to the body data, +//! the header is stored and cached for make search requests faster. +//! +//! **No secret information should ever be stored in the header** use std::collections::BTreeMap; use chrono::{Local, DateTime}; -use serde_json; -/// A generic payload for a record +/// An enum that wraps around all possible data types to store +/// as the value of a vault record. +/// +/// This doesn't include metadata attached to a field, just the +/// data representation itself (i.e. text, number or sub data-tree) #[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)] pub enum Payload { Text(String), @@ -17,13 +27,17 @@ pub enum Payload { BTreeMap(BTreeMap<String, Payload>), } -/// The header of a record +/// The public header of a record /// -/// Contains easily searchable fields of metadata. Nothing -/// in the Header should ever be considered secure as the -/// headers are kept cached for much longer than the rest -/// of the data. -#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +/// A header consists of always-available fields that +/// are hard-defined in the lockchain file format as well +/// as custom fields that can be declared by each application +/// specifically. +/// +/// You should never rely on the presence of custom fields as +/// older version of the software might not support them or +/// know about them! +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)] pub struct Header { pub name: String, pub category: String, @@ -33,67 +47,15 @@ pub struct Header { pub date_updated: DateTime<Local>, } +/// Represents a whole record in memory /// +/// The body field can be `None` if it hasn't been cached +/// yet. Calling `body()` will either resolve the data from disk +/// or still return `None` if the current setting doesn't support +/// body loading (such as the `lockchain-server` which has no +/// cryptocraphy subsystem) #[derive(Debug, Serialize, Deserialize)] pub struct Record { pub header: Header, - pub body: BTreeMap<String, Payload>, -} - - -impl Header { - - /// Create a new header with a name of a category - pub fn new(name: String, category: String) -> Header { - let me = Header { - name: name, - category: category, - tags: Vec::new(), - fields: BTreeMap::new(), - date_created: Local::now(), - date_updated: Local::now(), - }; - - return me; - } -} - -impl PartialEq for Record { - fn eq(&self, other: &Record) -> bool { - self.header == other.header - } + pub body: Option<BTreeMap<String, Payload>>, } - -impl Record { - - /// Create a new record - pub fn new(name: &str, category: &str) -> Record { - return Record { - header: Header::new(String::from(name), String::from(category)), - // fields: BTreeMap::new(), - body: BTreeMap::new(), - }; - } - - /// Set a simple key-value pair - pub fn set_data(&mut self, key: &str, val: Payload) { - self.body.insert(String::from(key), val); - } - - /// Contains a cloned value of single data field - pub fn get_data(&self, key: &str) -> Payload { - return self.body.get(key).unwrap().clone(); - } - - /// Serialise the entire body into a json tree - /// - /// Contains all secret values in a json tree that you can work with manually. - pub fn get_json(&self) -> String { - return serde_json::to_string(&self.body).unwrap(); - } - - /// Add a new tag to this record head. Checks that tags don't already exists - pub fn add_tag(&mut self, tag: &str) { - self.header.tags.push(String::from(tag)); - } -}
\ No newline at end of file diff --git a/lockchain-core/src/vault.rs b/lockchain-core/src/vault.rs index a027617..400f230 100644 --- a/lockchain-core/src/vault.rs +++ b/lockchain-core/src/vault.rs @@ -121,64 +121,4 @@ impl Vault { r.set_data(key, data); } - /// Sync current records to disk, overwriting existing files - pub fn sync(&mut self) { - let mut buffer = PathBuf::new(); - buffer.push(&self.path); - buffer.push("records"); - - for (name, record) in &self.records { - let encrypted = self.engine.encrypt(&record).unwrap(); - - /* <vault>/records/<name>.data */ - { - buffer.push(&format!("{}.data", name)); - let file = buffer.as_path(); - // println!("Saving file '{}' to '{}'", name, file.to_str().unwrap()); - - let mut handle = match file.exists() { - true => match File::open(file.as_os_str()) { - Ok(k) => k, - Err(e) => panic!("Failed to open file: {}", e), - }, - false => match File::create(file.as_os_str()) { - Ok(k) => k, - Err(e) => panic!("Failed to create file ({:?}): {}", file.as_os_str(), e), - }, - }; - - /* Write to disk */ - match handle.write_all(encrypted.as_bytes()) { - Err(e) => println!("An error was encountered while writing '{}': {}", name, e), - _ => {} - } - } - - buffer.pop(); - } - } - - /**************************/ - - /// Create all relevant directories - fn create_dirs(&mut self) -> ErrorType { - let mut path = PathBuf::new(); - path.push(&self.path); - - /* Check if the directories already exist */ - if path.as_path().exists() { - return ErrorType::DirectoryAlreadyExists; - } - - /* Create the directory */ - match fs::create_dir_all(path.as_path()) { - Err(_) => return ErrorType::FailedToInitialise, - _ => {} - }; - - /* Create a few other directories */ - path.push("records"); - fs::create_dir_all(path.as_path()).unwrap(); - return ErrorType::Success; - } } diff --git a/lockchain-core/src/api/mod.rs b/src/api/mod.rs index 114aa2b..114aa2b 100644 --- a/lockchain-core/src/api/mod.rs +++ b/src/api/mod.rs diff --git a/lockchain-core/src/api/rest.rs b/src/api/rest.rs index 5ff577d..5ff577d 100644 --- a/lockchain-core/src/api/rest.rs +++ b/src/api/rest.rs diff --git a/lockchain-core/src/security/crypto.rs b/src/security/crypto.rs index 23848f5..23848f5 100644 --- a/lockchain-core/src/security/crypto.rs +++ b/src/security/crypto.rs diff --git a/lockchain-core/src/security/keys.rs b/src/security/keys.rs index bde3e69..bde3e69 100644 --- a/lockchain-core/src/security/keys.rs +++ b/src/security/keys.rs diff --git a/lockchain-core/src/security/mod.rs b/src/security/mod.rs index 0f141ca..0f141ca 100644 --- a/lockchain-core/src/security/mod.rs +++ b/src/security/mod.rs diff --git a/lockchain-core/src/security/utils.rs b/src/security/utils.rs index 36e611c..36e611c 100644 --- a/lockchain-core/src/security/utils.rs +++ b/src/security/utils.rs diff --git a/lockchain-core/src/version.rs b/src/version.rs index 00c2d77..00c2d77 100644 --- a/lockchain-core/src/version.rs +++ b/src/version.rs |