open_lark/service/cloud_docs/permission/member/
auth.rs1use 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#[derive(Debug, Serialize, Default, Clone)]
19pub struct AuthPermissionRequest {
20 #[serde(skip)]
21 api_request: ApiRequest,
22 #[serde(skip)]
24 token: String,
25 #[serde(skip)]
27 obj_type: String,
28 #[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 pub fn token(mut self, token: impl ToString) -> Self {
61 self.request.token = token.to_string();
62 self
63 }
64
65 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 pub fn as_doc(mut self) -> Self {
73 self.request.obj_type = "doc".to_string();
74 self
75 }
76
77 pub fn as_sheet(mut self) -> Self {
79 self.request.obj_type = "sheet".to_string();
80 self
81 }
82
83 pub fn as_bitable(mut self) -> Self {
85 self.request.obj_type = "bitable".to_string();
86 self
87 }
88
89 pub fn as_wiki(mut self) -> Self {
91 self.request.obj_type = "wiki".to_string();
92 self
93 }
94
95 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 pub fn check_full_access(mut self) -> Self {
108 self.request.perm = "full_access".to_string();
109 self
110 }
111
112 pub fn check_edit(mut self) -> Self {
114 self.request.perm = "edit".to_string();
115 self
116 }
117
118 pub fn check_comment(mut self) -> Self {
120 self.request.perm = "comment".to_string();
121 self
122 }
123
124 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#[derive(Debug, Deserialize)]
138pub struct PermissionAuth {
139 pub is_permitted: bool,
141 pub perm: String,
143 pub actual_perm: Option<String>,
145}
146
147#[derive(Debug, Deserialize)]
149pub struct AuthPermissionResponse {
150 pub auth_result: PermissionAuth,
152}
153
154impl ApiResponseTrait for AuthPermissionResponse {
155 fn data_format() -> ResponseFormat {
156 ResponseFormat::Data
157 }
158}
159
160pub 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 pub fn has_permission(&self) -> bool {
184 self.is_permitted
185 }
186
187 pub fn checked_permission(&self) -> &str {
189 &self.perm
190 }
191
192 pub fn actual_permission(&self) -> Option<&str> {
194 self.actual_perm.as_deref()
195 }
196
197 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 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 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 pub fn has_permission(&self) -> bool {
254 self.auth_result.has_permission()
255 }
256
257 pub fn checked_permission(&self) -> &str {
259 self.auth_result.checked_permission()
260 }
261
262 pub fn actual_permission(&self) -> Option<&str> {
264 self.auth_result.actual_permission()
265 }
266
267 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 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, "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}