mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-25 19:01:01 +00:00
Remove dependency on http
This commit is contained in:
parent
5daf0a78d1
commit
aefb08e627
4 changed files with 30 additions and 59 deletions
|
@ -12,4 +12,3 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
http = "0.1.18"
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use http::header::{HeaderMap, HeaderName, HeaderValue, InvalidHeaderValue, AUTHORIZATION};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ALGORITHM_FIELD, ALGORITHM_VALUE, CREATED_FIELD, EXPIRES_FIELD, HEADERS_FIELD, KEY_ID_FIELD,
|
ALGORITHM_FIELD, ALGORITHM_VALUE, CREATED_FIELD, EXPIRES_FIELD, HEADERS_FIELD, KEY_ID_FIELD,
|
||||||
SIGNATURE_FIELD,
|
SIGNATURE_FIELD,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SIGNATURE_HEADER: &'static str = "Signature";
|
|
||||||
|
|
||||||
pub struct Signed {
|
pub struct Signed {
|
||||||
signature: String,
|
signature: String,
|
||||||
sig_headers: Vec<String>,
|
sig_headers: Vec<String>,
|
||||||
|
@ -24,20 +21,12 @@ pub struct Unsigned {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Signed {
|
impl Signed {
|
||||||
pub fn signature_header(self, hm: &mut HeaderMap) -> Result<(), InvalidHeaderValue> {
|
pub fn signature_header(self) -> String {
|
||||||
hm.insert(
|
format!("Signature {}", self.into_header())
|
||||||
AUTHORIZATION,
|
|
||||||
HeaderValue::from_str(&format!("Signature {}", self.into_header()))?,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn authorization_header(self, hm: &mut HeaderMap) -> Result<(), InvalidHeaderValue> {
|
pub fn authorization_header(self) -> String {
|
||||||
hm.insert(
|
self.into_header()
|
||||||
HeaderName::from_static(SIGNATURE_HEADER),
|
|
||||||
HeaderValue::from_str(&self.into_header())?,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_header(self) -> String {
|
fn into_header(self) -> String {
|
||||||
|
|
39
src/lib.rs
39
src/lib.rs
|
@ -1,9 +1,4 @@
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use http::{
|
|
||||||
header::{HeaderMap, ToStrError},
|
|
||||||
method::Method,
|
|
||||||
uri::PathAndQuery,
|
|
||||||
};
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
pub mod create;
|
pub mod create;
|
||||||
|
@ -34,11 +29,11 @@ pub struct Config {
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn normalize(
|
pub fn normalize(
|
||||||
&self,
|
&self,
|
||||||
method: Method,
|
method: &str,
|
||||||
path_and_query: &PathAndQuery,
|
path_and_query: &str,
|
||||||
headers: &HeaderMap,
|
headers: &mut BTreeMap<String, String>,
|
||||||
) -> Result<Unsigned, ToStrError> {
|
) -> Unsigned {
|
||||||
let (sig_headers, mut btm) = build_headers_list(headers)?;
|
let sig_headers = build_headers_list(headers);
|
||||||
|
|
||||||
let created = Utc::now();
|
let created = Utc::now();
|
||||||
let expires = created + self.expires;
|
let expires = created + self.expires;
|
||||||
|
@ -49,15 +44,15 @@ impl Config {
|
||||||
Some(created),
|
Some(created),
|
||||||
Some(expires),
|
Some(expires),
|
||||||
&sig_headers,
|
&sig_headers,
|
||||||
&mut btm,
|
headers,
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Unsigned {
|
Unsigned {
|
||||||
signing_string,
|
signing_string,
|
||||||
sig_headers,
|
sig_headers,
|
||||||
created,
|
created,
|
||||||
expires,
|
expires,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate<F, T>(&self, unvalidated: Unvalidated, f: F) -> Result<T, ValidateError>
|
pub fn validate<F, T>(&self, unvalidated: Unvalidated, f: F) -> Result<T, ValidateError>
|
||||||
|
@ -81,17 +76,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_headers_list(
|
fn build_headers_list(btm: &BTreeMap<String, String>) -> Vec<String> {
|
||||||
headers: &HeaderMap,
|
|
||||||
) -> Result<(Vec<String>, BTreeMap<String, String>), ToStrError> {
|
|
||||||
let btm: BTreeMap<String, String> = headers
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| {
|
|
||||||
v.to_str()
|
|
||||||
.map(|v| (k.as_str().to_lowercase().to_owned(), v.to_owned()))
|
|
||||||
})
|
|
||||||
.collect::<Result<BTreeMap<String, String>, _>>()?;
|
|
||||||
|
|
||||||
let http_header_keys: Vec<String> = btm.keys().cloned().collect();
|
let http_header_keys: Vec<String> = btm.keys().cloned().collect();
|
||||||
|
|
||||||
let mut sig_headers = vec![
|
let mut sig_headers = vec![
|
||||||
|
@ -102,12 +87,12 @@ fn build_headers_list(
|
||||||
|
|
||||||
sig_headers.extend(http_header_keys);
|
sig_headers.extend(http_header_keys);
|
||||||
|
|
||||||
Ok((sig_headers, btm))
|
sig_headers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_signing_string(
|
fn build_signing_string(
|
||||||
method: Method,
|
method: &str,
|
||||||
path_and_query: &PathAndQuery,
|
path_and_query: &str,
|
||||||
created: Option<DateTime<Utc>>,
|
created: Option<DateTime<Utc>>,
|
||||||
expires: Option<DateTime<Utc>>,
|
expires: Option<DateTime<Utc>>,
|
||||||
sig_headers: &[String],
|
sig_headers: &[String],
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use chrono::{DateTime, TimeZone, Utc};
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
use http::{
|
use std::{
|
||||||
header::{HeaderMap, ToStrError},
|
collections::{BTreeMap, HashMap},
|
||||||
method::Method,
|
error::Error,
|
||||||
uri::PathAndQuery,
|
fmt,
|
||||||
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, error::Error, fmt, str::FromStr};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
build_headers_list, build_signing_string, ALGORITHM_FIELD, CREATED, CREATED_FIELD,
|
build_signing_string, ALGORITHM_FIELD, CREATED, CREATED_FIELD, EXPIRES_FIELD, HEADERS_FIELD,
|
||||||
EXPIRES_FIELD, HEADERS_FIELD, KEY_ID_FIELD, SIGNATURE_FIELD,
|
KEY_ID_FIELD, SIGNATURE_FIELD,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Unvalidated {
|
pub struct Unvalidated {
|
||||||
|
@ -76,22 +76,20 @@ impl Unvalidated {
|
||||||
impl ParsedHeader {
|
impl ParsedHeader {
|
||||||
pub fn to_unvalidated(
|
pub fn to_unvalidated(
|
||||||
self,
|
self,
|
||||||
method: Method,
|
method: &str,
|
||||||
path_and_query: &PathAndQuery,
|
path_and_query: &str,
|
||||||
headers: &HeaderMap,
|
headers: &mut BTreeMap<String, String>,
|
||||||
) -> Result<Unvalidated, ToStrError> {
|
) -> Unvalidated {
|
||||||
let (_, mut btm) = build_headers_list(headers)?;
|
|
||||||
|
|
||||||
let signing_string = build_signing_string(
|
let signing_string = build_signing_string(
|
||||||
method,
|
method,
|
||||||
path_and_query,
|
path_and_query,
|
||||||
self.created,
|
self.created,
|
||||||
self.expires,
|
self.expires,
|
||||||
&self.headers,
|
&self.headers,
|
||||||
&mut btm,
|
headers,
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Unvalidated {
|
Unvalidated {
|
||||||
key_id: self.key_id,
|
key_id: self.key_id,
|
||||||
signature: self.signature,
|
signature: self.signature,
|
||||||
parsed_at: self.parsed_at,
|
parsed_at: self.parsed_at,
|
||||||
|
@ -99,7 +97,7 @@ impl ParsedHeader {
|
||||||
created: self.created,
|
created: self.created,
|
||||||
expires: self.expires,
|
expires: self.expires,
|
||||||
signing_string,
|
signing_string,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue