1use crate::browser::{LogoutBinding, SsoRequestBinding, SsoResponseBinding};
2use crate::model::RelayStateParam;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum ForceAuthn {
7 Required,
9 NotRequired,
11}
12
13impl ForceAuthn {
14 pub(super) fn as_bool(self) -> bool {
15 match self {
16 Self::Required => true,
17 Self::NotRequired => false,
18 }
19 }
20}
21
22#[derive(Debug, Clone)]
24pub struct StartSso {
25 pub(super) binding: SsoRequestBinding,
26 pub(super) response_binding: Option<SsoResponseBinding>,
27 pub(super) relay_state: RelayStateParam,
28 pub(super) force_authn: Option<ForceAuthn>,
29 pub(super) acs_index: Option<u16>,
30}
31
32impl StartSso {
33 pub fn redirect() -> Self {
35 Self::new(SsoRequestBinding::Redirect)
36 }
37
38 pub fn post() -> Self {
40 Self::new(SsoRequestBinding::Post)
41 }
42
43 pub fn simple_sign() -> Self {
45 Self::new(SsoRequestBinding::SimpleSign)
46 }
47
48 fn new(binding: SsoRequestBinding) -> Self {
49 Self {
50 binding,
51 response_binding: None,
52 relay_state: RelayStateParam::absent(),
53 force_authn: None,
54 acs_index: None,
55 }
56 }
57
58 pub fn response_binding(mut self, binding: SsoResponseBinding) -> Self {
60 self.response_binding = Some(binding);
61 self
62 }
63
64 pub fn relay_state(mut self, relay_state: RelayStateParam) -> Self {
66 self.relay_state = relay_state;
67 self
68 }
69
70 pub fn force_authn(mut self, force_authn: ForceAuthn) -> Self {
72 self.force_authn = Some(force_authn);
73 self
74 }
75
76 pub fn assertion_consumer_service_index(mut self, acs_index: u16) -> Self {
78 self.acs_index = Some(acs_index);
79 self
80 }
81}
82
83#[derive(Debug, Clone)]
85pub struct RespondSso {
86 pub(super) binding: SsoResponseBinding,
87 pub(super) relay_state: Option<RelayStateParam>,
88 response_signing: ResponseSigning,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92enum ResponseSigning {
93 FollowEncryptedCbcRecommendation,
94 Always,
95 AllowUnsignedEncryptedCbcForCompatibility,
96}
97
98impl RespondSso {
99 pub fn post() -> Self {
101 Self::new(SsoResponseBinding::Post)
102 }
103
104 pub fn simple_sign() -> Self {
106 Self::new(SsoResponseBinding::SimpleSign)
107 }
108
109 fn new(binding: SsoResponseBinding) -> Self {
110 Self {
111 binding,
112 relay_state: None,
113 response_signing: ResponseSigning::FollowEncryptedCbcRecommendation,
114 }
115 }
116
117 pub fn sign_response(mut self) -> Self {
122 self.response_signing = ResponseSigning::Always;
123 self
124 }
125
126 pub fn allow_unsigned_encrypted_cbc_for_compatibility(mut self) -> Self {
132 self.response_signing = ResponseSigning::AllowUnsignedEncryptedCbcForCompatibility;
133 self
134 }
135
136 pub fn relay_state(mut self, relay_state: RelayStateParam) -> Self {
141 self.relay_state = Some(relay_state);
142 self
143 }
144
145 pub(super) fn should_sign_response(
146 &self,
147 assertion_encrypted: bool,
148 data_encryption_algorithm: &str,
149 ) -> bool {
150 match self.response_signing {
151 ResponseSigning::FollowEncryptedCbcRecommendation => {
152 assertion_encrypted
153 && crate::constants::is_xml_encryption_cbc_algorithm(data_encryption_algorithm)
154 }
155 ResponseSigning::Always => true,
156 ResponseSigning::AllowUnsignedEncryptedCbcForCompatibility => false,
157 }
158 }
159}
160
161#[derive(Debug, Clone, Copy, PartialEq, Eq)]
163pub enum LogoutSigning {
164 FollowLocalPolicy,
166 Sign,
168 DoNotSignForCompatibility,
170}
171
172#[derive(Debug, Clone)]
174pub struct StartSlo {
175 pub(super) binding: LogoutBinding,
176 pub(super) relay_state: RelayStateParam,
177 pub(super) signing: LogoutSigning,
178}
179
180impl StartSlo {
181 pub fn redirect() -> Self {
183 Self::new(LogoutBinding::Redirect)
184 }
185
186 pub fn post() -> Self {
188 Self::new(LogoutBinding::Post)
189 }
190
191 pub fn simple_sign() -> Self {
193 Self::new(LogoutBinding::SimpleSign)
194 }
195
196 fn new(binding: LogoutBinding) -> Self {
197 Self {
198 binding,
199 relay_state: RelayStateParam::absent(),
200 signing: LogoutSigning::FollowLocalPolicy,
201 }
202 }
203
204 pub fn relay_state(mut self, relay_state: RelayStateParam) -> Self {
206 self.relay_state = relay_state;
207 self
208 }
209
210 pub fn signing(mut self, signing: LogoutSigning) -> Self {
212 self.signing = signing;
213 self
214 }
215}
216
217#[derive(Debug, Clone)]
219pub struct RespondSlo {
220 pub(super) binding: LogoutBinding,
221 pub(super) relay_state: Option<RelayStateParam>,
222}
223
224impl RespondSlo {
225 pub fn redirect() -> Self {
227 Self::new(LogoutBinding::Redirect)
228 }
229
230 pub fn post() -> Self {
232 Self::new(LogoutBinding::Post)
233 }
234
235 pub fn simple_sign() -> Self {
237 Self::new(LogoutBinding::SimpleSign)
238 }
239
240 fn new(binding: LogoutBinding) -> Self {
241 Self {
242 binding,
243 relay_state: None,
244 }
245 }
246
247 pub fn relay_state(mut self, relay_state: RelayStateParam) -> Self {
252 self.relay_state = Some(relay_state);
253 self
254 }
255}