about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2024-07-09 00:36:48 +0300
committerVika <vika@fireburn.ru>2024-07-09 22:44:01 +0300
commit4bacba7cece901f9c25a450eb4b7bc8969bb5e9e (patch)
tree3fadb955d1d53ac15b2247fb88050fbf6abd3717
parent2e9c292bb989ffff2c99aa2a6062962c913b3586 (diff)
downloadkittybox-4bacba7cece901f9c25a450eb4b7bc8969bb5e9e.tar.zst
Start working on login functionality
-rw-r--r--Cargo.lock5
-rw-r--r--Cargo.toml2
-rw-r--r--src/lib.rs1
-rw-r--r--src/login.rs45
-rw-r--r--src/main.rs5
-rw-r--r--templates/src/templates.rs2
6 files changed, 57 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 226a14d..fb53133 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -600,7 +600,12 @@ version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
 dependencies = [
+ "base64 0.21.2",
+ "hmac",
  "percent-encoding",
+ "rand 0.8.5",
+ "sha2",
+ "subtle",
  "time 0.3.23",
  "version_check",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index c38dabd..b71ac4e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -124,7 +124,7 @@ version = "^0.6.18"
 features = ["multipart", "json", "headers", "form", "macros"]
 [dependencies.axum-extra]
 version = "^0.7.4"
-features = ["cookie"]
+features = ["cookie", "cookie-signed"]
 [dependencies.chrono]        # Date and time library for Rust
 version = "^0.4.19"
 features = ["serde"]
diff --git a/src/lib.rs b/src/lib.rs
index c1bd965..04b3298 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,6 +8,7 @@ pub mod media;
 pub mod micropub;
 pub mod indieauth;
 pub mod webmentions;
+pub mod login;
 
 pub mod companion {
     use std::{collections::HashMap, sync::Arc};
diff --git a/src/login.rs b/src/login.rs
new file mode 100644
index 0000000..7f0314f
--- /dev/null
+++ b/src/login.rs
@@ -0,0 +1,45 @@
+use axum_extra::extract::cookie;
+
+/// Show a login page.
+async fn get() {
+    todo!()
+}
+
+/// Accept login and start the IndieAuth dance.
+async fn post() {
+    todo!()
+}
+
+/// Accept the return of the IndieAuth dance. Set a cookie for the
+/// required session.
+async fn callback() {
+    todo!()
+}
+
+/// Show the form necessary for logout. If JS is enabled,
+/// automatically POST the form.
+///
+/// This is essentially protection from CSRF and also from some kind
+/// of crawlers working with a user's cookies (wget?). If a crawler is
+/// stupid enough to execute JS and send a POST request though, that's
+/// on the crawler.
+async fn logout_page() {
+    todo!()
+}
+
+/// Erase the necessary cookies for login and invalidate the session.
+async fn logout() {
+    todo!()
+}
+
+/// Produce a router for all of the above.
+fn router(key: cookie::Key) -> axum::routing::Router<cookie::Key> {
+    axum::routing::Router::new()
+        .route("/start", axum::routing::get(get).post(post))
+        .route("/finish", axum::routing::get(callback))
+        .route("/logout", axum::routing::get(logout_page).post(logout))
+        // I'll need some kind of session store here too. It should be
+        // a key from UUIDs (128 bits is enough for a session token)
+        // to at least a URL, if not something more.
+        .with_state(key)
+}
diff --git a/src/main.rs b/src/main.rs
index b7a6035..9e541b9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -221,6 +221,9 @@ async fn compose_kittybox(
         other => unimplemented!("Unsupported backend: {other}")
     };
 
+    // TODO: load from environment
+    let cookie_key = axum_extra::extract::cookie::Key::generate();
+
     let router = router
         .route(
             "/.kittybox/static/:path",
@@ -228,11 +231,11 @@ async fn compose_kittybox(
         )
         .route("/.kittybox/coffee", teapot_route())
         .nest("/.kittybox/micropub/client", kittybox::companion::router())
+        .nest("/.kittybox/login", kittybox::login::router(cookie_key))
         .layer(tower_http::trace::TraceLayer::new_for_http())
         .layer(tower_http::catch_panic::CatchPanicLayer::new())
         .layer(tower_http::sensitive_headers::SetSensitiveHeadersLayer::new([
             axum::http::header::AUTHORIZATION,
-            // Not used yet, but will be eventually
             axum::http::header::COOKIE,
             axum::http::header::SET_COOKIE,
         ]));
diff --git a/templates/src/templates.rs b/templates/src/templates.rs
index 63c67c5..0196289 100644
--- a/templates/src/templates.rs
+++ b/templates/src/templates.rs
@@ -42,7 +42,7 @@ markup::define! {
                         }
                         li.shiftright {
                             @if user.is_none() {
-                                a #login[href="/login"] { "Sign in" }
+                                a #login[href="/login/start"] { "Sign in" }
                             } else {
                                 span {
                                     @user.as_ref().unwrap() " - " a #logout[href="/logout"] { "Sign out" }