use std::sync::Arc;
use crate::api::{ApiAccount, ApiDirectory, ApiIdentifier, ApiOrder, ApiRevocation};
use crate::cert::Certificate;
use crate::error::*;
use crate::order::{NewOrder, Order};
use crate::req::req_expect_header;
use crate::trans::Transport;
use crate::util::{base64url, read_json};
mod akey;
pub(crate) use self::akey::AcmeKey;
#[derive(Clone, Debug)]
pub(crate) struct AccountInner {
pub transport: Transport,
pub api_account: ApiAccount,
pub api_directory: ApiDirectory,
}
#[derive(Clone)]
pub struct Account {
inner: Arc<AccountInner>,
}
impl Account {
pub(crate) fn new(
transport: Transport,
api_account: ApiAccount,
api_directory: ApiDirectory,
) -> Self {
Account {
inner: Arc::new(AccountInner {
transport,
api_account,
api_directory,
}),
}
}
pub fn acme_private_key_pem(&self) -> Result<String> {
let pem = String::from_utf8(self.inner.transport.acme_key().to_pem()?)?;
Ok(pem)
}
pub fn new_order(&self, primary_name: &str, alt_names: &[&str]) -> Result<NewOrder> {
let prim_arr = [primary_name];
let domains = prim_arr.iter().chain(alt_names);
let order = ApiOrder {
identifiers: domains
.map(|s| ApiIdentifier {
_type: "dns".into(),
value: s.to_string(),
})
.collect(),
..Default::default()
};
let new_order_url = &self.inner.api_directory.newOrder;
let res = self.inner.transport.call(new_order_url, &order)?;
let order_url = req_expect_header(&res, "location")?;
let api_order: ApiOrder = read_json(res)?;
let order = Order::new(&self.inner, api_order, order_url);
Ok(NewOrder { order })
}
pub fn revoke_certificate(&self, cert: &Certificate, reason: RevocationReason) -> Result<()> {
let certificate = base64url(&cert.certificate_der()?);
let revoc = ApiRevocation {
certificate,
reason: reason as usize,
};
let url = &self.inner.api_directory.revokeCert;
self.inner.transport.call(url, &revoc)?;
Ok(())
}
pub fn api_account(&self) -> &ApiAccount {
&self.inner.api_account
}
}
pub enum RevocationReason {
Unspecified = 0,
KeyCompromise = 1,
CACompromise = 2,
AffiliationChanged = 3,
Superseded = 4,
CessationOfOperation = 5,
CertificateHold = 6,
RemoveFromCRL = 8,
PrivilegeWithdrawn = 9,
AACompromise = 10,
}
#[cfg(test)]
mod test {
use crate::*;
#[test]
fn test_create_order() -> Result<()> {
let server = crate::test::with_directory_server();
let url = DirectoryUrl::Other(&server.dir_url);
let dir = Directory::from_url(url)?;
let acc = dir.register_account(vec!["mailto:foo@bar.com".to_string()])?;
let _ = acc.new_order("acmetest.example.com", &[])?;
Ok(())
}
}