1use rustauth_core::plugin::PluginErrorCode;
2
3pub const PROVIDER_NOT_FOUND: &str = "PROVIDER_NOT_FOUND";
5pub const PROVIDER_EXISTS: &str = "PROVIDER_EXISTS";
7pub const INVALID_PROVIDER_ID: &str = "INVALID_PROVIDER_ID";
9pub const INVALID_PROVIDER_TYPE: &str = "INVALID_PROVIDER_TYPE";
11pub const DOMAIN_VERIFIED: &str = "DOMAIN_VERIFIED";
13pub const NO_PENDING_VERIFICATION: &str = "NO_PENDING_VERIFICATION";
15pub const SAML_INVALID_RESPONSE: &str = "SAML_INVALID_RESPONSE";
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum SsoErrorCategory {
21 Configuration,
23 UserInput,
25 Authorization,
27 NotFound,
29 IdentityProviderRuntime,
31 SuspectedAttack,
33 Unsupported,
35 Unexpected,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub struct SsoErrorDescriptor {
42 pub code: &'static str,
44 pub message: &'static str,
46 pub category: SsoErrorCategory,
48}
49
50const ERROR_DESCRIPTORS: &[SsoErrorDescriptor] = &[
51 descriptor(
52 PROVIDER_NOT_FOUND,
53 "SSO provider not found",
54 SsoErrorCategory::NotFound,
55 ),
56 descriptor(
57 "SAML_PROVIDER_NOT_FOUND",
58 "SAML provider not found",
59 SsoErrorCategory::NotFound,
60 ),
61 descriptor(
62 PROVIDER_EXISTS,
63 "SSO provider already exists",
64 SsoErrorCategory::UserInput,
65 ),
66 descriptor(
67 INVALID_PROVIDER_ID,
68 "Invalid provider id",
69 SsoErrorCategory::UserInput,
70 ),
71 descriptor(
72 INVALID_PROVIDER_TYPE,
73 "Invalid provider type",
74 SsoErrorCategory::UserInput,
75 ),
76 descriptor(
77 DOMAIN_VERIFIED,
78 "Domain has already been verified",
79 SsoErrorCategory::UserInput,
80 ),
81 descriptor(
82 NO_PENDING_VERIFICATION,
83 "No pending domain verification exists",
84 SsoErrorCategory::UserInput,
85 ),
86 descriptor(
87 "INVALID_ISSUER",
88 "Invalid issuer",
89 SsoErrorCategory::UserInput,
90 ),
91 descriptor(
92 "INVALID_DOMAIN",
93 "Invalid domain",
94 SsoErrorCategory::UserInput,
95 ),
96 descriptor(
97 "INVALID_CALLBACK_URL",
98 "Invalid callback URL",
99 SsoErrorCategory::UserInput,
100 ),
101 descriptor(
102 "INVALID_ERROR_CALLBACK_URL",
103 "Invalid error callback URL",
104 SsoErrorCategory::UserInput,
105 ),
106 descriptor(
107 "INVALID_NEW_USER_CALLBACK_URL",
108 "Invalid new-user callback URL",
109 SsoErrorCategory::UserInput,
110 ),
111 descriptor(
112 "DOMAIN_NOT_VERIFIED",
113 "Provider domain has not been verified",
114 SsoErrorCategory::Authorization,
115 ),
116 descriptor(
117 "INVALID_ORIGIN",
118 "Invalid request origin",
119 SsoErrorCategory::Authorization,
120 ),
121 descriptor(
122 "OIDC_PROVIDER_NOT_CONFIGURED",
123 "OIDC provider is not configured",
124 SsoErrorCategory::Configuration,
125 ),
126 descriptor(
127 "OIDC_CONFIG_NOT_CONFIGURED",
128 "OIDC config is not configured",
129 SsoErrorCategory::Configuration,
130 ),
131 descriptor(
132 "INVALID_OIDC_CONFIG",
133 "Invalid OIDC configuration",
134 SsoErrorCategory::Configuration,
135 ),
136 descriptor(
137 "SAML_PROVIDER_NOT_CONFIGURED",
138 "SAML provider is not configured",
139 SsoErrorCategory::Configuration,
140 ),
141 descriptor(
142 "SAML_CONFIG_NOT_CONFIGURED",
143 "SAML config is not configured",
144 SsoErrorCategory::Configuration,
145 ),
146 descriptor(
147 "INVALID_SAML_CONFIG",
148 "Invalid SAML configuration",
149 SsoErrorCategory::Configuration,
150 ),
151 descriptor(
152 "SAML_METADATA_TOO_LARGE",
153 "SAML metadata is too large",
154 SsoErrorCategory::Configuration,
155 ),
156 descriptor(
157 "SAML_UNKNOWN_ALGORITHM",
158 "Unknown SAML algorithm",
159 SsoErrorCategory::Configuration,
160 ),
161 descriptor(
162 "SAML_DEPRECATED_CONFIG_ALGORITHM",
163 "Deprecated SAML configuration algorithm",
164 SsoErrorCategory::Configuration,
165 ),
166 descriptor(
167 "SAML_ALGORITHM_NOT_ALLOWED",
168 "SAML algorithm is not allowed",
169 SsoErrorCategory::Configuration,
170 ),
171 descriptor(
172 "SAML_AUTHN_REQUEST_PRIVATE_KEY_REQUIRED",
173 "SAML AuthnRequest signing private key is required",
174 SsoErrorCategory::Configuration,
175 ),
176 descriptor(
177 "MISSING_SAML_RESPONSE",
178 "Missing SAML response",
179 SsoErrorCategory::IdentityProviderRuntime,
180 ),
181 descriptor(
182 "SAML_RESPONSE_TOO_LARGE",
183 "SAML response is too large",
184 SsoErrorCategory::IdentityProviderRuntime,
185 ),
186 descriptor(
187 "SAML_RESPONSE_NOT_SUCCESS",
188 "SAML response was not successful",
189 SsoErrorCategory::IdentityProviderRuntime,
190 ),
191 descriptor(
192 "SAML_SIGN_IN_FAILED",
193 "SAML sign-in failed",
194 SsoErrorCategory::IdentityProviderRuntime,
195 ),
196 descriptor(
197 "UNABLE_TO_EXTRACT_SAML_USER",
198 "Unable to extract SAML user",
199 SsoErrorCategory::IdentityProviderRuntime,
200 ),
201 descriptor(
202 "SAML_SESSION_NOT_FOUND",
203 "SAML session was not found",
204 SsoErrorCategory::IdentityProviderRuntime,
205 ),
206 descriptor(
207 SAML_INVALID_RESPONSE,
208 "Invalid SAML response",
209 SsoErrorCategory::SuspectedAttack,
210 ),
211 descriptor(
212 "INVALID_SAML_RESPONSE",
213 "Invalid SAML response",
214 SsoErrorCategory::SuspectedAttack,
215 ),
216 descriptor(
217 "REPLAYED_SAML_ASSERTION",
218 "Replayed SAML assertion",
219 SsoErrorCategory::SuspectedAttack,
220 ),
221 descriptor(
222 "INVALID_AUTHN_REQUEST_STATE",
223 "Invalid SAML AuthnRequest state",
224 SsoErrorCategory::SuspectedAttack,
225 ),
226 descriptor(
227 "INVALID_LOGOUT_REQUEST_STATE",
228 "Invalid SAML LogoutRequest state",
229 SsoErrorCategory::SuspectedAttack,
230 ),
231 descriptor(
232 "SAML_IN_RESPONSE_TO_PROVIDER_MISMATCH",
233 "SAML InResponseTo provider mismatch",
234 SsoErrorCategory::SuspectedAttack,
235 ),
236 descriptor(
237 "SAML_SIGNATURE_INVALID",
238 "Invalid SAML signature",
239 SsoErrorCategory::SuspectedAttack,
240 ),
241 descriptor(
242 "SAML_ASSERTION_SIGNATURE_REQUIRED",
243 "SAML assertion signature is required",
244 SsoErrorCategory::SuspectedAttack,
245 ),
246 descriptor(
247 "SAML_LOGOUT_REQUEST_SIGNATURE_REQUIRED",
248 "SAML LogoutRequest signature is required",
249 SsoErrorCategory::SuspectedAttack,
250 ),
251 descriptor(
252 "SAML_LOGOUT_RESPONSE_SIGNATURE_REQUIRED",
253 "SAML LogoutResponse signature is required",
254 SsoErrorCategory::SuspectedAttack,
255 ),
256 descriptor(
257 "SAML_DEPRECATED_RUNTIME_ALGORITHM",
258 "Deprecated SAML runtime algorithm",
259 SsoErrorCategory::SuspectedAttack,
260 ),
261 descriptor(
262 "SAML_DESTINATION_MISMATCH",
263 "SAML destination mismatch",
264 SsoErrorCategory::SuspectedAttack,
265 ),
266 descriptor(
267 "SAML_ISSUER_MISMATCH",
268 "SAML issuer mismatch",
269 SsoErrorCategory::SuspectedAttack,
270 ),
271 descriptor(
272 "SAML_IN_RESPONSE_TO_MISMATCH",
273 "SAML InResponseTo mismatch",
274 SsoErrorCategory::SuspectedAttack,
275 ),
276 descriptor(
277 "SAML_TIMESTAMP_INVALID",
278 "SAML timestamp is invalid",
279 SsoErrorCategory::SuspectedAttack,
280 ),
281 descriptor(
282 "SAML_RECIPIENT_MISMATCH",
283 "SAML recipient mismatch",
284 SsoErrorCategory::SuspectedAttack,
285 ),
286 descriptor(
287 "INVALID_EMAIL_DOMAIN",
288 "Invalid SSO email domain",
289 SsoErrorCategory::SuspectedAttack,
290 ),
291 descriptor(
292 "SAML_SIGNATURE_VALIDATION_NOT_IMPLEMENTED",
293 "SAML signature validation is not enabled",
294 SsoErrorCategory::Unsupported,
295 ),
296 descriptor(
297 "ENCRYPTED_SAML_ASSERTION_UNSUPPORTED",
298 "Encrypted SAML assertion is not supported",
299 SsoErrorCategory::Unsupported,
300 ),
301 descriptor(
302 "SAML_AUTHN_REQUEST_SIGNING_NOT_SUPPORTED",
303 "SAML AuthnRequest signing is not enabled",
304 SsoErrorCategory::Unsupported,
305 ),
306 descriptor(
307 "SAML_AUTHN_REQUEST_SIGNING_FAILED",
308 "SAML AuthnRequest signing failed",
309 SsoErrorCategory::Unexpected,
310 ),
311];
312
313const fn descriptor(
314 code: &'static str,
315 message: &'static str,
316 category: SsoErrorCategory,
317) -> SsoErrorDescriptor {
318 SsoErrorDescriptor {
319 code,
320 message,
321 category,
322 }
323}
324
325pub fn plugin_error_codes() -> Vec<PluginErrorCode> {
326 sso_error_descriptors()
327 .iter()
328 .map(|descriptor| PluginErrorCode::new(descriptor.code, descriptor.message))
329 .collect()
330}
331
332pub fn sso_error_descriptors() -> &'static [SsoErrorDescriptor] {
334 ERROR_DESCRIPTORS
335}
336
337pub fn sso_error_category(code: &str) -> SsoErrorCategory {
339 sso_error_descriptors()
340 .iter()
341 .find(|descriptor| descriptor.code == code)
342 .map(|descriptor| descriptor.category)
343 .unwrap_or(SsoErrorCategory::Unexpected)
344}