about summary refs log tree commit diff
path: root/src/indieauth/mod.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/indieauth/mod.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/indieauth/mod.rs')
-rw-r--r--src/indieauth/mod.rs19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/indieauth/mod.rs b/src/indieauth/mod.rs
index 0ac3dfd..ab38715 100644
--- a/src/indieauth/mod.rs
+++ b/src/indieauth/mod.rs
@@ -3,10 +3,10 @@ use microformats::types::Class;
 use tracing::error;
 use serde::Deserialize;
 use axum::{
-    extract::{Form, FromRef, Host, Json, Query, State}, http::StatusCode, response::{Html, IntoResponse, Response}
+    extract::{Form, FromRef, Json, Query, State}, http::StatusCode, response::{Html, IntoResponse, Response}
 };
 #[cfg_attr(not(feature = "webauthn"), allow(unused_imports))]
-use axum_extra::extract::cookie::{CookieJar, Cookie};
+use axum_extra::extract::{Host, cookie::{CookieJar, Cookie}};
 use axum_extra::{headers::{authorization::Bearer, Authorization, ContentType, HeaderMapExt}, TypedHeader};
 use crate::database::Storage;
 use kittybox_indieauth::{
@@ -65,7 +65,20 @@ impl axum::response::IntoResponse for IndieAuthResourceError {
     }
 }
 
-#[async_trait::async_trait]
+impl <A: AuthBackend + FromRef<St>, St: Clone + Send + Sync + 'static> axum::extract::OptionalFromRequestParts<St> for User<A> {
+    type Rejection = <Self as axum::extract::FromRequestParts<St>>::Rejection;
+
+    async fn from_request_parts(req: &mut axum::http::request::Parts, state: &St) -> Result<Option<Self>, Self::Rejection> {
+        let res = <Self as axum::extract::FromRequestParts<St>>::from_request_parts(req, state).await;
+
+        match res {
+            Ok(user) => Ok(Some(user)),
+            Err(IndieAuthResourceError::Unauthorized) => Ok(None),
+            Err(err) => Err(err),
+        }
+    }
+}
+
 impl <A: AuthBackend + FromRef<St>, St: Clone + Send + Sync + 'static> axum::extract::FromRequestParts<St> for User<A> {
     type Rejection = IndieAuthResourceError;