open_lark/service/cloud_docs/permission/member/
delete.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 DeletePermissionMemberRequest {
20 #[serde(skip)]
21 api_request: ApiRequest,
22 #[serde(skip)]
24 token: String,
25 #[serde(skip)]
27 obj_type: String,
28 #[serde(skip)]
30 member_type: String,
31 #[serde(skip)]
33 member_id: String,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 need_notification: Option<bool>,
37}
38
39impl DeletePermissionMemberRequest {
40 pub fn builder() -> DeletePermissionMemberRequestBuilder {
41 DeletePermissionMemberRequestBuilder::default()
42 }
43
44 pub fn new(
45 token: impl ToString,
46 obj_type: impl ToString,
47 member_type: impl ToString,
48 member_id: impl ToString,
49 ) -> Self {
50 Self {
51 token: token.to_string(),
52 obj_type: obj_type.to_string(),
53 member_type: member_type.to_string(),
54 member_id: member_id.to_string(),
55 ..Default::default()
56 }
57 }
58
59 pub fn for_user(token: impl ToString, obj_type: impl ToString, user_id: impl ToString) -> Self {
61 Self::new(token, obj_type, "user", user_id)
62 }
63
64 pub fn for_chat(token: impl ToString, obj_type: impl ToString, chat_id: impl ToString) -> Self {
66 Self::new(token, obj_type, "chat", chat_id)
67 }
68
69 pub fn for_department(
71 token: impl ToString,
72 obj_type: impl ToString,
73 department_id: impl ToString,
74 ) -> Self {
75 Self::new(token, obj_type, "department", department_id)
76 }
77}
78
79#[derive(Default)]
80pub struct DeletePermissionMemberRequestBuilder {
81 request: DeletePermissionMemberRequest,
82}
83
84impl DeletePermissionMemberRequestBuilder {
85 pub fn token(mut self, token: impl ToString) -> Self {
87 self.request.token = token.to_string();
88 self
89 }
90
91 pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
93 self.request.obj_type = obj_type.to_string();
94 self
95 }
96
97 pub fn as_doc(mut self) -> Self {
99 self.request.obj_type = "doc".to_string();
100 self
101 }
102
103 pub fn as_sheet(mut self) -> Self {
105 self.request.obj_type = "sheet".to_string();
106 self
107 }
108
109 pub fn as_bitable(mut self) -> Self {
111 self.request.obj_type = "bitable".to_string();
112 self
113 }
114
115 pub fn as_wiki(mut self) -> Self {
117 self.request.obj_type = "wiki".to_string();
118 self
119 }
120
121 pub fn member(mut self, member_type: impl ToString, member_id: impl ToString) -> Self {
123 self.request.member_type = member_type.to_string();
124 self.request.member_id = member_id.to_string();
125 self
126 }
127
128 pub fn user(mut self, user_id: impl ToString) -> Self {
130 self.request.member_type = "user".to_string();
131 self.request.member_id = user_id.to_string();
132 self
133 }
134
135 pub fn chat(mut self, chat_id: impl ToString) -> Self {
137 self.request.member_type = "chat".to_string();
138 self.request.member_id = chat_id.to_string();
139 self
140 }
141
142 pub fn department(mut self, department_id: impl ToString) -> Self {
144 self.request.member_type = "department".to_string();
145 self.request.member_id = department_id.to_string();
146 self
147 }
148
149 pub fn need_notification(mut self, need: bool) -> Self {
151 self.request.need_notification = Some(need);
152 self
153 }
154
155 pub fn with_notification(mut self) -> Self {
157 self.request.need_notification = Some(true);
158 self
159 }
160
161 pub fn without_notification(mut self) -> Self {
163 self.request.need_notification = Some(false);
164 self
165 }
166
167 pub fn build(mut self) -> DeletePermissionMemberRequest {
168 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
169 self.request
170 }
171}
172
173#[derive(Debug, Deserialize)]
175pub struct PermissionMemberDeleted {
176 pub member_type: String,
178 pub member_id: String,
180 pub delete_time: Option<i64>,
182 pub old_perm: Option<Permission>,
184 pub notified: Option<bool>,
186}
187
188#[derive(Debug, Deserialize)]
190pub struct DeletePermissionMemberResponse {
191 pub member: PermissionMemberDeleted,
193}
194
195impl ApiResponseTrait for DeletePermissionMemberResponse {
196 fn data_format() -> ResponseFormat {
197 ResponseFormat::Data
198 }
199}
200
201pub async fn delete_permission_member(
203 request: DeletePermissionMemberRequest,
204 config: &Config,
205 option: Option<RequestOption>,
206) -> SDKResult<BaseResponse<DeletePermissionMemberResponse>> {
207 let mut api_req = request.api_request;
208 api_req.http_method = Method::DELETE;
209 api_req.api_path = format!(
210 "{}?type={}&member_type={}",
211 EndpointBuilder::replace_params_from_array(
212 DRIVE_V1_PERMISSIONS_MEMBER_GET,
213 &[("token", &request.token), ("member_id", &request.member_id)]
214 ),
215 request.obj_type,
216 request.member_type
217 );
218
219 if let Some(need_notification) = request.need_notification {
221 api_req.api_path = format!(
222 "{}&need_notification={}",
223 api_req.api_path, need_notification
224 );
225 }
226
227 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
228
229 let api_resp = Transport::request(api_req, config, option).await?;
230 Ok(api_resp)
231}
232
233impl PermissionMemberDeleted {
234 pub fn member_id(&self) -> &str {
236 &self.member_id
237 }
238
239 pub fn member_type(&self) -> &str {
241 &self.member_type
242 }
243
244 pub fn old_permission(&self) -> Option<&Permission> {
246 self.old_perm.as_ref()
247 }
248
249 pub fn is_user(&self) -> bool {
251 self.member_type == "user"
252 }
253
254 pub fn is_chat(&self) -> bool {
256 self.member_type == "chat"
257 }
258
259 pub fn is_department(&self) -> bool {
261 self.member_type == "department"
262 }
263
264 pub fn was_notified(&self) -> bool {
266 self.notified.unwrap_or(false)
267 }
268
269 pub fn has_delete_time(&self) -> bool {
271 self.delete_time.is_some()
272 }
273
274 pub fn has_old_permission(&self) -> bool {
276 self.old_perm.is_some()
277 }
278
279 pub fn was_owner(&self) -> bool {
281 if let Some(old_perm) = &self.old_perm {
282 old_perm.is_owner()
283 } else {
284 false
285 }
286 }
287
288 pub fn could_edit(&self) -> bool {
290 if let Some(old_perm) = &self.old_perm {
291 old_perm.can_edit()
292 } else {
293 false
294 }
295 }
296
297 pub fn delete_time_formatted(&self) -> Option<String> {
299 self.delete_time
300 .map(|timestamp| format!("删除时间: {timestamp}"))
301 }
302
303 pub fn member_type_description(&self) -> String {
305 match self.member_type.as_str() {
306 "user" => "用户".to_string(),
307 "chat" => "群组".to_string(),
308 "department" => "部门".to_string(),
309 _ => "未知".to_string(),
310 }
311 }
312
313 pub fn old_permission_description(&self) -> Option<String> {
315 self.old_perm
316 .as_ref()
317 .map(|perm| perm.description().to_string())
318 }
319
320 pub fn summary(&self) -> String {
322 let mut parts = vec![format!(
323 "{} ({})",
324 self.member_id,
325 self.member_type_description()
326 )];
327
328 if let Some(old_perm_desc) = self.old_permission_description() {
329 parts.push(format!("原权限: {old_perm_desc}"));
330 }
331
332 if let Some(time) = self.delete_time_formatted() {
333 parts.push(time);
334 }
335
336 if self.was_notified() {
337 parts.push("已通知".to_string());
338 }
339
340 parts.join(", ")
341 }
342}
343
344impl DeletePermissionMemberResponse {
345 pub fn member_id(&self) -> &str {
347 self.member.member_id()
348 }
349
350 pub fn member_type(&self) -> &str {
352 self.member.member_type()
353 }
354
355 pub fn old_permission(&self) -> Option<&Permission> {
357 self.member.old_permission()
358 }
359
360 pub fn is_deleted(&self) -> bool {
362 !self.member.member_id.is_empty()
363 }
364
365 pub fn success_summary(&self) -> String {
367 format!("协作者权限移除成功: {}", self.member.summary())
368 }
369
370 pub fn was_notified(&self) -> bool {
372 self.member.was_notified()
373 }
374
375 pub fn deleted_owner(&self) -> bool {
377 self.member.was_owner()
378 }
379
380 pub fn deleted_editor(&self) -> bool {
382 self.member.could_edit()
383 }
384
385 pub fn delete_time(&self) -> Option<i64> {
387 self.member.delete_time
388 }
389
390 pub fn risk_level(&self) -> &'static str {
392 if self.deleted_owner() {
393 "高风险" } else if self.deleted_editor() {
395 "中风险" } else {
397 "低风险" }
399 }
400}
401
402#[cfg(test)]
403#[allow(unused_variables, unused_unsafe)]
404mod tests {
405 use super::*;
406
407 #[test]
408 fn test_delete_permission_member_request_builder() {
409 let request = DeletePermissionMemberRequest::builder()
410 .token("doccnxxxxxx")
411 .as_doc()
412 .user("user123")
413 .with_notification()
414 .build();
415
416 assert_eq!(request.token, "doccnxxxxxx");
417 assert_eq!(request.obj_type, "doc");
418 assert_eq!(request.member_type, "user");
419 assert_eq!(request.member_id, "user123");
420 assert_eq!(request.need_notification, Some(true));
421 }
422
423 #[test]
424 fn test_delete_permission_member_convenience_methods() {
425 let request = DeletePermissionMemberRequest::for_user("doccnxxxxxx", "doc", "user123");
426 assert_eq!(request.member_type, "user");
427 assert_eq!(request.member_id, "user123");
428
429 let request = DeletePermissionMemberRequest::for_chat("doccnxxxxxx", "doc", "chat456");
430 assert_eq!(request.member_type, "chat");
431 assert_eq!(request.member_id, "chat456");
432
433 let request =
434 DeletePermissionMemberRequest::for_department("doccnxxxxxx", "doc", "dept789");
435 assert_eq!(request.member_type, "department");
436 assert_eq!(request.member_id, "dept789");
437 }
438
439 #[test]
440 fn test_permission_member_deleted_methods() {
441 let member = PermissionMemberDeleted {
442 member_type: "user".to_string(),
443 member_id: "user123".to_string(),
444 delete_time: Some(1234567890),
445 old_perm: Some(Permission::Edit),
446 notified: Some(true),
447 };
448
449 assert!(member.is_user());
450 assert!(!member.is_chat());
451 assert!(!member.is_department());
452 assert!(member.was_notified());
453 assert!(member.has_delete_time());
454 assert!(member.has_old_permission());
455 assert!(!member.was_owner());
456 assert!(member.could_edit());
457 assert_eq!(member.member_type_description(), "用户");
458 assert_eq!(
459 member.old_permission_description(),
460 Some("编辑者".to_string())
461 );
462 }
463
464 #[test]
465 fn test_delete_permission_member_response_risk_level() {
466 let response_owner = DeletePermissionMemberResponse {
467 member: PermissionMemberDeleted {
468 member_type: "user".to_string(),
469 member_id: "user123".to_string(),
470 delete_time: Some(1234567890),
471 old_perm: Some(Permission::FullAccess),
472 notified: Some(true),
473 },
474 };
475 assert_eq!(response_owner.risk_level(), "高风险");
476
477 let response_editor = DeletePermissionMemberResponse {
478 member: PermissionMemberDeleted {
479 member_type: "user".to_string(),
480 member_id: "user123".to_string(),
481 delete_time: Some(1234567890),
482 old_perm: Some(Permission::Edit),
483 notified: Some(true),
484 },
485 };
486 assert_eq!(response_editor.risk_level(), "中风险");
487
488 let response_viewer = DeletePermissionMemberResponse {
489 member: PermissionMemberDeleted {
490 member_type: "user".to_string(),
491 member_id: "user123".to_string(),
492 delete_time: Some(1234567890),
493 old_perm: Some(Permission::View),
494 notified: Some(true),
495 },
496 };
497 assert_eq!(response_viewer.risk_level(), "低风险");
498 }
499}