Maintain OrderState within Order type
This commit is contained in:
parent
652c4815ec
commit
a2d4129201
|
@ -34,19 +34,20 @@ async fn main() -> anyhow::Result<()> {
|
|||
// process multiple orders in parallel for a single account.
|
||||
|
||||
let identifier = Identifier::Dns(opts.name);
|
||||
let (mut order, state) = account
|
||||
let mut order = account
|
||||
.new_order(&NewOrder {
|
||||
identifiers: &[identifier],
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let state = order.state();
|
||||
info!("order state: {:#?}", state);
|
||||
assert!(matches!(state.status, OrderStatus::Pending));
|
||||
|
||||
// Pick the desired challenge type and prepare the response.
|
||||
|
||||
let authorizations = order.authorizations(&state.authorizations).await.unwrap();
|
||||
let authorizations = order.authorizations().await.unwrap();
|
||||
let mut challenges = Vec::with_capacity(authorizations.len());
|
||||
for authz in &authorizations {
|
||||
match authz.status {
|
||||
|
@ -87,12 +88,12 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
let mut tries = 1u8;
|
||||
let mut delay = Duration::from_millis(250);
|
||||
let state = loop {
|
||||
loop {
|
||||
sleep(delay).await;
|
||||
let state = order.state().await.unwrap();
|
||||
let state = order.refresh().await.unwrap();
|
||||
if let OrderStatus::Ready | OrderStatus::Invalid = state.status {
|
||||
info!("order state: {:#?}", state);
|
||||
break state;
|
||||
break;
|
||||
}
|
||||
|
||||
delay *= 2;
|
||||
|
@ -104,10 +105,14 @@ async fn main() -> anyhow::Result<()> {
|
|||
return Err(anyhow::anyhow!("order is not ready"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if state.status == OrderStatus::Invalid {
|
||||
return Err(anyhow::anyhow!("order is invalid"));
|
||||
let state = order.state();
|
||||
if state.status != OrderStatus::Ready {
|
||||
return Err(anyhow::anyhow!(
|
||||
"unexpected order status: {:?}",
|
||||
state.status
|
||||
));
|
||||
}
|
||||
|
||||
let mut names = Vec::with_capacity(challenges.len());
|
||||
|
@ -125,7 +130,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
// Finalize the order and print certificate chain, private key and account credentials.
|
||||
|
||||
let cert_chain_pem = order.finalize(&csr, &state.finalize).await.unwrap();
|
||||
let cert_chain_pem = order.finalize(&csr).await.unwrap();
|
||||
info!("certficate chain:\n\n{}", cert_chain_pem,);
|
||||
info!("private key:\n\n{}", cert.serialize_private_key_pem());
|
||||
info!(
|
||||
|
|
63
src/lib.rs
63
src/lib.rs
|
@ -36,7 +36,8 @@ use types::{
|
|||
pub struct Order {
|
||||
account: Arc<AccountInner>,
|
||||
nonce: Option<String>,
|
||||
order_url: String,
|
||||
url: String,
|
||||
state: OrderState,
|
||||
}
|
||||
|
||||
impl Order {
|
||||
|
@ -55,12 +56,9 @@ impl Order {
|
|||
/// After the challenges have been set up, check the [`Order::state()`] to see
|
||||
/// if the order is ready to be finalized (or becomes invalid). Once it is
|
||||
/// ready, call `Order::finalize()` to get the certificate.
|
||||
pub async fn authorizations(
|
||||
&mut self,
|
||||
authz_urls: &[String],
|
||||
) -> Result<Vec<Authorization>, Error> {
|
||||
let mut authorizations = Vec::with_capacity(authz_urls.len());
|
||||
for url in authz_urls {
|
||||
pub async fn authorizations(&mut self) -> Result<Vec<Authorization>, Error> {
|
||||
let mut authorizations = Vec::with_capacity(self.state.authorizations.len());
|
||||
for url in &self.state.authorizations {
|
||||
authorizations.push(self.account.get(&mut self.nonce, url).await?);
|
||||
}
|
||||
Ok(authorizations)
|
||||
|
@ -77,15 +75,15 @@ impl Order {
|
|||
/// Request a certificate from the given Certificate Signing Request (CSR)
|
||||
///
|
||||
/// Creating a CSR is outside of the scope of instant-acme. Make sure you pass in a
|
||||
/// DER representation of the CSR in `csr_der` and the [`OrderState::finalize`] URL
|
||||
/// in `finalize_url`. The resulting `String` will contain the PEM-encoded certificate chain.
|
||||
pub async fn finalize(&mut self, csr_der: &[u8], finalize_url: &str) -> Result<String, Error> {
|
||||
/// DER representation of the CSR in `csr_der`. The resulting `String` will contain the
|
||||
/// PEM-encoded certificate chain.
|
||||
pub async fn finalize(&mut self, csr_der: &[u8]) -> Result<String, Error> {
|
||||
let rsp = self
|
||||
.account
|
||||
.post(
|
||||
Some(&FinalizeRequest::new(csr_der)),
|
||||
self.nonce.take(),
|
||||
finalize_url,
|
||||
&self.state.finalize,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -129,9 +127,28 @@ impl Order {
|
|||
self.account.get(&mut self.nonce, challenge_url).await
|
||||
}
|
||||
|
||||
/// Get the current state of the order
|
||||
pub async fn state(&mut self) -> Result<OrderState, Error> {
|
||||
self.account.get(&mut self.nonce, &self.order_url).await
|
||||
/// Refresh the current state of the order
|
||||
pub async fn refresh(&mut self) -> Result<&OrderState, Error> {
|
||||
let rsp = self
|
||||
.account
|
||||
.post(None::<&Empty>, self.nonce.take(), &self.url)
|
||||
.await?;
|
||||
|
||||
self.nonce = nonce_from_response(&rsp);
|
||||
self.state = Problem::check::<OrderState>(rsp).await?;
|
||||
Ok(&self.state)
|
||||
}
|
||||
|
||||
/// Get the last known state of the order
|
||||
///
|
||||
/// Call `refresh()` to get the latest state from the server.
|
||||
pub fn state(&mut self) -> &OrderState {
|
||||
&self.state
|
||||
}
|
||||
|
||||
/// Get the URL of the order
|
||||
pub fn url(&self) -> &str {
|
||||
&self.url
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,11 +202,8 @@ impl Account {
|
|||
|
||||
/// Create a new order based on the given [`NewOrder`]
|
||||
///
|
||||
/// Returns both an [`Order`] instance and the initial [`OrderState`].
|
||||
pub async fn new_order<'a>(
|
||||
&'a self,
|
||||
order: &NewOrder<'_>,
|
||||
) -> Result<(Order, OrderState), Error> {
|
||||
/// Returns an [`Order`] instance. Use the [`Order::state()`] method to inspect its state.
|
||||
pub async fn new_order<'a>(&'a self, order: &NewOrder<'_>) -> Result<Order, Error> {
|
||||
let rsp = self
|
||||
.inner
|
||||
.post(Some(order), None, &self.inner.client.urls.new_order)
|
||||
|
@ -202,15 +216,12 @@ impl Account {
|
|||
.and_then(|hv| hv.to_str().ok())
|
||||
.map(|s| s.to_owned());
|
||||
|
||||
let status = Problem::check(rsp).await?;
|
||||
Ok((
|
||||
Order {
|
||||
Ok(Order {
|
||||
account: self.inner.clone(),
|
||||
nonce,
|
||||
order_url: order_url.ok_or("no order URL found")?,
|
||||
},
|
||||
status,
|
||||
))
|
||||
url: order_url.ok_or("no order URL found")?,
|
||||
state: Problem::check::<OrderState>(rsp).await?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the account's credentials, which can be serialized
|
||||
|
|
Loading…
Reference in New Issue