From 23b28144a11a21f502152a70b1a76b2e064081c9 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 17 Nov 2022 22:18:51 -0500 Subject: [PATCH] Set up a bare memory auth context and a few endpoints --- server/Cargo.lock | 15 ++++++++ server/Cargo.toml | 2 + server/src/authentication.rs | 14 ++++++- server/src/main.rs | 72 +++++++++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/server/Cargo.lock b/server/Cargo.lock index c7ad80e..7f7abd5 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -673,6 +673,20 @@ name = "serde" version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "serde_json" @@ -704,6 +718,7 @@ dependencies = [ "anyhow", "rand", "rusqlite", + "serde", "sha2", "tempfile", "thiserror", diff --git a/server/Cargo.toml b/server/Cargo.toml index fefa208..a459342 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -2,6 +2,7 @@ name = "server" version = "0.1.0" edition = "2021" +default-run = "server" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -9,6 +10,7 @@ edition = "2021" anyhow = { version = "1" } rand = { version = "0.8" } rusqlite = { version = "0.26" } +serde = { version = "1.0", features = ["derive"] } sha2 = { version = "0.10" } thiserror = { version = "1" } tokio = { version = "1", features = ["full"] } diff --git a/server/src/authentication.rs b/server/src/authentication.rs index 7ed1f45..440864a 100644 --- a/server/src/authentication.rs +++ b/server/src/authentication.rs @@ -117,6 +117,12 @@ impl FromStr for Username { } } +impl From<&Username> for String { + fn from(s: &Username) -> Self { + s.0.clone() + } +} + impl From for String { fn from(s: Username) -> Self { s.0.clone() @@ -153,9 +159,11 @@ pub trait AuthenticationDB { fn validate_session(&self, session: SessionToken) -> AppResult<(), AuthenticationError>; fn get_user_id(&self, username: Username) -> AppResult; + + fn list_users(&self) -> AppResult, AuthenticationError>; } -#[derive(Default)] +#[derive(Debug, Default)] pub struct MemoryAuth { users: HashMap, inverse_users: HashMap, @@ -268,6 +276,10 @@ impl AuthenticationDB for MemoryAuth { .map(|u| u.clone()) .ok_or(AuthenticationError::UserNotFound)) } + + fn list_users(&self) -> AppResult, AuthenticationError> { + ok(self.users.keys().cloned().collect::>()) + } } #[cfg(test)] diff --git a/server/src/main.rs b/server/src/main.rs index 50e1927..b293ee8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,12 +1,77 @@ -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use serde::{Deserialize, Serialize}; +use std::{ + net::{IpAddr, Ipv4Addr, SocketAddr}, + sync::{Arc, RwLock}, +}; use warp::Filter; mod authentication; +use authentication::{AuthenticationDB, MemoryAuth, Username}; + mod database; mod errors; +#[derive(Serialize)] +struct ErrorResponse { + error: String, +} + +#[derive(Deserialize)] +struct MakeUserParameters { + username: String, +} + +#[derive(Serialize)] +struct MakeUserResponse { + userid: String, +} + #[tokio::main] pub async fn main() { + let auth_ctx: Arc> = Arc::new(RwLock::new(Default::default())); + + let make_user = { + let auth_ctx = auth_ctx.clone(); + warp::path!("api" / "v1" / "user") + .and(warp::put()) + .and(warp::body::json()) + .map(move |params: MakeUserParameters| { + let mut auth_ctx = auth_ctx.write().unwrap(); + println!("{:?}", *auth_ctx); + match (*auth_ctx).create_user(Username::from(params.username.as_str())) { + Ok(Ok(userid)) => warp::reply::json(&MakeUserResponse { + userid: String::from(userid), + }), + Ok(auth_error) => warp::reply::json(&ErrorResponse { + error: format!("{:?}", auth_error), + }), + Err(err) => panic!("{}", err), + } + }) + }; + + let list_users = { + let auth_ctx = auth_ctx.clone(); + warp::path!("api" / "v1" / "user") + .and(warp::get()) + .map(move || { + let auth_ctx = auth_ctx.read().unwrap(); + println!("{:?}", *auth_ctx); + match (*auth_ctx).list_users() { + Ok(Ok(users)) => warp::reply::json( + &users + .iter() + .map(|u| String::from(u)) + .collect::>(), + ), + Ok(auth_error) => warp::reply::json(&ErrorResponse { + error: format!("{:?}", auth_error), + }), + Err(err) => panic!("{}", err), + } + }) + }; + let echo_unauthenticated = warp::path!("api" / "v1" / "echo" / String).map(|param: String| { println!("param: {}", param); warp::reply::json(&vec!["unauthenticated", param.as_str()]) @@ -27,7 +92,10 @@ pub async fn main() { warp::reply::json(&vec!["authed", param.as_str()]) }); - let filter = echo_authenticated.or(echo_unauthenticated); + let filter = list_users + .or(make_user) + .or(echo_authenticated) + .or(echo_unauthenticated); let server = warp::serve(filter); server