1use super::group::{DefaultRoles, GroupMapping, GroupMappingResponse};
11use chrono::{DateTime, Utc};
12use serde::{Deserialize, Serialize};
13use uuid::Uuid;
14
15#[derive(Deserialize)]
16pub struct SSOConfigCreateRequest {
17 #[serde(default)]
18 pub enabled: bool,
19 #[serde(rename = "ssoEndpoint")]
20 pub sso_endpoint: Option<String>,
21 #[serde(rename = "publicCertificate")]
22 pub public_certificate: Option<String>,
23 #[serde(default)]
24 #[serde(rename = "signRequest")]
25 pub sign_request: bool,
26 #[serde(rename = "acsUrl")]
27 pub acs_url: Option<String>,
28 #[serde(rename = "spEntityId")]
29 pub sp_entity_id: Option<String>,
30 #[serde(rename = "type")]
31 pub config_type: Option<String>,
32 #[serde(rename = "oidcClientId")]
33 pub oidc_client_id: Option<String>,
34 #[serde(rename = "oidcSecret")]
35 pub oidc_secret: Option<String>,
36}
37
38#[derive(Serialize, Deserialize, Clone, Debug)]
39pub struct SSOConfigStorage {
40 pub id: String,
41 pub enabled: bool,
42 pub sso_endpoint: String,
43 pub public_certificate: String,
44 pub sign_request: bool,
45 pub acs_url: String,
46 pub sp_entity_id: String,
47 pub config_type: String,
48 pub oidc_client_id: String,
49 pub oidc_secret: String,
50 pub domains: Vec<Domain>,
51 pub groups: Vec<GroupMapping>,
52 pub default_roles: DefaultRoles,
53 pub generated_verification: Option<String>,
54 pub created_at: Option<DateTime<Utc>>,
55 pub updated_at: Option<DateTime<Utc>>,
56 pub config_metadata: Option<serde_json::Value>,
57 pub override_active_tenant: Option<bool>,
58 pub skip_email_domain_validation: Option<bool>,
59 pub sub_account_access_limit: Option<i32>,
60 pub role_ids: Vec<String>,
61}
62
63#[derive(Serialize)]
64pub struct SSOConfigResponse {
65 pub id: String,
66 pub enabled: bool,
67 #[serde(rename = "ssoEndpoint")]
68 pub sso_endpoint: String,
69 #[serde(rename = "publicCertificate")]
70 pub public_certificate: String,
71 #[serde(rename = "signRequest")]
72 pub sign_request: bool,
73 #[serde(rename = "acsUrl")]
74 pub acs_url: String,
75 #[serde(rename = "spEntityId")]
76 pub sp_entity_id: String,
77 #[serde(rename = "type")]
78 pub config_type: String,
79 #[serde(rename = "oidcClientId")]
80 pub oidc_client_id: String,
81 #[serde(rename = "oidcSecret")]
82 pub oidc_secret: String,
83 pub domains: Vec<DomainResponse>,
84 pub groups: Vec<GroupMappingResponse>,
85 #[serde(rename = "defaultRoles")]
86 pub default_roles: DefaultRoles,
87 #[serde(rename = "generatedVerification")]
88 pub generated_verification: Option<String>,
89 #[serde(rename = "createdAt")]
90 pub created_at: DateTime<Utc>,
91 #[serde(rename = "updatedAt")]
92 pub updated_at: DateTime<Utc>,
93 #[serde(rename = "configMetadata")]
94 pub config_metadata: Option<serde_json::Value>,
95 #[serde(rename = "overrideActiveTenant")]
96 pub override_active_tenant: bool,
97 #[serde(rename = "skipEmailDomainValidation")]
98 pub skip_email_domain_validation: bool,
99 #[serde(rename = "subAccountAccessLimit")]
100 pub sub_account_access_limit: i32,
101 #[serde(rename = "roleIds")]
102 pub role_ids: Vec<String>,
103}
104
105#[derive(Deserialize)]
106pub struct SSOConfigUpdateRequest {
107 pub enabled: Option<bool>,
108 #[serde(rename = "ssoEndpoint")]
109 pub sso_endpoint: Option<String>,
110 #[serde(rename = "publicCertificate")]
111 pub public_certificate: Option<String>,
112 #[serde(rename = "signRequest")]
113 pub sign_request: Option<bool>,
114 #[serde(rename = "acsUrl")]
115 pub acs_url: Option<String>,
116 #[serde(rename = "spEntityId")]
117 pub sp_entity_id: Option<String>,
118 #[serde(rename = "type")]
119 pub config_type: Option<String>,
120 #[serde(rename = "oidcClientId")]
121 pub oidc_client_id: Option<String>,
122 #[serde(rename = "oidcSecret")]
123 pub oidc_secret: Option<String>,
124}
125
126#[derive(Serialize, Deserialize, Clone, Debug)]
127pub struct Domain {
128 #[serde(default)]
129 pub id: String,
130 pub domain: String,
131 #[serde(default)]
132 pub validated: bool,
133 #[serde(default, rename = "ssoConfigId")]
134 pub sso_config_id: String,
135 #[serde(skip_deserializing)]
136 pub txt_record: String,
137}
138
139#[derive(Serialize)]
140pub struct DomainResponse {
141 pub id: String,
142 pub domain: String,
143 pub validated: bool,
144 #[serde(rename = "ssoConfigId")]
145 pub sso_config_id: String,
146 #[serde(rename = "txtRecord")]
147 pub txt_record: String,
148}
149
150#[derive(Deserialize)]
151pub struct DomainUpdateRequest {
152 pub domain: Option<String>,
153 pub validated: Option<bool>,
154}
155
156impl From<SSOConfigStorage> for SSOConfigResponse {
157 fn from(storage: SSOConfigStorage) -> Self {
158 SSOConfigResponse {
159 id: storage.id,
160 enabled: storage.enabled,
161 sso_endpoint: storage.sso_endpoint,
162 public_certificate: storage.public_certificate,
163 sign_request: storage.sign_request,
164 acs_url: storage.acs_url,
165 sp_entity_id: storage.sp_entity_id,
166 config_type: storage.config_type,
167 oidc_client_id: storage.oidc_client_id,
168 oidc_secret: storage.oidc_secret,
169 domains: storage
170 .domains
171 .into_iter()
172 .map(DomainResponse::from)
173 .collect(),
174 groups: storage
175 .groups
176 .into_iter()
177 .map(GroupMappingResponse::from)
178 .collect(),
179 default_roles: storage.default_roles,
180 generated_verification: storage.generated_verification,
181 created_at: storage.created_at.unwrap_or_else(Utc::now),
182 updated_at: storage.updated_at.unwrap_or_else(Utc::now),
183 config_metadata: storage.config_metadata,
184 override_active_tenant: storage.override_active_tenant.unwrap_or(false),
185 skip_email_domain_validation: storage.skip_email_domain_validation.unwrap_or(false),
186 sub_account_access_limit: storage.sub_account_access_limit.unwrap_or(0),
187 role_ids: storage.role_ids,
188 }
189 }
190}
191
192impl From<Domain> for DomainResponse {
193 fn from(domain: Domain) -> Self {
194 let txt_record = format!(
195 "_saml-domain-challenge.{}.{}.{}",
196 Uuid::new_v4(),
197 Uuid::new_v4(),
198 domain.domain
199 );
200
201 DomainResponse {
202 id: domain.id,
203 domain: domain.domain,
204 validated: domain.validated,
205 sso_config_id: domain.sso_config_id,
206 txt_record,
207 }
208 }
209}
210
211impl From<GroupMapping> for GroupMappingResponse {
212 fn from(group: GroupMapping) -> Self {
213 GroupMappingResponse {
214 id: group.id,
215 group: group.group,
216 role_ids: group.role_ids,
217 sso_config_id: group.sso_config_id,
218 enabled: group.enabled,
219 }
220 }
221}