http-signature-normalization/warp/src/lib.rs
2022-11-28 18:34:13 -06:00

74 lines
2.2 KiB
Rust

use http::{header::HeaderMap, Method};
pub use http_signature_normalization_http::{
verify::{Algorithm, DeprecatedAlgorithm, Unverified},
Config,
};
use std::{future::Future, pin::Pin};
use warp::{path::FullPath, Filter, Rejection};
#[cfg(feature = "digest")]
pub mod digest;
pub fn prepare_unverified(
config: Config,
) -> impl Filter<Extract = (Unverified,), Error = Rejection> + Clone {
warp::any()
.map(move || config.clone())
.and(warp::header::headers_cloned())
.and(warp::method())
.and(warp::path::full())
.and(warp::query::raw())
.and_then(
move |config: Config,
headers: HeaderMap,
method: Method,
path: FullPath,
query: String| {
let path_and_query = format!("{}?{}", path.as_str(), query).parse().unwrap();
async move {
config
.begin_verify(&method, Some(&path_and_query), headers)
.map_err(|_| warp::reject::not_found())
}
},
)
}
pub fn verify<T>(
config: Config,
verifier: impl Fn(Unverified) -> Pin<Box<dyn Future<Output = Result<T, ()>> + Send>>
+ Clone
+ Send
+ Sync,
) -> impl Filter<Extract = (T,), Error = Rejection> + Clone
where
T: Send,
{
warp::any()
.map(move || config.clone())
.and(warp::header::headers_cloned())
.and(warp::method())
.and(warp::path::full())
.and(warp::query::raw())
.and_then(move |config, headers, method, path, query| {
do_verify(config, headers, method, path, query, verifier.clone())
})
}
async fn do_verify<T>(
config: Config,
headers: HeaderMap,
method: Method,
path: FullPath,
query: String,
verifier: impl Fn(Unverified) -> Pin<Box<dyn Future<Output = Result<T, ()>> + Send>>,
) -> Result<T, warp::Rejection> {
let path_and_query = format!("{}?{}", path.as_str(), query).parse().unwrap();
match config.begin_verify(&method, Some(&path_and_query), headers) {
Ok(v) => verifier(v).await.map_err(|_| warp::reject::not_found()),
Err(_) => Err(warp::reject::not_found()),
}
}