aboutsummaryrefslogtreecommitdiff
path: root/lockchain-core/src/users/user.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lockchain-core/src/users/user.rs')
-rw-r--r--lockchain-core/src/users/user.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/lockchain-core/src/users/user.rs b/lockchain-core/src/users/user.rs
new file mode 100644
index 0000000..1f7c9a5
--- /dev/null
+++ b/lockchain-core/src/users/user.rs
@@ -0,0 +1,80 @@
+//! User representation module
+
+use super::rights::{Access, Role};
+use crypto::{encoding, hashing, random};
+use std::collections::HashMap;
+use traits::AutoEncoder;
+
+/// A generic user representation
+///
+/// A user has an identify check built in
+/// that can verify a passphrase
+/// but is ultimately only a metadata item for a API layers.
+/// Any layer is free to disregard these access rights
+/// (as such, they should not be considered security,
+/// only obscurity/ management control)
+///
+/// A company might not want to allow non-admins
+/// to create new vaults or users to delete records.
+/// This does not cryptographically stop anyone
+/// from breaking into the company server,
+/// swapping the source code and
+/// changing the rules!
+///
+/// An user can have multiple role-access pairs.
+///
+/// A user can be stored in a `UserStore`,
+/// along-side authorised keys
+#[derive(Serialize, Deserialize, Clone)]
+pub struct User {
+ #[doc(hidden)]
+ pub name: String,
+ #[doc(hidden)]
+ pub pw_hash: String,
+ #[doc(hidden)]
+ pub rights: HashMap<Access, Role>,
+ #[doc(hidden)]
+ pub token: Option<String>,
+}
+
+impl User {
+ /// Register a new user with a name and password
+ pub fn register(name: &str, pw: &str) -> Self {
+ Self {
+ name: name.into(),
+ pw_hash: encoding::base64_encode(&hashing::blake2(pw, name).to_vec()),
+ rights: HashMap::new(),
+ token: None,
+ }
+ }
+ /// Verify a user password input
+ pub fn verify(&self, pw: &str) -> bool {
+ 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!()
+ }
+ /// Generate a token unique to this user (or return the existing one)
+ pub fn token(&mut self) -> String {
+ if self.token.is_none() {
+ self.token = Some(encoding::base64_encode(&random::bytes(256)));
+ }
+
+ self.token.as_ref().unwrap().clone()
+ }
+ /// Verify that a user is allowed access to a piece of data
+ ///
+ /// `None` means "no access of any kind"
+ pub fn has_access(&self, item: Access) -> Option<Role> {
+ self.rights.get(&item).map(|i| i.clone())
+ }
+ /// Modify access to an item for a role or create a new access entry
+ pub fn give_access(&mut self, item: Access, role: Role) {
+ self.rights.insert(item, role);
+ }
+}
+
+impl AutoEncoder for User {}