From ac444f9286092f9a7b36f960d9b3d8a38d78ab8c Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Thu, 15 Aug 2024 21:28:53 +0200 Subject: [PATCH] Make layer generic over Request body type Nothing in the layer implementation actually depends on the Request's body type. So generalise over the body type, allowing the service implementation not longer be tied to axum specifically. --- jwt-authorizer/src/builder.rs | 2 +- jwt-authorizer/src/layer.rs | 36 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/jwt-authorizer/src/builder.rs b/jwt-authorizer/src/builder.rs index d1ec1bb..5f8799d 100644 --- a/jwt-authorizer/src/builder.rs +++ b/jwt-authorizer/src/builder.rs @@ -222,7 +222,7 @@ where self } - /// Build axum layer + /// Build layer #[deprecated(since = "0.10.0", note = "please use `IntoLayer::into_layer()` instead")] pub async fn layer(self) -> Result, InitError> { let val = self.validation.unwrap_or_default(); diff --git a/jwt-authorizer/src/layer.rs b/jwt-authorizer/src/layer.rs index 0b96120..7ccde38 100644 --- a/jwt-authorizer/src/layer.rs +++ b/jwt-authorizer/src/layer.rs @@ -1,6 +1,6 @@ -use axum::extract::Request; use futures_core::ready; use futures_util::future::{self, BoxFuture}; +use http::Request; use jsonwebtoken::TokenData; use pin_project::pin_project; use serde::de::DeserializeOwned; @@ -15,25 +15,26 @@ use crate::authorizer::Authorizer; use crate::AuthError; /// Trait for authorizing requests. -pub trait Authorize { - type Future: Future>; +pub trait Authorize { + type Future: Future, AuthError>>; /// Authorize the request. /// /// If the future resolves to `Ok(request)` then the request is allowed through, otherwise not. - fn authorize(&self, request: Request) -> Self::Future; + fn authorize(&self, request: Request) -> Self::Future; } -impl Authorize for AuthorizationService +impl Authorize for AuthorizationService where + B: Send + 'static, C: Clone + DeserializeOwned + Send + Sync + 'static, { - type Future = BoxFuture<'static, Result>; + type Future = BoxFuture<'static, Result, AuthError>>; /// The authorizers are sequentially applied (check_auth) until one of them validates the token. /// If no authorizer validates the token the request is rejected. /// - fn authorize(&self, mut request: Request) -> Self::Future { + fn authorize(&self, mut request: Request) -> Self::Future { let tkns_auths: Vec<(String, Arc>)> = self .auths .iter() @@ -154,21 +155,22 @@ where } } -impl Service for AuthorizationService +impl Service> for AuthorizationService where - S: Service + Clone, + B: Send + 'static, + S: Service> + Clone, S::Response: From, C: Clone + DeserializeOwned + Send + Sync + 'static, { type Response = S::Response; type Error = S::Error; - type Future = ResponseFuture; + type Future = ResponseFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } - fn call(&mut self, req: Request) -> Self::Future { + fn call(&mut self, req: Request) -> Self::Future { let inner = self.inner.clone(); // take the service that was ready let inner = std::mem::replace(&mut self.inner, inner); @@ -184,13 +186,14 @@ where #[pin_project] /// Response future for [`AuthorizationService`]. -pub struct ResponseFuture +pub struct ResponseFuture where - S: Service, + B: Send + 'static, + S: Service>, C: Clone + DeserializeOwned + Send + Sync + 'static, { #[pin] - state: State< as Authorize>::Future, S::Future>, + state: State< as Authorize>::Future, S::Future>, service: S, } @@ -206,9 +209,10 @@ enum State { }, } -impl Future for ResponseFuture +impl Future for ResponseFuture where - S: Service, + B: Send, + S: Service>, S::Response: From, C: Clone + DeserializeOwned + Send + Sync, {