]> git.proxmox.com Git - proxmox.git/blob - src/authorization.rs
expand helper function by eab credentials
[proxmox.git] / src / authorization.rs
1 //! Authorization and Challenge data.
2
3 use std::collections::HashMap;
4
5 use serde::{Deserialize, Serialize};
6 use serde_json::Value;
7
8 use crate::order::Identifier;
9 use crate::request::Request;
10 use crate::Error;
11
12 /// Status of an [`Authorization`].
13 #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
14 #[serde(rename_all = "lowercase")]
15 pub enum Status {
16 /// The authorization was deactivated by the client.
17 Deactivated,
18
19 /// The authorization expired.
20 Expired,
21
22 /// The authorization failed and is now invalid.
23 Invalid,
24
25 /// Validation is pending.
26 Pending,
27
28 /// The authorization was revoked by the server.
29 Revoked,
30
31 /// The identifier is authorized.
32 Valid,
33 }
34
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 }
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 }
47 }
48
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.
51 #[derive(Deserialize, Serialize)]
52 #[serde(rename_all = "camelCase")]
53 pub struct Authorization {
54 /// The identifier (usually domain name) this authorization is for.
55 pub identifier: Identifier,
56
57 /// The current status of this authorization entry.
58 pub status: Status,
59
60 /// Expiration date for the authorization.
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub expires: Option<String>,
63
64 /// List of challenges which can be used to complete this authorization.
65 pub challenges: Vec<Challenge>,
66
67 /// The authorization is for a wildcard domain.
68 #[serde(default, skip_serializing_if = "is_false")]
69 pub wildcard: bool,
70 }
71
72 /// The state of a challenge.
73 #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
74 #[serde(rename_all = "lowercase")]
75 pub enum ChallengeStatus {
76 /// The challenge is pending and has not been validated yet.
77 Pending,
78
79 /// The valiation is in progress.
80 Processing,
81
82 /// The challenge was successfully validated.
83 Valid,
84
85 /// Validation of this challenge failed.
86 Invalid,
87 }
88
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 }
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 }
101 }
102
103 /// A challenge object contains information on how to complete an authorization for an order.
104 #[derive(Deserialize, Serialize)]
105 #[serde(rename_all = "camelCase")]
106 pub struct Challenge {
107 /// The challenge type (such as `"dns-01"`).
108 #[serde(rename = "type")]
109 pub ty: String,
110
111 /// The current challenge status.
112 pub status: ChallengeStatus,
113
114 /// The URL used to post to in order to begin the validation for this challenge.
115 pub url: String,
116
117 /// Contains the remaining fields of the Challenge object, such as the `token`.
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 }
135
136 /// Represents an in-flight query for an authorization.
137 ///
138 /// This is created via [`Account::get_authorization`](crate::Account::get_authorization()).
139 pub struct GetAuthorization {
140 //order: OrderData,
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.
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 }