1use serde::{Deserialize, Serialize};
16
17use crate::client::{get_admin_id, get_owner, Client, Response};
18use crate::error::Result;
19use crate::serde_util::null_to_default;
20
21#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase", default)]
23pub struct AccountItem {
24 pub name: String,
25 pub visible: bool,
26 pub view_rule: String,
27 pub modify_rule: String,
28 pub regex: String,
29 pub tab: String,
30}
31
32#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase", default)]
34pub struct ThemeData {
35 pub theme_type: String,
36 pub color_primary: String,
37 pub border_radius: i32,
38 pub is_compact: bool,
39 pub is_enabled: bool,
40}
41
42#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "camelCase", default)]
44pub struct MfaItem {
45 pub name: String,
46 pub rule: String,
47}
48
49#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
52#[serde(rename_all = "camelCase", default)]
53pub struct Organization {
54 pub owner: String,
55 pub name: String,
56 pub created_time: String,
57
58 pub display_name: String,
59 pub website_url: String,
60 pub logo: String,
61 pub logo_dark: String,
62 pub favicon: String,
63 pub has_privilege_consent: bool,
64 pub password_type: String,
65 pub password_salt: String,
66 #[serde(deserialize_with = "null_to_default")]
67 pub password_options: Vec<String>,
68 pub password_obfuscator_type: String,
69 pub password_obfuscator_key: String,
70 pub password_expire_days: i32,
71 pub token_retention_days: i32,
72 pub record_retention_days: i32,
73 #[serde(deserialize_with = "null_to_default")]
74 pub country_codes: Vec<String>,
75 pub default_avatar: String,
76 pub use_permanent_avatar: bool,
77 pub default_application: String,
78 pub default_token_format: String,
79 #[serde(deserialize_with = "null_to_default")]
80 pub user_types: Vec<String>,
81 #[serde(deserialize_with = "null_to_default")]
82 pub tags: Vec<String>,
83 #[serde(deserialize_with = "null_to_default")]
84 pub languages: Vec<String>,
85 pub theme_data: Option<ThemeData>,
86 pub master_password: String,
87 pub default_password: String,
88 pub master_verification_code: String,
89 pub ip_whitelist: String,
90 pub init_score: i32,
91 pub enable_soft_deletion: bool,
92 pub is_profile_public: bool,
93 pub use_email_as_username: bool,
94 pub enable_tour: bool,
95 pub disable_signin: bool,
96 pub disable_console: bool,
97 pub ip_restriction: String,
98 #[serde(deserialize_with = "null_to_default")]
99 pub nav_items: Vec<String>,
100 #[serde(deserialize_with = "null_to_default")]
101 pub user_nav_items: Vec<String>,
102 #[serde(deserialize_with = "null_to_default")]
103 pub widget_items: Vec<String>,
104
105 #[serde(deserialize_with = "null_to_default")]
106 pub mfa_items: Vec<MfaItem>,
107 pub mfa_remember_in_hours: i32,
108 pub account_menu: String,
109 #[serde(deserialize_with = "null_to_default")]
110 pub account_items: Vec<AccountItem>,
111
112 pub dcr_policy: String,
113
114 #[serde(deserialize_with = "null_to_default")]
115 pub ldap_attributes: Vec<String>,
116
117 pub kerberos_realm: String,
118 pub kerberos_kdc_host: String,
119 pub kerberos_keytab: String,
120 pub kerberos_service_name: String,
121
122 pub org_balance: f64,
123 pub user_balance: f64,
124 pub balance_credit: f64,
125 pub balance_currency: String,
126}
127
128impl Client {
129 pub async fn get_organization(&self, name: &str) -> Result<Option<Organization>> {
131 self.get_object("get-organization", &[("id", &get_admin_id(name))])
132 .await
133 }
134
135 pub async fn get_organizations(&self) -> Result<Vec<Organization>> {
137 self.get_list("get-organizations", &[("owner", "admin")])
138 .await
139 }
140
141 pub async fn get_organization_names(&self) -> Result<Vec<Organization>> {
143 self.get_list("get-organization-names", &[("owner", "admin")])
144 .await
145 }
146
147 pub async fn add_organization(&self, organization: &Organization) -> Result<bool> {
149 Ok(self
150 .modify_organization("add-organization", organization, &[])
151 .await?
152 .1)
153 }
154
155 pub async fn update_organization(&self, organization: &Organization) -> Result<bool> {
157 Ok(self
158 .modify_organization("update-organization", organization, &[])
159 .await?
160 .1)
161 }
162
163 pub async fn delete_organization(&self, organization: &Organization) -> Result<bool> {
165 Ok(self
166 .modify_organization("delete-organization", organization, &[])
167 .await?
168 .1)
169 }
170
171 async fn modify_organization(
172 &self,
173 action: &str,
174 organization: &Organization,
175 columns: &[&str],
176 ) -> Result<(Response, bool)> {
177 let mut organization = organization.clone();
178 organization.owner = get_owner(&organization.owner, "admin");
179
180 let id = format!("{}/{}", organization.owner, organization.name);
181 self.modify_object(action, &id, &organization, columns)
182 .await
183 }
184}