cloud_storage/resources/
object_access_control.rs

1#![allow(unused_imports)]
2
3pub use crate::resources::common::{Entity, ProjectTeam, Role};
4use crate::{error::GoogleResponse, resources::common::ListResponse};
5
6/// The ObjectAccessControls resources represent the Access Control Lists (ACLs) for objects within
7/// Google Cloud Storage. ACLs let you specify who has access to your data and to what extent.
8///
9/// ```text,ignore
10/// Important: The methods for this resource fail with a 400 Bad Request response for buckets with
11/// uniform bucket-level access enabled. Use storage.buckets.getIamPolicy and
12/// storage.buckets.setIamPolicy to control access instead.
13/// ```
14///
15/// There are two roles that can be assigned to an entity:
16///
17/// READERs can get an object, though the acl property will not be revealed.
18/// OWNERs are READERs, and they can get the acl property, update an object, and call all
19/// objectAccessControls methods on the object. The owner of an object is always an OWNER.
20///
21/// For more information, see Access Control, with the caveat that this API uses READER and OWNER
22/// instead of READ and FULL_CONTROL.
23#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
24#[serde(rename_all = "camelCase")]
25pub struct ObjectAccessControl {
26    /// The kind of item this is. For object access control entries, this is always
27    /// `storage#objectAccessControl`.
28    pub kind: String,
29    /// The ID of the access-control entry.
30    pub id: String,
31    /// The link to this access-control entry.
32    pub self_link: String,
33    /// The name of the bucket.
34    pub bucket: String,
35    /// The name of the object, if applied to an object.
36    pub object: String,
37    /// The content generation of the object, if applied to an object.
38    pub generation: Option<String>,
39    /// The entity holding the permission, in one of the following forms:
40    ///
41    /// user-userId
42    /// user-email
43    /// group-groupId
44    /// group-email
45    /// domain-domain
46    /// project-team-projectId
47    /// allUsers
48    /// allAuthenticatedUsers
49    ///
50    /// Examples:
51    ///
52    /// The user liz@example.com would be user-liz@example.com.
53    /// The group example@googlegroups.com would be group-example@googlegroups.com.
54    /// To refer to all members of the G Suite for Business domain example.com, the entity would be
55    /// domain-example.com.
56    pub entity: Entity,
57    /// The access permission for the entity.
58    pub role: Role,
59    /// The email address associated with the entity, if any.
60    pub email: Option<String>,
61    /// The ID for the entity, if any.
62    pub entity_id: Option<String>,
63    /// The domain associated with the entity, if any.
64    pub domain: Option<String>,
65    /// The project team associated with the entity, if any.
66    pub project_team: Option<ProjectTeam>,
67    /// HTTP 1.1 Entity tag for the access-control entry.
68    pub etag: String,
69}
70
71/// Used to create a new `ObjectAccessControl` object.
72#[derive(Debug, PartialEq, serde::Serialize)]
73#[serde(rename_all = "camelCase")]
74pub struct NewObjectAccessControl {
75    /// The entity holding the permission, in one of the following forms:
76    ///
77    /// user-userId
78    /// user-email
79    /// group-groupId
80    /// group-email
81    /// domain-domain
82    /// project-team-projectId
83    /// allUsers
84    /// allAuthenticatedUsers
85    ///
86    /// Examples:
87    ///
88    /// The user liz@example.com would be user-liz@example.com.
89    /// The group example@googlegroups.com would be group-example@googlegroups.com.
90    /// To refer to all members of the G Suite for Business domain example.com, the entity would be
91    /// domain-example.com.
92    pub entity: Entity,
93    /// The access permission for the entity.
94    pub role: Role,
95}
96
97#[allow(unused)]
98#[derive(Debug, serde::Deserialize)]
99#[serde(rename_all = "camelCase")]
100struct ObjectAccessControlList {
101    kind: String,
102    items: Vec<ObjectAccessControl>,
103}
104
105impl ObjectAccessControl {
106    /// Creates a new ACL entry on the specified `object`.
107    ///
108    /// ### Important
109    /// This method fails with a 400 Bad Request response for buckets with uniform
110    /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
111    /// control access instead.
112    #[cfg(feature = "global-client")]
113    pub async fn create(
114        bucket: &str,
115        object: &str,
116        new_object_access_control: &NewObjectAccessControl,
117    ) -> crate::Result<Self> {
118        crate::CLOUD_CLIENT
119            .object_access_control()
120            .create(bucket, object, new_object_access_control)
121            .await
122    }
123
124    /// The synchronous equivalent of `ObjectAccessControl::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        object: &str,
132        new_object_access_control: &NewObjectAccessControl,
133    ) -> crate::Result<Self> {
134        crate::runtime()?.block_on(Self::create(bucket, object, new_object_access_control))
135    }
136
137    /// Retrieves `ACL` entries on the specified object.
138    ///
139    /// ### Important
140    /// Important: This method fails with a 400 Bad Request response for buckets with uniform
141    /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
142    /// control access instead.
143    #[cfg(feature = "global-client")]
144    pub async fn list(bucket: &str, object: &str) -> crate::Result<Vec<Self>> {
145        crate::CLOUD_CLIENT
146            .object_access_control()
147            .list(bucket, object)
148            .await
149    }
150
151    /// The synchronous equivalent of `ObjectAccessControl::list`.
152    ///
153    /// ### Features
154    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
155    #[cfg(all(feature = "global-client", feature = "sync"))]
156    pub fn list_sync(bucket: &str, object: &str) -> crate::Result<Vec<Self>> {
157        crate::runtime()?.block_on(Self::list(bucket, object))
158    }
159
160    /// Returns the `ACL` entry for the specified entity on the specified bucket.
161    ///
162    /// ### Important
163    /// Important: This method fails with a 400 Bad Request response for buckets with uniform
164    /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
165    /// control access instead.
166    #[cfg(feature = "global-client")]
167    pub async fn read(bucket: &str, object: &str, entity: &Entity) -> crate::Result<Self> {
168        crate::CLOUD_CLIENT
169            .object_access_control()
170            .read(bucket, object, entity)
171            .await
172    }
173
174    /// The synchronous equivalent of `ObjectAccessControl::read`.
175    ///
176    /// ### Features
177    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
178    #[cfg(all(feature = "global-client", feature = "sync"))]
179    pub fn read_sync(bucket: &str, object: &str, entity: &Entity) -> crate::Result<Self> {
180        crate::runtime()?.block_on(Self::read(bucket, object, entity))
181    }
182
183    /// Updates an ACL entry on the specified object.
184    ///
185    /// ### Important
186    /// Important: This method fails with a 400 Bad Request response for buckets with uniform
187    /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
188    /// control access instead.
189    #[cfg(feature = "global-client")]
190    pub async fn update(&self) -> crate::Result<Self> {
191        crate::CLOUD_CLIENT
192            .object_access_control()
193            .update(self)
194            .await
195    }
196
197    /// The synchronous equivalent of `ObjectAccessControl::update`.
198    ///
199    /// ### Features
200    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
201    #[cfg(all(feature = "global-client", feature = "sync"))]
202    pub fn update_sync(&self) -> crate::Result<Self> {
203        crate::runtime()?.block_on(self.update())
204    }
205
206    /// Permanently deletes the ACL entry for the specified entity on the specified object.
207    ///
208    /// ### Important
209    /// Important: This method fails with a 400 Bad Request response for buckets with uniform
210    /// bucket-level access enabled. Use `Bucket::get_iam_policy` and `Bucket::set_iam_policy` to
211    /// control access instead.
212    #[cfg(feature = "global-client")]
213    pub async fn delete(self) -> crate::Result<()> {
214        crate::CLOUD_CLIENT
215            .object_access_control()
216            .delete(self)
217            .await
218    }
219
220    /// The synchronous equivalent of `ObjectAccessControl::delete`.
221    ///
222    /// ### Features
223    /// This function requires that the feature flag `sync` is enabled in `Cargo.toml`.
224    #[cfg(all(feature = "global-client", feature = "sync"))]
225    pub fn delete_sync(self) -> crate::Result<()> {
226        crate::runtime()?.block_on(self.delete())
227    }
228}
229
230#[cfg(all(test, feature = "global-client"))]
231mod tests {
232    use super::*;
233    use crate::Object;
234
235    #[tokio::test]
236    async fn create() {
237        let bucket = crate::read_test_bucket().await;
238        Object::create(
239            &bucket.name,
240            vec![0, 1],
241            "test-object-access-controls-create",
242            "text/plain",
243        )
244        .await
245        .unwrap();
246        let new_bucket_access_control = NewObjectAccessControl {
247            entity: Entity::AllUsers,
248            role: Role::Reader,
249        };
250        ObjectAccessControl::create(
251            &bucket.name,
252            "test-object-access-controls-create",
253            &new_bucket_access_control,
254        )
255        .await
256        .unwrap();
257    }
258
259    #[tokio::test]
260    async fn list() {
261        let bucket = crate::read_test_bucket().await;
262        Object::create(
263            &bucket.name,
264            vec![0, 1],
265            "test-object-access-controls-list",
266            "text/plain",
267        )
268        .await
269        .unwrap();
270        ObjectAccessControl::list(&bucket.name, "test-object-access-controls-list")
271            .await
272            .unwrap();
273    }
274
275    #[tokio::test]
276    async fn read() {
277        let bucket = crate::read_test_bucket().await;
278        Object::create(
279            &bucket.name,
280            vec![0, 1],
281            "test-object-access-controls-read",
282            "text/plain",
283        )
284        .await
285        .unwrap();
286        let new_bucket_access_control = NewObjectAccessControl {
287            entity: Entity::AllUsers,
288            role: Role::Reader,
289        };
290        ObjectAccessControl::create(
291            &bucket.name,
292            "test-object-access-controls-read",
293            &new_bucket_access_control,
294        )
295        .await
296        .unwrap();
297        ObjectAccessControl::read(
298            &bucket.name,
299            "test-object-access-controls-read",
300            &Entity::AllUsers,
301        )
302        .await
303        .unwrap();
304    }
305
306    #[tokio::test]
307    async fn update() {
308        // use a seperate bucket to prevent synchronization issues
309        let bucket = crate::create_test_bucket("test-object-access-controls-update").await;
310        let new_bucket_access_control = NewObjectAccessControl {
311            entity: Entity::AllUsers,
312            role: Role::Reader,
313        };
314        Object::create(&bucket.name, vec![0, 1], "test-update", "text/plain")
315            .await
316            .unwrap();
317        ObjectAccessControl::create(&bucket.name, "test-update", &new_bucket_access_control)
318            .await
319            .unwrap();
320        let mut acl = ObjectAccessControl::read(&bucket.name, "test-update", &Entity::AllUsers)
321            .await
322            .unwrap();
323        acl.entity = Entity::AllAuthenticatedUsers;
324        acl.update().await.unwrap();
325        Object::delete(&bucket.name, "test-update").await.unwrap();
326        bucket.delete().await.unwrap();
327    }
328
329    #[tokio::test]
330    async fn delete() {
331        // use a seperate bucket to prevent synchronization issues
332        let bucket = crate::create_test_bucket("test-object-access-controls-delete").await;
333        let new_bucket_access_control = NewObjectAccessControl {
334            entity: Entity::AllUsers,
335            role: Role::Reader,
336        };
337        Object::create(&bucket.name, vec![0, 1], "test-delete", "text/plain")
338            .await
339            .unwrap();
340        ObjectAccessControl::create(&bucket.name, "test-delete", &new_bucket_access_control)
341            .await
342            .unwrap();
343        let acl = ObjectAccessControl::read(&bucket.name, "test-delete", &Entity::AllUsers)
344            .await
345            .unwrap();
346        acl.delete().await.unwrap();
347        Object::delete(&bucket.name, "test-delete").await.unwrap();
348        bucket.delete().await.unwrap();
349    }
350
351    #[cfg(all(feature = "global-client", feature = "sync"))]
352    mod sync {
353        use super::*;
354
355        #[test]
356        fn create() {
357            let bucket = crate::read_test_bucket_sync();
358            Object::create_sync(
359                &bucket.name,
360                vec![0, 1],
361                "test-object-access-controls-create",
362                "text/plain",
363            )
364            .unwrap();
365            let new_bucket_access_control = NewObjectAccessControl {
366                entity: Entity::AllUsers,
367                role: Role::Reader,
368            };
369            ObjectAccessControl::create_sync(
370                &bucket.name,
371                "test-object-access-controls-create",
372                &new_bucket_access_control,
373            )
374            .unwrap();
375        }
376
377        #[test]
378        fn list() {
379            let bucket = crate::read_test_bucket_sync();
380            Object::create_sync(
381                &bucket.name,
382                vec![0, 1],
383                "test-object-access-controls-list",
384                "text/plain",
385            )
386            .unwrap();
387            ObjectAccessControl::list_sync(&bucket.name, "test-object-access-controls-list")
388                .unwrap();
389        }
390
391        #[test]
392        fn read() {
393            let bucket = crate::read_test_bucket_sync();
394            Object::create_sync(
395                &bucket.name,
396                vec![0, 1],
397                "test-object-access-controls-read",
398                "text/plain",
399            )
400            .unwrap();
401            let new_bucket_access_control = NewObjectAccessControl {
402                entity: Entity::AllUsers,
403                role: Role::Reader,
404            };
405            ObjectAccessControl::create_sync(
406                &bucket.name,
407                "test-object-access-controls-read",
408                &new_bucket_access_control,
409            )
410            .unwrap();
411            ObjectAccessControl::read_sync(
412                &bucket.name,
413                "test-object-access-controls-read",
414                &Entity::AllUsers,
415            )
416            .unwrap();
417        }
418
419        #[test]
420        fn update() {
421            // use a seperate bucket to prevent synchronization issues
422            let bucket = crate::create_test_bucket_sync("test-object-access-controls-update");
423            let new_bucket_access_control = NewObjectAccessControl {
424                entity: Entity::AllUsers,
425                role: Role::Reader,
426            };
427            Object::create_sync(&bucket.name, vec![0, 1], "test-update", "text/plain").unwrap();
428            ObjectAccessControl::create_sync(
429                &bucket.name,
430                "test-update",
431                &new_bucket_access_control,
432            )
433            .unwrap();
434            let mut acl =
435                ObjectAccessControl::read_sync(&bucket.name, "test-update", &Entity::AllUsers)
436                    .unwrap();
437            acl.entity = Entity::AllAuthenticatedUsers;
438            acl.update_sync().unwrap();
439            Object::delete_sync(&bucket.name, "test-update").unwrap();
440            bucket.delete_sync().unwrap();
441        }
442
443        #[test]
444        fn delete() {
445            // use a seperate bucket to prevent synchronization issues
446            let bucket = crate::create_test_bucket_sync("test-object-access-controls-delete");
447            let new_bucket_access_control = NewObjectAccessControl {
448                entity: Entity::AllUsers,
449                role: Role::Reader,
450            };
451            Object::create_sync(&bucket.name, vec![0, 1], "test-delete", "text/plain").unwrap();
452            ObjectAccessControl::create_sync(
453                &bucket.name,
454                "test-delete",
455                &new_bucket_access_control,
456            )
457            .unwrap();
458            let acl =
459                ObjectAccessControl::read_sync(&bucket.name, "test-delete", &Entity::AllUsers)
460                    .unwrap();
461            acl.delete_sync().unwrap();
462            Object::delete_sync(&bucket.name, "test-delete").unwrap();
463            bucket.delete_sync().unwrap();
464        }
465    }
466}