cloud_storage/resources/bucket_access_control.rs
1pub use crate::resources::common::{Entity, ProjectTeam, Role};
2
3/// The BucketAccessControl resource represents the Access Control Lists (ACLs) for buckets within
4/// Google Cloud Storage. ACLs let you specify who has access to your data and to what extent.
5///
6/// ```text,ignore
7/// Important: This method fails with a 400 Bad Request response for buckets with uniform
8/// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
9/// control access instead.
10/// ```
11///
12/// There are three roles that can be assigned to an entity:
13///
14/// * READERs can get the bucket, though no acl property will be returned, and list the bucket's
15/// objects.
16/// * WRITERs are READERs, and they can insert objects into the bucket and delete the bucket's
17/// objects.
18/// * OWNERs are WRITERs, and they can get the acl property of a bucket, update a bucket, and call
19/// all BucketAccessControl methods on the bucket.
20#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
21#[serde(rename_all = "camelCase")]
22pub struct BucketAccessControl {
23 /// The kind of item this is. For bucket access control entries, this is always
24 /// `storage#bucketAccessControl`.
25 pub kind: String,
26 /// The ID of the access-control entry.
27 pub id: String,
28 /// The link to this access-control entry.
29 pub self_link: String,
30 /// The name of the bucket.
31 pub bucket: String,
32 /// The entity holding the permission, in one of the following forms:
33 ///
34 /// * `user-userId`
35 /// * `user-email`
36 /// * `group-groupId`
37 /// * `group-email`
38 /// * `domain-domain`
39 /// * `project-team-projectId`
40 /// * `allUsers`
41 /// * `allAuthenticatedUsers`
42 ///
43 /// Examples:
44 ///
45 /// * The user liz@example.com would be user-liz@example.com.
46 /// * The group example@googlegroups.com would be group-example@googlegroups.com.
47 /// * To refer to all members of the G Suite for Business domain example.com, the entity would
48 /// be domain-example.com.
49 pub entity: Entity,
50 /// The access permission for the entity.
51 pub role: Role,
52 /// The email address associated with the entity, if any.
53 pub email: Option<String>,
54 /// The ID for the entity, if any.
55 pub entity_id: Option<String>,
56 /// The domain associated with the entity, if any.
57 pub domain: Option<String>,
58 /// The project team associated with the entity, if any.
59 pub project_team: Option<ProjectTeam>,
60 /// HTTP 1.1 Entity tag for the access-control entry.
61 pub etag: String,
62}
63
64/// Model that can be used to create a new BucketAccessControl object.
65#[derive(Debug, PartialEq, serde::Serialize)]
66#[serde(rename_all = "camelCase")]
67pub struct NewBucketAccessControl {
68 /// The entity holding the permission, in one of the following forms:
69 ///
70 /// * `user-userId`
71 /// * `user-email`
72 /// * `group-groupId`
73 /// * `group-email`
74 /// * `domain-domain`
75 /// * `project-team-projectId`
76 /// * `allUsers`
77 /// * `allAuthenticatedUsers`
78 ///
79 /// Examples:
80 ///
81 /// * The user liz@example.com would be user-liz@example.com.
82 /// * The group example@googlegroups.com would be group-example@googlegroups.com.
83 /// * To refer to all members of the G Suite for Business domain example.com, the entity would
84 /// be domain-example.com.
85 pub entity: Entity,
86 /// The access permission for the entity.
87 pub role: Role,
88}
89
90impl BucketAccessControl {
91 /// Create a new `BucketAccessControl` using the provided `NewBucketAccessControl`, related to
92 /// the `Bucket` provided by the `bucket_name` argument.
93 ///
94 /// ### Important
95 /// Important: This method fails with a 400 Bad Request response for buckets with uniform
96 /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
97 /// control access instead.
98 /// ### Example
99 /// ```rust,no_run
100 /// # #[tokio::main]
101 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
102 /// use cloud_storage::bucket_access_control::{BucketAccessControl, NewBucketAccessControl};
103 /// use cloud_storage::bucket_access_control::{Role, Entity};
104 ///
105 /// let new_bucket_access_control = NewBucketAccessControl {
106 /// entity: Entity::AllUsers,
107 /// role: Role::Reader,
108 /// };
109 /// BucketAccessControl::create("mybucket", &new_bucket_access_control).await?;
110 /// # Ok(())
111 /// # }
112 /// ```
113 #[cfg(feature = "global-client")]
114 pub async fn create(
115 bucket: &str,
116 new_bucket_access_control: &NewBucketAccessControl,
117 ) -> crate::Result<Self> {
118 crate::CLOUD_CLIENT
119 .bucket_access_control()
120 .create(bucket, new_bucket_access_control)
121 .await
122 }
123
124 /// The synchronous equivalent of `BucketAccessControl::create`.
125 ///
126 /// ### Features
127 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
128 #[cfg(all(feature = "global-client", feature = "sync"))]
129 pub fn create_sync(
130 bucket: &str,
131 new_bucket_access_control: &NewBucketAccessControl,
132 ) -> crate::Result<Self> {
133 crate::runtime()?.block_on(Self::create(bucket, new_bucket_access_control))
134 }
135
136 /// Returns all `BucketAccessControl`s related to this bucket.
137 ///
138 /// ### Important
139 /// Important: This method fails with a 400 Bad Request response for buckets with uniform
140 /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
141 /// control access instead.
142 /// ### Example
143 /// ```rust,no_run
144 /// # #[tokio::main]
145 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
146 /// use cloud_storage::bucket_access_control::BucketAccessControl;
147 ///
148 /// let acls = BucketAccessControl::list("mybucket").await?;
149 /// # Ok(())
150 /// # }
151 /// ```
152 #[cfg(feature = "global-client")]
153 pub async fn list(bucket: &str) -> crate::Result<Vec<Self>> {
154 crate::CLOUD_CLIENT
155 .bucket_access_control()
156 .list(bucket)
157 .await
158 }
159
160 /// The synchronous equivalent of `BucketAccessControl::list`.
161 ///
162 /// ### Features
163 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
164 #[cfg(all(feature = "global-client", feature = "sync"))]
165 pub fn list_sync(bucket: &str) -> crate::Result<Vec<Self>> {
166 crate::runtime()?.block_on(Self::list(bucket))
167 }
168
169 /// Returns the ACL entry for the specified entity on the specified bucket.
170 ///
171 /// ### Important
172 /// Important: This method fails with a 400 Bad Request response for buckets with uniform
173 /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
174 /// control access instead.
175 /// ### Example
176 /// ```rust,no_run
177 /// # #[tokio::main]
178 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
179 /// use cloud_storage::bucket_access_control::{BucketAccessControl, Entity};
180 ///
181 /// let controls = BucketAccessControl::read("mybucket", &Entity::AllUsers).await?;
182 /// # Ok(())
183 /// # }
184 /// ```
185 #[cfg(feature = "global-client")]
186 pub async fn read(bucket: &str, entity: &Entity) -> crate::Result<Self> {
187 crate::CLOUD_CLIENT
188 .bucket_access_control()
189 .read(bucket, entity)
190 .await
191 }
192
193 /// The synchronous equivalent of `BucketAccessControl::read`.
194 ///
195 /// ### Features
196 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
197 #[cfg(all(feature = "global-client", feature = "sync"))]
198 pub fn read_sync(bucket: &str, entity: &Entity) -> crate::Result<Self> {
199 crate::runtime()?.block_on(Self::read(bucket, entity))
200 }
201
202 /// Update this `BucketAccessControl`.
203 ///
204 /// ### Important
205 /// Important: This method fails with a 400 Bad Request response for buckets with uniform
206 /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
207 /// control access instead.
208 /// ### Example
209 /// ```rust,no_run
210 /// # #[tokio::main]
211 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
212 /// use cloud_storage::bucket_access_control::{BucketAccessControl, Entity};
213 ///
214 /// let mut acl = BucketAccessControl::read("mybucket", &Entity::AllUsers).await?;
215 /// acl.entity = Entity::AllAuthenticatedUsers;
216 /// acl.update().await?;
217 /// # Ok(())
218 /// # }
219 /// ```
220 #[cfg(feature = "global-client")]
221 pub async fn update(&self) -> crate::Result<Self> {
222 crate::CLOUD_CLIENT
223 .bucket_access_control()
224 .update(self)
225 .await
226 }
227
228 /// The synchronous equivalent of `BucketAccessControl::update`.
229 ///
230 /// ### Features
231 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
232 #[cfg(all(feature = "global-client", feature = "sync"))]
233 pub fn update_sync(&self) -> crate::Result<Self> {
234 crate::runtime()?.block_on(self.update())
235 }
236
237 /// Permanently deletes the ACL entry for the specified entity on the specified bucket.
238 ///
239 /// ### Important
240 /// Important: This method fails with a 400 Bad Request response for buckets with uniform
241 /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
242 /// control access instead.
243 /// ### Example
244 /// ```rust,no_run
245 /// # #[tokio::main]
246 /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
247 /// use cloud_storage::bucket_access_control::{BucketAccessControl, Entity};
248 ///
249 /// let controls = BucketAccessControl::read("mybucket", &Entity::AllUsers).await?;
250 /// controls.delete().await?;
251 /// # Ok(())
252 /// # }
253 /// ```
254 #[cfg(feature = "global-client")]
255 pub async fn delete(self) -> crate::Result<()> {
256 crate::CLOUD_CLIENT
257 .bucket_access_control()
258 .delete(self)
259 .await
260 }
261
262 /// The synchronous equivalent of `BucketAccessControl::delete`.
263 ///
264 /// ### Features
265 /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
266 #[cfg(all(feature = "global-client", feature = "sync"))]
267 pub fn delete_sync(self) -> crate::Result<()> {
268 crate::runtime()?.block_on(self.delete())
269 }
270}
271
272#[cfg(all(test, feature = "global-client"))]
273mod tests {
274 use super::*;
275
276 #[tokio::test]
277 async fn create() -> Result<(), Box<dyn std::error::Error>> {
278 let bucket = crate::read_test_bucket().await;
279 let new_bucket_access_control = NewBucketAccessControl {
280 entity: Entity::AllUsers,
281 role: Role::Reader,
282 };
283 BucketAccessControl::create(&bucket.name, &new_bucket_access_control)
284 .await
285 .unwrap();
286 Ok(())
287 }
288
289 #[tokio::test]
290 async fn list() -> Result<(), Box<dyn std::error::Error>> {
291 let bucket = crate::read_test_bucket().await;
292 BucketAccessControl::list(&bucket.name).await?;
293 Ok(())
294 }
295
296 #[tokio::test]
297 async fn read() -> Result<(), Box<dyn std::error::Error>> {
298 let bucket = crate::read_test_bucket().await;
299 BucketAccessControl::read(&bucket.name, &Entity::AllUsers).await?;
300 Ok(())
301 }
302
303 #[tokio::test]
304 async fn update() -> Result<(), Box<dyn std::error::Error>> {
305 // use a seperate bucket to prevent synchronization issues
306 let bucket = crate::create_test_bucket("test-update-bucket-access-controls").await;
307 let new_bucket_access_control = NewBucketAccessControl {
308 entity: Entity::AllUsers,
309 role: Role::Reader,
310 };
311 BucketAccessControl::create(&bucket.name, &new_bucket_access_control).await?;
312 let mut acl = BucketAccessControl::read(&bucket.name, &Entity::AllUsers).await?;
313 acl.entity = Entity::AllAuthenticatedUsers;
314 acl.update().await?;
315 bucket.delete().await?;
316 Ok(())
317 }
318
319 #[tokio::test]
320 async fn delete() -> Result<(), Box<dyn std::error::Error>> {
321 // use a seperate bucket to prevent synchronization issues
322 let bucket = crate::create_test_bucket("test-delete-bucket-access-controls").await;
323 let new_bucket_access_control = NewBucketAccessControl {
324 entity: Entity::AllUsers,
325 role: Role::Reader,
326 };
327 BucketAccessControl::create(&bucket.name, &new_bucket_access_control).await?;
328 let acl = BucketAccessControl::read(&bucket.name, &Entity::AllUsers).await?;
329 acl.delete().await?;
330 bucket.delete().await?;
331 Ok(())
332 }
333
334 #[cfg(all(feature = "global-client", feature = "sync"))]
335 mod sync {
336 use super::*;
337
338 #[test]
339 fn create() -> Result<(), Box<dyn std::error::Error>> {
340 let bucket = crate::read_test_bucket_sync();
341 let new_bucket_access_control = NewBucketAccessControl {
342 entity: Entity::AllUsers,
343 role: Role::Reader,
344 };
345 BucketAccessControl::create_sync(&bucket.name, &new_bucket_access_control)?;
346 Ok(())
347 }
348
349 #[test]
350 fn list() -> Result<(), Box<dyn std::error::Error>> {
351 let bucket = crate::read_test_bucket_sync();
352 BucketAccessControl::list_sync(&bucket.name)?;
353 Ok(())
354 }
355
356 #[test]
357 fn read() -> Result<(), Box<dyn std::error::Error>> {
358 let bucket = crate::read_test_bucket_sync();
359 BucketAccessControl::read_sync(&bucket.name, &Entity::AllUsers)?;
360 Ok(())
361 }
362
363 #[test]
364 fn update() -> Result<(), Box<dyn std::error::Error>> {
365 // use a seperate bucket to prevent synchronization issues
366 let bucket = crate::create_test_bucket_sync("test-update-bucket-access-controls");
367 let new_bucket_access_control = NewBucketAccessControl {
368 entity: Entity::AllUsers,
369 role: Role::Reader,
370 };
371 BucketAccessControl::create_sync(&bucket.name, &new_bucket_access_control)?;
372 let mut acl = BucketAccessControl::read_sync(&bucket.name, &Entity::AllUsers)?;
373 acl.entity = Entity::AllAuthenticatedUsers;
374 acl.update_sync()?;
375 bucket.delete_sync()?;
376 Ok(())
377 }
378
379 #[test]
380 fn delete() -> Result<(), Box<dyn std::error::Error>> {
381 // use a seperate bucket to prevent synchronization issues
382 let bucket = crate::create_test_bucket_sync("test-delete-bucket-access-controls");
383 let new_bucket_access_control = NewBucketAccessControl {
384 entity: Entity::AllUsers,
385 role: Role::Reader,
386 };
387 BucketAccessControl::create_sync(&bucket.name, &new_bucket_access_control)?;
388 let acl = BucketAccessControl::read_sync(&bucket.name, &Entity::AllUsers)?;
389 acl.delete_sync()?;
390 bucket.delete_sync()?;
391 Ok(())
392 }
393 }
394}