Skip to main content

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}