1use serde::{Deserialize, Serialize};
16
17use crate::cert::Cert;
18use crate::client::{get_admin_id, get_owner, Client, Response};
19use crate::error::Result;
20use crate::organization::{Organization, ThemeData};
21use crate::provider::Provider;
22use crate::serde_util::null_to_default;
23use crate::user::ScopeDescription;
24
25#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase", default)]
27pub struct ProviderItem {
28 pub owner: String,
29 pub name: String,
30
31 pub can_sign_up: bool,
32 pub can_sign_in: bool,
33 pub can_unlink: bool,
34 pub binding_rule: Option<Vec<String>>,
35 #[serde(deserialize_with = "null_to_default")]
36 pub country_codes: Vec<String>,
37 pub prompted: bool,
38 pub signup_group: String,
39 pub rule: String,
40 pub provider: Option<Provider>,
41}
42
43#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
44#[serde(rename_all = "camelCase", default)]
45pub struct ScopeItem {
46 pub name: String,
47 pub display_name: String,
48 pub description: String,
49 #[serde(deserialize_with = "null_to_default")]
51 pub tools: Vec<String>,
52}
53
54#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
55#[serde(rename_all = "camelCase", default)]
56pub struct SignupItem {
57 pub name: String,
58 pub visible: bool,
59 pub required: bool,
60 pub prompted: bool,
61 pub r#type: String,
62 pub custom_css: String,
63 pub label: String,
64 pub placeholder: String,
65 #[serde(deserialize_with = "null_to_default")]
66 pub options: Vec<String>,
67 pub regex: String,
68 pub rule: String,
69}
70
71#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase", default)]
73pub struct SigninMethod {
74 pub name: String,
75 pub display_name: String,
76 pub rule: String,
77}
78
79#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
80#[serde(rename_all = "camelCase", default)]
81pub struct SigninItem {
82 pub name: String,
83 pub visible: bool,
84 pub label: String,
85 pub custom_css: String,
86 pub placeholder: String,
87 pub rule: String,
88 pub is_custom: bool,
89}
90
91#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase", default)]
93pub struct SamlItem {
94 pub name: String,
95 pub name_format: String,
96 pub value: String,
97}
98
99#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase", default)]
101pub struct JwtItem {
102 pub name: String,
103 pub category: String,
104 pub value: String,
105 pub r#type: String,
106}
107
108#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase", default)]
112pub struct Application {
113 pub owner: String,
114 pub name: String,
115 pub created_time: String,
116
117 pub display_name: String,
118 pub category: String,
119 pub r#type: String,
120 #[serde(deserialize_with = "null_to_default")]
121 pub scopes: Vec<ScopeItem>,
122 pub logo: String,
123 pub title: String,
124 pub favicon: String,
125 pub order: i32,
126 pub homepage_url: String,
127 pub description: String,
128 pub organization: String,
129 pub cert: String,
130 pub default_group: String,
131 pub default_tag: String,
132 pub header_html: String,
133 pub page_html: String,
134 pub enable_password: bool,
135 pub enable_sign_up: bool,
136 pub enable_guest_signin: bool,
137 pub disable_signin: bool,
138 pub enable_signin_session: bool,
139 pub enable_auto_signin: bool,
140 pub enable_code_signin: bool,
141 pub enable_exclusive_signin: bool,
142 pub enable_saml_compress: bool,
143 pub enable_saml_c14n10: bool,
144 pub enable_saml_post_binding: bool,
145 pub disable_saml_attributes: bool,
146 pub enable_saml_assertion_signature: bool,
147 pub use_email_as_saml_name_id: bool,
148 pub enable_web_authn: bool,
149 pub enable_link_with_email: bool,
150 pub org_choice_mode: String,
151 pub saml_reply_url: String,
152 #[serde(deserialize_with = "null_to_default")]
153 pub providers: Vec<ProviderItem>,
154 #[serde(deserialize_with = "null_to_default")]
155 pub signin_methods: Vec<SigninMethod>,
156 #[serde(deserialize_with = "null_to_default")]
157 pub signup_items: Vec<SignupItem>,
158 #[serde(deserialize_with = "null_to_default")]
159 pub signin_items: Vec<SigninItem>,
160 #[serde(deserialize_with = "null_to_default")]
161 pub grant_types: Vec<String>,
162 pub organization_obj: Option<Organization>,
163 pub cert_public_key: String,
164 #[serde(deserialize_with = "null_to_default")]
165 pub tags: Vec<String>,
166 #[serde(deserialize_with = "null_to_default")]
167 pub saml_attributes: Vec<SamlItem>,
168 pub saml_hash_algorithm: String,
169 pub saml_c14n_prefix: String,
170 pub is_shared: bool,
171 pub ip_restriction: String,
172
173 pub client_id: String,
174 pub client_secret: String,
175 pub client_cert: String,
176 #[serde(deserialize_with = "null_to_default")]
177 pub redirect_uris: Vec<String>,
178 pub backchannel_logout_uri: String,
179 pub forced_redirect_origin: String,
180 pub token_format: String,
181 pub token_signing_method: String,
182 #[serde(deserialize_with = "null_to_default")]
183 pub token_fields: Vec<String>,
184 #[serde(deserialize_with = "null_to_default")]
185 pub token_attributes: Vec<JwtItem>,
186 pub expire_in_hours: f64,
187 pub refresh_expire_in_hours: f64,
188 pub cookie_expire_in_hours: i64,
189 pub signup_url: String,
190 pub signin_url: String,
191 pub forget_url: String,
192 pub affiliation_url: String,
193 pub ip_whitelist: String,
194 pub terms_of_use: String,
195 pub signup_html: String,
196 pub signin_html: String,
197 pub theme_data: Option<ThemeData>,
198 pub footer_html: String,
199 pub form_css: String,
200 pub form_css_mobile: String,
201 pub form_offset: i32,
202 pub form_side_html: String,
203 pub form_background_url: String,
204 pub form_background_url_mobile: String,
205
206 pub failed_signin_limit: i32,
207 pub failed_signin_frozen_time: i32,
208 pub code_resend_timeout: i32,
209
210 #[serde(deserialize_with = "null_to_default")]
211 pub custom_scopes: Vec<ScopeDescription>,
212
213 pub domain: String,
215 #[serde(deserialize_with = "null_to_default")]
216 pub other_domains: Vec<String>,
217 pub upstream_host: String,
218 pub ssl_mode: String,
219 pub ssl_cert: String,
220
221 #[serde(rename = "CertObj")]
222 pub cert_obj: Option<Cert>,
223
224 pub registration_access_token: String,
225}
226
227impl Client {
228 pub async fn get_applications(&self) -> Result<Vec<Application>> {
230 self.get_list("get-applications", &[("owner", "admin")])
231 .await
232 }
233
234 pub async fn get_organization_applications(&self) -> Result<Vec<Application>> {
236 self.get_list(
237 "get-organization-applications",
238 &[
239 ("owner", "admin"),
240 ("organization", &self.config.organization_name),
241 ],
242 )
243 .await
244 }
245
246 pub async fn get_application(&self, name: &str) -> Result<Option<Application>> {
248 self.get_object("get-application", &[("id", &get_admin_id(name))])
249 .await
250 }
251
252 pub async fn add_application(&self, application: &Application) -> Result<bool> {
254 Ok(self
255 .modify_application("add-application", application, &[])
256 .await?
257 .1)
258 }
259
260 pub async fn update_application(&self, application: &Application) -> Result<bool> {
262 Ok(self
263 .modify_application("update-application", application, &[])
264 .await?
265 .1)
266 }
267
268 pub async fn delete_application(&self, application: &Application) -> Result<bool> {
270 Ok(self
271 .modify_application("delete-application", application, &[])
272 .await?
273 .1)
274 }
275
276 async fn modify_application(
277 &self,
278 action: &str,
279 application: &Application,
280 columns: &[&str],
281 ) -> Result<(Response, bool)> {
282 let mut application = application.clone();
283 application.owner = get_owner(&application.owner, "admin");
284
285 let id = format!("{}/{}", application.owner, application.name);
286 self.modify_object(action, &id, &application, columns).await
287 }
288}