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}