]>
Commit | Line | Data |
---|---|---|
7bd0bfe1 WB |
1 | //! Authorization and Challenge data. |
2 | ||
aa230682 WB |
3 | use std::collections::HashMap; |
4 | ||
5 | use serde::{Deserialize, Serialize}; | |
6 | use serde_json::Value; | |
7 | ||
8 | use crate::order::Identifier; | |
afc59f6d WB |
9 | use crate::request::Request; |
10 | use crate::Error; | |
aa230682 | 11 | |
5f0ba968 | 12 | /// Status of an [`Authorization`]. |
dbabed68 | 13 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] |
aa230682 WB |
14 | #[serde(rename_all = "lowercase")] |
15 | pub enum Status { | |
7bd0bfe1 | 16 | /// The authorization was deactivated by the client. |
aa230682 | 17 | Deactivated, |
7bd0bfe1 WB |
18 | |
19 | /// The authorization expired. | |
aa230682 | 20 | Expired, |
7bd0bfe1 WB |
21 | |
22 | /// The authorization failed and is now invalid. | |
aa230682 | 23 | Invalid, |
7bd0bfe1 WB |
24 | |
25 | /// Validation is pending. | |
aa230682 | 26 | Pending, |
7bd0bfe1 WB |
27 | |
28 | /// The authorization was revoked by the server. | |
aa230682 | 29 | Revoked, |
7bd0bfe1 WB |
30 | |
31 | /// The identifier is authorized. | |
aa230682 WB |
32 | Valid, |
33 | } | |
34 | ||
5a70f0c3 WB |
35 | impl Status { |
36 | /// Convenience method to check if the status is 'pending'. | |
37 | #[inline] | |
38 | pub fn is_pending(self) -> bool { | |
39 | self == Status::Pending | |
40 | } | |
37b4c4f6 WB |
41 | |
42 | /// Convenience method to check if the status is 'valid'. | |
43 | #[inline] | |
44 | pub fn is_valid(self) -> bool { | |
45 | self == Status::Valid | |
46 | } | |
5a70f0c3 WB |
47 | } |
48 | ||
7bd0bfe1 WB |
49 | /// Represents an authorization state for an order. The user is expected to pick a challenge, |
50 | /// execute it, and the request validation for it. | |
aa230682 WB |
51 | #[derive(Deserialize, Serialize)] |
52 | #[serde(rename_all = "camelCase")] | |
53 | pub struct Authorization { | |
7bd0bfe1 | 54 | /// The identifier (usually domain name) this authorization is for. |
aa230682 WB |
55 | pub identifier: Identifier, |
56 | ||
7bd0bfe1 | 57 | /// The current status of this authorization entry. |
aa230682 WB |
58 | pub status: Status, |
59 | ||
7bd0bfe1 | 60 | /// Expiration date for the authorization. |
aa230682 WB |
61 | #[serde(skip_serializing_if = "Option::is_none")] |
62 | pub expires: Option<String>, | |
63 | ||
7bd0bfe1 | 64 | /// List of challenges which can be used to complete this authorization. |
aa230682 WB |
65 | pub challenges: Vec<Challenge>, |
66 | ||
7bd0bfe1 | 67 | /// The authorization is for a wildcard domain. |
aa230682 WB |
68 | #[serde(default, skip_serializing_if = "is_false")] |
69 | pub wildcard: bool, | |
70 | } | |
71 | ||
7bd0bfe1 | 72 | /// The state of a challenge. |
dbabed68 | 73 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] |
afc59f6d WB |
74 | #[serde(rename_all = "lowercase")] |
75 | pub enum ChallengeStatus { | |
7bd0bfe1 | 76 | /// The challenge is pending and has not been validated yet. |
afc59f6d | 77 | Pending, |
7bd0bfe1 WB |
78 | |
79 | /// The valiation is in progress. | |
afc59f6d | 80 | Processing, |
7bd0bfe1 WB |
81 | |
82 | /// The challenge was successfully validated. | |
afc59f6d | 83 | Valid, |
7bd0bfe1 WB |
84 | |
85 | /// Validation of this challenge failed. | |
afc59f6d WB |
86 | Invalid, |
87 | } | |
88 | ||
5a70f0c3 WB |
89 | impl ChallengeStatus { |
90 | /// Convenience method to check if the status is 'pending'. | |
91 | #[inline] | |
92 | pub fn is_pending(self) -> bool { | |
93 | self == ChallengeStatus::Pending | |
94 | } | |
37b4c4f6 WB |
95 | |
96 | /// Convenience method to check if the status is 'valid'. | |
97 | #[inline] | |
98 | pub fn is_valid(self) -> bool { | |
99 | self == ChallengeStatus::Valid | |
100 | } | |
5a70f0c3 WB |
101 | } |
102 | ||
7bd0bfe1 | 103 | /// A challenge object contains information on how to complete an authorization for an order. |
aa230682 WB |
104 | #[derive(Deserialize, Serialize)] |
105 | #[serde(rename_all = "camelCase")] | |
106 | pub struct Challenge { | |
7bd0bfe1 | 107 | /// The challenge type (such as `"dns-01"`). |
aa230682 WB |
108 | #[serde(rename = "type")] |
109 | pub ty: String, | |
110 | ||
7bd0bfe1 | 111 | /// The current challenge status. |
afc59f6d WB |
112 | pub status: ChallengeStatus, |
113 | ||
7bd0bfe1 | 114 | /// The URL used to post to in order to begin the validation for this challenge. |
afc59f6d WB |
115 | pub url: String, |
116 | ||
7bd0bfe1 | 117 | /// Contains the remaining fields of the Challenge object, such as the `token`. |
aa230682 WB |
118 | #[serde(flatten)] |
119 | pub data: HashMap<String, Value>, | |
120 | } | |
121 | ||
122 | impl Challenge { | |
123 | /// Most challenges have a `token` used for key authorizations. This is a convenience helper to | |
124 | /// access it. | |
125 | pub fn token(&self) -> Option<&str> { | |
126 | self.data.get("token").and_then(Value::as_str) | |
127 | } | |
128 | } | |
129 | ||
130 | /// Serde helper | |
131 | #[inline] | |
132 | fn is_false(b: &bool) -> bool { | |
133 | !*b | |
134 | } | |
afc59f6d WB |
135 | |
136 | /// Represents an in-flight query for an authorization. | |
137 | /// | |
7bd0bfe1 | 138 | /// This is created via [`Account::get_authorization`](crate::Account::get_authorization()). |
afc59f6d WB |
139 | pub struct GetAuthorization { |
140 | //order: OrderData, | |
7bd0bfe1 WB |
141 | /// The request to send to the ACME provider. This is wrapped in an option in order to allow |
142 | /// moving it out instead of copying the contents. | |
143 | /// | |
144 | /// When generated via [`Account::get_authorization`](crate::Account::get_authorization()), | |
145 | /// this is guaranteed to be `Some`. | |
146 | /// | |
147 | /// The response should be passed to the the [`response`](GetAuthorization::response()) method. | |
afc59f6d WB |
148 | pub request: Option<Request>, |
149 | } | |
150 | ||
151 | impl GetAuthorization { | |
152 | pub(crate) fn new(request: Request) -> Self { | |
153 | Self { | |
154 | request: Some(request), | |
155 | } | |
156 | } | |
157 | ||
158 | /// Deal with the response we got from the server. | |
159 | pub fn response(self, response_body: &[u8]) -> Result<Authorization, Error> { | |
160 | Ok(serde_json::from_slice(response_body)?) | |
161 | } | |
162 | } |