diff options
Diffstat (limited to 'lockchain-core/src/users')
-rw-r--r-- | lockchain-core/src/users/keystore.rs | 65 | ||||
-rw-r--r-- | lockchain-core/src/users/mod.rs | 32 | ||||
-rw-r--r-- | lockchain-core/src/users/rights.rs | 22 | ||||
-rw-r--r-- | lockchain-core/src/users/secrets.rs | 32 | ||||
-rw-r--r-- | lockchain-core/src/users/store.rs | 39 |
5 files changed, 168 insertions, 22 deletions
diff --git a/lockchain-core/src/users/keystore.rs b/lockchain-core/src/users/keystore.rs new file mode 100644 index 0000000..71d7be2 --- /dev/null +++ b/lockchain-core/src/users/keystore.rs @@ -0,0 +1,65 @@ +//! 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 + +use traits::{AutoEncoder, Base64AutoEncoder}; +use {crypto::Key, meta::MetaDomain}; + +use std::collections::HashMap; + +#[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 338cc5e..e9205d1 100644 --- a/lockchain-core/src/users/mod.rs +++ b/lockchain-core/src/users/mod.rs @@ -14,10 +14,19 @@ //! data to load and store them into a metadata store. mod auth; +mod rights; mod tokens; +mod keystore; + +mod store; +mod secrets; + pub use self::auth::pam_authenticate; +pub use self::keystore::KeyStore; pub use self::tokens::Token; + pub use errors::AuthError; +pub use self::rights::{Access, Role}; use crypto::{encoding, hashing, random}; use std::collections::HashMap; @@ -26,27 +35,6 @@ use { traits::{AutoEncoder, Base64AutoEncoder}, }; -/// Specifies access to a resource -#[derive(Hash, Serialize, Deserialize, Clone, PartialEq, Eq)] -pub enum Access { - /// Allows access to vault metadata & index files - Vault(Role), - /// Allows access to a record resource inside a vault - Record(Role, String), -} - -impl AutoEncoder for Access {} - -/// Specifies the capabilities of a user -#[derive(Hash, Serialize, Deserialize, Clone, PartialEq, Eq)] -pub enum Role { - Reader, - Editor, - Admin, -} - -impl AutoEncoder for Role {} - /// A generic user representation /// /// A user has an identify check built in that can verify a passphrase @@ -83,7 +71,7 @@ impl User { self.pw_hash == encoding::base64_encode(&hashing::blake2(pw, &self.name).to_vec()) } /// Provides a hook to use second-factor authentication to authorise - /// + /// /// This is meant to be used with an external Yubikey pub fn second_auth_verify(&mut self) -> bool { unimplemented!() diff --git a/lockchain-core/src/users/rights.rs b/lockchain-core/src/users/rights.rs new file mode 100644 index 0000000..4404253 --- /dev/null +++ b/lockchain-core/src/users/rights.rs @@ -0,0 +1,22 @@ +use traits::AutoEncoder; + +/// Specifies access to a resource +#[derive(Hash, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub enum Access { + /// Allows access to vault metadata & index files + Vault(Role), + /// Allows access to a record resource inside a vault + Record(Role, String), +} + +impl AutoEncoder for Access {} + +/// Specifies the capabilities of a user +#[derive(Hash, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub enum Role { + Reader, + Editor, + Admin, +} + +impl AutoEncoder for Role {} diff --git a/lockchain-core/src/users/secrets.rs b/lockchain-core/src/users/secrets.rs new file mode 100644 index 0000000..8210a09 --- /dev/null +++ b/lockchain-core/src/users/secrets.rs @@ -0,0 +1,32 @@ +use traits::AutoEncoder; + +/// Specifies the type of secret that's used to derive a vault user secret +#[derive(Serialize, Deserialize)] +pub enum SecretType { + /// A simple password + Plain, + /// A keyfile that allows asymetric trust operations + Keyfile, + /// Signing a user password with the id of a yubikey + Combine, +} + +impl AutoEncoder for SecretType {} + +/// The backing secret for user authentication +/// +/// This is _always_ in a non-recoverable form, i.e. a hash +/// and salted password. **However** it does reveal something +/// about the user setup, i.e. the type of secret used. +/// +/// Depending on what secret is used, there are other operations that +/// might be supported to verify operations. For example, a `Keyfile` +/// secret can deposit the entire public key in the `content` field, +/// then use asymmetric operations to verify operations more thoroughly. +#[derive(Serialize, Deserialize)] +pub struct UserSecret { + tt: SecretType, + content: String, +} + +impl AutoEncoder for UserSecret {} diff --git a/lockchain-core/src/users/store.rs b/lockchain-core/src/users/store.rs new file mode 100644 index 0000000..d400668 --- /dev/null +++ b/lockchain-core/src/users/store.rs @@ -0,0 +1,39 @@ +use super::rights::Access; +use super::secrets::SecretType; +use crypto::Key; +use std::collections::HashMap; + +/// A thin user keystore +/// +/// It's implementation can manage multiple keys per user, of various +/// types and constrained for limited access rights. +pub struct KeyStore { + store: HashMap<String, StoreUser>, +} + +struct StoreUser { + name: String, + keys: HashMap<Access, Key>, +} + +impl KeyStore { + /// Create a new, empty keystore + /// + /// This is most likely *not* what you want. Instead, transform + /// a `MetaData` object into a keystore. + pub fn new() -> Self { + Self { + store: HashMap::new(), + } + } + + pub fn add_user(&mut self) {} + + pub fn rm_user(&mut self) {} + + pub fn add_key(&mut self, user: String, k: Key, access: Access) {} + + pub fn get_key(&self, user: String, access: Access) -> &Key { + unimplemented!() + } +} |