Skip to main content

ts_control_serde/
user.rs

1use chrono::{DateTime, Utc};
2use serde::Deserialize;
3use url::Url;
4
5/// A unique integer ID for a [`Login`]. This is not used by Tailscale node software, but is used
6/// in the control plane.
7pub type LoginId = i64;
8
9/// A unique integer ID for a [`User`].
10pub type UserId = i64;
11
12/// Represents a [`User`] from a specific identity provider (IdP), not associated with any
13/// particular Tailnet.
14#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
15#[serde(rename_all = "PascalCase")]
16pub struct Login<'a> {
17    /// The unique integer ID of this login. Unused on the Tailscale node-side, but used by the
18    /// control plane.
19    #[serde(rename = "ID")]
20    pub id: LoginId,
21    /// A string representation of the IdP itself, e.g. "google", "github", "okta_foo", etc.
22    #[serde(borrow)]
23    pub provider: &'a str,
24    /// An email address or "email-ish" string (e.g. "alice@github") associated with this Tailscale
25    /// user, according to the IdP.
26    #[serde(borrow)]
27    pub login_name: &'a str,
28    /// If populated, the display name of this Tailscale user, according to the IdP. Can be
29    /// overridden by a value in the [`User::display_name`] field.
30    #[serde(borrow, default)]
31    pub display_name: Option<&'a str>,
32    /// If populated, a URL to a profile picture representing this Tailscale user, according to the
33    /// IdP. Can be overridden by a value in the [`User::profile_pic_url`] field.
34    #[serde(
35        rename = "ProfilePicURL",
36        deserialize_with = "crate::util::deserialize_string_option",
37        default
38    )]
39    pub profile_pic_url: Option<Url>,
40}
41
42/// A Tailscale user.
43///
44/// A [`User`] can have multiple [`Login`]s associated with it (e.g. gmail and github oauth),
45/// although as of 2019, none of the UIs support this.
46///
47/// Some fields are inherited from the [`Login`]s and can be overridden, such as
48/// [`User::display_name`] and [`User::profile_pic_url`].
49#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
50#[serde(rename_all = "PascalCase")]
51pub struct User<'a> {
52    /// The unique integer ID of this Tailscale user.
53    #[serde(rename = "ID")]
54    pub id: UserId,
55    /// If populated, the display name of this Tailscale user. Overrides the value in any IdP-
56    /// provided [`Login::display_name`] field.
57    #[serde(borrow, default)]
58    pub display_name: Option<&'a str>,
59    /// If populated, a URL to a profile picture representing this Tailscale user. Overrides the
60    /// IdP-provided value in any [`Login::profile_pic_url`] field.
61    #[serde(
62        rename = "ProfilePicURL",
63        deserialize_with = "crate::util::deserialize_string_option",
64        default
65    )]
66    pub profile_pic_url: Option<Url>,
67    /// The date and time that this Tailscale user was created, in the UTC timezone.
68    #[serde(default)]
69    pub created: Option<DateTime<Utc>>,
70}
71
72/// Display-friendly data for a [`User`]. Includes the [`Login::login_name`] for display purposes.
73/// but *not* the [`Login::provider`]. Also includes derived data from one of the [`Login`]s
74/// associated with a [`User`].
75#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
76#[serde(rename_all = "PascalCase")]
77pub struct UserProfile<'a> {
78    /// The unique integer ID of this Tailscale user this [`UserProfile`] is associated with.
79    #[serde(rename = "ID")]
80    pub id: UserId,
81    /// An email address or "email-ish" string (e.g. "alice@github") associated with this Tailscale
82    /// user's [`UserProfile`], according to the IdP. For display purposes only.
83    #[serde(borrow, default)]
84    pub login_name: &'a str,
85    /// If populated, the display name of this Tailscale user (e.g. "Alice Smith"), according to
86    /// the IdP.
87    #[serde(borrow, default)]
88    pub display_name: Option<&'a str>,
89    /// If populated, a URL to a profile picture representing this Tailscale user.
90    #[serde(
91        rename = "ProfilePicURL",
92        deserialize_with = "crate::util::deserialize_string_option",
93        default
94    )]
95    pub profile_pic_url: Option<Url>,
96}