Ensure result order when searching for sso_user

pull/3899/head
Timshel 3 months ago
parent 5b3e8933fd
commit 95387be709

@ -1,6 +1,7 @@
use crate::util::{format_date, get_uuid, retry}; use crate::util::{format_date, get_uuid, retry};
use chrono::{NaiveDateTime, TimeDelta, Utc}; use chrono::{NaiveDateTime, TimeDelta, Utc};
use serde_json::Value; use serde_json::Value;
use std::cmp::Ordering;
use crate::crypto; use crate::crypto;
use crate::CONFIG; use crate::CONFIG;
@ -487,7 +488,8 @@ impl SsoUser {
} }
// Written as an union to make the query more lisible than using an `or_filter`. // 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( pub async fn find_by_identifier_or_email(
identifier: &str, identifier: &str,
mail: &str, mail: &str,
@ -496,7 +498,7 @@ impl SsoUser {
let lower_mail = mail.to_lowercase(); let lower_mail = mail.to_lowercase();
db_run! {conn: { db_run! {conn: {
users::table let mut res = users::table
.inner_join(sso_users::table) .inner_join(sso_users::table)
.select(<(UserDb, Option<SsoUserDb>)>::as_select()) .select(<(UserDb, Option<SsoUserDb>)>::as_select())
.filter(sso_users::identifier.eq(identifier)) .filter(sso_users::identifier.eq(identifier))
@ -509,8 +511,17 @@ impl SsoUser {
.load(conn) .load(conn)
.expect("Error searching user by SSO identifier and email") .expect("Error searching user by SSO identifier and email")
.into_iter() .into_iter()
.next()
.map(|(user, sso_user)| { (user.from_db(), sso_user.from_db()) }) .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()
}} }}
} }
} }

Loading…
Cancel
Save