aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2018-09-06 00:26:02 +0200
committerKatharina Fey <kookie@spacekookie.de>2018-09-06 00:26:02 +0200
commit8b9c8668e9a3aaa56a41be04859a05abb94db60c (patch)
tree6e1040187349f1debfe37314b1548cc47565a0ae
parent3e37ff9be9060ed8f26d10eb95c4b70219e0b1e2 (diff)
Refactoring the vault trait to consume a generator struct
-rw-r--r--lockchain-core/src/initialise.rs55
-rw-r--r--lockchain-core/src/lib.rs2
-rw-r--r--lockchain-core/src/traits.rs20
-rw-r--r--lockchain-core/src/users/keystore.rs70
-rw-r--r--lockchain-core/src/users/mod.rs137
-rw-r--r--lockchain-files/examples/create.rs4
6 files changed, 75 insertions, 213 deletions
diff --git a/lockchain-core/src/initialise.rs b/lockchain-core/src/initialise.rs
new file mode 100644
index 0000000..6ae48a9
--- /dev/null
+++ b/lockchain-core/src/initialise.rs
@@ -0,0 +1,55 @@
+//! A shared initialisation block for vaults
+//!
+//! All vaults, regardless of backends
+//! or persistence layer
+//! share the same common principles
+//! of users and permissions.
+//!
+//! This means that intiailisation is shared,
+//! regardless of what backend implements it.
+//!
+//! A `VaultGenerator` takes arguments
+//! for a generic backend,
+//! calls functions provided by said backend
+//! and then returns the actual backend.
+
+use traits::{Body, Vault};
+
+/// A generator is initialised with a generic backend
+/// which can then chain-call functions to setup the
+/// base functionality of a Vault, and then yield
+/// a working and initialised instance of the
+/// generic vault backend.
+pub struct Generator {
+ #[doc(hidden)]
+ pub name: Option<String>,
+ #[doc(hidden)]
+ pub location: Option<String>,
+}
+
+impl Generator {
+ /// Start a new generator for a generic type
+ pub fn new() -> Self {
+ Self {
+ name: None,
+ location: None,
+ }
+ }
+
+ pub fn path<S: Into<String>>(self, name: S, location: S) -> Self {
+ Self {
+ name: Some(name.into()),
+ location: Some(location.into()),
+ ..self
+ }
+ }
+
+ /// Finally call this function to construct the vault
+ pub fn finalise<V, B>(self) -> V
+ where
+ V: Vault<B>,
+ B: Body,
+ {
+ V::new(self)
+ }
+}
diff --git a/lockchain-core/src/lib.rs b/lockchain-core/src/lib.rs
index 2ec812e..9c9ba95 100644
--- a/lockchain-core/src/lib.rs
+++ b/lockchain-core/src/lib.rs
@@ -76,6 +76,8 @@ mod record;
pub mod traits;
pub mod users;
+mod initialise;
+
pub use self::crypto::PackedData;
pub use self::meta::{MetaDomain, VaultMetadata};
pub use self::record::{EncryptedBody, Header, Payload, Record};
diff --git a/lockchain-core/src/traits.rs b/lockchain-core/src/traits.rs
index 58b63b2..efde578 100644
--- a/lockchain-core/src/traits.rs
+++ b/lockchain-core/src/traits.rs
@@ -11,10 +11,11 @@
//! compilation work without external crates but not calling
//! functions at runtime.
+use initialise::Generator;
use meta::{MetaDomain, VaultMetadata};
use record::{EncryptedBody, Header, Payload, Record};
use serde::{de::DeserializeOwned, Serialize};
-use users::Token;
+use users::{Access, Token};
use base64;
use serde_json::{self, Error as SerdeError};
@@ -117,19 +118,28 @@ pub trait FileIO: AutoEncoder {
/// authentication will need to be backed by some persistence layer
/// (i.e. lockchain-files)
///
-///
pub trait Vault<T>: Send + LoadRecord<T>
where
T: Body,
{
- /// A shared constructor for all vault implementations
- fn new(name: &str, location: &str) -> Self;
+ /// Consumes a vault generator to construct a vault
+ fn new(cfg: Generator) -> Self;
/// Load and open an existing vault
fn load(name: &str, location: &str) -> Option<Box<Self>>;
/// Unlock the vault for a specific user
fn authenticate(&mut self, username: &str, secret: &str) -> Token;
/// End a specific user session
fn deauthenticate(&mut self, username: &str, _: Token);
+ /// Create a new user with a list of initial access rights
+ fn create_user(
+ &mut self,
+ token: Token,
+ username: &str,
+ secret: &str,
+ access: Vec<Access>,
+ ) -> Result<(), ()>;
+ /// Delete a user
+ fn delete_user(&mut self, token: Token, username: &str);
/// Get basic vault metadata
fn metadata(&self) -> VaultMetadata;
@@ -138,7 +148,7 @@ where
/// Pull a specific record from the backend
fn pull(&mut self, name: &str);
/// Sync all changes back to the backend
- ///
+ ///
/// Ultimately it's up to the backend to decide
/// how changes are synced.
/// It's free to ignore any sync requests
diff --git a/lockchain-core/src/users/keystore.rs b/lockchain-core/src/users/keystore.rs
deleted file mode 100644
index 7da77ec..0000000
--- a/lockchain-core/src/users/keystore.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-//! A keystore is a specific implementation of a metadata store
-//!
-//! At it's core it provides three simple functions
-//!
-//! - Adding keys for a user
-//! - Removing keys
-//! - Retrieving keys
-//!
-//! **This module is meant to be used by lockchain-library implementations**
-
-#![deprecated(since="0.10.0", note="Use the `userstore::UserStore` structure instead")]
-
-use traits::{AutoEncoder, Base64AutoEncoder};
-use {crypto::Key, meta::MetaDomain};
-
-use std::collections::HashMap;
-
-/// A utility wrapper around a Username -> Key collection
-#[derive(Serialize, Deserialize)]
-pub struct KeyStore {
- keys: HashMap<String, Key>,
-}
-
-impl KeyStore {
- pub fn add_key(&mut self, user: &str, key: Key) {
- self.keys.insert(user.into(), key);
- }
-
- pub fn revoke_key(&mut self, user: &str) {
- self.keys.remove(user);
- }
-}
-
-impl AutoEncoder for KeyStore {}
-
-impl From<MetaDomain> for KeyStore {
- fn from(d: MetaDomain) -> Self {
- Self {
- keys: d
- .all()
- .iter()
- .map(|(k, v)| {
- (
- k.clone(),
- match v {
- ::Payload::Text(s) => Key::decode(&String::from_base64(s)).unwrap(),
- _ => unreachable!(),
- },
- )
- })
- .collect(),
- }
- }
-}
-
-impl From<KeyStore> for MetaDomain {
- fn from(ks: KeyStore) -> Self {
- MetaDomain::new("keystore").fill(
- ks.keys
- .iter()
- .map(|(name, key)| {
- (
- name.clone(),
- ::Payload::Text(key.encode().unwrap().to_base64()),
- )
- })
- .collect(),
- )
- }
-}
diff --git a/lockchain-core/src/users/mod.rs b/lockchain-core/src/users/mod.rs
index 6482264..3fce31c 100644
--- a/lockchain-core/src/users/mod.rs
+++ b/lockchain-core/src/users/mod.rs
@@ -36,140 +36,3 @@ use {
meta::MetaDomain,
traits::{AutoEncoder, Base64AutoEncoder},
};
-
-/// A utility structure that manages users and can be derived
-/// from/into a metadata object. By default this process uses
-/// base64 encoding.
-///
-/// The workflow for this is to create a new `UserStore`, add
-/// users and then use `meta_push_domain` and give it the
-/// `UserStore::into()` which is then encoded automatically.
-/// The reverse action works the same way
-#[deprecated(since="0.10.0", note="Use the `userstore::UserStore` structure instead")]
-#[allow(deprecated)]
-#[derive(Serialize, Deserialize)]
-pub struct UserStore {
- /// A map between username – user item
- users: HashMap<String, User>,
- registry: HashMap<String, Vec<Access>>,
-}
-
-impl UserStore {
- /// Generate a sign-up token for a new user which needs to be
- /// provided in order for them to create an account.
- pub fn get_token(&mut self, access: Vec<Access>) -> String {
- let token = ::crypto::encoding::base64_encode(&::crypto::random::bytes(128));
- self.registry.insert(
- token.clone(),
- if access.is_empty() {
- vec![Access::Vault(Role::Reader)]
- } else {
- access
- },
- );
-
- token
- }
-
- pub fn get_user(&self, name: &str) -> Option<&User> {
- self.users.get(name)
- }
-
- pub fn get_all(&self) -> &HashMap<String, User> {
- &self.users
- }
-
- pub fn add(&mut self, user: User) -> Option<()> {
- self.users.insert(user.name.clone(), user);
- Some(())
- }
-}
-
-impl Default for UserStore {
- fn default() -> Self {
- Self {
- users: HashMap::new(),
- registry: HashMap::new(),
- }
- }
-}
-
-impl AutoEncoder for UserStore {}
-
-/// Allow users to turn MetaDomains
-/// that *are* userstores into a UserStore easily
-///
-/// Will most likely `panic!` if called on a non UserStore
-impl From<(MetaDomain, MetaDomain)> for UserStore {
- fn from((users, registry): (MetaDomain, MetaDomain)) -> Self {
- Self {
- users: users
- .all()
- .iter()
- .map(|(k, v)| {
- (
- k.clone(),
- match v {
- ::Payload::Text(s) => User::decode(&String::from_base64(s)).unwrap(),
- _ => unreachable!(),
- },
- )
- })
- .collect(),
- registry: registry
- .all()
- .iter()
- .map(|(k, v)| {
- (
- k.clone(),
- match v {
- ::Payload::List(regs) => regs
- .iter()
- .map(|reg| {
- Access::decode(&String::from_base64(match reg {
- ::Payload::Text(s) => s,
- _ => unreachable!(),
- })).unwrap()
- })
- .collect(),
- _ => unreachable!(),
- },
- )
- })
- .collect(),
- }
- }
-}
-
-impl From<UserStore> for (MetaDomain, MetaDomain) {
- fn from(us: UserStore) -> Self {
- (
- MetaDomain::new("userstore").fill(
- us.users
- .iter()
- .map(|(name, user)| {
- (
- name.clone(),
- ::Payload::Text(user.encode().unwrap().to_base64()),
- )
- })
- .collect(),
- ),
- MetaDomain::new("registry").fill(
- us.registry
- .iter()
- .map(|(name, reg)| {
- (
- name.clone(),
- ::Payload::List(
- reg.iter()
- .map(|reg| ::Payload::Text(reg.encode().unwrap().to_base64()))
- .collect(),
- ),
- )
- })
- .collect(),
- ),
- )
- }
-}
diff --git a/lockchain-files/examples/create.rs b/lockchain-files/examples/create.rs
index 5ced78a..b152cac 100644
--- a/lockchain-files/examples/create.rs
+++ b/lockchain-files/examples/create.rs
@@ -12,7 +12,9 @@ fn main() {
let path = env::args().nth(1).unwrap();
let name = env::args().nth(2).unwrap();
- let _vault: DataVault<EncryptedBody> = DataVault::new(&name, &path);
+ let vault: DataVault<EncryptedBody> = DataVault::new(&name, &path);
+
+