|
|
@ -1,6 +1,7 @@ |
|
|
|
use crate::util::{format_date, get_uuid, retry}; |
|
|
|
use chrono::{NaiveDateTime, TimeDelta, Utc}; |
|
|
|
use serde_json::Value; |
|
|
|
use std::cmp::Ordering; |
|
|
|
|
|
|
|
use crate::crypto; |
|
|
|
use crate::CONFIG; |
|
|
@ -487,7 +488,8 @@ impl SsoUser { |
|
|
|
} |
|
|
|
|
|
|
|
// Written as an union to make the query more lisible than using an `or_filter`.
|
|
|
|
// But `first()` does not appear to work with `union()` so we use `load()`.
|
|
|
|
// If there is a match on identifier and email we want the identifier match.
|
|
|
|
// We sort results in code since UNION does not garanty order and DBs order NULL differently.
|
|
|
|
pub async fn find_by_identifier_or_email( |
|
|
|
identifier: &str, |
|
|
|
mail: &str, |
|
|
@ -496,7 +498,7 @@ impl SsoUser { |
|
|
|
let lower_mail = mail.to_lowercase(); |
|
|
|
|
|
|
|
db_run! {conn: { |
|
|
|
users::table |
|
|
|
let mut res = users::table |
|
|
|
.inner_join(sso_users::table) |
|
|
|
.select(<(UserDb, Option<SsoUserDb>)>::as_select()) |
|
|
|
.filter(sso_users::identifier.eq(identifier)) |
|
|
@ -509,8 +511,17 @@ impl SsoUser { |
|
|
|
.load(conn) |
|
|
|
.expect("Error searching user by SSO identifier and email") |
|
|
|
.into_iter() |
|
|
|
.next() |
|
|
|
.map(|(user, sso_user)| { (user.from_db(), sso_user.from_db()) }) |
|
|
|
.collect::<Vec<(User, Option<SsoUser>)>>(); |
|
|
|
|
|
|
|
res.sort_by(|(_, sso_user), _| { |
|
|
|
match sso_user { |
|
|
|
Some(db_sso_user) if db_sso_user.identifier == identifier => Ordering::Less, |
|
|
|
_ => Ordering::Greater, |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
res.into_iter().next() |
|
|
|
}} |
|
|
|
} |
|
|
|
} |
|
|
|