dinio_sdk/api/users.rs
1//! `/api/v1/users` (`../core/src/api/users.ts`), the self-service part only. Listing,
2//! creating and deleting users, and changing `role` or `enabled`, are Admin-only and not in
3//! this SDK.
4
5use reqwest::Method;
6use uuid::Uuid;
7
8use crate::api::IssuedKey;
9use crate::auth::Secret;
10use crate::client::Client;
11use crate::error::Result;
12use crate::models::User;
13
14/// The caller's own user account, from [`Client::users`].
15///
16/// Needs a personal key: a zone key has no user and gets
17/// [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden).
18pub struct Users<'a> {
19 client: &'a Client,
20}
21
22impl<'a> Users<'a> {
23 pub(crate) fn new(client: &'a Client) -> Self {
24 Self { client }
25 }
26
27 /// One user, by uuid or email. A non-Admin can read only their own account; this is
28 /// also how to learn your own uuid (Core has no "who am I" route yet).
29 ///
30 /// `GET /api/v1/users/:ref`
31 ///
32 /// # Errors
33 ///
34 /// * [`ErrorCode::NotFound`](crate::ErrorCode::NotFound) if there is no such user.
35 /// * [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden) for another user's account,
36 /// or with a zone key.
37 ///
38 /// # Examples
39 ///
40 /// ```no_run
41 /// # async fn example(client: &dinio_sdk::Client) -> dinio_sdk::Result<()> {
42 /// let me = client.users().get("ana@example.com").await?;
43 /// println!("my uuid is {}", me.uuid);
44 /// # Ok(())
45 /// # }
46 /// ```
47 pub async fn get(&self, user: &str) -> Result<User> {
48 let request = self.client.request(Method::GET, &["users", user])?;
49 Ok(self.client.send(request).await?.0)
50 }
51
52 /// Issues a new personal key (`du_…`) and returns it. Core shows the key only in this
53 /// response and keeps just its hash, so store it now. A previous personal key stops
54 /// working immediately, also for this client: build a new client with the new key.
55 ///
56 /// `POST /api/v1/users/:uuid/api-key`
57 ///
58 /// # Errors
59 ///
60 /// [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden) for another user's account, or
61 /// with a zone key.
62 ///
63 /// # Examples
64 ///
65 /// ```no_run
66 /// # async fn example(client: &dinio_sdk::Client) -> dinio_sdk::Result<()> {
67 /// let me = client.users().get("ana@example.com").await?;
68 /// let key = client.users().create_api_key(me.uuid).await?;
69 /// // From here on, only a client built with `key` works; Core never returns it again.
70 /// println!("{}", key.expose());
71 /// # Ok(())
72 /// # }
73 /// ```
74 pub async fn create_api_key(&self, uuid: Uuid) -> Result<Secret> {
75 let request = self
76 .client
77 .request(Method::POST, &["users", &uuid.to_string(), "api-key"])?;
78 let (issued, _): (IssuedKey, _) = self.client.send(request).await?;
79 Ok(issued.api_key)
80 }
81
82 /// Revokes the user's personal key; the account then has none
83 /// ([`User::has_api_key`] is `false`). If it is the key this client uses, the client
84 /// stops working.
85 ///
86 /// `DELETE /api/v1/users/:uuid/api-key`
87 ///
88 /// # Errors
89 ///
90 /// [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden) for another user's account, or
91 /// with a zone key.
92 pub async fn revoke_api_key(&self, uuid: Uuid) -> Result<User> {
93 let request = self
94 .client
95 .request(Method::DELETE, &["users", &uuid.to_string(), "api-key"])?;
96 Ok(self.client.send(request).await?.0)
97 }
98}