diff --git a/.gitignore b/.gitignore index cb7f85d..c800b27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -*.json \ No newline at end of file +*.json +client/* \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index d5a52a4..41497e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,6 +140,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + [[package]] name = "fnv" version = "1.0.7" @@ -170,6 +190,17 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "futures-task" version = "0.3.28" @@ -183,9 +214,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -396,6 +429,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tower-cookies", "tower-http", "tracing", "tracing-subscriber", @@ -504,6 +538,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -679,6 +719,15 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.11.1" @@ -743,6 +792,35 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -804,6 +882,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-cookies" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40f38d941a2ffd8402b36e02ae407637a9caceb693aaf2edc910437db0f36984" +dependencies = [ + "async-trait", + "axum-core", + "cookie", + "futures-util", + "http", + "parking_lot", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-http" version = "0.4.4" diff --git a/Cargo.toml b/Cargo.toml index d4d2d94..8d8a709 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ macaddr = { version = "1.0.1", features = ["serde"] } serde = { version = "1.0.189", features = ["derive"] } serde_json = "1.0.107" tokio = { version = "1.33.0", features = ["full"] } +tower-cookies = "0.9.0" tower-http = "0.4.4" tracing = "0.1.40" tracing-subscriber = "0.3.17" diff --git a/src/main.rs b/src/main.rs index 0bc8863..0ae1674 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use tracing_subscriber; mod config_manager; mod definitions; -mod router; +mod web; #[tokio::main] async fn main() { @@ -14,11 +14,11 @@ async fn main() { // let mut config_manager = config_manager::new_config_manager().unwrap(); - let app = router::get_router(); + let main_router = web::router::get_router(); info!("Server started successfully"); axum::Server::bind(&"[::]:8080".parse().unwrap()) - .serve(app.await.into_make_service()) + .serve(main_router.await.into_make_service()) .await .unwrap(); diff --git a/src/router.rs b/src/router.rs deleted file mode 100644 index f13fcf2..0000000 --- a/src/router.rs +++ /dev/null @@ -1,23 +0,0 @@ -use axum::{ - response::IntoResponse, - routing::{get, post}, - Json, Router, -}; - -use tracing::info; - -pub async fn get_router() -> Router { - Router::new().route("/health", get(health_checker_handler)) -} - -pub async fn health_checker_handler() -> impl IntoResponse { - info!("health hit"); - const MESSAGE: &str = "Hello there"; - - let json_response = serde_json::json!({ - "status": "success", - "message": MESSAGE - }); - - Json(json_response) -} diff --git a/src/web/auth.rs b/src/web/auth.rs new file mode 100644 index 0000000..9c851d0 --- /dev/null +++ b/src/web/auth.rs @@ -0,0 +1,97 @@ +use std::collections::HashMap; +use std::hash::Hash; + +use axum::routing::post; +use axum::{Json, Router}; +use serde::Deserialize; +use tower_cookies::Cookies; + +use axum::{ + extract::Extension, + http::{Request, StatusCode}, + middleware::{self, Next}, + response::{IntoResponse, Response}, +}; + +const SESSION_COOKIE: &str = "session"; + +#[derive(Clone, Debug)] +struct SessionState { + sessions: HashMap, +} + +#[derive(Clone, Debug)] +struct Session { + username: String, + //expires: time, +} + +#[derive(Clone, Debug, Deserialize)] +struct LoginParameters { + username: String, + password: String, +} + +pub fn routes() -> Router { + let state = SessionState { + sessions: HashMap::new(), + }; + + Router::new() + .route("/session", post(session_handler)) + .route("/login", post(login_handler)) + .route("/logout", post(logout_handler)) +} + +async fn session_handler() -> impl IntoResponse { + //return Err(StatusCode::UNAUTHORIZED); + todo!() +} + +async fn login_handler( + cookies: Cookies, + Json(payload): Json, + // mut session_state: SessionState, +) -> impl IntoResponse { + //cookies.add(Cookie::new()); + todo!() +} + +async fn logout_handler( + cookies: Cookies, + // mut session_state: SessionState +) -> impl IntoResponse { + /* + if let Some(session_cookie) = cookies.get(SESSION_COOKIE) { + let session_id = session_cookie.value(); + + // TODO check that sessions_id is a valid uuidv4 + + session_state.sessions.remove(session_id); + cookies.remove(session_cookie); + } + */ + todo!() +} + +pub async fn mw_auth( + cookies: Cookies, + mut req: Request, + next: Next, + // session_state: SessionState, +) -> Result { + /* + if let Some(session_cookie) = cookies.get(SESSION_COOKIE) { + let session_id = session_cookie.value(); + + // TODO check that sessions_id is a valid uuidv4 + + if let Some(session) = session_state.sessions.get(session_id) { + req.extensions_mut().insert(session.clone()); + return Ok(next.run(req).await); + } + } + return Err(StatusCode::UNAUTHORIZED); + */ + todo!() +} diff --git a/src/web/mod.rs b/src/web/mod.rs new file mode 100644 index 0000000..cf24610 --- /dev/null +++ b/src/web/mod.rs @@ -0,0 +1,3 @@ +pub mod auth; +pub mod router; +pub mod rpc; diff --git a/src/web/router.rs b/src/web/router.rs new file mode 100644 index 0000000..171556e --- /dev/null +++ b/src/web/router.rs @@ -0,0 +1,15 @@ +use axum::{middleware, Router}; + +use tower_cookies::CookieManagerLayer; + +#[derive(Clone)] +struct tmp {} + +pub async fn get_router() -> Router { + Router::new() + .merge(super::auth::routes()) + .nest("/api", super::rpc::routes()) + .layer(middleware::from_fn_with_state(tmp {}, super::auth::mw_auth)) + .layer(CookieManagerLayer::new()) + // .fallback_service(service) +} diff --git a/src/web/rpc.rs b/src/web/rpc.rs new file mode 100644 index 0000000..77e3e45 --- /dev/null +++ b/src/web/rpc.rs @@ -0,0 +1,5 @@ +use axum::Router; + +pub fn routes() -> Router { + Router::new() +}