cloud_storage/client/hmac_key.rs
1use crate::{
2 error::GoogleResponse,
3 hmac_key::{HmacKey, HmacMeta, HmacState},
4};
5
6/// Operations on [`HmacKey`](HmacKey)s.
7#[derive(Debug)]
8pub struct HmacKeyClient<'a>(pub(super) &'a super::Client);
9
10impl<'a> HmacKeyClient<'a> {
11 /// Creates a new HMAC key for the specified service account.
12 ///
13 /// The authenticated user must have `storage.hmacKeys.create` permission for the project in
14 /// which the key will be created.
15 ///
16 /// For general information about HMAC keys in Cloud Storage, see
17 /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
18 /// ### Example
19 /// ```
20 /// # #[tokio::main]
21 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 /// use cloud_storage::Client;
23 /// use cloud_storage::hmac_key::HmacKey;
24 ///
25 /// let client = Client::default();
26 /// let hmac_key = client.hmac_key().create().await?;
27 /// # use cloud_storage::hmac_key::HmacState;
28 /// # client.hmac_key().update(&hmac_key.metadata.access_id, HmacState::Inactive).await?;
29 /// # client.hmac_key().delete(&hmac_key.metadata.access_id).await?;
30 /// # Ok(())
31 /// # }
32 /// ```
33 pub async fn create(&self) -> crate::Result<HmacKey> {
34 use reqwest::header::CONTENT_LENGTH;
35
36 let url = format!(
37 "{}/projects/{}/hmacKeys",
38 crate::BASE_URL,
39 crate::SERVICE_ACCOUNT.project_id
40 );
41 let query = [("serviceAccountEmail", &crate::SERVICE_ACCOUNT.client_email)];
42 let mut headers = self.0.get_headers().await?;
43 headers.insert(CONTENT_LENGTH, 0.into());
44 let result: GoogleResponse<HmacKey> = self
45 .0
46 .client
47 .post(&url)
48 .headers(headers)
49 .query(&query)
50 .send()
51 .await?
52 .json()
53 .await?;
54 match result {
55 GoogleResponse::Success(s) => Ok(s),
56 GoogleResponse::Error(e) => Err(e.into()),
57 }
58 }
59
60 /// Retrieves a list of HMAC keys matching the criteria. Since the HmacKey is secret, this does
61 /// not return a `HmacKey`, but a `HmacMeta`. This is a redacted version of a `HmacKey`, but
62 /// with the secret data omitted.
63 ///
64 /// The authenticated user must have `storage.hmacKeys.list` permission for the project in which
65 /// the key exists.
66 ///
67 /// For general information about HMAC keys in Cloud Storage, see
68 /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
69 /// ### Example
70 /// ```
71 /// # #[tokio::main]
72 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
73 /// use cloud_storage::Client;
74 /// use cloud_storage::hmac_key::HmacKey;
75 ///
76 /// let client = Client::default();
77 /// let all_hmac_keys = client.hmac_key().list().await?;
78 /// # Ok(())
79 /// # }
80 /// ```
81 pub async fn list(&self) -> crate::Result<Vec<HmacMeta>> {
82 let url = format!(
83 "{}/projects/{}/hmacKeys",
84 crate::BASE_URL,
85 crate::SERVICE_ACCOUNT.project_id
86 );
87 let response = self
88 .0
89 .client
90 .get(&url)
91 .headers(self.0.get_headers().await?)
92 .send()
93 .await?
94 .text()
95 .await?;
96 let result: Result<GoogleResponse<crate::hmac_key::ListResponse>, _> =
97 serde_json::from_str(&response);
98
99 // This function rquires more complicated error handling because when there is only one
100 // entry, Google will return the response `{ "kind": "storage#hmacKeysMetadata" }` instead
101 // of a list with one element. This breaks the parser.
102 match result {
103 Ok(parsed) => match parsed {
104 GoogleResponse::Success(s) => Ok(s.items),
105 GoogleResponse::Error(e) => Err(e.into()),
106 },
107 Err(_) => Ok(vec![]),
108 }
109 }
110
111 /// Retrieves an HMAC key's metadata. Since the HmacKey is secret, this does not return a
112 /// `HmacKey`, but a `HmacMeta`. This is a redacted version of a `HmacKey`, but with the secret
113 /// data omitted.
114 ///
115 /// The authenticated user must have `storage.hmacKeys.get` permission for the project in which
116 /// the key exists.
117 ///
118 /// For general information about HMAC keys in Cloud Storage, see
119 /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
120 /// ### Example
121 /// ```no_run
122 /// # #[tokio::main]
123 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
124 /// use cloud_storage::Client;
125 /// use cloud_storage::hmac_key::HmacKey;
126 ///
127 /// let client = Client::default();
128 /// let key = client.hmac_key().read("some identifier").await?;
129 /// # Ok(())
130 /// # }
131 pub async fn read(&self, access_id: &str) -> crate::Result<HmacMeta> {
132 let url = format!(
133 "{}/projects/{}/hmacKeys/{}",
134 crate::BASE_URL,
135 crate::SERVICE_ACCOUNT.project_id,
136 access_id
137 );
138 let result: GoogleResponse<HmacMeta> = self
139 .0
140 .client
141 .get(&url)
142 .headers(self.0.get_headers().await?)
143 .send()
144 .await?
145 .json()
146 .await?;
147 match result {
148 GoogleResponse::Success(s) => Ok(s),
149 GoogleResponse::Error(e) => Err(e.into()),
150 }
151 }
152
153 /// Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.
154 /// Since the HmacKey is secret, this does not return a `HmacKey`, but a `HmacMeta`. This is a
155 /// redacted version of a `HmacKey`, but with the secret data omitted.
156 ///
157 /// The authenticated user must have `storage.hmacKeys.update` permission for the project in
158 /// which the key exists.
159 ///
160 /// For general information about HMAC keys in Cloud Storage, see
161 /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
162 /// ### Example
163 /// ```no_run
164 /// # #[tokio::main]
165 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
166 /// use cloud_storage::Client;
167 /// use cloud_storage::hmac_key::{HmacKey, HmacState};
168 ///
169 /// let client = Client::default();
170 /// let key = client.hmac_key().update("your key", HmacState::Active).await?;
171 /// # Ok(())
172 /// # }
173 pub async fn update(&self, access_id: &str, state: HmacState) -> crate::Result<HmacMeta> {
174 let url = format!(
175 "{}/projects/{}/hmacKeys/{}",
176 crate::BASE_URL,
177 crate::SERVICE_ACCOUNT.project_id,
178 access_id
179 );
180 serde_json::to_string(&crate::hmac_key::UpdateMeta { state })?;
181 let result: GoogleResponse<HmacMeta> = self
182 .0
183 .client
184 .put(&url)
185 .headers(self.0.get_headers().await?)
186 .json(&crate::hmac_key::UpdateMeta { state })
187 .send()
188 .await?
189 .json()
190 .await?;
191 match result {
192 GoogleResponse::Success(s) => Ok(s),
193 GoogleResponse::Error(e) => Err(e.into()),
194 }
195 }
196
197 /// Deletes an HMAC key. Note that a key must be set to `Inactive` first.
198 ///
199 /// The authenticated user must have storage.hmacKeys.delete permission for the project in which
200 /// the key exists.
201 ///
202 /// For general information about HMAC keys in Cloud Storage, see
203 /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
204 /// ### Example
205 /// ```no_run
206 /// # #[tokio::main]
207 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
208 /// use cloud_storage::Client;
209 /// use cloud_storage::hmac_key::{HmacKey, HmacState};
210 ///
211 /// let client = Client::default();
212 /// let key = client.hmac_key().update("your key", HmacState::Inactive).await?; // this is required.
213 /// client.hmac_key().delete(&key.access_id).await?;
214 /// # Ok(())
215 /// # }
216 pub async fn delete(&self, access_id: &str) -> crate::Result<()> {
217 let url = format!(
218 "{}/projects/{}/hmacKeys/{}",
219 crate::BASE_URL,
220 crate::SERVICE_ACCOUNT.project_id,
221 access_id
222 );
223 let response = self
224 .0
225 .client
226 .delete(&url)
227 .headers(self.0.get_headers().await?)
228 .send()
229 .await?;
230 if response.status().is_success() {
231 Ok(())
232 } else {
233 Err(crate::Error::Google(response.json().await?))
234 }
235 }
236}