open_lark/service/cloud_docs/permission/public_v1/
patch.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 PatchPermissionPublicRequest {
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    #[serde(skip_serializing_if = "Option::is_none")]
29    link_share_setting: Option<String>,
30    /// 是否允许复制
31    #[serde(skip_serializing_if = "Option::is_none")]
32    allow_copy: Option<bool>,
33    /// 是否允许评论
34    #[serde(skip_serializing_if = "Option::is_none")]
35    allow_comment: Option<bool>,
36    /// 是否允许保存副本
37    #[serde(skip_serializing_if = "Option::is_none")]
38    allow_save_copy: Option<bool>,
39    /// 水印设置
40    #[serde(skip_serializing_if = "Option::is_none")]
41    watermark_setting: Option<String>,
42}
43
44impl PatchPermissionPublicRequest {
45    pub fn builder() -> PatchPermissionPublicRequestBuilder {
46        PatchPermissionPublicRequestBuilder::default()
47    }
48
49    pub fn new(token: impl ToString, obj_type: impl ToString) -> Self {
50        Self {
51            token: token.to_string(),
52            obj_type: obj_type.to_string(),
53            ..Default::default()
54        }
55    }
56
57    /// 更新文档权限设置
58    pub fn for_doc(token: impl ToString) -> Self {
59        Self::new(token, "doc")
60    }
61
62    /// 更新电子表格权限设置
63    pub fn for_sheet(token: impl ToString) -> Self {
64        Self::new(token, "sheet")
65    }
66
67    /// 更新多维表格权限设置
68    pub fn for_bitable(token: impl ToString) -> Self {
69        Self::new(token, "bitable")
70    }
71
72    /// 更新知识库权限设置
73    pub fn for_wiki(token: impl ToString) -> Self {
74        Self::new(token, "wiki")
75    }
76}
77
78#[derive(Default)]
79pub struct PatchPermissionPublicRequestBuilder {
80    request: PatchPermissionPublicRequest,
81}
82
83impl PatchPermissionPublicRequestBuilder {
84    /// 文档token
85    pub fn token(mut self, token: impl ToString) -> Self {
86        self.request.token = token.to_string();
87        self
88    }
89
90    /// 文档类型
91    pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
92        self.request.obj_type = obj_type.to_string();
93        self
94    }
95
96    /// 设置为文档类型
97    pub fn as_doc(mut self) -> Self {
98        self.request.obj_type = "doc".to_string();
99        self
100    }
101
102    /// 设置为电子表格类型
103    pub fn as_sheet(mut self) -> Self {
104        self.request.obj_type = "sheet".to_string();
105        self
106    }
107
108    /// 设置为多维表格类型
109    pub fn as_bitable(mut self) -> Self {
110        self.request.obj_type = "bitable".to_string();
111        self
112    }
113
114    /// 设置为知识库类型
115    pub fn as_wiki(mut self) -> Self {
116        self.request.obj_type = "wiki".to_string();
117        self
118    }
119
120    /// 设置链接分享设置
121    pub fn link_share_setting(mut self, setting: impl ToString) -> Self {
122        self.request.link_share_setting = Some(setting.to_string());
123        self
124    }
125
126    /// 关闭分享
127    pub fn close_sharing(mut self) -> Self {
128        self.request.link_share_setting = Some("closed".to_string());
129        self
130    }
131
132    /// 组织内可读
133    pub fn tenant_readable(mut self) -> Self {
134        self.request.link_share_setting = Some("tenant_readable".to_string());
135        self
136    }
137
138    /// 组织内可编辑
139    pub fn tenant_editable(mut self) -> Self {
140        self.request.link_share_setting = Some("tenant_editable".to_string());
141        self
142    }
143
144    /// 任何人可读
145    pub fn anyone_readable(mut self) -> Self {
146        self.request.link_share_setting = Some("anyone_readable".to_string());
147        self
148    }
149
150    /// 任何人可编辑
151    pub fn anyone_editable(mut self) -> Self {
152        self.request.link_share_setting = Some("anyone_editable".to_string());
153        self
154    }
155
156    /// 是否允许复制
157    pub fn allow_copy(mut self, allow: bool) -> Self {
158        self.request.allow_copy = Some(allow);
159        self
160    }
161
162    /// 允许复制
163    pub fn enable_copy(mut self) -> Self {
164        self.request.allow_copy = Some(true);
165        self
166    }
167
168    /// 禁止复制
169    pub fn disable_copy(mut self) -> Self {
170        self.request.allow_copy = Some(false);
171        self
172    }
173
174    /// 是否允许评论
175    pub fn allow_comment(mut self, allow: bool) -> Self {
176        self.request.allow_comment = Some(allow);
177        self
178    }
179
180    /// 允许评论
181    pub fn enable_comment(mut self) -> Self {
182        self.request.allow_comment = Some(true);
183        self
184    }
185
186    /// 禁止评论
187    pub fn disable_comment(mut self) -> Self {
188        self.request.allow_comment = Some(false);
189        self
190    }
191
192    /// 是否允许保存副本
193    pub fn allow_save_copy(mut self, allow: bool) -> Self {
194        self.request.allow_save_copy = Some(allow);
195        self
196    }
197
198    /// 允许保存副本
199    pub fn enable_save_copy(mut self) -> Self {
200        self.request.allow_save_copy = Some(true);
201        self
202    }
203
204    /// 禁止保存副本
205    pub fn disable_save_copy(mut self) -> Self {
206        self.request.allow_save_copy = Some(false);
207        self
208    }
209
210    /// 水印设置
211    pub fn watermark_setting(mut self, setting: impl ToString) -> Self {
212        self.request.watermark_setting = Some(setting.to_string());
213        self
214    }
215
216    /// 开启水印
217    pub fn enable_watermark(mut self) -> Self {
218        self.request.watermark_setting = Some("visible".to_string());
219        self
220    }
221
222    /// 关闭水印
223    pub fn disable_watermark(mut self) -> Self {
224        self.request.watermark_setting = Some("none".to_string());
225        self
226    }
227
228    /// 设置为安全模式(限制性设置)
229    pub fn secure_mode(mut self) -> Self {
230        self.request.link_share_setting = Some("tenant_readable".to_string());
231        self.request.allow_copy = Some(false);
232        self.request.allow_comment = Some(false);
233        self.request.allow_save_copy = Some(false);
234        self.request.watermark_setting = Some("visible".to_string());
235        self
236    }
237
238    /// 设置为开放模式(宽松设置)
239    pub fn open_mode(mut self) -> Self {
240        self.request.link_share_setting = Some("anyone_editable".to_string());
241        self.request.allow_copy = Some(true);
242        self.request.allow_comment = Some(true);
243        self.request.allow_save_copy = Some(true);
244        self.request.watermark_setting = Some("none".to_string());
245        self
246    }
247
248    pub fn build(mut self) -> PatchPermissionPublicRequest {
249        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
250        self.request
251    }
252}
253
254/// 权限更新结果
255#[derive(Debug, Deserialize)]
256pub struct PermissionUpdateResult {
257    /// 链接分享设置
258    pub link_share_setting: Option<String>,
259    /// 是否允许复制
260    pub allow_copy: Option<bool>,
261    /// 是否允许评论
262    pub allow_comment: Option<bool>,
263    /// 是否允许保存副本
264    pub allow_save_copy: Option<bool>,
265    /// 水印设置
266    pub watermark_setting: Option<String>,
267    /// 更新时间
268    pub update_time: Option<i64>,
269}
270
271/// 更新云文档权限设置响应
272#[derive(Debug, Deserialize)]
273pub struct PatchPermissionPublicResponse {
274    /// 更新后的权限设置
275    pub permission_public: PermissionUpdateResult,
276}
277
278impl ApiResponseTrait for PatchPermissionPublicResponse {
279    fn data_format() -> ResponseFormat {
280        ResponseFormat::Data
281    }
282}
283
284/// 更新云文档权限设置
285pub async fn patch_permission_public(
286    request: PatchPermissionPublicRequest,
287    config: &Config,
288    option: Option<RequestOption>,
289) -> SDKResult<BaseResponse<PatchPermissionPublicResponse>> {
290    let mut api_req = request.api_request;
291    api_req.http_method = Method::PATCH;
292    api_req.api_path =
293        EndpointBuilder::replace_param(DRIVE_V1_PERMISSIONS_PUBLIC, "token", &request.token);
294
295    // 添加查询参数
296    api_req
297        .query_params
298        .insert(QueryParams::TYPE, request.obj_type);
299
300    api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
301
302    let api_resp = Transport::request(api_req, config, option).await?;
303    Ok(api_resp)
304}
305
306impl PermissionUpdateResult {
307    /// 获取分享级别描述
308    pub fn share_level_description(&self) -> Option<&'static str> {
309        self.link_share_setting
310            .as_ref()
311            .map(|setting| match setting.as_str() {
312                "closed" => "关闭分享",
313                "tenant_readable" => "组织内可读",
314                "tenant_editable" => "组织内可编辑",
315                "anyone_readable" => "任何人可读",
316                "anyone_editable" => "任何人可编辑",
317                _ => "未知设置",
318            })
319    }
320
321    /// 是否有更新时间
322    pub fn has_update_time(&self) -> bool {
323        self.update_time.is_some()
324    }
325
326    /// 获取更新时间格式化字符串
327    pub fn update_time_formatted(&self) -> Option<String> {
328        self.update_time
329            .map(|timestamp| format!("更新时间: {timestamp}"))
330    }
331
332    /// 获取权限变更摘要
333    pub fn changes_summary(&self) -> Vec<String> {
334        let mut changes = Vec::new();
335
336        if let Some(ref setting) = self.link_share_setting {
337            changes.push(format!(
338                "分享设置: {}",
339                match setting.as_str() {
340                    "closed" => "关闭分享",
341                    "tenant_readable" => "组织内可读",
342                    "tenant_editable" => "组织内可编辑",
343                    "anyone_readable" => "任何人可读",
344                    "anyone_editable" => "任何人可编辑",
345                    _ => setting,
346                }
347            ));
348        }
349
350        if let Some(allow_copy) = self.allow_copy {
351            changes.push(format!(
352                "复制权限: {}",
353                if allow_copy { "允许" } else { "禁止" }
354            ));
355        }
356
357        if let Some(allow_comment) = self.allow_comment {
358            changes.push(format!(
359                "评论权限: {}",
360                if allow_comment { "允许" } else { "禁止" }
361            ));
362        }
363
364        if let Some(allow_save_copy) = self.allow_save_copy {
365            changes.push(format!(
366                "保存副本: {}",
367                if allow_save_copy { "允许" } else { "禁止" }
368            ));
369        }
370
371        if let Some(ref watermark) = self.watermark_setting {
372            changes.push(format!(
373                "水印设置: {}",
374                match watermark.as_str() {
375                    "visible" => "显示水印",
376                    "none" => "无水印",
377                    _ => watermark,
378                }
379            ));
380        }
381
382        changes
383    }
384
385    /// 计算安全级别
386    pub fn security_level(&self) -> &'static str {
387        if let Some(ref setting) = self.link_share_setting {
388            match setting.as_str() {
389                "closed" => "最安全",
390                "tenant_readable" => "较安全",
391                "tenant_editable" => "中等安全",
392                "anyone_readable" => "较低安全",
393                "anyone_editable" => "低安全",
394                _ => "未知",
395            }
396        } else {
397            "未变更"
398        }
399    }
400}
401
402impl PatchPermissionPublicResponse {
403    /// 获取更新结果
404    pub fn update_result(&self) -> &PermissionUpdateResult {
405        &self.permission_public
406    }
407
408    /// 是否更新成功
409    pub fn is_updated(&self) -> bool {
410        // 如果有任何字段有值,说明更新成功
411        self.permission_public.link_share_setting.is_some()
412            || self.permission_public.allow_copy.is_some()
413            || self.permission_public.allow_comment.is_some()
414            || self.permission_public.allow_save_copy.is_some()
415            || self.permission_public.watermark_setting.is_some()
416    }
417
418    /// 获取更新摘要
419    pub fn update_summary(&self) -> String {
420        let changes = self.permission_public.changes_summary();
421        if changes.is_empty() {
422            "权限设置无变更".to_string()
423        } else {
424            format!("权限设置已更新: {}", changes.join(", "))
425        }
426    }
427
428    /// 获取安全性评估
429    pub fn security_assessment(&self) -> String {
430        format!(
431            "安全级别: {} - {}",
432            self.permission_public.security_level(),
433            self.get_security_tips()
434        )
435    }
436
437    /// 获取安全建议
438    fn get_security_tips(&self) -> &'static str {
439        if let Some(ref setting) = self.permission_public.link_share_setting {
440            match setting.as_str() {
441                "closed" => "文档仅限邀请用户访问,安全性最高",
442                "tenant_readable" => "组织内用户可查看,适合内部分享",
443                "tenant_editable" => "组织内用户可编辑,注意权限管控",
444                "anyone_readable" => "任何人可查看,建议开启密码保护",
445                "anyone_editable" => "任何人可编辑,存在安全风险",
446                _ => "权限设置需要进一步确认",
447            }
448        } else {
449            "权限设置保持原有配置"
450        }
451    }
452
453    /// 获取操作建议
454    pub fn operation_recommendations(&self) -> Vec<String> {
455        let mut recommendations = Vec::new();
456
457        if let Some(ref setting) = self.permission_public.link_share_setting {
458            if setting == "anyone_editable" || setting == "anyone_readable" {
459                recommendations.push("建议设置密码保护".to_string());
460
461                if self.permission_public.allow_copy == Some(true) {
462                    recommendations.push("建议禁止复制以防止内容泄露".to_string());
463                }
464
465                if self.permission_public.watermark_setting != Some("visible".to_string()) {
466                    recommendations.push("建议开启水印以标识来源".to_string());
467                }
468            }
469        }
470
471        if recommendations.is_empty() {
472            recommendations.push("当前权限配置合理".to_string());
473        }
474
475        recommendations
476    }
477}
478
479#[cfg(test)]
480#[allow(unused_variables, unused_unsafe)]
481mod tests {
482    use super::*;
483
484    #[test]
485    fn test_patch_permission_public_request_builder() {
486        let request = PatchPermissionPublicRequest::builder()
487            .token("doccnxxxxxx")
488            .as_doc()
489            .tenant_readable()
490            .disable_copy()
491            .enable_comment()
492            .enable_watermark()
493            .build();
494
495        assert_eq!(request.token, "doccnxxxxxx");
496        assert_eq!(request.obj_type, "doc");
497        assert_eq!(
498            request.link_share_setting,
499            Some("tenant_readable".to_string())
500        );
501        assert_eq!(request.allow_copy, Some(false));
502        assert_eq!(request.allow_comment, Some(true));
503        assert_eq!(request.watermark_setting, Some("visible".to_string()));
504    }
505
506    #[test]
507    fn test_convenience_modes() {
508        let secure_request = PatchPermissionPublicRequest::builder()
509            .token("doccnxxxxxx")
510            .as_doc()
511            .secure_mode()
512            .build();
513
514        assert_eq!(
515            secure_request.link_share_setting,
516            Some("tenant_readable".to_string())
517        );
518        assert_eq!(secure_request.allow_copy, Some(false));
519        assert_eq!(secure_request.allow_comment, Some(false));
520        assert_eq!(secure_request.allow_save_copy, Some(false));
521        assert_eq!(
522            secure_request.watermark_setting,
523            Some("visible".to_string())
524        );
525
526        let open_request = PatchPermissionPublicRequest::builder()
527            .token("doccnxxxxxx")
528            .as_doc()
529            .open_mode()
530            .build();
531
532        assert_eq!(
533            open_request.link_share_setting,
534            Some("anyone_editable".to_string())
535        );
536        assert_eq!(open_request.allow_copy, Some(true));
537        assert_eq!(open_request.allow_comment, Some(true));
538        assert_eq!(open_request.allow_save_copy, Some(true));
539        assert_eq!(open_request.watermark_setting, Some("none".to_string()));
540    }
541
542    #[test]
543    fn test_permission_update_result_methods() {
544        let result = PermissionUpdateResult {
545            link_share_setting: Some("tenant_editable".to_string()),
546            allow_copy: Some(false),
547            allow_comment: Some(true),
548            allow_save_copy: Some(false),
549            watermark_setting: Some("visible".to_string()),
550            update_time: Some(1234567890),
551        };
552
553        assert_eq!(result.share_level_description(), Some("组织内可编辑"));
554        assert!(result.has_update_time());
555        assert_eq!(result.security_level(), "中等安全");
556
557        let changes = result.changes_summary();
558        assert_eq!(changes.len(), 5);
559        assert!(changes.iter().any(|c| c.contains("组织内可编辑")));
560        assert!(changes.iter().any(|c| c.contains("复制权限: 禁止")));
561        assert!(changes.iter().any(|c| c.contains("评论权限: 允许")));
562    }
563}