Skip to main content

smbcloud_model/
app_auth.rs

1use crate::ar_date_format;
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use tsync::tsync;
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct AuthApp {
8    pub id: String,
9    pub secret: Option<String>,
10    pub name: String,
11    // Serialized as a number by the API, like `Deployment`/`MailApp`. The
12    // create/update payloads take it as a String because it comes from a CLI
13    // arg — the two are intentionally different types.
14    pub project_id: Option<i32>,
15    pub support_email: Option<String>,
16    #[serde(with = "ar_date_format")]
17    pub created_at: DateTime<Utc>,
18    #[serde(with = "ar_date_format")]
19    pub updated_at: DateTime<Utc>,
20}
21
22#[derive(Serialize, Deserialize, Debug, Clone)]
23pub struct AuthAppCreate {
24    pub name: String,
25    pub project_id: String,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub support_email: Option<String>,
28}
29
30#[derive(Serialize, Deserialize, Debug, Clone, Default)]
31pub struct AuthAppUpdate {
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub name: Option<String>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub support_email: Option<String>,
36}
37
38impl AuthAppUpdate {
39    pub fn is_empty(&self) -> bool {
40        self.name.is_none() && self.support_email.is_none()
41    }
42}
43
44/// A public OAuth client registered against an AuthApp for the hosted
45/// Authorization Code + PKCE flow.
46///
47/// These are public clients: no client secret is issued, so security rests on
48/// PKCE plus the `redirect_uris` allowlist. `redirect_uris` is a newline-
49/// separated list. `client_id` is the public identifier (prefixed `auc_`) sent
50/// in the `/authorize` request.
51#[derive(Serialize, Deserialize, Debug, Clone)]
52#[tsync]
53pub struct AuthAppClient {
54    pub id: i64,
55    pub client_id: String,
56    pub name: String,
57    pub redirect_uris: String,
58    pub confidential: bool,
59    pub auth_app_id: String,
60    #[serde(with = "ar_date_format")]
61    pub created_at: DateTime<Utc>,
62    #[serde(with = "ar_date_format")]
63    pub updated_at: DateTime<Utc>,
64}
65
66/// Request body for registering a new public OAuth client on an AuthApp.
67/// `redirect_uris` is a newline-separated allowlist; each entry must be https,
68/// a loopback http URL, or a custom scheme (native apps).
69#[derive(Serialize, Deserialize, Debug, Clone)]
70#[tsync]
71pub struct AuthAppClientCreate {
72    pub name: String,
73    pub redirect_uris: String,
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79    use serde_json::json;
80    #[test]
81    fn test_auth_app_create() {
82        let auth_app_create = AuthAppCreate {
83            name: "test".to_owned(),
84            project_id: "1".to_owned(),
85            support_email: None,
86        };
87        let json = json!({
88            "name": "test",
89            "project_id": "1",
90        });
91        assert_eq!(serde_json::to_value(auth_app_create).unwrap(), json);
92    }
93}