From 232c9d1b58e2f01ed12280a9fcada6c0641519d6 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Mon, 9 Jul 2018 10:58:26 +0200 Subject: Restoring the API handlers again, making it all work with the new Error system (all stubs for now) --- lockchain-core/src/errors/mod.rs | 5 + lockchain-http/src/handlers.rs | 442 ++++++++++++++++++--------------------- lockchain-http/src/lib.rs | 88 ++++---- lockchain-http/src/models/mod.rs | 15 +- 4 files changed, 249 insertions(+), 301 deletions(-) diff --git a/lockchain-core/src/errors/mod.rs b/lockchain-core/src/errors/mod.rs index d6347a1..5cfd944 100644 --- a/lockchain-core/src/errors/mod.rs +++ b/lockchain-core/src/errors/mod.rs @@ -22,6 +22,11 @@ use std::fmt::{Display, Formatter, Result}; #[derive(Debug, Serialize, Deserialize)] pub enum Error { + /// A common "unknown" type for errors + /// that can't be associated with a type or + /// simply need to be stubbed until more + /// information is available. + Unknown, /// A basic vault operation error Vault(VaultError), /// Errors occuring during authentication diff --git a/lockchain-http/src/handlers.rs b/lockchain-http/src/handlers.rs index f89248f..f68f158 100644 --- a/lockchain-http/src/handlers.rs +++ b/lockchain-http/src/handlers.rs @@ -1,11 +1,12 @@ //! Definition of the core lockchain API use actix_web::{HttpRequest, Json, Responder}; -use lockchain::{ - traits::{Body, Vault}, Record, -}; -use models::{inputs::*, responses::*, NoneError, Response}; +use lockchain::errors::{Error as LockError, *}; +use lockchain::traits::{Body, Vault}; +use lockchain::Record; + +use models::{inputs::*, responses::*, Response}; use state::ApiState; use std::intrinsics; @@ -13,261 +14,216 @@ use std::sync::{Arc, Mutex}; type HttpRequestState = HttpRequest>>; -// /// GET /vault -// /// -// /// Check the documentation for more information about how to provide payloads -// pub fn get_vaults(req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// let state = req.state().lock().unwrap(); -// Json(VaultList { -// vaults: state.vaults().iter().map(|s| s.to_string()).collect(), -// count: state.count(), -// }) -// } - -// /// PUT /vault -// /// -// /// Check the documentation for more information about how to provide payloads -// pub fn create_vault( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// let mut state = req.state().lock().unwrap(); -// let location = if state.bound_scope { -// state.working_dir.clone().join(&item.location) -// } else { -// (&item.location).into() -// }; - -// state.add_vault(&item.name, V::new(&item.name, location.to_str().unwrap())); -// Json(Response::Success::) -// } - -// pub fn delete_vault( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } - -// pub fn scope_vault( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } - -// pub fn unscope_vault( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(Response::Failure::(OperationFailed { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// })) - -// // Json() -// } - -// /// POST /vault/{vault-id} -// pub fn update_vault(_req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } - -// pub fn get_all_records(_req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } - -// /// PUT /vault/{vault-id}/records -// pub fn create_record(_req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; - -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } - -// /// GET /vault/{vault-id}/records/{record-id} -// pub fn get_record( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// let mut state = req.state().lock().unwrap(); -// let vault = state.get_vault(""); +/// GET /vault +/// +/// Check the documentation for more information about how to provide payloads +pub fn get_vaults(req: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + let state = req.state().lock().unwrap(); + Json(VaultList { + vaults: state.vaults().iter().map(|s| s.to_string()).collect(), + count: state.count(), + }) +} -// use lockchain::errors::Error as LockError; +/// PUT /vault +/// +/// Check the documentation for more information about how to provide payloads +pub fn create_vault( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + let mut state = req.state().lock().unwrap(); + let location = if state.bound_scope { + state.working_dir.clone().join(&item.location) + } else { + (&item.location).into() + }; + + state.add_vault(&item.name, V::new(&item.name, location.to_str().unwrap())); + Json(Response::Success) +} -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } +pub fn delete_vault( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// /// POST /vault/{vault-id}/records/{record-id} -// pub fn update_record(_req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; +pub fn scope_vault( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } +pub fn unscope_vault( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// /// DELETE /vault/{vault-id}/records/{record-id} -// pub fn delete_record(_req: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; +/// POST /vault/{vault-id} +pub fn update_vault(_req: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } +pub fn get_all_records(_req: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -#[allow(dead_code)] -pub fn foo(_req: HttpRequestState>) -> impl Responder +/// PUT /vault/{vault-id}/records +pub fn create_record(_req: HttpRequestState>) -> impl Responder where B: Body, V: Vault, { - use lockchain::errors::Error as LockError; - use models::{NoneError, Response}; - let a = 5; + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} - match a { - 5 => Json(Response::Failure::(OperationFailed { - explain: "BOOOOM!".into(), - error: LockError::FailedSelfTest, - })), - _ => Json(Response::Success::), - } +/// GET /vault/{vault-id}/records/{record-id} +pub fn get_record( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + let mut state = req.state().lock().unwrap(); + let vault = state.get_vault(""); - // } else { - // Json(Response::Success::) - // } + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) } -// /// PUT /authenticate -// pub fn authenticate( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::users::*; -// let Authenticate { username, password } = item.into_inner(); - -// Json(match pam_authenticate(&username, &password) { -// Ok(()) => { -// /* Store the token for auth later */ -// let state = req.state().lock().unwrap(); -// let token = String::new(); -// state.tokens.insert(token.clone()); +/// POST /vault/{vault-id}/records/{record-id} +pub fn update_record(_req: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// Response::Token(TokenMessage { -// username, -// token: token, -// }) -// } -// Err(e) => Response::Failure(OperationFailed { -// reason: "Failed to authenticate user".into(), -// error: e.into(), -// }), -// }) -// } +/// DELETE /vault/{vault-id}/records/{record-id} +pub fn delete_record(_req: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// /// PUT /de-authenticate -// pub fn deauthenticate( -// (item, req): (Json, HttpRequestState>), -// ) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// use lockchain::errors::Error as LockError; +/// PUT /authenticate +pub fn authenticate( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + use lockchain::users::*; + let Authenticate { username, password } = item.into_inner(); + + Json(match pam_authenticate(&username, &password) { + Ok(()) => { + /* Store the token for auth later */ + let mut state = req.state().lock().unwrap(); + let token = String::new(); + state.tokens.insert(token.clone()); + + Response::Token(TokenMessage { + username, + token: token, + }) + } + Err(e) => Response::Failure(OperationFailed { + explain: "Failed to authenticate user".into(), + error: LockError::Auth(AuthError::UserNotAuthorised), + }), + }) +} -// Json(OperationFailed:: { -// reason: "Not implemented".into(), -// error: LockError::UnknownFailure.into(), -// }) -// } +/// PUT /de-authenticate +pub fn deauthenticate( + (item, req): (Json, HttpRequestState>), +) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(OperationFailed { + explain: "Not implemented".into(), + error: LockError::Unknown, + }) +} -// /// GET /api -// /// -// /// Check the documentation for more information about how to provide payloads -// pub fn api_data>(_: HttpRequestState>) -> impl Responder -// where -// B: Body, -// V: Vault, -// { -// Json(ApiInformation { -// version: "1.0".into(), -// providers: vec![ -// unsafe { intrinsics::type_name::() }.into(), -// unsafe { intrinsics::type_name::() }.into(), -// ], -// hostname: None, -// supported: "1.0".into(), -// }) -// } +/// GET /api +/// +/// Check the documentation for more information about how to provide payloads +pub fn api_data>(_: HttpRequestState>) -> impl Responder +where + B: Body, + V: Vault, +{ + Json(ApiInformation { + version: "1.0".into(), + providers: vec![ + unsafe { intrinsics::type_name::() }.into(), + unsafe { intrinsics::type_name::() }.into(), + ], + hostname: None, + supported: "1.0".into(), + }) +} diff --git a/lockchain-http/src/lib.rs b/lockchain-http/src/lib.rs index e51e23f..dfe1211 100644 --- a/lockchain-http/src/lib.rs +++ b/lockchain-http/src/lib.rs @@ -71,52 +71,52 @@ where server::new(move || { vec![ - // App::with_state(Arc::clone(&state)) - // .resource("/vaults", |r| { - // // Get existing vaults - // r.method(http::Method::GET).with(handlers::get_vaults); + App::with_state(Arc::clone(&state)) + .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); + // 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); - // }) - // .resource("/vaults/scope", |r| { - // // Bring an existing vault into scope (if authorised) - // r.method(http::Method::PUT).with(handlers::scope_vault); - // // Remove an existing vault from API scope (if authorised) - // r.method(http::Method::DELETE).with(handlers::unscope_vault); - // }) - // .resource("/vaults/{vaultid}", |r| { - // // Update vault metadata (access rights, users, indices, etc) - // r.method(http::Method::POST).with(handlers::update_vault) - // }) - // .resource("/vaults/{vaultid}/records", |r| { - // // Get the vault record index (omits records without access) - // r.method(http::Method::GET).with(handlers::get_all_records); - // // Create a new record (if authorised) in the vault - // r.method(http::Method::PUT).with(handlers::create_record); - // }) - // .resource("/vaults/{vaultid}/records/{recordid}", |r| { - // // Get a specific record from a vault - // r.method(http::Method::GET).with(handlers::get_record); - // // Update a specific record - // r.method(http::Method::POST).with(handlers::update_record); - // // Delete a specific record from a vault - // r.method(http::Method::DELETE).with(handlers::delete_record); - // }) - // .resource("/users/login", |r| { - // // Request a new auth token - // r.method(http::Method::POST).with(handlers::authenticate) - // }) - // .resource("/users/logout", |r| { - // // Hand-in active auth token - // r.method(http::Method::POST).with(handlers::deauthenticate) - // }) - // .resource("/api", |r| { - // r.method(http::Method::GET).with(handlers::api_data); - // }), + // Delete entire vault (if authorised) + r.method(http::Method::DELETE).with(handlers::delete_vault); + }) + .resource("/vaults/scope", |r| { + // Bring an existing vault into scope (if authorised) + r.method(http::Method::PUT).with(handlers::scope_vault); + // Remove an existing vault from API scope (if authorised) + r.method(http::Method::DELETE).with(handlers::unscope_vault); + }) + .resource("/vaults/{vaultid}", |r| { + // Update vault metadata (access rights, users, indices, etc) + r.method(http::Method::POST).with(handlers::update_vault) + }) + .resource("/vaults/{vaultid}/records", |r| { + // Get the vault record index (omits records without access) + r.method(http::Method::GET).with(handlers::get_all_records); + // Create a new record (if authorised) in the vault + r.method(http::Method::PUT).with(handlers::create_record); + }) + .resource("/vaults/{vaultid}/records/{recordid}", |r| { + // Get a specific record from a vault + r.method(http::Method::GET).with(handlers::get_record); + // Update a specific record + r.method(http::Method::POST).with(handlers::update_record); + // Delete a specific record from a vault + r.method(http::Method::DELETE).with(handlers::delete_record); + }) + .resource("/users/login", |r| { + // Request a new auth token + r.method(http::Method::POST).with(handlers::authenticate) + }) + .resource("/users/logout", |r| { + // Hand-in active auth token + r.method(http::Method::POST).with(handlers::deauthenticate) + }) + .resource("/api", |r| { + r.method(http::Method::GET).with(handlers::api_data); + }), ] }).bind(format!("{}:{}", bind, port)) .map_err(|e| e.into()) diff --git a/lockchain-http/src/models/mod.rs b/lockchain-http/src/models/mod.rs index f83dc35..e0207c4 100644 --- a/lockchain-http/src/models/mod.rs +++ b/lockchain-http/src/models/mod.rs @@ -5,8 +5,7 @@ pub mod responses; /// A wrapper model for various API response types #[derive(Serialize, Deserialize)] -pub enum Response -{ +pub enum Response { /// Indicate general success of an operation Success, /// Indicate a failure of some kind @@ -18,15 +17,3 @@ pub enum Response /// Returns a list of all vaults Vaults(responses::VaultList), } - -#[derive(Debug, Serialize, Deserialize, Copy, Clone, Eq, PartialEq)] -pub struct NoneError; -impl Error for NoneError {} - -use std::fmt::{Display, Formatter, Result}; - -impl Display for NoneError { - fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "") - } -} -- cgit v1.2.3