open_lark/service/cloud_docs/permission/member/
auth.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    req_option::RequestOption,
12    SDKResult,
13};
14
15use super::batch_create::Permission;
16
17/// 判断当前用户是否有某权限请求
18#[derive(Debug, Serialize, Default, Clone)]
19pub struct AuthPermissionRequest {
20    #[serde(skip)]
21    api_request: ApiRequest,
22    /// 文档token
23    #[serde(skip)]
24    token: String,
25    /// 文档类型
26    #[serde(skip)]
27    obj_type: String,
28    /// 要检查的权限
29    #[serde(skip)]
30    perm: String,
31}
32
33impl AuthPermissionRequest {
34    pub fn builder() -> AuthPermissionRequestBuilder {
35        AuthPermissionRequestBuilder::default()
36    }
37
38    pub fn new(token: impl ToString, obj_type: impl ToString, perm: Permission) -> Self {
39        Self {
40            token: token.to_string(),
41            obj_type: obj_type.to_string(),
42            perm: match perm {
43                Permission::FullAccess => "full_access".to_string(),
44                Permission::Edit => "edit".to_string(),
45                Permission::Comment => "comment".to_string(),
46                Permission::View => "view".to_string(),
47            },
48            ..Default::default()
49        }
50    }
51}
52
53#[derive(Default)]
54pub struct AuthPermissionRequestBuilder {
55    request: AuthPermissionRequest,
56}
57
58impl AuthPermissionRequestBuilder {
59    /// 文档token
60    pub fn token(mut self, token: impl ToString) -> Self {
61        self.request.token = token.to_string();
62        self
63    }
64
65    /// 文档类型
66    pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
67        self.request.obj_type = obj_type.to_string();
68        self
69    }
70
71    /// 设置为文档类型
72    pub fn as_doc(mut self) -> Self {
73        self.request.obj_type = "doc".to_string();
74        self
75    }
76
77    /// 设置为电子表格类型
78    pub fn as_sheet(mut self) -> Self {
79        self.request.obj_type = "sheet".to_string();
80        self
81    }
82
83    /// 设置为多维表格类型
84    pub fn as_bitable(mut self) -> Self {
85        self.request.obj_type = "bitable".to_string();
86        self
87    }
88
89    /// 设置为知识库类型
90    pub fn as_wiki(mut self) -> Self {
91        self.request.obj_type = "wiki".to_string();
92        self
93    }
94
95    /// 要检查的权限
96    pub fn permission(mut self, perm: Permission) -> Self {
97        self.request.perm = match perm {
98            Permission::FullAccess => "full_access".to_string(),
99            Permission::Edit => "edit".to_string(),
100            Permission::Comment => "comment".to_string(),
101            Permission::View => "view".to_string(),
102        };
103        self
104    }
105
106    /// 检查是否有所有者权限
107    pub fn check_full_access(mut self) -> Self {
108        self.request.perm = "full_access".to_string();
109        self
110    }
111
112    /// 检查是否有编辑权限
113    pub fn check_edit(mut self) -> Self {
114        self.request.perm = "edit".to_string();
115        self
116    }
117
118    /// 检查是否有评论权限
119    pub fn check_comment(mut self) -> Self {
120        self.request.perm = "comment".to_string();
121        self
122    }
123
124    /// 检查是否有查看权限
125    pub fn check_view(mut self) -> Self {
126        self.request.perm = "view".to_string();
127        self
128    }
129
130    pub fn build(mut self) -> AuthPermissionRequest {
131        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
132        self.request
133    }
134}
135
136/// 权限检查结果
137#[derive(Debug, Deserialize)]
138pub struct PermissionAuth {
139    /// 是否有该权限
140    pub is_permitted: bool,
141    /// 检查的权限类型
142    pub perm: String,
143    /// 用户实际权限(如果有)
144    pub actual_perm: Option<String>,
145}
146
147/// 判断当前用户是否有某权限响应
148#[derive(Debug, Deserialize)]
149pub struct AuthPermissionResponse {
150    /// 权限检查结果
151    pub auth_result: PermissionAuth,
152}
153
154impl ApiResponseTrait for AuthPermissionResponse {
155    fn data_format() -> ResponseFormat {
156        ResponseFormat::Data
157    }
158}
159
160/// 判断当前用户是否有某权限
161pub async fn auth_permission(
162    request: AuthPermissionRequest,
163    config: &Config,
164    option: Option<RequestOption>,
165) -> SDKResult<BaseResponse<AuthPermissionResponse>> {
166    let mut api_req = request.api_request;
167    api_req.http_method = Method::GET;
168    api_req.api_path = format!(
169        "{}?type={}&perm={}",
170        EndpointBuilder::replace_param(DRIVE_V1_PERMISSIONS_MEMBERS_AUTH, "token", &request.token),
171        request.obj_type,
172        request.perm
173    );
174
175    api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
176
177    let api_resp = Transport::request(api_req, config, option).await?;
178    Ok(api_resp)
179}
180
181impl PermissionAuth {
182    /// 是否有权限
183    pub fn has_permission(&self) -> bool {
184        self.is_permitted
185    }
186
187    /// 获取检查的权限类型
188    pub fn checked_permission(&self) -> &str {
189        &self.perm
190    }
191
192    /// 获取实际权限
193    pub fn actual_permission(&self) -> Option<&str> {
194        self.actual_perm.as_deref()
195    }
196
197    /// 获取权限描述
198    pub fn permission_description(&self) -> String {
199        let checked = match self.perm.as_str() {
200            "full_access" => "所有者",
201            "edit" => "编辑",
202            "comment" => "评论",
203            "view" => "查看",
204            _ => "未知",
205        };
206
207        if self.is_permitted {
208            format!("有{checked}权限")
209        } else {
210            format!("无{checked}权限")
211        }
212    }
213
214    /// 权限级别比较
215    pub fn actual_permission_level(&self) -> u8 {
216        match self.actual_perm.as_deref() {
217            Some("view") => 1,
218            Some("comment") => 2,
219            Some("edit") => 3,
220            Some("full_access") => 4,
221            _ => 0,
222        }
223    }
224
225    /// 是否有更高级别的权限
226    pub fn has_higher_permission(&self) -> bool {
227        if let Some(actual) = &self.actual_perm {
228            let checked_level = match self.perm.as_str() {
229                "view" => 1,
230                "comment" => 2,
231                "edit" => 3,
232                "full_access" => 4,
233                _ => 0,
234            };
235
236            let actual_level = match actual.as_str() {
237                "view" => 1,
238                "comment" => 2,
239                "edit" => 3,
240                "full_access" => 4,
241                _ => 0,
242            };
243
244            actual_level > checked_level
245        } else {
246            false
247        }
248    }
249}
250
251impl AuthPermissionResponse {
252    /// 是否有权限
253    pub fn has_permission(&self) -> bool {
254        self.auth_result.has_permission()
255    }
256
257    /// 获取检查的权限
258    pub fn checked_permission(&self) -> &str {
259        self.auth_result.checked_permission()
260    }
261
262    /// 获取实际权限
263    pub fn actual_permission(&self) -> Option<&str> {
264        self.auth_result.actual_permission()
265    }
266
267    /// 获取权限摘要
268    pub fn summary(&self) -> String {
269        let mut parts = vec![self.auth_result.permission_description()];
270
271        if let Some(actual) = self.actual_permission() {
272            if actual != self.checked_permission() {
273                let actual_desc = match actual {
274                    "full_access" => "所有者",
275                    "edit" => "编辑者",
276                    "comment" => "评论者",
277                    "view" => "阅读者",
278                    _ => "未知",
279                };
280                parts.push(format!("实际权限: {actual_desc}"));
281            }
282        }
283
284        parts.join(", ")
285    }
286
287    /// 是否可以执行指定操作
288    pub fn can_perform_action(&self, action: &str) -> bool {
289        if !self.has_permission() {
290            return false;
291        }
292
293        match action {
294            "read" | "view" => true, // 有任何权限都能查看
295            "comment" => self.auth_result.actual_permission_level() >= 2,
296            "edit" | "write" => self.auth_result.actual_permission_level() >= 3,
297            "manage" | "admin" => self.auth_result.actual_permission_level() >= 4,
298            _ => false,
299        }
300    }
301}
302
303#[cfg(test)]
304#[allow(unused_variables, unused_unsafe)]
305mod tests {
306    use super::*;
307
308    #[test]
309    fn test_auth_permission_request_builder() {
310        let request = AuthPermissionRequest::builder()
311            .token("doccnxxxxxx")
312            .as_doc()
313            .check_edit()
314            .build();
315
316        assert_eq!(request.token, "doccnxxxxxx");
317        assert_eq!(request.obj_type, "doc");
318        assert_eq!(request.perm, "edit");
319    }
320
321    #[test]
322    fn test_auth_permission_new() {
323        let request = AuthPermissionRequest::new("doccnxxxxxx", "doc", Permission::Edit);
324        assert_eq!(request.perm, "edit");
325    }
326}