Skip to main content

ali_oss_rs/
acl.rs

1//! Object acl module
2
3use async_trait::async_trait;
4
5use crate::{
6    acl_common::{build_get_object_acl_request, build_put_object_acl_request, parse_object_acl_from_xml},
7    common::VersionIdOnlyOptions,
8    object_common::ObjectAcl,
9    Client, Result,
10};
11
12pub type PutObjectAclOptions = VersionIdOnlyOptions;
13pub type GetObjectAclOptions = VersionIdOnlyOptions;
14
15#[async_trait]
16pub trait ObjectAclOperations {
17    /// Get an object's acl.
18    ///
19    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/getobjectacl>
20    async fn get_object_acl<S1, S2>(&self, bucket_name: S1, object_key: S2, options: Option<GetObjectAclOptions>) -> Result<ObjectAcl>
21    where
22        S1: AsRef<str> + Send,
23        S2: AsRef<str> + Send;
24
25    /// Put an object's acl. If you want to restore the object's acl to follow bucket acl settings, pass acl as `ObjectAcl::Default`
26    ///
27    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/putobjectacl>
28    async fn put_object_acl<S1, S2>(&self, bucket_name: S1, object_key: S2, acl: ObjectAcl, options: Option<GetObjectAclOptions>) -> Result<()>
29    where
30        S1: AsRef<str> + Send,
31        S2: AsRef<str> + Send;
32}
33
34#[async_trait]
35impl ObjectAclOperations for Client {
36    /// Get an object's acl.
37    ///
38    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/getobjectacl>
39    async fn get_object_acl<S1, S2>(&self, bucket_name: S1, object_key: S2, options: Option<GetObjectAclOptions>) -> Result<ObjectAcl>
40    where
41        S1: AsRef<str> + Send,
42        S2: AsRef<str> + Send,
43    {
44        let request = build_get_object_acl_request(bucket_name.as_ref(), object_key.as_ref(), &options)?;
45        let (_, content) = self.do_request::<String>(request).await?;
46        parse_object_acl_from_xml(&content)
47    }
48
49    /// Put an object's acl. If you want to restore the object's acl to follow bucket acl settings, pass acl as `ObjectAcl::Default`
50    ///
51    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/putobjectacl>
52    async fn put_object_acl<S1, S2>(&self, bucket_name: S1, object_key: S2, acl: ObjectAcl, options: Option<GetObjectAclOptions>) -> Result<()>
53    where
54        S1: AsRef<str> + Send,
55        S2: AsRef<str> + Send,
56    {
57        let request = build_put_object_acl_request(bucket_name.as_ref(), object_key.as_ref(), acl, &options)?;
58        let _ = self.do_request::<()>(request).await?;
59        Ok(())
60    }
61}
62
63#[cfg(test)]
64mod test_object_acl_async {
65    use std::sync::Once;
66
67    use reqwest::StatusCode;
68    use uuid::Uuid;
69
70    use crate::{acl::ObjectAclOperations, object::ObjectOperations, object_common::ObjectAcl, Client};
71
72    static INIT: Once = Once::new();
73
74    fn setup() {
75        INIT.call_once(|| {
76            simple_logger::init_with_level(log::Level::Debug).unwrap();
77            dotenvy::dotenv().unwrap();
78        });
79    }
80
81    #[tokio::test]
82    async fn test_object_acl_async() {
83        log::debug!("test a private object update to public");
84        setup();
85
86        let client = Client::from_env();
87
88        let bucket_name = "yuanyq";
89        let object_key = format!("rust-sdk-test/{}.jpg", Uuid::new_v4());
90        let file_path = "/home/yuanyq/Pictures/01-cover.jpg";
91
92        let response = client.put_object_from_file(bucket_name, &object_key, file_path, None).await;
93
94        assert!(response.is_ok());
95
96        let response = client.put_object_acl(bucket_name, &object_key, ObjectAcl::PublicRead, None).await;
97        assert!(response.is_ok());
98
99        let response = client.get_object_acl(bucket_name, &object_key, None).await;
100        assert!(response.is_ok());
101        let ret = response.unwrap();
102        assert_eq!(ObjectAcl::PublicRead, ret);
103
104        let url = format!("https://{}.oss-cn-beijing.aliyuncs.com/{}", bucket_name, object_key);
105        let status = reqwest::get(&url).await.unwrap().status();
106        assert_eq!(StatusCode::OK, status);
107
108        let response = client.put_object_acl(bucket_name, &object_key, ObjectAcl::Default, None).await;
109        assert!(response.is_ok());
110
111        let response = client.get_object_acl(bucket_name, &object_key, None).await;
112        assert!(response.is_ok());
113        let ret = response.unwrap();
114        assert_eq!(ObjectAcl::Default, ret);
115
116        let url = format!("https://{}.oss-cn-beijing.aliyuncs.com/{}", bucket_name, object_key);
117        let status = reqwest::get(&url).await.unwrap().status();
118        assert_eq!(StatusCode::FORBIDDEN, status);
119
120        client.delete_object(bucket_name, &object_key, None).await.unwrap();
121    }
122}