diff options
Diffstat (limited to 'crates/sellershut/src/server/middleware/sign_request.rs')
-rw-r--r-- | crates/sellershut/src/server/middleware/sign_request.rs | 64 |
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) + }) + } +} |