Add Verified FromRequest types for optional middlewares

This commit is contained in:
asonix 2019-09-13 18:27:04 -05:00
parent fef18d96db
commit f4139af189
4 changed files with 49 additions and 12 deletions

View file

@ -33,7 +33,7 @@ impl SignatureVerify for MyVerify {
}
}
fn index() -> &'static str {
fn index(_: (DigestVerified, SignatureVerified)) -> &'static str {
"Eyyyyup"
}
@ -44,8 +44,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
HttpServer::new(move || {
App::new()
.wrap(VerifyDigest::new(Sha256::new()))
.wrap(VerifySignature::new(MyVerify, config.clone()).authorization())
.wrap(VerifyDigest::new(Sha256::new()).optional())
.wrap(
VerifySignature::new(MyVerify, config.clone())
.authorization()
.optional(),
)
.route("/", web::post().to(index))
})
.bind("127.0.0.1:8010")?

View file

@ -1,9 +1,9 @@
use actix_web::{
dev::{Body, Service, ServiceRequest, ServiceResponse, Transform},
dev::{Body, Payload, Service, ServiceRequest, ServiceResponse, Transform},
error::PayloadError,
http::header::HeaderValue,
web::Bytes,
HttpMessage, HttpResponse, ResponseError,
FromRequest, HttpMessage, HttpRequest, HttpResponse, ResponseError,
};
use failure::Fail;
use futures::{
@ -15,9 +15,10 @@ use std::{cell::RefCell, rc::Rc};
use super::{DigestPart, DigestVerify};
#[derive(Copy, Clone, Debug)]
pub struct DigestVerified;
pub struct VerifyDigest<T>(bool, T);
pub struct VerifyMiddleware<T, S>(Rc<RefCell<S>>, bool, T);
#[derive(Debug, Fail)]
#[fail(display = "Error verifying digest")]
pub struct VerifyError;
@ -35,6 +36,19 @@ where
}
}
impl FromRequest for DigestVerified {
type Error = VerifyError;
type Future = Result<Self, Self::Error>;
type Config = ();
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
req.extensions()
.get::<Self>()
.map(|s| *s)
.ok_or(VerifyError)
}
}
impl<T, S> Transform<S> for VerifyDigest<T>
where
T: DigestVerify + Clone + 'static,
@ -98,6 +112,8 @@ where
.into(),
);
req.extensions_mut().insert(DigestVerified);
Either::A(service.borrow_mut().call(req))
} else {
Either::B(err(VerifyError.into()))

View file

@ -16,13 +16,15 @@ pub mod create;
pub mod middleware;
pub mod prelude {
pub use crate::{
middleware::VerifySignature, verify::Unverified, Config, Sign, SignatureVerify, Verify,
VerifyError,
middleware::{SignatureVerified, VerifySignature},
verify::Unverified,
Config, Sign, SignatureVerify, Verify, VerifyError,
};
#[cfg(feature = "digest")]
pub use crate::digest::{
middleware::VerifyDigest, DigestClient, DigestCreate, DigestPart, DigestVerify, SignExt,
middleware::{DigestVerified, VerifyDigest},
DigestClient, DigestCreate, DigestPart, DigestVerify, SignExt,
};
pub use actix_web::http::header::{InvalidHeaderValue, ToStrError};

View file

@ -1,7 +1,6 @@
use actix_web::{
body::Body,
dev::{Service, ServiceRequest, ServiceResponse, Transform},
HttpResponse, ResponseError,
dev::{Body, Payload, Service, ServiceRequest, ServiceResponse, Transform},
FromRequest, HttpMessage, HttpRequest, HttpResponse, ResponseError,
};
use failure::Fail;
use futures::{
@ -12,6 +11,8 @@ use std::{cell::RefCell, rc::Rc};
use crate::{Config, SignatureVerify};
#[derive(Copy, Clone, Debug)]
pub struct SignatureVerified;
#[derive(Clone, Debug)]
pub struct VerifySignature<T>(T, Config, HeaderKind, bool);
#[derive(Clone, Debug)]
@ -84,6 +85,7 @@ where
.from_err::<actix_web::Error>()
.and_then(move |verified| {
if verified {
req.extensions_mut().insert(SignatureVerified);
Either::A(service.borrow_mut().call(req))
} else {
Either::B(err(VerifyError.into()))
@ -103,6 +105,19 @@ impl HeaderKind {
}
}
impl FromRequest for SignatureVerified {
type Error = VerifyError;
type Future = Result<Self, Self::Error>;
type Config = ();
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
req.extensions()
.get::<Self>()
.map(|s| *s)
.ok_or(VerifyError)
}
}
impl<T, S> Transform<S> for VerifySignature<T>
where
T: SignatureVerify + Clone + 'static,