mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-28 04:11:02 +00:00
Update to actix-web 4.0.0-beta.3
This commit is contained in:
parent
983d48d76a
commit
d3c715ecc5
9 changed files with 42 additions and 47 deletions
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "http-signature-normalization-actix"
|
name = "http-signature-normalization-actix"
|
||||||
description = "An HTTP Signatures library that leaves the signing to you"
|
description = "An HTTP Signatures library that leaves the signing to you"
|
||||||
version = "0.5.0-beta.2"
|
version = "0.5.0-beta.3"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
license-file = "LICENSE"
|
license-file = "LICENSE"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -25,9 +25,9 @@ name = "client"
|
||||||
required-features = ["sha-2"]
|
required-features = ["sha-2"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "4.0.0-beta.1", default-features = false }
|
actix-web = { version = "4.0.0-beta.3", default-features = false }
|
||||||
awc = { version = "3.0.0-beta.1", default-features = false }
|
awc = "3.0.0-beta.2"
|
||||||
base64 = { version = "0.12", optional = true }
|
base64 = { version = "0.13", optional = true }
|
||||||
chrono = "0.4.6"
|
chrono = "0.4.6"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
http-signature-normalization = { version = "0.5.1", path = ".." }
|
http-signature-normalization = { version = "0.5.1", path = ".." }
|
||||||
|
@ -37,5 +37,5 @@ sha3 = { version = "0.9", optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "=2.0.0-beta.1"
|
actix-rt = "2.0.2"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
|
|
|
@ -13,10 +13,10 @@ This crate provides extensions the ClientRequest type from Actix Web, and provid
|
||||||
|
|
||||||
#### First, add this crate to your dependencies
|
#### First, add this crate to your dependencies
|
||||||
```toml
|
```toml
|
||||||
actix-rt = "=2.0.0-beta.1"
|
actix-rt = "2.0.2"
|
||||||
actix-web = "4.0.0-beta.1"
|
actix-web = "4.0.0-beta.3"
|
||||||
thiserror = "0.1"
|
thiserror = "0.1"
|
||||||
http-signature-normalization-actix = { version = "0.5.0-beta.1", default-features = false, features = ["sha-2"] }
|
http-signature-normalization-actix = { version = "0.5.0-beta.2", default-features = false, features = ["sha-2"] }
|
||||||
sha2 = "0.9"
|
sha2 = "0.9"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ async fn request(config: Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let mut response = Client::default()
|
let mut response = Client::default()
|
||||||
.post("http://127.0.0.1:8010/")
|
.post("http://127.0.0.1:8010/")
|
||||||
.header("User-Agent", "Actix Web")
|
.append_header(("User-Agent", "Actix Web"))
|
||||||
.header("Accept", "text/plain")
|
.append_header(("Accept", "text/plain"))
|
||||||
.set(actix_web::http::header::Date(SystemTime::now().into()))
|
.insert_header(actix_web::http::header::Date(SystemTime::now().into()))
|
||||||
.signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| {
|
.signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| {
|
||||||
println!("Signing String\n{}", s);
|
println!("Signing String\n{}", s);
|
||||||
Ok(base64::encode(s)) as Result<_, MyError>
|
Ok(base64::encode(s)) as Result<_, MyError>
|
||||||
|
@ -62,11 +62,8 @@ pub enum MyError {
|
||||||
Canceled,
|
Canceled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BlockingError<MyError>> for MyError {
|
impl From<BlockingError> for MyError {
|
||||||
fn from(b: BlockingError<MyError>) -> Self {
|
fn from(_: BlockingError) -> Self {
|
||||||
match b {
|
MyError::Canceled
|
||||||
BlockingError::Error(e) => e,
|
|
||||||
_ => MyError::Canceled,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,11 +111,11 @@ where
|
||||||
type Error = actix_web::Error;
|
type Error = actix_web::Error;
|
||||||
type Future = Pin<Box<FutResult<Self::Response, Self::Error>>>;
|
type Future = Pin<Box<FutResult<Self::Response, Self::Error>>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
self.0.poll_ready(cx)
|
self.0.poll_ready(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
||||||
if let Some(digest) = req.headers().get("Digest") {
|
if let Some(digest) = req.headers().get("Digest") {
|
||||||
let vec = match parse_digest(digest) {
|
let vec = match parse_digest(digest) {
|
||||||
Some(vec) => vec,
|
Some(vec) => vec,
|
||||||
|
@ -164,7 +164,7 @@ where
|
||||||
verify_digest.update(&bytes2.as_ref());
|
verify_digest.update(&bytes2.as_ref());
|
||||||
Ok(verify_digest) as Result<T, VerifyError>
|
Ok(verify_digest) as Result<T, VerifyError>
|
||||||
})
|
})
|
||||||
.await?;
|
.await??;
|
||||||
|
|
||||||
if tx.is_closed() {
|
if tx.is_closed() {
|
||||||
warn!("Payload dropped. If this was unexpected, it could be that the payload isn't required in the route this middleware is guarding");
|
warn!("Payload dropped. If this was unexpected, it could be that the payload isn't required in the route this middleware is guarding");
|
||||||
|
@ -174,7 +174,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let verified =
|
let verified =
|
||||||
web::block(move || Ok(verify_digest.verify(&vec)) as Result<_, VerifyError>).await?;
|
web::block(move || Ok(verify_digest.verify(&vec)) as Result<_, VerifyError>).await??;
|
||||||
|
|
||||||
if verified {
|
if verified {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//! request when request bodies are present
|
//! request when request bodies are present
|
||||||
|
|
||||||
use actix_web::{client::ClientRequest, error::BlockingError, http::header::InvalidHeaderValue};
|
use actix_web::{client::ClientRequest, error::BlockingError, http::header::InvalidHeaderValue};
|
||||||
|
use awc::SendClientRequest;
|
||||||
use std::{fmt::Display, future::Future, pin::Pin};
|
use std::{fmt::Display, future::Future, pin::Pin};
|
||||||
|
|
||||||
use crate::{Config, PrepareSignError, Sign};
|
use crate::{Config, PrepareSignError, Sign};
|
||||||
|
@ -51,7 +52,7 @@ pub trait SignExt: Sign {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -73,7 +74,7 @@ pub trait SignExt: Sign {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -115,7 +116,7 @@ where
|
||||||
///
|
///
|
||||||
/// This is analogous to `ClientRequest::send_body` and uses the body provided when producing
|
/// This is analogous to `ClientRequest::send_body` and uses the body provided when producing
|
||||||
/// the digest
|
/// the digest
|
||||||
pub fn send(self) -> awc::SendClientRequest {
|
pub fn send(self) -> SendClientRequest {
|
||||||
self.req.send_body(self.body.as_ref().to_vec())
|
self.req.send_body(self.body.as_ref().to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl SignExt for ClientRequest {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -35,10 +35,10 @@ impl SignExt for ClientRequest {
|
||||||
let d = digest.compute(v.as_ref());
|
let d = digest.compute(v.as_ref());
|
||||||
Ok((d, v)) as Result<(String, V), E>
|
Ok((d, v)) as Result<(String, V), E>
|
||||||
})
|
})
|
||||||
.await?;
|
.await??;
|
||||||
|
|
||||||
let c = self
|
let c = self
|
||||||
.set_header("Digest", format!("{}={}", D::NAME, d))
|
.insert_header(("Digest", format!("{}={}", D::NAME, d)))
|
||||||
.authorization_signature(config, key_id, f)
|
.authorization_signature(config, key_id, f)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ impl SignExt for ClientRequest {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<DigestClient<V>, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -72,10 +72,10 @@ impl SignExt for ClientRequest {
|
||||||
let d = digest.compute(v.as_ref());
|
let d = digest.compute(v.as_ref());
|
||||||
Ok((d, v)) as Result<(String, V), E>
|
Ok((d, v)) as Result<(String, V), E>
|
||||||
})
|
})
|
||||||
.await?;
|
.await??;
|
||||||
|
|
||||||
let c = self
|
let c = self
|
||||||
.set_header("Digest", format!("{}={}", D::NAME, d))
|
.insert_header(("Digest", format!("{}={}", D::NAME, d)))
|
||||||
.signature(config, key_id, f)
|
.signature(config, key_id, f)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -151,12 +151,9 @@
|
||||||
//! Canceled,
|
//! Canceled,
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! impl From<BlockingError<MyError>> for MyError {
|
//! impl From<BlockingError> for MyError {
|
||||||
//! fn from(b: BlockingError<MyError>) -> Self {
|
//! fn from(_: BlockingError) -> Self {
|
||||||
//! match b {
|
//! MyError::Canceled,
|
||||||
//! BlockingError::Error(e) => e,
|
|
||||||
//! _ => MyError::Canceled,
|
|
||||||
//! }
|
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -243,7 +240,7 @@ pub trait Sign {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -261,7 +258,7 @@ pub trait Sign {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
|
|
@ -90,13 +90,13 @@ where
|
||||||
|
|
||||||
impl<T, S, B> VerifyMiddleware<T, S>
|
impl<T, S, B> VerifyMiddleware<T, S>
|
||||||
where
|
where
|
||||||
T: SignatureVerify + 'static,
|
T: SignatureVerify + Clone + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
|
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
|
||||||
B: MessageBody + 'static,
|
B: MessageBody + 'static,
|
||||||
{
|
{
|
||||||
fn handle(
|
fn handle(
|
||||||
&mut self,
|
&self,
|
||||||
req: ServiceRequest,
|
req: ServiceRequest,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<ServiceResponse<B>, Error>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<ServiceResponse<B>, Error>>>> {
|
||||||
let res = self.1.begin_verify(
|
let res = self.1.begin_verify(
|
||||||
|
@ -133,7 +133,7 @@ where
|
||||||
let key_id = unverified.key_id().to_owned();
|
let key_id = unverified.key_id().to_owned();
|
||||||
|
|
||||||
let f1 = unverified.verify(|signature, signing_string| {
|
let f1 = unverified.verify(|signature, signing_string| {
|
||||||
self.4.signature_verify(
|
self.4.clone().signature_verify(
|
||||||
algorithm,
|
algorithm,
|
||||||
key_id.clone(),
|
key_id.clone(),
|
||||||
signature.to_string(),
|
signature.to_string(),
|
||||||
|
@ -218,11 +218,11 @@ where
|
||||||
type Error = actix_web::Error;
|
type Error = actix_web::Error;
|
||||||
type Future = Pin<Box<FutResult<Self::Response, Self::Error>>>;
|
type Future = Pin<Box<FutResult<Self::Response, Self::Error>>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
self.0.poll_ready(cx)
|
self.0.poll_ready(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: ServiceRequest) -> Self::Future {
|
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||||
let authorization = req.headers().get("Authorization").is_some();
|
let authorization = req.headers().get("Authorization").is_some();
|
||||||
let signature = req.headers().get("Signature").is_some();
|
let signature = req.headers().get("Signature").is_some();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ impl Sign for ClientRequest {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -38,7 +38,7 @@ impl Sign for ClientRequest {
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
) -> Pin<Box<dyn Future<Output = Result<Self, E>>>>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>>
|
E: From<BlockingError>
|
||||||
+ From<PrepareSignError>
|
+ From<PrepareSignError>
|
||||||
+ From<InvalidHeaderValue>
|
+ From<InvalidHeaderValue>
|
||||||
+ std::fmt::Debug
|
+ std::fmt::Debug
|
||||||
|
@ -63,7 +63,7 @@ async fn prepare<F, E, K>(
|
||||||
) -> Result<Signed, E>
|
) -> Result<Signed, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<BlockingError<E>> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
E: From<BlockingError> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
||||||
K: Display,
|
K: Display,
|
||||||
{
|
{
|
||||||
let mut headers = request.headers().clone();
|
let mut headers = request.headers().clone();
|
||||||
|
@ -93,7 +93,7 @@ where
|
||||||
|
|
||||||
let key_id = key_id.to_string();
|
let key_id = key_id.to_string();
|
||||||
|
|
||||||
let signed = web::block(move || unsigned.sign(key_id, f)).await?;
|
let signed = web::block(move || unsigned.sign(key_id, f)).await??;
|
||||||
|
|
||||||
Ok(signed)
|
Ok(signed)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue