|
27 | 27 |
|
28 | 28 | extern crate tracing;
|
29 | 29 | use mas_data_model::TchapConfig;
|
| 30 | +use mas_storage::BoxRepository; |
30 | 31 | use tracing::info;
|
31 | 32 |
|
32 | 33 | mod identity_client;
|
@@ -233,6 +234,80 @@ pub async fn is_email_allowed(
|
233 | 234 | }
|
234 | 235 | }
|
235 | 236 |
|
| 237 | +/// Search for a user by email with fallback rules |
| 238 | +/// |
| 239 | +/// # Parameters |
| 240 | +/// * `repo` - Repository access |
| 241 | +/// * `email` - The email to search for |
| 242 | +/// * `fallback_rules` - Fallback rules for email transformation |
| 243 | +/// |
| 244 | +/// # Returns |
| 245 | +/// Option<`mas_data_model::User`> - The found user if any |
| 246 | +pub async fn search_user_by_email( |
| 247 | + repo: &mut BoxRepository, |
| 248 | + email: &str, |
| 249 | + tchap_config: &TchapConfig, |
| 250 | +) -> Result<Option<mas_data_model::User>, mas_storage::RepositoryError> { |
| 251 | + tracing::info!("Matching oidc identity by email:{}", email); |
| 252 | + let maybe_user_email = repo.user_email().find_by_email(email).await?; |
| 253 | + |
| 254 | + if let Some(user_email) = maybe_user_email { |
| 255 | + let maybe_user_found: Option<mas_data_model::User> = |
| 256 | + repo.user().lookup(user_email.user_id).await?; |
| 257 | + return Ok(maybe_user_found); |
| 258 | + } |
| 259 | + |
| 260 | + tracing::info!( |
| 261 | + "Email not found, Matching oidc identity by email using fallback rules:{}", |
| 262 | + email |
| 263 | + ); |
| 264 | + let fallback_rules = &tchap_config.email_lookup_fallback_rules; |
| 265 | + // let fallback_rules: Value = |
| 266 | + // serde_json::from_str(r#"[{"match":"@numerique.gouv.fr", |
| 267 | + // "search":"@beta.gouv.fr"}]"#) .unwrap(); |
| 268 | + |
| 269 | + // Iterate on fallback_rules, if a rule 'match' matches the email, |
| 270 | + // replace by value of 'search' and lookup again the email |
| 271 | + for rule in fallback_rules { |
| 272 | + let match_pattern = &rule.match_with; |
| 273 | + let search_value = &rule.search; |
| 274 | + tracing::info!( |
| 275 | + "Checking fallback rules {} : {}", |
| 276 | + match_pattern, |
| 277 | + search_value |
| 278 | + ); |
| 279 | + |
| 280 | + // Check if email contains the match pattern |
| 281 | + if email.contains(match_pattern) { |
| 282 | + // Replace match pattern with search value |
| 283 | + let transformed_email = email.replace(match_pattern, search_value); |
| 284 | + tracing::debug!( |
| 285 | + "Search by transformed email fallback rules {}", |
| 286 | + transformed_email |
| 287 | + ); |
| 288 | + |
| 289 | + // Look up the transformed email |
| 290 | + let maybe_transformed_user_email = |
| 291 | + repo.user_email().find_by_email(&transformed_email).await?; |
| 292 | + |
| 293 | + if let Some(transformed_user_email) = maybe_transformed_user_email { |
| 294 | + let user_found: Option<mas_data_model::User> = |
| 295 | + repo.user().lookup(transformed_user_email.user_id).await?; |
| 296 | + tracing::info!( |
| 297 | + "User found with fallback rules {} : {}", |
| 298 | + match_pattern, |
| 299 | + search_value |
| 300 | + ); |
| 301 | + |
| 302 | + return Ok(user_found); |
| 303 | + } |
| 304 | + } |
| 305 | + } |
| 306 | + |
| 307 | + Ok(None) |
| 308 | +} |
| 309 | +//:tchap: end |
| 310 | + |
236 | 311 | pub use self::test_utils::*;
|
237 | 312 |
|
238 | 313 | #[cfg(test)]
|
|
0 commit comments