about summary refs log tree commit diff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-01-01 23:17:56 +0300
committerVika <vika@fireburn.ru>2025-01-01 23:17:56 +0300
commitd10710326da703f69eaa06723dc66e330fd32745 (patch)
treee4a32c2a7f2e4a61d1f3f6237977de64e47470ae /src/lib.rs
parent675141379067858376698d5f75ab163977d33e3a (diff)
downloadkittybox-d10710326da703f69eaa06723dc66e330fd32745.tar.zst
axum: 0.7.9 → 0.8.1
Some breaking changes. For better or for worse. The optional extractor
breaking change is a double-edged sword, since not all extractors can
be used with `Option<T>` now, and you have to use
`Result<T, T::Rejection>` even when you want to ignore an error coming
from an extractor, such as `Query`.

However, this allows catching errors on authorization extractors even
in places where authorization is optional.

Change-Id: I35f809d3adf27dbef0e7ee93dc1a7af178b7d014
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs37
1 files changed, 12 insertions, 25 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 5fe3b18..e6bc24c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,8 +3,8 @@
 
 use std::sync::Arc;
 
-use axum::extract::{FromRef, FromRequestParts};
-use axum_extra::extract::{cookie::Key, SignedCookieJar};
+use axum::extract::{FromRef, FromRequestParts, OptionalFromRequestParts};
+use axum_extra::extract::{cookie::{Cookie, Key}, SignedCookieJar};
 use database::{FileStorage, PostgresStorage, Storage};
 use indieauth::backend::{AuthBackend, FileBackend as FileAuthBackend};
 use kittybox_util::queue::JobQueue;
@@ -64,36 +64,23 @@ impl axum::response::IntoResponse for NoSessionError {
     }
 }
 
-#[async_trait::async_trait]
-impl<S> FromRequestParts<S> for Session
+impl<S> OptionalFromRequestParts<S> for Session
 where
     SessionStore: FromRef<S>,
     Key: FromRef<S>,
     S: Send + Sync,
 {
-    type Rejection = NoSessionError;
+    type Rejection = std::convert::Infallible;
 
-    async fn from_request_parts(parts: &mut axum::http::request::Parts, state: &S) ->  Result<Self, Self::Rejection> {
+    async fn from_request_parts(parts: &mut axum::http::request::Parts, state: &S) ->  Result<Option<Self>, Self::Rejection> {
         let jar = SignedCookieJar::<Key>::from_request_parts(parts, state).await.unwrap();
         let session_store = SessionStore::from_ref(state).read_owned().await;
 
-        tracing::debug!("Cookie jar: {:#?}", jar);
-        let cookie = match jar.get("session_id") {
-            Some(cookie) => {
-                tracing::debug!("Session ID cookie: {}", cookie);
-                cookie
-            },
-            None => { return Err(NoSessionError) }
-        };
-
-        session_store.get(
-            &dbg!(cookie.value_trimmed())
-                .parse()
-                .map_err(|err| {
-                    tracing::error!("Error parsing cookie: {}", err);
-                    NoSessionError
-                })?
-        ).cloned().ok_or(NoSessionError)
+        Ok(jar.get("session_id")
+            .as_ref()
+            .map(Cookie::value_trimmed)
+            .and_then(|id| uuid::Uuid::parse_str(id).ok())
+            .and_then(|id| session_store.get(&id).cloned()))
     }
 }
 
@@ -264,7 +251,7 @@ pub mod companion {
 
         axum::Router::new()
             .route(
-                "/:filename",
+                "/{filename}",
                 axum::routing::get(map_to_static)
                     .layer(Extension(resources))
             )
@@ -309,7 +296,7 @@ St: Clone + Send + Sync + 'static
         .route("/.kittybox/health", get(health_check::<S>))
         .nest("/.kittybox/login", crate::login::router::<St, S>())
         .route(
-            "/.kittybox/static/:path",
+            "/.kittybox/static/{path}",
             axum::routing::get(crate::frontend::statics)
         )
         .route("/.kittybox/coffee", get(teapot_route))