open_lark/service/cloud_docs/permission/public_v1/
get.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::core::{
5    api_req::ApiRequest,
6    api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
7    config::Config,
8    constants::AccessTokenType,
9    endpoints::{cloud_docs::*, EndpointBuilder},
10    http::Transport,
11    query_params::QueryParams,
12    req_option::RequestOption,
13    SDKResult,
14};
15
16/// 获取云文档权限设置请求
17#[derive(Debug, Serialize, Default, Clone)]
18pub struct GetPermissionPublicRequest {
19    #[serde(skip)]
20    api_request: ApiRequest,
21    /// 文档token
22    #[serde(skip)]
23    token: String,
24    /// 文档类型
25    #[serde(skip)]
26    obj_type: String,
27}
28
29impl GetPermissionPublicRequest {
30    pub fn builder() -> GetPermissionPublicRequestBuilder {
31        GetPermissionPublicRequestBuilder::default()
32    }
33
34    pub fn new(token: impl ToString, obj_type: impl ToString) -> Self {
35        Self {
36            token: token.to_string(),
37            obj_type: obj_type.to_string(),
38            ..Default::default()
39        }
40    }
41
42    /// 获取文档权限设置
43    pub fn for_doc(token: impl ToString) -> Self {
44        Self::new(token, "doc")
45    }
46
47    /// 获取电子表格权限设置
48    pub fn for_sheet(token: impl ToString) -> Self {
49        Self::new(token, "sheet")
50    }
51
52    /// 获取多维表格权限设置
53    pub fn for_bitable(token: impl ToString) -> Self {
54        Self::new(token, "bitable")
55    }
56
57    /// 获取知识库权限设置
58    pub fn for_wiki(token: impl ToString) -> Self {
59        Self::new(token, "wiki")
60    }
61}
62
63#[derive(Default)]
64pub struct GetPermissionPublicRequestBuilder {
65    request: GetPermissionPublicRequest,
66}
67
68impl GetPermissionPublicRequestBuilder {
69    /// 文档token
70    pub fn token(mut self, token: impl ToString) -> Self {
71        self.request.token = token.to_string();
72        self
73    }
74
75    /// 文档类型
76    pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
77        self.request.obj_type = obj_type.to_string();
78        self
79    }
80
81    /// 设置为文档类型
82    pub fn as_doc(mut self) -> Self {
83        self.request.obj_type = "doc".to_string();
84        self
85    }
86
87    /// 设置为电子表格类型
88    pub fn as_sheet(mut self) -> Self {
89        self.request.obj_type = "sheet".to_string();
90        self
91    }
92
93    /// 设置为多维表格类型
94    pub fn as_bitable(mut self) -> Self {
95        self.request.obj_type = "bitable".to_string();
96        self
97    }
98
99    /// 设置为知识库类型
100    pub fn as_wiki(mut self) -> Self {
101        self.request.obj_type = "wiki".to_string();
102        self
103    }
104
105    pub fn build(mut self) -> GetPermissionPublicRequest {
106        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
107        self.request
108    }
109}
110
111/// 公开访问设置
112#[derive(Debug, Deserialize)]
113pub struct PublicSettings {
114    /// 链接分享设置
115    pub link_share_setting: String,
116    /// 密码保护(如果有)
117    pub password_switch: bool,
118    /// 是否允许复制
119    pub allow_copy: bool,
120    /// 是否允许评论
121    pub allow_comment: bool,
122    /// 是否允许保存副本
123    pub allow_save_copy: bool,
124    /// 访问权限
125    pub access_setting: Option<String>,
126    /// 水印设置
127    pub watermark_setting: Option<String>,
128}
129
130/// 获取云文档权限设置响应
131#[derive(Debug, Deserialize)]
132pub struct GetPermissionPublicResponse {
133    /// 公开访问设置
134    pub permission_public: PublicSettings,
135    /// 外部访问设置(如果有)
136    pub external_access: Option<serde_json::Value>,
137}
138
139impl ApiResponseTrait for GetPermissionPublicResponse {
140    fn data_format() -> ResponseFormat {
141        ResponseFormat::Data
142    }
143}
144
145/// 获取云文档权限设置
146pub async fn get_permission_public(
147    request: GetPermissionPublicRequest,
148    config: &Config,
149    option: Option<RequestOption>,
150) -> SDKResult<BaseResponse<GetPermissionPublicResponse>> {
151    let mut api_req = request.api_request;
152    api_req.http_method = Method::GET;
153    api_req.api_path =
154        EndpointBuilder::replace_param(DRIVE_V1_PERMISSIONS_PUBLIC, "token", &request.token);
155
156    // 添加查询参数
157    api_req
158        .query_params
159        .insert(QueryParams::TYPE, request.obj_type);
160
161    api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
162
163    let api_resp = Transport::request(api_req, config, option).await?;
164    Ok(api_resp)
165}
166
167impl PublicSettings {
168    /// 是否开启了链接分享
169    pub fn is_link_share_enabled(&self) -> bool {
170        self.link_share_setting == "tenant_readable"
171            || self.link_share_setting == "tenant_editable"
172            || self.link_share_setting == "anyone_readable"
173            || self.link_share_setting == "anyone_editable"
174    }
175
176    /// 是否允许组织内访问
177    pub fn is_tenant_accessible(&self) -> bool {
178        self.link_share_setting == "tenant_readable" || self.link_share_setting == "tenant_editable"
179    }
180
181    /// 是否允许任何人访问
182    pub fn is_anyone_accessible(&self) -> bool {
183        self.link_share_setting == "anyone_readable" || self.link_share_setting == "anyone_editable"
184    }
185
186    /// 是否允许编辑
187    pub fn is_editable(&self) -> bool {
188        self.link_share_setting == "tenant_editable" || self.link_share_setting == "anyone_editable"
189    }
190
191    /// 是否仅可读
192    pub fn is_readonly(&self) -> bool {
193        self.link_share_setting == "tenant_readable" || self.link_share_setting == "anyone_readable"
194    }
195
196    /// 是否开启密码保护
197    pub fn has_password_protection(&self) -> bool {
198        self.password_switch
199    }
200
201    /// 获取分享级别描述
202    pub fn share_level_description(&self) -> &'static str {
203        match self.link_share_setting.as_str() {
204            "closed" => "关闭分享",
205            "tenant_readable" => "组织内可读",
206            "tenant_editable" => "组织内可编辑",
207            "anyone_readable" => "任何人可读",
208            "anyone_editable" => "任何人可编辑",
209            _ => "未知设置",
210        }
211    }
212
213    /// 获取权限摘要
214    pub fn permissions_summary(&self) -> String {
215        let mut features = Vec::new();
216
217        if self.allow_copy {
218            features.push("允许复制");
219        }
220        if self.allow_comment {
221            features.push("允许评论");
222        }
223        if self.allow_save_copy {
224            features.push("允许保存副本");
225        }
226        if self.password_switch {
227            features.push("密码保护");
228        }
229
230        if features.is_empty() {
231            "基础权限".to_string()
232        } else {
233            features.join(", ")
234        }
235    }
236
237    /// 获取安全级别
238    pub fn security_level(&self) -> &'static str {
239        if self.link_share_setting == "closed" {
240            "最安全"
241        } else if self.password_switch {
242            "较安全"
243        } else if self.is_tenant_accessible() {
244            "中等安全"
245        } else if self.is_anyone_accessible() {
246            "较低安全"
247        } else {
248            "未知"
249        }
250    }
251}
252
253impl GetPermissionPublicResponse {
254    /// 获取公开设置
255    pub fn public_settings(&self) -> &PublicSettings {
256        &self.permission_public
257    }
258
259    /// 是否允许外部访问
260    pub fn allows_external_access(&self) -> bool {
261        self.permission_public.is_link_share_enabled()
262    }
263
264    /// 获取设置摘要
265    pub fn settings_summary(&self) -> String {
266        format!(
267            "{} - {} (安全级别: {})",
268            self.permission_public.share_level_description(),
269            self.permission_public.permissions_summary(),
270            self.permission_public.security_level()
271        )
272    }
273
274    /// 是否有外部访问配置
275    pub fn has_external_config(&self) -> bool {
276        self.external_access.is_some()
277    }
278
279    /// 安全性建议
280    pub fn security_recommendations(&self) -> Vec<String> {
281        let mut recommendations = Vec::new();
282
283        if !self.permission_public.password_switch && self.permission_public.is_anyone_accessible()
284        {
285            recommendations.push("建议开启密码保护以提高安全性".to_string());
286        }
287
288        if self.permission_public.allow_copy && self.permission_public.is_anyone_accessible() {
289            recommendations.push("建议限制复制权限以防止内容泄露".to_string());
290        }
291
292        if self.permission_public.is_editable() && self.permission_public.is_anyone_accessible() {
293            recommendations.push("建议将编辑权限限制在组织内".to_string());
294        }
295
296        if recommendations.is_empty() {
297            recommendations.push("当前权限设置合理".to_string());
298        }
299
300        recommendations
301    }
302}
303
304#[cfg(test)]
305#[allow(unused_variables, unused_unsafe)]
306mod tests {
307    use super::*;
308
309    #[test]
310    fn test_get_permission_public_request_builder() {
311        let request = GetPermissionPublicRequest::builder()
312            .token("doccnxxxxxx")
313            .as_doc()
314            .build();
315
316        assert_eq!(request.token, "doccnxxxxxx");
317        assert_eq!(request.obj_type, "doc");
318    }
319
320    #[test]
321    fn test_convenience_methods() {
322        let request = GetPermissionPublicRequest::for_doc("doccnxxxxxx");
323        assert_eq!(request.obj_type, "doc");
324
325        let request = GetPermissionPublicRequest::for_sheet("shtcnxxxxxx");
326        assert_eq!(request.obj_type, "sheet");
327
328        let request = GetPermissionPublicRequest::for_bitable("bblcnxxxxxx");
329        assert_eq!(request.obj_type, "bitable");
330
331        let request = GetPermissionPublicRequest::for_wiki("wikicnxxxxxx");
332        assert_eq!(request.obj_type, "wiki");
333    }
334
335    #[test]
336    fn test_public_settings_methods() {
337        let settings = PublicSettings {
338            link_share_setting: "tenant_editable".to_string(),
339            password_switch: true,
340            allow_copy: true,
341            allow_comment: true,
342            allow_save_copy: false,
343            access_setting: None,
344            watermark_setting: None,
345        };
346
347        assert!(settings.is_link_share_enabled());
348        assert!(settings.is_tenant_accessible());
349        assert!(!settings.is_anyone_accessible());
350        assert!(settings.is_editable());
351        assert!(!settings.is_readonly());
352        assert!(settings.has_password_protection());
353        assert_eq!(settings.share_level_description(), "组织内可编辑");
354        assert_eq!(settings.security_level(), "较安全");
355    }
356}