summaryrefslogtreecommitdiffstats
path: root/crates/sellershut/src/server/middleware/sign_request.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/sellershut/src/server/middleware/sign_request.rs')
-rw-r--r--crates/sellershut/src/server/middleware/sign_request.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/sellershut/src/server/middleware/sign_request.rs b/crates/sellershut/src/server/middleware/sign_request.rs
new file mode 100644
index 0000000..a8f2f3a
--- /dev/null
+++ b/crates/sellershut/src/server/middleware/sign_request.rs
@@ -0,0 +1,64 @@
+use activitypub_federation::config::FederationConfig;
+use axum::{body::Body, extract::Request, response::Response};
+use futures_util::future::BoxFuture;
+use hmac::{Hmac, Mac};
+use sha2::{Sha256, digest::KeyInit};
+use std::task::{Context, Poll};
+use tower::{Layer, Service};
+
+use crate::state::AppHandle;
+
+type HmacSha256 = Hmac<Sha256>;
+
+#[derive(Clone)]
+pub struct SignRequestLayer {
+ state: FederationConfig<AppHandle>,
+}
+
+impl SignRequestLayer {
+ pub fn new(state: &FederationConfig<AppHandle>) -> Self {
+ Self {
+ state: state.to_owned(),
+ }
+ }
+}
+
+impl<S> Layer<S> for SignRequestLayer {
+ type Service = SignRequestMiddleware<S>;
+
+ fn layer(&self, inner: S) -> Self::Service {
+ SignRequestMiddleware {
+ inner,
+ state: self.state.clone(),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub struct SignRequestMiddleware<S> {
+ inner: S,
+ state: FederationConfig<AppHandle>,
+}
+
+impl<S> Service<Request> for SignRequestMiddleware<S>
+where
+ S: Service<Request, Response = Response> + Send + 'static,
+ S::Future: Send + 'static,
+{
+ type Response = S::Response;
+ type Error = S::Error;
+ // `BoxFuture` is a type alias for `Pin<Box<dyn Future + Send + 'a>>`
+ type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ self.inner.poll_ready(cx)
+ }
+
+ fn call(&mut self, request: Request) -> Self::Future {
+ let future = self.inner.call(request);
+ Box::pin(async move {
+ let response: Response = future.await?;
+ Ok(response)
+ })
+ }
+}