1use std::collections::BTreeMap;
2
3use rustauth_core::secret::SecretString;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct SamlProviderConfig {
10 pub issuer: String,
12 #[serde(default)]
13 pub entry_point: String,
15 pub cert: String,
17 pub callback_url: String,
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub acs_url: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub audience: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub idp_metadata: Option<SamlIdpMetadata>,
28 pub sp_metadata: SamlSpMetadata,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub mapping: Option<SamlMapping>,
33 #[serde(default = "default_want_assertions_signed")]
35 pub want_assertions_signed: bool,
36 pub authn_requests_signed: bool,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub signature_algorithm: Option<String>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub digest_algorithm: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub identifier_format: Option<String>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub private_key: Option<SecretString>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub decryption_pvk: Option<SecretString>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub additional_params: Option<BTreeMap<String, serde_json::Value>>,
56}
57
58pub type SamlConfig = SamlProviderConfig;
60
61const fn default_want_assertions_signed() -> bool {
62 true
63}
64
65#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
66#[serde(rename_all = "camelCase")]
67pub struct SamlIdpMetadata {
69 pub metadata: Option<String>,
70 #[serde(rename = "entityID", alias = "entityId")]
71 pub entity_id: Option<String>,
72 #[serde(rename = "entityURL", alias = "entityUrl")]
73 pub entity_url: Option<String>,
74 #[serde(rename = "redirectURL", alias = "redirectUrl")]
75 pub redirect_url: Option<String>,
76 pub cert: Option<String>,
77 pub private_key: Option<SecretString>,
78 pub private_key_pass: Option<SecretString>,
79 pub is_assertion_encrypted: Option<bool>,
80 pub enc_private_key: Option<SecretString>,
81 pub enc_private_key_pass: Option<SecretString>,
82 pub single_sign_on_service: Option<Vec<SamlService>>,
83 pub single_logout_service: Option<Vec<SamlService>>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87pub struct SamlService {
89 #[serde(rename = "Binding")]
90 pub binding: String,
91 #[serde(rename = "Location")]
92 pub location: String,
93}
94
95#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct SamlSpMetadata {
99 pub metadata: Option<String>,
100 #[serde(rename = "entityID", alias = "entityId")]
101 pub entity_id: Option<String>,
102 pub binding: Option<String>,
103 pub private_key: Option<SecretString>,
104 pub private_key_pass: Option<SecretString>,
105 pub is_assertion_encrypted: Option<bool>,
106 pub enc_private_key: Option<SecretString>,
107 pub enc_private_key_pass: Option<SecretString>,
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct SamlMapping {
114 pub id: Option<String>,
115 pub email: Option<String>,
116 pub email_verified: Option<String>,
117 pub name: Option<String>,
118 pub first_name: Option<String>,
119 pub last_name: Option<String>,
120 pub extra_fields: Option<BTreeMap<String, String>>,
121}