75 lines
2.1 KiB
Rust
75 lines
2.1 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use http::header::{HeaderMap, HeaderName, HeaderValue, InvalidHeaderValue, AUTHORIZATION};
|
|
|
|
use crate::{
|
|
ALGORITHM_FIELD, ALGORITHM_VALUE, CREATED_FIELD, EXPIRES_FIELD, HEADERS_FIELD, KEY_ID_FIELD,
|
|
SIGNATURE_FIELD,
|
|
};
|
|
|
|
const SIGNATURE_HEADER: &'static str = "Signature";
|
|
|
|
pub struct Signed {
|
|
signature: String,
|
|
sig_headers: Vec<String>,
|
|
created: DateTime<Utc>,
|
|
expires: DateTime<Utc>,
|
|
key_id: String,
|
|
}
|
|
|
|
pub struct Unsigned {
|
|
pub(crate) signing_string: String,
|
|
pub(crate) sig_headers: Vec<String>,
|
|
pub(crate) created: DateTime<Utc>,
|
|
pub(crate) expires: DateTime<Utc>,
|
|
}
|
|
|
|
impl Signed {
|
|
pub fn signature_header(self, hm: &mut HeaderMap) -> Result<(), InvalidHeaderValue> {
|
|
hm.insert(
|
|
AUTHORIZATION,
|
|
HeaderValue::from_str(&format!("Signature {}", self.into_header()))?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn authorization_header(self, hm: &mut HeaderMap) -> Result<(), InvalidHeaderValue> {
|
|
hm.insert(
|
|
HeaderName::from_static(SIGNATURE_HEADER),
|
|
HeaderValue::from_str(&self.into_header())?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
fn into_header(self) -> String {
|
|
let header_parts = [
|
|
(KEY_ID_FIELD, self.key_id),
|
|
(ALGORITHM_FIELD, ALGORITHM_VALUE.to_owned()),
|
|
(CREATED_FIELD, self.created.timestamp().to_string()),
|
|
(EXPIRES_FIELD, self.expires.timestamp().to_string()),
|
|
(HEADERS_FIELD, self.sig_headers.join(" ")),
|
|
(SIGNATURE_FIELD, self.signature),
|
|
];
|
|
|
|
header_parts
|
|
.iter()
|
|
.map(|(k, v)| format!("{}=\"{}\"", k, v))
|
|
.collect::<Vec<_>>()
|
|
.join(",")
|
|
}
|
|
}
|
|
|
|
impl Unsigned {
|
|
pub fn sign<F, E>(self, key_id: String, f: F) -> Result<Signed, E>
|
|
where
|
|
F: FnOnce(&str) -> Result<Vec<u8>, E>,
|
|
{
|
|
(f)(&self.signing_string).map(|v| Signed {
|
|
signature: base64::encode(&v),
|
|
sig_headers: self.sig_headers,
|
|
created: self.created,
|
|
expires: self.expires,
|
|
key_id,
|
|
})
|
|
}
|
|
}
|