aboutsummaryrefslogtreecommitdiff
path: root/lockchain-core/src/users
diff options
context:
space:
mode:
Diffstat (limited to 'lockchain-core/src/users')
-rw-r--r--lockchain-core/src/users/keystore.rs65
-rw-r--r--lockchain-core/src/users/mod.rs32
-rw-r--r--lockchain-core/src/users/rights.rs22
-rw-r--r--lockchain-core/src/users/secrets.rs32
-rw-r--r--lockchain-core/src/users/store.rs39
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!()
+ }
+}