drive_v3/resources/permissions.rs
1use reqwest::Method;
2use drive_v3_macros::{DriveRequestBuilder, request};
3
4use super::DriveRequestBuilder;
5use crate::{objects, Credentials};
6
7#[request(
8 method=Method::POST,
9 url="https://www.googleapis.com/drive/v3/files/{file_id}/permissions",
10 returns=objects::Permission,
11)]
12#[derive(DriveRequestBuilder)]
13/// A request builder to create a permission for a file or shared drive.
14pub struct CreateRequest {
15 /// A plain text custom message to include in the notification email.
16 #[drive_v3(parameter)]
17 email_message: Option<String>,
18
19 /// This parameter will only take effect if the item is not in a shared
20 /// drive and the request is attempting to transfer the ownership of the
21 /// item.
22 ///
23 /// If set to `true`, the item will be moved to the new owner's My Drive
24 /// root folder and all prior parents removed. If set to `false`,
25 /// parents are not changed.
26 #[drive_v3(parameter)]
27 move_to_new_owners_root: Option<bool>,
28
29 /// Whether to send a notification email when sharing to users or
30 /// groups.
31 ///
32 /// This defaults to `true` for users and groups, and is not allowed for
33 /// other requests. It must not be disabled for ownership transfers.
34 #[drive_v3(parameter)]
35 send_notification_email: Option<bool>,
36
37 /// Whether the requesting application supports both My Drives and
38 /// shared drives.
39 #[drive_v3(parameter)]
40 supports_all_drives: Option<bool>,
41
42 /// Whether to transfer ownership to the specified user and downgrade
43 /// the current owner to a writer.
44 ///
45 /// This parameter is required as an acknowledgement of the side effect.
46 #[drive_v3(parameter)]
47 transfer_ownership: Option<bool>,
48
49 /// Issue the request as a domain administrator.
50 ///
51 /// if set to `true`, then the requester will be granted access if they
52 /// are an administrator of the domain to which the shared drive
53 /// belongs.
54 #[drive_v3(parameter)]
55 use_domain_admin_access: Option<bool>,
56
57 /// The permission which will be applied.
58 #[drive_v3(body)]
59 permission: Option<objects::Permission>,
60}
61
62#[request(
63 method=Method::DELETE,
64 url="https://www.googleapis.com/drive/v3/files/{file_id}/permissions/{permission_id}",
65 returns=(),
66)]
67#[derive(DriveRequestBuilder)]
68/// A request builder to delete a permission.
69pub struct DeleteRequest {
70 /// Whether the requesting application supports both My Drives and
71 /// shared drives.
72 #[drive_v3(parameter)]
73 supports_all_drives: Option<bool>,
74
75 /// Issue the request as a domain administrator.
76 ///
77 /// if set to `true`, then the requester will be granted access if they
78 /// are an administrator of the domain to which the shared drive
79 /// belongs.
80 #[drive_v3(parameter)]
81 use_domain_admin_access: Option<bool>,
82}
83
84#[request(
85 method=Method::GET,
86 url="https://www.googleapis.com/drive/v3/files/{file_id}/permissions/{permission_id}",
87 returns=objects::Permission,
88)]
89#[derive(DriveRequestBuilder)]
90/// A request builder to get a permission by ID.
91pub struct GetRequest {
92 /// Whether the requesting application supports both My Drives and
93 /// shared drives.
94 #[drive_v3(parameter)]
95 supports_all_drives: Option<bool>,
96
97 /// Issue the request as a domain administrator.
98 ///
99 /// if set to `true`, then the requester will be granted access if they
100 /// are an administrator of the domain to which the shared drive
101 /// belongs.
102 #[drive_v3(parameter)]
103 use_domain_admin_access: Option<bool>,
104}
105
106#[request(
107 method=Method::GET,
108 url="https://www.googleapis.com/drive/v3/files/{file_id}/permissions",
109 returns=objects::PermissionList,
110)]
111#[derive(DriveRequestBuilder)]
112/// A request builder to list a file's or shared drive's permissions.
113pub struct ListRequest {
114 /// The maximum number of permissions to return per page.
115 ///
116 /// When not set for files in a shared drive, at most 100 results will
117 /// be returned. When not set for files that are not in a shared drive,
118 /// the entire list will be returned.
119 #[drive_v3(parameter)]
120 page_size: Option<i64>,
121
122 /// The token for continuing a previous list request on the next page.
123 ///
124 /// This should be set to the value of
125 /// [`next_page_token`](objects::PermissionList::next_page_token) from
126 /// the previous response.
127 #[drive_v3(parameter)]
128 page_token: Option<String>,
129
130 /// Whether the requesting application supports both My Drives and
131 /// shared drives.
132 #[drive_v3(parameter)]
133 supports_all_drives: Option<bool>,
134
135 /// Issue the request as a domain administrator.
136 ///
137 /// if set to `true`, then the requester will be granted access if they
138 /// are an administrator of the domain to which the shared drive
139 /// belongs.
140 #[drive_v3(parameter)]
141 use_domain_admin_access: Option<bool>,
142
143 /// Specifies which additional view's permissions to include in the
144 /// response.
145 ///
146 /// Only `published` is supported.
147 #[drive_v3(parameter)]
148 include_permissions_for_view: Option<String>,
149}
150
151#[request(
152 method=Method::PATCH,
153 url="https://www.googleapis.com/drive/v3/files/{file_id}/permissions/{permission_id}",
154 returns=objects::Permission,
155)]
156#[derive(DriveRequestBuilder)]
157/// A request builder to update a permission for a file or shared drive.
158pub struct UpdateRequest {
159 /// Whether to remove the expiration date.
160 #[drive_v3(parameter)]
161 remove_expiration: Option<bool>,
162
163 /// Whether the requesting application supports both My Drives and
164 /// shared drives.
165 #[drive_v3(parameter)]
166 supports_all_drives: Option<bool>,
167
168 /// Whether to transfer ownership to the specified user and downgrade
169 /// the current owner to a writer.
170 ///
171 /// This parameter is required as an acknowledgement of the side effect.
172 #[drive_v3(parameter)]
173 transfer_ownership: Option<bool>,
174
175 /// Issue the request as a domain administrator.
176 ///
177 /// if set to `true`, then the requester will be granted access if they
178 /// are an administrator of the domain to which the shared drive
179 /// belongs.
180 #[drive_v3(parameter)]
181 use_domain_admin_access: Option<bool>,
182
183 /// The permission which will be applied.
184 #[drive_v3(body)]
185 permission: Option<objects::Permission>,
186}
187
188/// Permissions for a file.
189///
190/// A permission grants a user, group, domain, or the world access to a file or
191/// a folder hierarchy.
192///
193/// Some resource methods (such as [`permissions.update`](Permissions::update))
194/// require a `permission_id`. Use the [`permissions.list`](Permissions::list)
195/// method to retrieve the ID for a file, folder, or shared drive.
196///
197/// # Examples:
198///
199/// List the permission in a file
200///
201/// ```no_run
202/// # use drive_v3::{Error, Credentials, Drive};
203/// #
204/// # let drive = Drive::new( &Credentials::from_file(
205/// # "../.secure-files/google_drive_credentials.json",
206/// # &["https://www.googleapis.com/auth/drive.file"],
207/// # )? );
208/// #
209/// let file_id = "some-file-id";
210/// let permission_list = drive.permissions.list(&file_id).execute()?;
211///
212/// if let Some(permissions) = permission_list.permissions {
213/// for permission in permissions {
214/// println!("{}", permission);
215/// }
216/// }
217/// # Ok::<(), Error>(())
218/// ```
219#[derive(Debug, Clone, PartialEq, Eq)]
220pub struct Permissions {
221 /// Credentials used to authenticate a user's access to this resource.
222 credentials: Credentials,
223}
224
225impl Permissions {
226 /// Creates a new [`Permissions`] resource with the given [`Credentials`].
227 pub fn new( credentials: &Credentials ) -> Self {
228 Self { credentials: credentials.clone() }
229 }
230
231 /// Creates a permission for a file or shared drive.
232 ///
233 /// See Google's
234 /// [documentation](https://developers.google.com/drive/api/reference/rest/v3/permissions/create)
235 /// for more information.
236 ///
237 /// # Warning
238 ///
239 /// Concurrent permissions operations on the same file are not supported;
240 /// only the last update is applied.
241 ///
242 /// # Requires one of the following OAuth scopes:
243 ///
244 /// - `https://www.googleapis.com/auth/drive`
245 /// - `https://www.googleapis.com/auth/drive.file`
246 ///
247 /// # Examples:
248 ///
249 /// ```no_run
250 /// use drive_v3::objects::Permission;
251 /// # use drive_v3::{Error, Credentials, Drive};
252 /// #
253 /// # let drive = Drive::new( &Credentials::from_file(
254 /// # "../.secure-files/google_drive_credentials.json",
255 /// # &["https://www.googleapis.com/auth/drive.file"],
256 /// # )? );
257 ///
258 /// let permission = Permission {
259 /// permission_type: Some( "anyone".to_string() ),
260 /// role: Some( "reader".to_string() ),
261 /// ..Default::default()
262 /// };
263 ///
264 /// let file_id = "some-file-id";
265 ///
266 /// let created_permission = drive.permissions.create(&file_id)
267 /// .permission(&permission)
268 /// .execute()?;
269 ///
270 /// assert_eq!(created_permission.permission_type, permission.permission_type);
271 /// assert_eq!(created_permission.role, permission.role);
272 /// # Ok::<(), Error>(())
273 /// ```
274 pub fn create<T: AsRef<str>> ( &self, file_id: T ) -> CreateRequest {
275 CreateRequest::new(&self.credentials, file_id)
276 }
277
278 /// Deletes a permission.
279 ///
280 /// See Google's
281 /// [documentation](https://developers.google.com/drive/api/reference/rest/v3/permissions/delete)
282 /// for more information.
283 ///
284 /// # Warning
285 ///
286 /// Concurrent permissions operations on the same file are not supported;
287 /// only the last update is applied.
288 ///
289 /// # Requires one of the following OAuth scopes:
290 ///
291 /// - `https://www.googleapis.com/auth/drive`
292 /// - `https://www.googleapis.com/auth/drive.file`
293 ///
294 /// # Examples:
295 ///
296 /// ```no_run
297 /// # use drive_v3::{Error, Credentials, Drive};
298 /// #
299 /// # let drive = Drive::new( &Credentials::from_file(
300 /// # "../.secure-files/google_drive_credentials.json",
301 /// # &["https://www.googleapis.com/auth/drive.file"],
302 /// # )? );
303 /// #
304 /// let file_id = "some-file-id";
305 /// let permission_id = "some-permission-id";
306 ///
307 /// let response = drive.permissions.delete(&file_id, &permission_id).execute();
308 ///
309 /// assert!( response.is_ok() );
310 /// # Ok::<(), Error>(())
311 /// ```
312 pub fn delete<T, U> ( &self, file_id: T, permission_id: U ) -> DeleteRequest
313 where
314 T: AsRef<str>,
315 U: AsRef<str>
316 {
317 DeleteRequest::new(&self.credentials, file_id, permission_id)
318 }
319
320 /// Gets a permission by ID.
321 ///
322 /// See Google's
323 /// [documentation](https://developers.google.com/drive/api/reference/rest/v3/permissions/get)
324 /// for more information.
325 ///
326 /// # Requires one of the following OAuth scopes:
327 ///
328 /// - `https://www.googleapis.com/auth/drive`
329 /// - `https://www.googleapis.com/auth/drive.file`
330 /// - `https://www.googleapis.com/auth/drive.metadata`
331 /// - `https://www.googleapis.com/auth/drive.metadata.readonly`
332 /// - `https://www.googleapis.com/auth/drive.photos.readonly`
333 /// - `https://www.googleapis.com/auth/drive.readonly`
334 ///
335 /// # Examples:
336 ///
337 /// ```no_run
338 /// # use drive_v3::{Error, Credentials, Drive};
339 /// #
340 /// # let drive = Drive::new( &Credentials::from_file(
341 /// # "../.secure-files/google_drive_credentials.json",
342 /// # &["https://www.googleapis.com/auth/drive.file"],
343 /// # )? );
344 /// #
345 /// let file_id = "some-file-id";
346 /// let permission_id = "some-permission-id";
347 ///
348 /// let permission = drive.permissions.get(&file_id, &permission_id).execute()?;
349 ///
350 /// println!("This is the file's permission:\n{}", permission);
351 /// # Ok::<(), Error>(())
352 /// ```
353 pub fn get<T, U> ( &self, file_id: T, permission_id: U ) -> GetRequest
354 where
355 T: AsRef<str>,
356 U: AsRef<str>
357 {
358 GetRequest::new(&self.credentials, file_id, permission_id)
359 }
360
361 /// Lists a file's or shared drive's permissions.
362 ///
363 /// See Google's
364 /// [documentation](https://developers.google.com/drive/api/reference/rest/v3/permissions/list)
365 /// for more information.
366 ///
367 /// # Requires one of the following OAuth scopes:
368 ///
369 /// - `https://www.googleapis.com/auth/drive`
370 /// - `https://www.googleapis.com/auth/drive.file`
371 /// - `https://www.googleapis.com/auth/drive.metadata`
372 /// - `https://www.googleapis.com/auth/drive.metadata.readonly`
373 /// - `https://www.googleapis.com/auth/drive.photos.readonly`
374 /// - `https://www.googleapis.com/auth/drive.readonly`
375 ///
376 /// # Examples:
377 ///
378 /// ```no_run
379 /// # use drive_v3::{Error, Credentials, Drive};
380 /// #
381 /// # let drive = Drive::new( &Credentials::from_file(
382 /// # "../.secure-files/google_drive_credentials.json",
383 /// # &["https://www.googleapis.com/auth/drive.file"],
384 /// # )? );
385 /// #
386 /// let file_id = "some-file-id";
387 /// let permission_list = drive.permissions.list(&file_id).execute()?;
388 ///
389 /// if let Some(permissions) = permission_list.permissions {
390 /// for permission in permissions {
391 /// println!("{}", permission);
392 /// }
393 /// }
394 /// # Ok::<(), Error>(())
395 /// ```
396 pub fn list<T: AsRef<str>> ( &self, file_id: T ) -> ListRequest {
397 ListRequest::new(&self.credentials, file_id)
398 }
399
400 /// Updates a permission with patch semantics.
401 ///
402 /// See Google's
403 /// [documentation](https://developers.google.com/drive/api/reference/rest/v3/permissions/update)
404 /// for more information.
405 ///
406 /// # Warning
407 ///
408 /// Concurrent permissions operations on the same file are not supported;
409 /// only the last update is applied.
410 ///
411 /// # Requires one of the following OAuth scopes:
412 ///
413 /// - `https://www.googleapis.com/auth/drive`
414 /// - `https://www.googleapis.com/auth/drive.file`
415 ///
416 /// # Examples:
417 ///
418 /// ```no_run
419 /// use drive_v3::objects::Permission;
420 /// # use drive_v3::{Error, Credentials, Drive};
421 /// #
422 /// # let drive = Drive::new( &Credentials::from_file(
423 /// # "../.secure-files/google_drive_credentials.json",
424 /// # &["https://www.googleapis.com/auth/drive.file"],
425 /// # )? );
426 ///
427 /// let updated_permission = Permission {
428 /// permission_type: Some( "anyone".to_string() ),
429 /// role: Some( "commenter".to_string() ),
430 /// ..Default::default()
431 /// };
432 ///
433 /// let file_id = "some-file-id";
434 /// let permission_id = "some-permission-id";
435 ///
436 /// let permission = drive.permissions.update(&file_id, &permission_id)
437 /// .permission(&updated_permission)
438 /// .execute()?;
439 ///
440 /// assert_eq!(permission.permission_type, updated_permission.permission_type);
441 /// assert_eq!(permission.role, updated_permission.role);
442 /// # Ok::<(), Error>(())
443 /// ```
444 pub fn update<T, U> ( &self, file_id: T, permission_id: U ) -> UpdateRequest
445 where
446 T: AsRef<str>,
447 U: AsRef<str>
448 {
449 UpdateRequest::new(&self.credentials, file_id, permission_id)
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 use super::Permissions;
456 use crate::{ErrorKind, objects, resources};
457 use crate::utils::test::{INVALID_CREDENTIALS, VALID_CREDENTIALS};
458
459 fn get_resource() -> Permissions {
460 Permissions::new(&VALID_CREDENTIALS)
461 }
462
463 fn get_invalid_resource() -> Permissions {
464 Permissions::new(&INVALID_CREDENTIALS)
465 }
466
467 fn get_files_resource() -> resources::Files {
468 resources::Files::new(&VALID_CREDENTIALS)
469 }
470
471 fn delete_file( file: &objects::File ) -> crate::Result<()> {
472 get_files_resource().delete( file.clone().id.unwrap() ).execute()
473 }
474
475 fn get_test_file_metadata() -> objects::File {
476 objects::File {
477 name: Some( "test.txt".to_string() ),
478 description: Some( "a test file".to_string() ),
479 mime_type: Some( "text/plain".to_string() ),
480 ..Default::default()
481 }
482 }
483
484 fn get_test_drive_file() -> crate::Result<objects::File> {
485 let metadata = get_test_file_metadata();
486
487 get_files_resource().create()
488 .upload_type(objects::UploadType::Multipart)
489 .metadata(&metadata)
490 .content_string("content")
491 .execute()
492 }
493
494 fn get_test_permission( ) -> objects::Permission {
495 objects::Permission {
496 permission_type: Some( "anyone".to_string() ),
497 role: Some( "reader".to_string() ),
498 ..Default::default()
499 }
500 }
501
502 fn get_test_drive_permission( file: &objects::File ) -> crate::Result<objects::Permission> {
503 let test_permission = get_test_permission();
504
505 get_resource().create( &file.clone().id.unwrap() )
506 .permission(&test_permission)
507 .execute()
508 }
509
510 #[test]
511 fn new_test() {
512 let valid_resource = get_resource();
513 let invalid_resource = get_invalid_resource();
514
515 assert_eq!( valid_resource.credentials, VALID_CREDENTIALS.clone() );
516 assert_eq!( invalid_resource.credentials, INVALID_CREDENTIALS.clone() );
517 }
518
519 #[test]
520 fn create_test() {
521 let test_drive_file = get_test_drive_file().unwrap();
522 let test_permission = get_test_permission();
523
524 let response = get_resource().create( &test_drive_file.clone().id.unwrap() )
525 .permission(&test_permission)
526 .execute();
527
528 assert!( response.is_ok() );
529
530 let permission = response.unwrap();
531 assert_eq!(permission.permission_type, test_permission.permission_type);
532 assert_eq!(permission.role, test_permission.role);
533
534 delete_file(&test_drive_file).expect("Failed to cleanup created file");
535 }
536
537 #[test]
538 fn create_invalid_test() {
539 let response = get_invalid_resource().create("invalid-id")
540 .execute();
541
542 assert!( response.is_err() );
543 assert_eq!( response.unwrap_err().kind, ErrorKind::Response );
544 }
545
546 #[test]
547 fn delete_test() {
548 let test_drive_file = get_test_drive_file().unwrap();
549 let test_drive_permission = get_test_drive_permission(&test_drive_file).unwrap();
550
551 let response = get_resource().delete(
552 &test_drive_file.clone().id.unwrap(),
553 &test_drive_permission.clone().id.unwrap(),
554 )
555 .execute();
556
557 assert!( response.is_ok() );
558
559 delete_file(&test_drive_file).expect("Failed to cleanup created file");
560 }
561
562 #[test]
563 fn delete_invalid_test() {
564 let response = get_invalid_resource().delete("invalid-id", "invalid-id")
565 .execute();
566
567 assert!( response.is_err() );
568 assert_eq!( response.unwrap_err().kind, ErrorKind::Response );
569 }
570
571 #[test]
572 fn get_test() {
573 let test_drive_file = get_test_drive_file().unwrap();
574 let test_drive_permission = get_test_drive_permission(&test_drive_file).unwrap();
575
576 let response = get_resource().get(
577 &test_drive_file.clone().id.unwrap(),
578 &test_drive_permission.clone().id.unwrap(),
579 )
580 .execute();
581
582 assert!( response.is_ok() );
583
584 let permission = response.unwrap();
585 assert_eq!(permission, test_drive_permission);
586
587 delete_file(&test_drive_file).expect("Failed to cleanup created file");
588 }
589
590 #[test]
591 fn get_invalid_test() {
592 let response = get_invalid_resource().get("invalid-id", "invalid-id")
593 .execute();
594
595 assert!( response.is_err() );
596 assert_eq!( response.unwrap_err().kind, ErrorKind::Response );
597 }
598
599 #[test]
600 fn list_test() {
601 let test_drive_file = get_test_drive_file().unwrap();
602 let test_drive_permission = get_test_drive_permission(&test_drive_file).unwrap();
603
604 let response = get_resource().list( &test_drive_file.clone().id.unwrap() )
605 .execute();
606
607 assert!( response.is_ok() );
608
609 let permissions = response.unwrap().permissions.unwrap();
610 assert!( permissions.contains(&test_drive_permission) );
611
612 delete_file(&test_drive_file).expect("Failed to cleanup created file");
613 }
614
615 #[test]
616 fn list_invalid_test() {
617 let response = get_invalid_resource().list("invalid-id")
618 .execute();
619
620 assert!( response.is_err() );
621 assert_eq!( response.unwrap_err().kind, ErrorKind::Response );
622 }
623
624 #[test]
625 fn update_test() {
626 let test_drive_file = get_test_drive_file().unwrap();
627 let test_drive_permission = get_test_drive_permission(&test_drive_file).unwrap();
628
629 let updated_permission = objects::Permission {
630 role: Some( "commenter".to_string() ),
631 ..Default::default()
632 };
633
634 let response = get_resource().update(
635 &test_drive_file.clone().id.unwrap(),
636 &test_drive_permission.clone().id.unwrap(),
637 )
638 .permission(&updated_permission)
639 .execute();
640
641 assert!( response.is_ok() );
642
643 let permission = response.unwrap();
644 assert_eq!(permission.role, updated_permission.role);
645
646 delete_file(&test_drive_file).expect("Failed to cleanup created file");
647 }
648
649 #[test]
650 fn update_invalid_test() {
651 let response = get_invalid_resource().update("invalid-id", "invalid-id")
652 .execute();
653
654 assert!( response.is_err() );
655 assert_eq!( response.unwrap_err().kind, ErrorKind::Response );
656 }
657}