securitydept_session_context/config/
validator.rs1use securitydept_utils::redirect::RedirectTargetConfig;
2
3use super::SessionContextConfigSource;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct SessionContextConfigValidationError {
7 pub field_path: String,
8 pub code: String,
9 pub message: String,
10}
11
12impl SessionContextConfigValidationError {
13 pub fn new(
14 field_path: impl Into<String>,
15 code: impl Into<String>,
16 message: impl Into<String>,
17 ) -> Self {
18 Self {
19 field_path: field_path.into(),
20 code: code.into(),
21 message: message.into(),
22 }
23 }
24}
25
26impl std::fmt::Display for SessionContextConfigValidationError {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 write!(
29 f,
30 "session_context config validation failed for {} ({}): {}",
31 self.field_path, self.code, self.message
32 )
33 }
34}
35
36impl std::error::Error for SessionContextConfigValidationError {}
37
38pub trait SessionContextConfigValidator {
39 fn validate_session_context_config<S>(
40 &self,
41 config: &S,
42 ) -> Result<(), SessionContextConfigValidationError>
43 where
44 S: SessionContextConfigSource + ?Sized;
45}
46
47#[derive(Debug, Clone, Copy, Default)]
48pub struct NoopSessionContextConfigValidator;
49
50impl SessionContextConfigValidator for NoopSessionContextConfigValidator {
51 fn validate_session_context_config<S>(
52 &self,
53 _config: &S,
54 ) -> Result<(), SessionContextConfigValidationError>
55 where
56 S: SessionContextConfigSource + ?Sized,
57 {
58 Ok(())
59 }
60}
61
62impl<V> SessionContextConfigValidator for &V
63where
64 V: SessionContextConfigValidator + ?Sized,
65{
66 fn validate_session_context_config<S>(
67 &self,
68 config: &S,
69 ) -> Result<(), SessionContextConfigValidationError>
70 where
71 S: SessionContextConfigSource + ?Sized,
72 {
73 (*self).validate_session_context_config(config)
74 }
75}
76
77impl<V> SessionContextConfigValidator for [V]
78where
79 V: SessionContextConfigValidator,
80{
81 fn validate_session_context_config<S>(
82 &self,
83 config: &S,
84 ) -> Result<(), SessionContextConfigValidationError>
85 where
86 S: SessionContextConfigSource + ?Sized,
87 {
88 for validator in self {
89 validator.validate_session_context_config(config)?;
90 }
91
92 Ok(())
93 }
94}
95
96impl<V, const N: usize> SessionContextConfigValidator for [V; N]
97where
98 V: SessionContextConfigValidator,
99{
100 fn validate_session_context_config<S>(
101 &self,
102 config: &S,
103 ) -> Result<(), SessionContextConfigValidationError>
104 where
105 S: SessionContextConfigSource + ?Sized,
106 {
107 self.as_slice().validate_session_context_config(config)
108 }
109}
110
111impl<V> SessionContextConfigValidator for Vec<V>
112where
113 V: SessionContextConfigValidator,
114{
115 fn validate_session_context_config<S>(
116 &self,
117 config: &S,
118 ) -> Result<(), SessionContextConfigValidationError>
119 where
120 S: SessionContextConfigSource + ?Sized,
121 {
122 self.as_slice().validate_session_context_config(config)
123 }
124}
125
126impl<A, B> SessionContextConfigValidator for (A, B)
127where
128 A: SessionContextConfigValidator,
129 B: SessionContextConfigValidator,
130{
131 fn validate_session_context_config<S>(
132 &self,
133 config: &S,
134 ) -> Result<(), SessionContextConfigValidationError>
135 where
136 S: SessionContextConfigSource + ?Sized,
137 {
138 self.0.validate_session_context_config(config)?;
139 self.1.validate_session_context_config(config)
140 }
141}
142
143impl<A, B, C> SessionContextConfigValidator for (A, B, C)
144where
145 A: SessionContextConfigValidator,
146 B: SessionContextConfigValidator,
147 C: SessionContextConfigValidator,
148{
149 fn validate_session_context_config<S>(
150 &self,
151 config: &S,
152 ) -> Result<(), SessionContextConfigValidationError>
153 where
154 S: SessionContextConfigSource + ?Sized,
155 {
156 self.0.validate_session_context_config(config)?;
157 self.1.validate_session_context_config(config)?;
158 self.2.validate_session_context_config(config)
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
163pub struct SessionContextFixedPostAuthRedirectValidator {
164 post_auth_redirect: RedirectTargetConfig,
165}
166
167impl SessionContextFixedPostAuthRedirectValidator {
168 pub fn new(post_auth_redirect: RedirectTargetConfig) -> Self {
169 Self { post_auth_redirect }
170 }
171}
172
173impl SessionContextConfigValidator for SessionContextFixedPostAuthRedirectValidator {
174 fn validate_session_context_config<S>(
175 &self,
176 config: &S,
177 ) -> Result<(), SessionContextConfigValidationError>
178 where
179 S: SessionContextConfigSource + ?Sized,
180 {
181 if config.post_auth_redirect_config() != &self.post_auth_redirect {
182 return Err(SessionContextConfigValidationError::new(
183 "post_auth_redirect",
184 "fixed_post_auth_redirect_conflict",
185 "session post_auth_redirect is fixed by the host and cannot be overridden",
186 ));
187 }
188
189 Ok(())
190 }
191}