cloud_storage/resources/
hmac_key.rs

1#![allow(unused_imports)]
2#![allow(dead_code)]
3
4use crate::error::GoogleResponse;
5
6/// The `HmacKey` resource represents an HMAC key within Cloud Storage. The resource consists of a
7/// secret and `HmacMeta`. HMAC keys can be used as credentials for service accounts. For more
8/// information, see HMAC Keys.
9///
10/// Note that the `HmacKey` resource is only returned when you use `HmacKey::create`. Other
11/// methods, such as `HmacKey::read`, return the metadata portion of the HMAC key resource.
12#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
13#[serde(rename_all = "camelCase")]
14pub struct HmacKey {
15    /// The kind of item this is. For HMAC keys, this is always `storage#hmacKey`.
16    pub kind: String,
17    /// HMAC key metadata.
18    pub metadata: HmacMeta,
19    /// HMAC secret key material.
20    pub secret: String,
21}
22
23/// Contains information about an Hmac Key.
24#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct HmacMeta {
27    /// The kind of item this is. For HMAC key metadata, this is always `storage#hmacKeyMetadata`.
28    pub kind: String,
29    /// The ID of the HMAC key, including the Project ID and the Access ID.
30    pub id: String,
31    /// The link to this resource.
32    pub self_link: String,
33    /// The access ID of the HMAC Key.
34    pub access_id: String,
35    /// The Project ID of the project that owns the service account to which the key authenticates.
36    pub project_id: String,
37    /// The email address of the key's associated service account.
38    pub service_account_email: String,
39    /// The state of the key.
40    pub state: HmacState,
41    /// The creation time of the HMAC key.
42    pub time_created: chrono::DateTime<chrono::Utc>,
43    /// The last modification time of the HMAC key metadata.
44    pub updated: chrono::DateTime<chrono::Utc>,
45    /// HTTP 1.1 Entity tag for the HMAC key.
46    pub etag: String,
47}
48
49/// The state of an Hmac Key.
50#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
51#[serde(rename_all = "UPPERCASE")]
52pub enum HmacState {
53    /// This Hmac key is currently used.
54    Active,
55    /// This Hmac key has been set to inactive.
56    Inactive,
57    /// This Hmac key has been permanently deleted.
58    Deleted,
59}
60
61#[derive(Debug, serde::Deserialize)]
62pub(crate) struct ListResponse {
63    pub(crate) items: Vec<HmacMeta>,
64}
65
66#[derive(serde::Serialize)]
67struct UpdateRequest {
68    secret: String,
69    metadata: UpdateMeta,
70}
71
72#[derive(serde::Serialize)]
73pub(crate) struct UpdateMeta {
74    pub(crate) state: HmacState,
75}
76
77impl HmacKey {
78    /// Creates a new HMAC key for the specified service account.
79    ///
80    /// The authenticated user must have `storage.hmacKeys.create` permission for the project in
81    /// which the key will be created.
82    ///
83    /// For general information about HMAC keys in Cloud Storage, see
84    /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
85    /// ### Example
86    /// ```
87    /// # #[tokio::main]
88    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
89    /// use cloud_storage::hmac_key::HmacKey;
90    ///
91    /// let hmac_key = HmacKey::create().await?;
92    /// # use cloud_storage::hmac_key::HmacState;
93    /// # HmacKey::update(&hmac_key.metadata.access_id, HmacState::Inactive).await?;
94    /// # HmacKey::delete(&hmac_key.metadata.access_id).await?;
95    /// # Ok(())
96    /// # }
97    /// ```
98    #[cfg(feature = "global-client")]
99    pub async fn create() -> crate::Result<Self> {
100        crate::CLOUD_CLIENT.hmac_key().create().await
101    }
102
103    /// The synchronous equivalent of `HmacKey::create`.
104    ///
105    /// ### Features
106    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
107    #[cfg(all(feature = "global-client", feature = "sync"))]
108    pub fn create_sync() -> crate::Result<Self> {
109        crate::runtime()?.block_on(Self::create())
110    }
111
112    /// Retrieves a list of HMAC keys matching the criteria. Since the HmacKey is secret, this does
113    /// not return a `HmacKey`, but a `HmacMeta`. This is a redacted version of a `HmacKey`, but
114    /// with the secret data omitted.
115    ///
116    /// The authenticated user must have `storage.hmacKeys.list` permission for the project in which
117    /// the key exists.
118    ///
119    /// For general information about HMAC keys in Cloud Storage, see
120    /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
121    /// ### Example
122    /// ```
123    /// # #[tokio::main]
124    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
125    /// use cloud_storage::hmac_key::HmacKey;
126    ///
127    /// let all_hmac_keys = HmacKey::list().await?;
128    /// # Ok(())
129    /// # }
130    /// ```
131    #[cfg(feature = "global-client")]
132    pub async fn list() -> crate::Result<Vec<HmacMeta>> {
133        crate::CLOUD_CLIENT.hmac_key().list().await
134    }
135
136    /// The synchronous equivalent of `HmacKey::list`.
137    ///
138    /// ### Features
139    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
140    #[cfg(all(feature = "global-client", feature = "sync"))]
141    pub fn list_sync() -> crate::Result<Vec<HmacMeta>> {
142        crate::runtime()?.block_on(Self::list())
143    }
144
145    /// Retrieves an HMAC key's metadata. Since the HmacKey is secret, this does not return a
146    /// `HmacKey`, but a `HmacMeta`. This is a redacted version of a `HmacKey`, but with the secret
147    /// data omitted.
148    ///
149    /// The authenticated user must have `storage.hmacKeys.get` permission for the project in which
150    /// the key exists.
151    ///
152    /// For general information about HMAC keys in Cloud Storage, see
153    /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
154    /// ### Example
155    /// ```no_run
156    /// # #[tokio::main]
157    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
158    /// use cloud_storage::hmac_key::HmacKey;
159    ///
160    /// let key = HmacKey::read("some identifier").await?;
161    /// # Ok(())
162    /// # }
163    #[cfg(feature = "global-client")]
164    pub async fn read(access_id: &str) -> crate::Result<HmacMeta> {
165        crate::CLOUD_CLIENT.hmac_key().read(access_id).await
166    }
167
168    /// The synchronous equivalent of `HmacKey::read`.
169    ///
170    /// ### Features
171    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
172    #[cfg(all(feature = "global-client", feature = "sync"))]
173    pub fn read_sync(access_id: &str) -> crate::Result<HmacMeta> {
174        crate::runtime()?.block_on(Self::read(access_id))
175    }
176
177    /// Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.
178    /// Since the HmacKey is secret, this does not return a `HmacKey`, but a `HmacMeta`. This is a
179    /// redacted version of a `HmacKey`, but with the secret data omitted.
180    ///
181    /// The authenticated user must have `storage.hmacKeys.update` permission for the project in
182    /// which the key exists.
183    ///
184    /// For general information about HMAC keys in Cloud Storage, see
185    /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
186    /// ### Example
187    /// ```no_run
188    /// # #[tokio::main]
189    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
190    /// use cloud_storage::hmac_key::{HmacKey, HmacState};
191    ///
192    /// let key = HmacKey::update("your key", HmacState::Active).await?;
193    /// # Ok(())
194    /// # }
195    #[cfg(feature = "global-client")]
196    pub async fn update(access_id: &str, state: HmacState) -> crate::Result<HmacMeta> {
197        crate::CLOUD_CLIENT
198            .hmac_key()
199            .update(access_id, state)
200            .await
201    }
202
203    /// The synchronous equivalent of `HmacKey::update`.
204    ///
205    /// ### Features
206    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
207    #[cfg(all(feature = "global-client", feature = "sync"))]
208    pub fn update_sync(access_id: &str, state: HmacState) -> crate::Result<HmacMeta> {
209        crate::runtime()?.block_on(Self::update(access_id, state))
210    }
211
212    /// Deletes an HMAC key. Note that a key must be set to `Inactive` first.
213    ///
214    /// The authenticated user must have storage.hmacKeys.delete permission for the project in which
215    /// the key exists.
216    ///
217    /// For general information about HMAC keys in Cloud Storage, see
218    /// [HMAC Keys](https://cloud.google.com/storage/docs/authentication/hmackeys).
219    /// ### Example
220    /// ```no_run
221    /// # #[tokio::main]
222    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
223    /// use cloud_storage::hmac_key::{HmacKey, HmacState};
224    ///
225    /// let key = HmacKey::update("your key", HmacState::Inactive).await?; // this is required.
226    /// HmacKey::delete(&key.access_id).await?;
227    /// # Ok(())
228    /// # }
229    #[cfg(feature = "global-client")]
230    pub async fn delete(access_id: &str) -> crate::Result<()> {
231        crate::CLOUD_CLIENT.hmac_key().delete(access_id).await
232    }
233
234    /// The synchronous equivalent of `HmacKey::delete`.
235    #[cfg(all(feature = "global-client", feature = "sync"))]
236    pub fn delete_sync(access_id: &str) -> crate::Result<()> {
237        crate::runtime()?.block_on(Self::delete(access_id))
238    }
239}
240
241#[cfg(all(test, feature = "global-client"))]
242mod tests {
243    use super::*;
244
245    async fn get_test_hmac() -> HmacMeta {
246        match HmacKey::create().await {
247            Ok(key) => key.metadata,
248            Err(_) => HmacKey::list().await.unwrap().pop().unwrap(),
249        }
250    }
251
252    async fn remove_test_hmac(access_id: &str) {
253        HmacKey::update(access_id, HmacState::Inactive)
254            .await
255            .unwrap();
256        HmacKey::delete(access_id).await.unwrap();
257    }
258
259    #[tokio::test]
260    async fn create() -> Result<(), Box<dyn std::error::Error>> {
261        let key = HmacKey::create().await?;
262        remove_test_hmac(&key.metadata.access_id).await;
263        Ok(())
264    }
265
266    #[tokio::test]
267    async fn list() -> Result<(), Box<dyn std::error::Error>> {
268        HmacKey::list().await?;
269        Ok(())
270    }
271
272    #[tokio::test]
273    async fn read() -> Result<(), Box<dyn std::error::Error>> {
274        let key = get_test_hmac().await;
275        HmacKey::read(&key.access_id).await?;
276        remove_test_hmac(&key.access_id).await;
277        Ok(())
278    }
279
280    #[tokio::test]
281    async fn update() -> Result<(), Box<dyn std::error::Error>> {
282        let key = get_test_hmac().await;
283        HmacKey::update(&key.access_id, HmacState::Inactive).await?;
284        HmacKey::delete(&key.access_id).await?;
285        Ok(())
286    }
287
288    #[tokio::test]
289    async fn delete() -> Result<(), Box<dyn std::error::Error>> {
290        let key = get_test_hmac().await;
291        HmacKey::update(&key.access_id, HmacState::Inactive).await?;
292        HmacKey::delete(&key.access_id).await?;
293        Ok(())
294    }
295
296    #[tokio::test]
297    async fn clear_keys() -> Result<(), Box<dyn std::error::Error>> {
298        let keys = HmacKey::list().await?;
299        for key in &keys {
300            if key.state != HmacState::Inactive {
301                HmacKey::update(&key.access_id, HmacState::Inactive).await?;
302            }
303            HmacKey::delete(&key.access_id).await?;
304        }
305        Ok(())
306    }
307
308    #[cfg(all(feature = "global-client", feature = "sync"))]
309    mod sync {
310        use super::*;
311
312        fn get_test_hmac() -> HmacMeta {
313            match HmacKey::create_sync() {
314                Ok(key) => key.metadata,
315                Err(_) => HmacKey::list_sync().unwrap().pop().unwrap(),
316            }
317        }
318
319        fn remove_test_hmac(access_id: &str) {
320            HmacKey::update_sync(access_id, HmacState::Inactive).unwrap();
321            HmacKey::delete_sync(access_id).unwrap();
322        }
323
324        #[test]
325        fn create() -> Result<(), Box<dyn std::error::Error>> {
326            let key = HmacKey::create_sync()?;
327            remove_test_hmac(&key.metadata.access_id);
328            Ok(())
329        }
330
331        #[test]
332        fn list() -> Result<(), Box<dyn std::error::Error>> {
333            HmacKey::list_sync()?;
334            Ok(())
335        }
336
337        #[test]
338        fn read() -> Result<(), Box<dyn std::error::Error>> {
339            let key = get_test_hmac();
340            HmacKey::read_sync(&key.access_id)?;
341            remove_test_hmac(&key.access_id);
342            Ok(())
343        }
344
345        #[test]
346        fn update() -> Result<(), Box<dyn std::error::Error>> {
347            let key = get_test_hmac();
348            HmacKey::update_sync(&key.access_id, HmacState::Inactive)?;
349            HmacKey::delete_sync(&key.access_id)?;
350            Ok(())
351        }
352
353        #[test]
354        fn delete() -> Result<(), Box<dyn std::error::Error>> {
355            let key = get_test_hmac();
356            HmacKey::update_sync(&key.access_id, HmacState::Inactive)?;
357            HmacKey::delete_sync(&key.access_id)?;
358            Ok(())
359        }
360    }
361}