smbcloud_model/
app_auth.rs1use 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 pub project_id: Option<i32>,
15 pub support_email: Option<String>,
16 pub apple_oauth_enabled: Option<bool>,
18 pub apple_oauth_client_id: Option<String>,
20 pub apple_oauth_configured: Option<bool>,
22 pub apple_oauth_secret_present: Option<bool>,
24 #[serde(with = "ar_date_format")]
25 pub created_at: DateTime<Utc>,
26 #[serde(with = "ar_date_format")]
27 pub updated_at: DateTime<Utc>,
28}
29
30#[derive(Serialize, Deserialize, Debug, Clone)]
31pub struct AuthAppCreate {
32 pub name: String,
33 pub project_id: String,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub support_email: Option<String>,
36}
37
38#[derive(Serialize, Deserialize, Debug, Clone, Default)]
39pub struct AuthAppUpdate {
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub name: Option<String>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub support_email: Option<String>,
44}
45
46impl AuthAppUpdate {
47 pub fn is_empty(&self) -> bool {
48 self.name.is_none() && self.support_email.is_none()
49 }
50}
51
52#[derive(Serialize, Deserialize, Debug, Clone)]
60#[tsync]
61pub struct AuthAppClient {
62 pub id: i64,
63 pub client_id: String,
64 pub name: String,
65 pub redirect_uris: String,
66 pub confidential: bool,
67 pub auth_app_id: String,
68 #[serde(with = "ar_date_format")]
69 pub created_at: DateTime<Utc>,
70 #[serde(with = "ar_date_format")]
71 pub updated_at: DateTime<Utc>,
72}
73
74#[derive(Serialize, Deserialize, Debug, Clone)]
78#[tsync]
79pub struct AuthAppClientCreate {
80 pub name: String,
81 pub redirect_uris: String,
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use serde_json::json;
88
89 #[test]
90 fn auth_app_apple_settings_are_optional_and_typed() -> Result<(), serde_json::Error> {
91 let mut payload = json!({
92 "id": "app-id",
93 "name": "Example",
94 "created_at": "2026-09-30T08:00:00.000+00:00",
95 "updated_at": "2026-09-30T08:00:00.000+00:00"
96 });
97 let legacy: AuthApp = serde_json::from_value(payload.clone())?;
98 assert_eq!(legacy.apple_oauth_enabled, None);
99 assert_eq!(legacy.apple_oauth_client_id, None);
100 assert_eq!(legacy.apple_oauth_configured, None);
101 assert_eq!(legacy.apple_oauth_secret_present, None);
102
103 payload["apple_oauth_enabled"] = json!(true);
104 payload["apple_oauth_client_id"] = json!("com.example.web");
105 payload["apple_oauth_configured"] = json!(true);
106 payload["apple_oauth_secret_present"] = json!(true);
107 let configured: AuthApp = serde_json::from_value(payload)?;
108 assert_eq!(configured.apple_oauth_enabled, Some(true));
109 assert_eq!(
110 configured.apple_oauth_client_id.as_deref(),
111 Some("com.example.web")
112 );
113 assert_eq!(configured.apple_oauth_configured, Some(true));
114 assert_eq!(configured.apple_oauth_secret_present, Some(true));
115
116 let serialized = serde_json::to_value(&configured)?;
117 assert_eq!(serialized["apple_oauth_enabled"], json!(true));
118 assert_eq!(
119 serialized["apple_oauth_client_id"],
120 json!("com.example.web")
121 );
122 assert_eq!(serialized["apple_oauth_configured"], json!(true));
123 assert_eq!(serialized["apple_oauth_secret_present"], json!(true));
124 Ok(())
125 }
126 #[test]
127 fn test_auth_app_create() {
128 let auth_app_create = AuthAppCreate {
129 name: "test".to_owned(),
130 project_id: "1".to_owned(),
131 support_email: None,
132 };
133 let json = json!({
134 "name": "test",
135 "project_id": "1",
136 });
137 assert_eq!(serde_json::to_value(auth_app_create).unwrap(), json);
138 }
139}