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}