dco3/nodes/
mod.rs

1//! This module implements a subset of the nodes DRACOON API.
2//! Documentation can be found here: <https://download.dracoon.com/api/swagger-ui/index.html?configUrl=/api/spec_v4/swagger-config#/nodes>
3pub use self::{models::*, rooms::models::*};
4use super::{client::errors::DracoonClientError, models::ListAllParams};
5use async_trait::async_trait;
6use tokio::io::{AsyncRead, AsyncWrite, BufReader};
7
8pub mod download;
9pub mod folders;
10pub mod models;
11pub mod nodes;
12pub mod rooms;
13pub mod upload;
14
15/// This trait provides methods to manage nodes.
16/// Specifically, there's a method to obtain a node for a given path and
17/// all relevant methods to list nodes (get, search), move, copy and deleted nodes.
18///
19/// To download a node, use the [Download] trait.
20/// To upload a node, use the [Upload] trait.
21/// To manage rooms, use the [Rooms] trait.
22/// To manage folders, use the [Folders] trait.
23#[async_trait]
24pub trait Nodes {
25    /// Returns a list of nodes.
26    /// ```no_run
27    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes, nodes::{NodesFilter, NodesSortBy}, models::{ListAllParams, SortOrder}};
28    /// # #[tokio::main]
29    /// # async fn main() {
30    /// # let dracoon = Dracoon::builder()
31    /// #  .with_base_url("https://dracoon.team")
32    /// #  .with_client_id("client_id")
33    /// #  .with_client_secret("client_secret")
34    /// #  .build()
35    /// #  .unwrap()
36    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
37    /// #  .await
38    /// #  .unwrap();
39    /// let nodes = dracoon.nodes().get_nodes(None, None, None).await.unwrap();
40    ///
41    /// // get all nodes for a parent
42    /// let nodes = dracoon.nodes().get_nodes(Some(123), None, None).await.unwrap();
43    ///
44    /// // get all nodes visible as room manager / admin
45    /// let nodes = dracoon.nodes().get_nodes(None, Some(true), None).await.unwrap();
46    ///
47    /// // use filtering and sorting
48    /// let params = ListAllParams::builder()
49    ///    .with_filter(NodesFilter::is_file())
50    ///    .with_filter(NodesFilter::name_contains("foo"))
51    ///    .with_sort(NodesSortBy::name(SortOrder::Desc))
52    ///    .build();
53    ///
54    /// let nodes = dracoon.nodes().get_nodes(None, None, Some(params)).await.unwrap();
55    /// # }
56    /// ```
57    async fn get_nodes(
58        &self,
59        parent_id: Option<u64>,
60        room_manager: Option<bool>,
61        params: Option<ListAllParams>,
62    ) -> Result<NodeList, DracoonClientError>;
63    /// Searches for a node via given path.
64    /// ```no_run
65    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes, nodes::{NodesFilter, NodesSortBy}, models::{ListAllParams, SortOrder}};
66    /// # #[tokio::main]
67    /// # async fn main() {
68    /// # let dracoon = Dracoon::builder()
69    /// #  .with_base_url("https://dracoon.team")
70    /// #  .with_client_id("client_id")
71    /// #  .with_client_secret("client_secret")
72    /// #  .build()
73    /// #  .unwrap()
74    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
75    /// #  .await
76    /// #  .unwrap();
77    /// let node = dracoon.nodes().get_node_from_path("/foo/bar").await.unwrap();
78    /// match node {
79    ///    Some(node) => println!("Found node: {}", node.name),
80    ///    None => println!("Node not found"),
81    /// };
82    /// # }
83    /// ```
84    async fn get_node_from_path(&self, path: &str) -> Result<Option<Node>, DracoonClientError>;
85    /// Searches for nodes by search string.
86    /// ```no_run
87    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes, nodes::{NodesSearchFilter, NodesSearchSortBy}, models::{ListAllParams, SortOrder}};
88    /// # #[tokio::main]
89    /// # async fn main() {
90    /// # let dracoon = Dracoon::builder()
91    /// #  .with_base_url("https://dracoon.team")
92    /// #  .with_client_id("client_id")
93    /// #  .with_client_secret("client_secret")
94    /// #  .build()
95    /// #  .unwrap()
96    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
97    /// #  .await
98    /// #  .unwrap();
99    /// // search for nodes ("*" is wildcard)
100    /// let nodes = dracoon.nodes().search_nodes("foo", None, None, None).await.unwrap();
101    ///
102    /// // search for nodes in a parent
103    /// let nodes = dracoon.nodes().search_nodes("foo", Some(123), None, None).await.unwrap();
104    ///
105    /// // search for nodes in a parent with a depth level (-1 is full tree)
106    /// let nodes = dracoon.nodes().search_nodes("foo", Some(123), Some(1), None).await.unwrap();
107    ///
108    /// // use filtering and sorting
109    /// let params = ListAllParams::builder()
110    ///                .with_filter(NodesSearchFilter::is_file())
111    ///                .with_filter(NodesSearchFilter::size_greater_equals(100))
112    ///                .with_sort(NodesSearchSortBy::name(SortOrder::Desc))
113    ///                .build();
114    /// let nodes = dracoon.nodes().search_nodes("foo", None, None, Some(params)).await.unwrap();
115    /// # }
116    /// ```
117    async fn search_nodes(
118        &self,
119        search_string: &str,
120        parent_id: Option<u64>,
121        depth_level: Option<i8>,
122        params: Option<ListAllParams>,
123    ) -> Result<NodeList, DracoonClientError>;
124
125    /// Returns a node by id.
126    /// ```no_run
127    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes};
128    /// # #[tokio::main]
129    /// # async fn main() {
130    /// # let dracoon = Dracoon::builder()
131    /// #  .with_base_url("https://dracoon.team")
132    /// #  .with_client_id("client_id")
133    /// #  .with_client_secret("client_secret")
134    /// #  .build()
135    /// #  .unwrap()
136    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
137    /// #  .await
138    /// #  .unwrap();
139    /// let node = dracoon.nodes().get_node(123).await.unwrap();
140    /// # }
141    /// ```
142    async fn get_node(&self, node_id: u64) -> Result<Node, DracoonClientError>;
143    /// Deletes a node by id.
144    /// ```no_run
145    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes};
146    /// # #[tokio::main]
147    /// # async fn main() {
148    /// # let dracoon = Dracoon::builder()
149    /// #  .with_base_url("https://dracoon.team")
150    /// #  .with_client_id("client_id")
151    /// #  .with_client_secret("client_secret")
152    /// #  .build()
153    /// #  .unwrap()
154    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
155    /// #  .await
156    /// #  .unwrap();
157    /// dracoon.nodes().delete_node(123).await.unwrap();
158    /// # }
159    /// ```
160    async fn delete_node(&self, node_id: u64) -> Result<(), DracoonClientError>;
161    /// Deletes multiple nodes by ids.
162    /// ```no_run
163    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes};
164    /// # #[tokio::main]
165    /// # async fn main() {
166    /// # let dracoon = Dracoon::builder()
167    /// #  .with_base_url("https://dracoon.team")
168    /// #  .with_client_id("client_id")
169    /// #  .with_client_secret("client_secret")
170    /// #  .build()
171    /// #  .unwrap()
172    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
173    /// #  .await
174    /// #  .unwrap();
175    /// let node_ids = vec![123, 456];
176    /// dracoon.nodes().delete_nodes(node_ids.into()).await.unwrap();
177    /// # }
178    /// ```
179    async fn delete_nodes(&self, req: DeleteNodesRequest) -> Result<(), DracoonClientError>;
180    /// Move nodes to a target parent node (folder or room).
181    /// ```no_run
182    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes};
183    /// # #[tokio::main]
184    /// # async fn main() {
185    /// # let dracoon = Dracoon::builder()
186    /// #  .with_base_url("https://dracoon.team")
187    /// #  .with_client_id("client_id")
188    /// #  .with_client_secret("client_secret")
189    /// #  .build()
190    /// #  .unwrap()
191    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
192    /// #  .await
193    /// #  .unwrap();
194    /// let node_ids = vec![123, 456];
195    /// dracoon.nodes().move_nodes(node_ids.into(), 789).await.unwrap();
196    /// # }
197    /// ```
198    async fn move_nodes(
199        &self,
200        req: TransferNodesRequest,
201        target_parent_id: u64,
202    ) -> Result<Node, DracoonClientError>;
203    /// Copy nodes to a target parent node (folder or room).
204    /// ```no_run
205    /// # use dco3::{Dracoon, auth::OAuth2Flow, Nodes};
206    /// # #[tokio::main]
207    /// # async fn main() {
208    /// # let dracoon = Dracoon::builder()
209    /// #  .with_base_url("https://dracoon.team")
210    /// #  .with_client_id("client_id")
211    /// #  .with_client_secret("client_secret")
212    /// #  .build()
213    /// #  .unwrap()
214    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
215    /// #  .await
216    /// #  .unwrap();
217    /// let node_ids = vec![123, 456];
218    /// dracoon.nodes().copy_nodes(node_ids.into(), 789).await.unwrap();
219    /// # }
220    /// ```
221    async fn copy_nodes(
222        &self,
223        req: TransferNodesRequest,
224        target_parent_id: u64,
225    ) -> Result<Node, DracoonClientError>;
226}
227
228#[async_trait]
229pub trait MissingFileKeys {
230    /// Distributes missing file keys using the user keypair.
231    /// Returns the total amount missing keys.
232    /// If the total amount is larger than 100, more keys need distribution
233    /// and the method should be called again.
234    /// ```no_run
235    /// # use dco3::{Dracoon, OAuth2Flow, MissingFileKeys};
236    /// # #[tokio::main]
237    /// # async fn main() {
238    /// # let dracoon = Dracoon::builder()
239    /// #  .with_base_url("https://dracoon.team")
240    /// #  .with_client_id("client_id")
241    /// #  .with_client_secret("client_secret")
242    /// #  .build()
243    /// #  .unwrap()
244    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
245    /// #  .await
246    /// #  .unwrap();
247    /// let mut missing_keys = dracoon.distribute_missing_keys(None, None, None).await.unwrap();
248    ///
249    /// while missing_keys > 100 {
250    /// // loop until no more keys need distribution
251    /// missing_keys = dracoon.distribute_missing_keys(None, None, None).await.unwrap();
252    /// }
253    ///
254    /// // distribute missing keys for a specific room
255    /// let missing_room_keys = dracoon.distribute_missing_keys(Some(123), None, None).await.unwrap();
256    ///
257    /// // distribute missing keys for a specific file
258    /// let missing_file_keys = dracoon.distribute_missing_keys(None, Some(123), None).await.unwrap();
259    ///
260    /// // distribute missing keys for a specific user
261    /// let missing_user_keys = dracoon.distribute_missing_keys(None, None, Some(123)).await.unwrap();
262    ///
263    /// # }
264    async fn distribute_missing_keys(
265        &self,
266        room_id: Option<u64>,
267        file_id: Option<u64>,
268        user_id: Option<u64>,
269    ) -> Result<u64, DracoonClientError>;
270}
271
272#[async_trait]
273pub trait Folders {
274    /// Creates a folder in the provided parent room.
275    /// ```no_run
276    /// # use dco3::{Dracoon, auth::OAuth2Flow, Folders, nodes::CreateFolderRequest};
277    /// # #[tokio::main]
278    /// # async fn main() {
279    /// # let dracoon = Dracoon::builder()
280    /// #  .with_base_url("https://dracoon.team")
281    /// #  .with_client_id("client_id")
282    /// #  .with_client_secret("client_secret")
283    /// #  .build()
284    /// #  .unwrap()
285    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
286    /// #  .await
287    /// #  .unwrap();
288    /// let folder = CreateFolderRequest::builder("My Folder", 123)
289    ///                                .with_classification(1)
290    ///                                .with_notes("My notes")
291    ///                                .build();
292    /// let folder = dracoon.nodes().create_folder(folder).await.unwrap();
293    /// # }
294    /// ```
295    async fn create_folder(&self, req: CreateFolderRequest) -> Result<Node, DracoonClientError>;
296    /// Updates a folder with given params by id.
297    /// ```no_run
298    /// # use dco3::{Dracoon, auth::OAuth2Flow, Folders, nodes::UpdateFolderRequest};
299    /// # #[tokio::main]
300    /// # async fn main() {
301    /// # let dracoon = Dracoon::builder()
302    /// #  .with_base_url("https://dracoon.team")
303    /// #  .with_client_id("client_id")
304    /// #  .with_client_secret("client_secret")
305    /// #  .build()
306    /// #  .unwrap()
307    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
308    /// #  .await
309    /// #  .unwrap();
310    /// let update = UpdateFolderRequest::builder()
311    ///                              .with_name("My Folder")
312    ///                              .with_classification(2)
313    ///                              .build();
314    /// dracoon.nodes().update_folder(123, update).await.unwrap();
315    /// # }
316    /// ```
317    async fn update_folder(
318        &self,
319        folder_id: u64,
320        req: UpdateFolderRequest,
321    ) -> Result<Node, DracoonClientError>;
322}
323/// This trait provides methods to manage rooms.
324///
325///  - Create a room
326///  - Update a room
327///  - Configure a room
328///  - Get the policies of a room
329///  - Set the policies of a room
330///  - Encrypt a room
331///  - Get groups of a room
332///  - Add groups to a room
333///  - Delete groups from a room
334///  - Get users of a room
335///  - Add users to a room
336///  - Delete users from a room
337///  
338///  To delete a room, use the `delete_node` method from the `Nodes` trait.
339#[async_trait]
340pub trait Rooms {
341    /// Creates a room.
342    /// ```no_run
343    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::CreateRoomRequest};
344    /// # #[tokio::main]
345    /// # async fn main() {
346    /// # let dracoon = Dracoon::builder()
347    /// #  .with_base_url("https://dracoon.team")
348    /// #  .with_client_id("client_id")
349    /// #  .with_client_secret("client_secret")
350    /// #  .build()
351    /// #  .unwrap()
352    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
353    /// #  .await
354    /// #  .unwrap();
355    /// let room = CreateRoomRequest::builder("My Room")
356    ///                              .with_parent_id(123)
357    ///                              .with_classification(1)
358    ///                              .build();
359    /// let room = dracoon.nodes().create_room(room).await.unwrap();
360    /// # }
361    /// ```
362    async fn create_room(
363        &self,
364        create_room_req: CreateRoomRequest,
365    ) -> Result<Node, DracoonClientError>;
366    /// Updates a room by id.
367    /// ```no_run
368    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::UpdateRoomRequest};
369    /// # #[tokio::main]
370    /// # async fn main() {
371    /// # let dracoon = Dracoon::builder()
372    /// #  .with_base_url("https://dracoon.team")
373    /// #  .with_client_id("client_id")
374    /// #  .with_client_secret("client_secret")
375    /// #  .build()
376    /// #  .unwrap()
377    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
378    /// #  .await
379    /// #  .unwrap();
380    /// let room = UpdateRoomRequest::builder()
381    ///                              .with_name("My new Room")
382    ///                              .build();
383    /// let room = dracoon.nodes().update_room(123, room).await.unwrap();
384    /// # }
385    /// ```
386    async fn update_room(
387        &self,
388        room_id: u64,
389        update_room_req: UpdateRoomRequest,
390    ) -> Result<Node, DracoonClientError>;
391    /// Configures a room by id.
392    /// ```no_run
393    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::ConfigRoomRequest};
394    /// # #[tokio::main]
395    /// # async fn main() {
396    /// # let dracoon = Dracoon::builder()
397    /// #  .with_base_url("https://dracoon.team")
398    /// #  .with_client_id("client_id")
399    /// #  .with_client_secret("client_secret")
400    /// #  .build()
401    /// #  .unwrap()
402    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
403    /// #  .await
404    /// #  .unwrap();
405    /// let room = ConfigRoomRequest::builder()
406    ///                              .with_inherit_permissions(true)
407    ///                              .with_recycle_bin_retention_period(30)
408    ///                              .build();
409    /// let room = dracoon.nodes().config_room(123, room).await.unwrap();
410    /// # }
411    /// ```
412    async fn config_room(
413        &self,
414        room_id: u64,
415        config_room_req: ConfigRoomRequest,
416    ) -> Result<Node, DracoonClientError>;
417    /// Gets the policies of a room by id.
418    /// ```no_run
419    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::RoomPolicies};
420    /// # #[tokio::main]
421    /// # async fn main() {
422    /// # let dracoon = Dracoon::builder()
423    /// #  .with_base_url("https://dracoon.team")
424    /// #  .with_client_id("client_id")
425    /// #  .with_client_secret("client_secret")
426    /// #  .build()
427    /// #  .unwrap()
428    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
429    /// #  .await
430    /// #  .unwrap();
431    ///  let policies = dracoon.nodes().get_room_policies(123).await.unwrap();
432    /// # }
433    /// ```
434    async fn get_room_policies(&self, room_id: u64) -> Result<RoomPolicies, DracoonClientError>;
435    /// Set the policies of a room by id.
436    /// ```no_run
437    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::RoomPoliciesRequest};
438    /// # #[tokio::main]
439    /// # async fn main() {
440    /// # let dracoon = Dracoon::builder()
441    /// #  .with_base_url("https://dracoon.team")
442    /// #  .with_client_id("client_id")
443    /// #  .with_client_secret("client")
444    /// #  .build()
445    /// #  .unwrap()
446    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
447    /// #  .await
448    /// #  .unwrap();
449    /// let new_policies = RoomPoliciesRequest::builder()
450    ///                            .with_default_expiration_period(60 * 60 * 24 * 30)
451    ///                            .with_virus_protection_enabled(true)
452    ///                            .build();
453    /// dracoon.nodes().update_room_policies(123, new_policies).await.unwrap();
454    /// # }
455    /// ```
456    //
457    async fn update_room_policies(
458        &self,
459        room_id: u64,
460        policy_room_req: RoomPoliciesRequest,
461    ) -> Result<(), DracoonClientError>;
462    /// Encrypts a room by id.
463    /// ```no_run
464    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms, nodes::EncryptRoomRequest};
465    /// # #[tokio::main]
466    /// # async fn main() {
467    /// # let dracoon = Dracoon::builder()
468    /// #  .with_base_url("https://dracoon.team")
469    /// #  .with_client_id("client_id")
470    /// #  .with_client_secret("client_secret")
471    /// #  .build()
472    /// #  .unwrap()
473    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
474    /// #  .await
475    /// #  .unwrap();
476    /// let encryption = EncryptRoomRequest::builder(true)
477    ///                           .try_with_data_room_rescue_key("Secret123")
478    ///                           .unwrap()
479    ///                           .build();
480    /// let room = dracoon.nodes().encrypt_room(123, encryption).await.unwrap();
481    /// # }
482    /// ```
483    async fn encrypt_room(
484        &self,
485        room_id: u64,
486        encrypt_room_req: EncryptRoomRequest,
487    ) -> Result<Node, DracoonClientError>;
488    /// Gets groups of a room by id with optional params.
489    /// ```no_run
490    /// # use dco3::{Dracoon, auth::OAuth2Flow, Rooms};
491    /// # #[tokio::main]
492    /// # async fn main() {
493    /// # let dracoon = Dracoon::builder()
494    /// #  .with_base_url("https://dracoon.team")
495    /// #  .with_client_id("client_id")
496    /// #  .with_client_secret("client_secret")
497    /// #  .build()
498    /// #  .unwrap()
499    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
500    /// #  .await
501    /// #  .unwrap();
502    /// let groups = dracoon.nodes().get_room_groups(123, None).await.unwrap();
503    /// # }
504    /// ```
505    async fn get_room_groups(
506        &self,
507        room_id: u64,
508        params: Option<ListAllParams>,
509    ) -> Result<RoomGroupList, DracoonClientError>;
510
511    /// Updates room groups by id.
512    /// Gets groups of a room by id with optional params.
513    /// ```no_run
514    /// # use dco3::{Dracoon, OAuth2Flow, Rooms, nodes::{RoomGroupsAddBatchRequestItem, NodePermissions}};
515    /// # #[tokio::main]
516    /// # async fn main() {
517    /// # let dracoon = Dracoon::builder()
518    /// #  .with_base_url("https://dracoon.team")
519    /// #  .with_client_id("client_id")
520    /// #  .with_client_secret("client_secret")
521    /// #  .build()
522    /// #  .unwrap()
523    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
524    /// #  .await
525    /// #  .unwrap();
526    ///
527    /// // add a a list of updates
528    /// let group_updates = vec![RoomGroupsAddBatchRequestItem::new(123, NodePermissions::new_with_read_permissions(), None)];
529    /// dracoon.nodes().update_room_groups(123, group_updates.into()).await.unwrap();
530    /// # }
531    /// ```
532    async fn update_room_groups(
533        &self,
534        room_id: u64,
535        room_groups_update_req: RoomGroupsAddBatchRequest,
536    ) -> Result<(), DracoonClientError>;
537
538    /// Deletes room groups by id.
539    /// Gets groups of a room by id with optional params.
540    /// ```no_run
541    /// # use dco3::{Dracoon, OAuth2Flow, Rooms};
542    /// # #[tokio::main]
543    /// # async fn main() {
544    /// # let dracoon = Dracoon::builder()
545    /// #  .with_base_url("https://dracoon.team")
546    /// #  .with_client_id("client_id")
547    /// #  .with_client_secret("client_secret")
548    /// #  .build()
549    /// #  .unwrap()
550    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
551    /// #  .await
552    /// #  .unwrap();
553    /// // You can use a vec
554    /// let group_ids = vec![1, 2, 3];
555    /// dracoon.nodes().delete_room_groups(123, group_ids.into()).await.unwrap();
556    /// # }
557    /// ```
558    async fn delete_room_groups(
559        &self,
560        room_id: u64,
561        room_groups_del_req: RoomGroupsDeleteBatchRequest,
562    ) -> Result<(), DracoonClientError>;
563
564    /// Gets users of a room by id with optional params.
565    /// Gets groups of a room by id with optional params.
566    /// ```no_run
567    /// # use dco3::{Dracoon, OAuth2Flow, Rooms};
568    /// # #[tokio::main]
569    /// # async fn main() {
570    /// # let dracoon = Dracoon::builder()
571    /// #  .with_base_url("https://dracoon.team")
572    /// #  .with_client_id("client_id")
573    /// #  .with_client_secret("client_secret")
574    /// #  .build()
575    /// #  .unwrap()
576    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
577    /// #  .await
578    /// #  .unwrap();
579    /// let users = dracoon.nodes().get_room_users(123, None).await.unwrap();
580    /// # }
581    /// ```
582    async fn get_room_users(
583        &self,
584        room_id: u64,
585        params: Option<ListAllParams>,
586    ) -> Result<RoomUserList, DracoonClientError>;
587
588    /// Updates room users by id.
589    /// Gets groups of a room by id with optional params.
590    /// ```no_run
591    /// # use dco3::{Dracoon, OAuth2Flow, Rooms, nodes::{RoomUsersAddBatchRequestItem, NodePermissions}};
592    /// # #[tokio::main]
593    /// # async fn main() {
594    /// # let dracoon = Dracoon::builder()
595    /// #  .with_base_url("https://dracoon.team")
596    /// #  .with_client_id("client_id")
597    /// #  .with_client_secret("client_secret")
598    /// #  .build()
599    /// #  .unwrap()
600    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
601    /// #  .await
602    /// #  .unwrap();
603    ///
604    /// // add a a list of updates
605    /// let user_updates = vec![RoomUsersAddBatchRequestItem::new(123, NodePermissions::new_with_read_permissions())];
606    /// dracoon.nodes().update_room_users(123, user_updates.into()).await.unwrap();
607    /// # }
608    /// ```
609    async fn update_room_users(
610        &self,
611        room_id: u64,
612        room_users_update_req: RoomUsersAddBatchRequest,
613    ) -> Result<(), DracoonClientError>;
614    /// Deletes room users by id.
615    /// Gets groups of a room by id with optional params.
616    /// ```no_run
617    /// # use dco3::{Dracoon, OAuth2Flow, Rooms};
618    /// # #[tokio::main]
619    /// # async fn main() {
620    /// # let dracoon = Dracoon::builder()
621    /// #  .with_base_url("https://dracoon.team")
622    /// #  .with_client_id("client_id")
623    /// #  .with_client_secret("client_secret")
624    /// #  .build()
625    /// #  .unwrap()
626    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
627    /// #  .await
628    /// #  .unwrap();
629    /// // You can use a vec
630    /// let user_ids = vec![1, 2, 3];
631    /// dracoon.nodes().delete_room_users(123, user_ids.into()).await.unwrap();
632    /// # }
633    /// ```
634    async fn delete_room_users(
635        &self,
636        room_id: u64,
637        room_users_del_req: RoomUsersDeleteBatchRequest,
638    ) -> Result<(), DracoonClientError>;
639    /// Deletes room users by id.
640    /// Gets groups of a room by id with optional params.
641    /// ```no_run
642    /// # use dco3::{Dracoon, OAuth2Flow, Rooms, nodes::RoomGuestUserInvitation};
643    /// # #[tokio::main]
644    /// # async fn main() {
645    /// # let dracoon = Dracoon::builder()
646    /// #  .with_base_url("https://dracoon.team")
647    /// #  .with_client_id("client_id")
648    /// #  .with_client_secret("client_secret")
649    /// #  .build()
650    /// #  .unwrap()
651    /// #  .connect(OAuth2Flow::PasswordFlow("username".into(), "password".into()))
652    /// #  .await
653    /// #  .unwrap();
654    /// // You can use a vec
655    /// let guest = RoomGuestUserInvitation::new("email", "first name", "last name");
656    /// dracoon.nodes().invite_guest_users(123, vec![guest].into()).await.unwrap();
657    /// # }
658    /// ```
659    async fn invite_guest_users(
660        &self,
661        room_id: u64,
662        invite_req: RoomGuestUserAddRequest,
663    ) -> Result<(), DracoonClientError>;
664}
665/// This trait represents the download functionality and provides
666/// a signle method to download a stream of bytes to a writer.
667/// This rquires a mutable reference to the client because the download method
668/// needs to be able to check for the secret and set it for the client if encryption is used.
669#[async_trait]
670pub trait Download {
671    /// Downloads a file (node) to the given writer buffer
672    /// Example
673    /// ```no_run
674    /// use dco3::{Dracoon, OAuth2Flow, Download, Nodes};
675    ///
676    /// #[tokio::main]
677    /// async fn main() {
678    ///    let client = Dracoon::builder()
679    ///      .with_base_url("https://dracoon.team")
680    ///      .with_client_id("client_id")
681    ///      .with_client_secret("client_secret")
682    ///      // if you do not pass a password, encrypted uploads will fail with an error
683    ///      .with_encryption_password("encryption_password")
684    ///      .build()
685    ///      .unwrap()
686    ///      .connect(OAuth2Flow::password_flow("username", "password"))
687    ///      .await
688    ///      .unwrap();
689    ///
690    ///   let node_id = 123u64;
691    ///
692    ///   let node = client.nodes().get_node(node_id).await.unwrap();
693    ///
694    ///   let mut writer = tokio::io::BufWriter::new(tokio::fs::File::create("test.txt").await.unwrap());
695    ///
696    ///   client.download(&node, &mut writer, None, None).await.unwrap();
697    ///
698    ///   // or with progress callback (boxed closure)
699    ///   client.download(&node, &mut writer, Some(Box::new(|progress, total| {
700    ///    println!("Download progress: {}", progress);
701    ///    println!("File total: {}", total);
702    ///  })), None).await.unwrap();
703    /// // or with chunksize
704    /// let  chunksize: usize = 1024 * 1024 * 10;
705    /// client.download(&node, &mut writer, None, Some(chunksize)).await.unwrap();
706    /// }
707    /// ```
708    async fn download<'w>(
709        &'w self,
710        node: &Node,
711        writer: &'w mut (dyn AsyncWrite + Send + Unpin),
712        mut callback: Option<DownloadProgressCallback>,
713        chunksize: Option<usize>,
714    ) -> Result<(), DracoonClientError>;
715}
716
717/// This trait represents the upload functionality and provides
718/// a single method to upload a stream of bytes by passing a buffered reader.
719/// This rquires a mutable reference to the client because the upload method
720/// needs to be able to check for the secret and set it for the client if encryption is used.
721#[async_trait]
722pub trait Upload<R: AsyncRead> {
723    /// Uploads a stream (buffered reader) with given file meta info to the given parent node
724    /// # Example
725    /// ```no_run
726    /// use dco3::{Dracoon, OAuth2Flow, Upload, Nodes, nodes::{FileMeta, UploadOptions, ResolutionStrategy}};
727    /// #[cfg(not(doctest))]
728    /// #[tokio::main]
729    /// async fn main() {
730    ///    let client = Dracoon::builder()
731    ///      .with_base_url("https://dracoon.team")
732    ///      .with_client_id("client_id")
733    ///      .with_client_secret("client_secret")
734    ///      // if you do not pass a password, encrypted uploads will fail with an error
735    ///      .with_encryption_password("encryption_password")
736    ///      .build()
737    ///      .unwrap()
738    ///      .connect(OAuth2Flow::password_flow("username", "password"))
739    ///      .await
740    ///      .unwrap();
741    ///
742    /// let file = tokio::fs::File::open("test.txt").await.unwrap();
743    /// let file_meta = FileMeta::builder("test.txt", 123456)
744    /// .with_timestamp_modification("2020-01-01T00:00:00.000Z".parse().unwrap())
745    /// .build();
746    ///
747    ///
748    /// let parent_node_id = 123u64;
749    ///
750    /// let parent_node = client.nodes().get_node(parent_node_id).await.unwrap();
751    ///
752    /// let reader = tokio::io::BufReader::new(file);
753    ///
754    /// let options = UploadOptions::builder(file_meta)
755    ///               .with_resolution_strategy(ResolutionStrategy::AutoRename)
756    ///               .build();
757    ///
758    /// let chunk_size = 1024 * 1024 * 10; // 10 MB - DEFAULT is 32 MB
759    ///
760    /// client.upload(&parent_node, options, reader, None, Some(chunk_size)).await.unwrap();
761    ///
762    /// // or with progress callback (boxed closure)
763    /// let file = tokio::fs::File::open("test.txt").await.unwrap();
764    /// let file_meta = FileMeta::builder("test.txt", 123456)
765    /// .with_timestamp_modification("2020-01-01T00:00:00.000Z".parse().unwrap())
766    /// .build();
767    /// let options = UploadOptions::builder(file_meta)
768    ///               .with_resolution_strategy(ResolutionStrategy::AutoRename)
769    ///               .build();
770    /// let reader = tokio::io::BufReader::new(file);
771    /// client.upload(&parent_node, options, reader, Some(Box::new(|progress, total| {  
772    ///   println!("Upload progress: {}", progress);
773    ///  println!("File total: {}", total);
774    /// })), Some(chunk_size)).await.unwrap();
775    /// }
776    /// ```
777    ///
778    ///
779    async fn upload<'r>(
780        &'r self,
781        parent_node: &Node,
782        upload_options: UploadOptions,
783        mut reader: BufReader<R>,
784        mut callback: Option<UploadProgressCallback>,
785        chunk_size: Option<usize>,
786    ) -> Result<Node, DracoonClientError>;
787}