acme: define trait to abstract over signer types

This commit is contained in:
Dirkjan Ochtman 2022-05-10 14:12:25 +02:00 committed by Dirkjan Ochtman
parent bed1565783
commit 8604aa483e
1 changed files with 31 additions and 4 deletions

View File

@ -104,7 +104,7 @@ impl Account {
let client = Client::new(server_url).await?; let client = Client::new(server_url).await?;
let key = Key::generate()?; let key = Key::generate()?;
let nonce = client.nonce().await?; let nonce = client.nonce().await?;
let header = key.key_header(&nonce, &client.urls.new_account); let header = key.header(&nonce, &client.urls.new_account);
let body = key.signed_json(Some(account), header)?; let body = key.signed_json(Some(account), header)?;
let rsp = client let rsp = client
@ -236,7 +236,7 @@ impl AccountInner {
None => self.client.nonce().await?, None => self.client.nonce().await?,
}; };
let header = self.key_id_header(&nonce, url); let header = self.header(&nonce, url);
let body = self.key.signed_json(payload, header)?; let body = self.key.signed_json(payload, header)?;
Ok(self Ok(self
.client .client
@ -247,8 +247,10 @@ impl AccountInner {
.send() .send()
.await?) .await?)
} }
}
fn key_id_header<'n, 'u: 'n, 'a: 'u>(&'a self, nonce: &'n str, url: &'u str) -> Header<'n> { impl Signer for AccountInner {
fn header<'n, 'u: 'n, 's: 'u>(&'s self, nonce: &'n str, url: &'u str) -> Header<'n> {
Header { Header {
alg: self.key.signing_algorithm, alg: self.key.signing_algorithm,
key: KeyOrKeyId::KeyId(&self.id), key: KeyOrKeyId::KeyId(&self.id),
@ -256,6 +258,10 @@ impl AccountInner {
url, url,
} }
} }
fn key(&self) -> &Key {
&self.key
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -339,8 +345,10 @@ impl Key {
signature: base64::encode_config(signature.as_ref(), URL_SAFE_NO_PAD), signature: base64::encode_config(signature.as_ref(), URL_SAFE_NO_PAD),
})?)) })?))
} }
}
fn key_header<'n, 'u: 'n, 'k: 'u>(&'k self, nonce: &'n str, url: &'u str) -> Header<'n> { impl Signer for Key {
fn header<'n, 'u: 'n, 's: 'u>(&'s self, nonce: &'n str, url: &'u str) -> Header<'n> {
Header { Header {
alg: self.signing_algorithm, alg: self.signing_algorithm,
key: KeyOrKeyId::from_key(&self.inner), key: KeyOrKeyId::from_key(&self.inner),
@ -348,6 +356,25 @@ impl Key {
url, url,
} }
} }
fn key(&self) -> &Key {
self
}
}
trait Signer {
fn signed_json(
&self,
payload: Option<&impl Serialize>,
nonce: &str,
url: &str,
) -> Result<Body, Error> {
self.key().signed_json(payload, self.header(nonce, url))
}
fn header<'n, 'u: 'n, 's: 'u>(&'s self, nonce: &'n str, url: &'u str) -> Header<'n>;
fn key(&self) -> &Key;
} }
fn nonce_from_response(rsp: &Response) -> Option<String> { fn nonce_from_response(rsp: &Response) -> Option<String> {