aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2018-07-10 20:47:13 +0200
committerKatharina Fey <kookie@spacekookie.de>2018-07-10 20:47:13 +0200
commite1e9c73476ba2792c3582ee7ecd14d0b39c3eef4 (patch)
tree39237e46485669260da5038cb011d8382f879a7a
parent7dfaacb94c8e4a37fb68fcaa7435c8cc8a08e7f9 (diff)
Adding an example of how to register a user and adding new metadata
vault endpoints functions
-rw-r--r--lockchain-core/examples/user_registry.rs33
-rw-r--r--lockchain-core/src/meta.rs2
-rw-r--r--lockchain-core/src/traits.rs2
-rw-r--r--lockchain-core/src/users/mod.rs19
-rw-r--r--lockchain-files/examples/create.rs23
-rw-r--r--lockchain-files/examples/register_user.rs0
-rw-r--r--lockchain-files/src/lib.rs4
-rw-r--r--lockchain-http/src/handlers.rs81
-rw-r--r--lockchain-http/src/lib.rs17
9 files changed, 158 insertions, 23 deletions
diff --git a/lockchain-core/examples/user_registry.rs b/lockchain-core/examples/user_registry.rs
new file mode 100644
index 0000000..8bb5c69
--- /dev/null
+++ b/lockchain-core/examples/user_registry.rs
@@ -0,0 +1,33 @@
+//! User registry in a vault is done via the metadata store
+//!
+//! In addition to that the `lockchain-core ` provides some simple
+//! utilities to manage Users and UserStore objects, mapping them
+//! onto metadata stores.
+//!
+//! In this example we will define a function that takes a generic
+//! Vault implementation backend (because lockchain-core doesn't
+//! provide a concrete way of doing this) and registering a user
+//! into it.
+//!
+//! Please note you can't actually _run_ this code example, because
+//! no concrete type can be known. The exact same example (with a type)
+//! can however be found in `lockchain-files`
+
+
+extern crate lockchain_core as lockchain;
+use lockchain::users::{User, UserStore, Access, Role};
+use lockchain::traits::Vault;
+use lockchain::EncryptedBody;
+
+fn main() {
+ // register(your_vault_here, "spacekookie", "password");
+}
+
+/// This function takes a generic Vault which MUST implement
+/// the EncryptedBody backend. This would normally be the case
+/// for the `DataVault` provided by `lockchain-files`
+fn register<V: Vault<EncryptedBody>>(vault: &mut V, username: &str, password: &str) {
+ let me = User::register(username, password);
+}
+
+
diff --git a/lockchain-core/src/meta.rs b/lockchain-core/src/meta.rs
index cf3eb36..317e821 100644
--- a/lockchain-core/src/meta.rs
+++ b/lockchain-core/src/meta.rs
@@ -32,7 +32,7 @@ pub struct VaultMetadata {
///
/// It implements a series of traits which means it's possible to easily
/// interact with to store data.
-#[derive(Debug, Serialize, Deserialize)]
+#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct MetaDomain {
/// The name of this meta domain
name: String,
diff --git a/lockchain-core/src/traits.rs b/lockchain-core/src/traits.rs
index 4e66d8f..088ee84 100644
--- a/lockchain-core/src/traits.rs
+++ b/lockchain-core/src/traits.rs
@@ -148,6 +148,8 @@ where
fn meta_set(&mut self, domain: &str, name: &str, data: Payload) -> Option<()>;
/// Get the value of a (unique) field inside a domain
fn meta_get(&mut self, domain: &str, name: &str) -> Option<Payload>;
+ /// Check if a metadomain exists, regardless of data or depth
+ fn meta_exists(&self, domain: &str) -> bool;
}
/// Auto-implement this trait to serialise types to json
diff --git a/lockchain-core/src/users/mod.rs b/lockchain-core/src/users/mod.rs
index a5cf79e..630e2a8 100644
--- a/lockchain-core/src/users/mod.rs
+++ b/lockchain-core/src/users/mod.rs
@@ -21,7 +21,10 @@ pub use errors::AuthError;
use crypto::{encoding, hashing, random};
use std::collections::HashMap;
-use {meta::MetaDomain, traits::AutoEncoder};
+use {
+ meta::MetaDomain,
+ traits::{AutoEncoder, Base64AutoEncoder},
+};
/// Specifies access to a resource
#[derive(Hash, Serialize, Deserialize, Clone, PartialEq, Eq)]
@@ -115,6 +118,11 @@ impl UserStore {
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 {
@@ -141,7 +149,7 @@ impl From<MetaDomain> for UserStore {
(
k.clone(),
match v {
- ::Payload::Text(s) => User::decode(s).unwrap(),
+ ::Payload::Text(s) => User::decode(&String::from_base64(s)).unwrap(),
_ => unreachable!(),
},
)
@@ -156,7 +164,12 @@ impl From<UserStore> for MetaDomain {
MetaDomain::new("userstore").fill(
us.users
.iter()
- .map(|(name, user)| (name.clone(), ::Payload::Text(user.encode().unwrap())))
+ .map(|(name, user)| {
+ (
+ name.clone(),
+ ::Payload::Text(user.encode().unwrap().to_base64()),
+ )
+ })
.collect(),
)
}
diff --git a/lockchain-files/examples/create.rs b/lockchain-files/examples/create.rs
index f6ecb8e..db2b8e9 100644
--- a/lockchain-files/examples/create.rs
+++ b/lockchain-files/examples/create.rs
@@ -3,6 +3,7 @@ extern crate lockchain_files as files;
use files::DataVault;
use lcc::traits::Vault;
+use lcc::users::{User, UserStore};
use lcc::{EncryptedBody, Payload, Record};
use std::env;
@@ -12,14 +13,20 @@ fn main() {
let name = env::args().nth(2).unwrap();
let mut vault: DataVault<EncryptedBody> = DataVault::new(&name, &path);
- vault.meta_add_domain("userstore").unwrap();
- vault
- .meta_set(
- "userstore",
- "spacekookie",
- Payload::Text("<access token here>".into()),
- )
- .unwrap();
+ let mut store = match vault.meta_pull_domain("userstore") {
+ Some(m) => m.clone().into(),
+ _ => UserStore::default(),
+ };
+
+ /* Some users of our vault have the same password :S */
+ store.add(User::register("alice", "password"));
+ store.add(User::register("bob", "password"));
+ store.add(User::register("carol", "password"));
+ store.add(User::register("darius", "password"));
+ store.add(User::register("elena", "password"));
+ store.add(User::register("farah", "password"));
+
+ vault.meta_push_domain(store.into());
vault.sync();
} else {
eprintln!("Usage: create <path> <name> [FLAGS] (there are no flags)")
diff --git a/lockchain-files/examples/register_user.rs b/lockchain-files/examples/register_user.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lockchain-files/examples/register_user.rs
diff --git a/lockchain-files/src/lib.rs b/lockchain-files/src/lib.rs
index b94c5b1..cdbfecb 100644
--- a/lockchain-files/src/lib.rs
+++ b/lockchain-files/src/lib.rs
@@ -141,4 +141,8 @@ impl<T: Body> Vault<T> for DataVault<T> {
fn meta_get(&mut self, domain: &str, name: &str) -> Option<Payload> {
Some(self.metadata.get(domain)?.get_field(name)?.clone())
}
+
+ fn meta_exists(&self, domain: &str) -> bool {
+ self.metadata.contains_key(domain)
+ }
}
diff --git a/lockchain-http/src/handlers.rs b/lockchain-http/src/handlers.rs
index f68f158..8ce44da 100644
--- a/lockchain-http/src/handlers.rs
+++ b/lockchain-http/src/handlers.rs
@@ -165,8 +165,85 @@ where
})
}
+pub fn get_all_metadata<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn put_metadata<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn get_metadata<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn update_metadata<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn vault_register<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn vault_login<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
+pub fn vault_logout<B, V>(_req: HttpRequestState<ApiState<B, V>>) -> impl Responder
+where
+ B: Body,
+ V: Vault<B>,
+{
+ Json(OperationFailed {
+ explain: "Not implemented".into(),
+ error: LockError::Unknown,
+ })
+}
+
/// PUT /authenticate
-pub fn authenticate<B, V>(
+pub fn login<B, V>(
(item, req): (Json<Authenticate>, HttpRequestState<ApiState<B, V>>),
) -> impl Responder
where
@@ -196,7 +273,7 @@ where
}
/// PUT /de-authenticate
-pub fn deauthenticate<B, V>(
+pub fn logout<B, V>(
(item, req): (Json<Deauthenticate>, HttpRequestState<ApiState<B, V>>),
) -> impl Responder
where
diff --git a/lockchain-http/src/lib.rs b/lockchain-http/src/lib.rs
index 3adb503..961ad21 100644
--- a/lockchain-http/src/lib.rs
+++ b/lockchain-http/src/lib.rs
@@ -75,10 +75,8 @@ where
.resource("/vaults", |r| {
// Get existing vaults
r.method(http::Method::GET).with(handlers::get_vaults);
-
// Create new vault (if authorised)
r.method(http::Method::PUT).with(handlers::create_vault);
-
// Delete entire vault (if authorised)
r.method(http::Method::DELETE).with(handlers::delete_vault);
})
@@ -115,31 +113,32 @@ where
})
.resource("/vaults/{vaultid}/metadata/{metaid}", |r| {
// Get a specific metadata field
- r.method(http::Method::GET).with(handlers::get_all_records);
+ r.method(http::Method::GET).with(handlers::get_metadata);
// Update a specific metadata field
- r.method(http::Method::POST).with(handlers::get_all_records);
+ r.method(http::Method::POST).with(handlers::update_metadata);
})
.resource("/vaults/{vaultid}/register", |r| {
// Register a new user in a vault (with a registry token)
- r.method(http::Method::POST).with(handlers::deauthenticate)
+ r.method(http::Method::POST).with(handlers::vault_register)
})
.resource("/vaults/{vaultid}/login", |r| {
// Login as a user for this vault
- r.method(http::Method::POST).with(handlers::authenticate)
+ r.method(http::Method::POST).with(handlers::vault_login)
})
.resource("/vaults/{vaultid}/logout", |r| {
// Logout, closing an existing session
- r.method(http::Method::POST).with(handlers::deauthenticate)
+ r.method(http::Method::POST).with(handlers::vault_logout)
})
.resource("/users/login", |r| {
// Request a new auth token
- r.method(http::Method::POST).with(handlers::authenticate)
+ r.method(http::Method::POST).with(handlers::login)
})
.resource("/users/logout", |r| {
// Hand-in active auth token
- r.method(http::Method::POST).with(handlers::deauthenticate)
+ r.method(http::Method::POST).with(handlers::logout)
})
.resource("/api", |r| {
+ // Get information about this API endpoint
r.method(http::Method::GET).with(handlers::api_data);
}),
]