b453d5d
use models::users::user::{self, ProfileVisibility};
use models::users::user_emails;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};
use time::OffsetDateTime;
use crate::errors::AuthError;
use crate::services::AuthService;
pub async fn upsert(
service: &AuthService,
public: &kenauth::proto::common::v1::UserPublic,
) -> Result<user::Model, AuthError> {
let db = service.db().write();
let now = OffsetDateTime::now_utc();
let lower = public.username.to_lowercase();
let display_name = if public.displayname.trim().is_empty() {
public.username.clone()
} else {
public.displayname.clone()
};
let avatar_url = public.avatar_url.clone();
let existing = user::Entity::find_by_id(public.user_id)
.one(db)
.await?
.or_else(|| None);
let row = match existing {
Some(row) => {
let mut am: user::ActiveModel = row.into();
am.username = Set(public.username.clone());
am.lower_name = Set(lower);
am.display_name = Set(display_name);
am.avatar_url = Set(avatar_url);
am.is_active = Set(true);
am.prohibit_login = Set(false);
am.updated_at = Set(now);
am.update(db).await?
}
None => {
user::ActiveModel {
uid: Set(public.user_id),
username: Set(public.username.clone()),
lower_name: Set(lower),
display_name: Set(display_name),
avatar_url: Set(avatar_url),
is_active: Set(true),
is_restricted: Set(false),
prohibit_login: Set(false),
visibility: Set(ProfileVisibility::Public),
bot: Set(false),
system: Set(false),
last_login_at: Set(None),
last_login_ip_hash: Set(None),
version: Set(1),
passwd_hash: Set(None),
password_last_changed_at: Set(None),
passwd_version: Set(None),
totp_encrypted_secret: Set(None),
totp_enabled: Set(false),
totp_last_used_at: Set(None),
totp_last_counter: Set(None),
timezone: Set(None),
locale: Set(None),
language: Set(None),
created_at: Set(now),
updated_at: Set(now),
}
.insert(db)
.await?
}
};
if !public.email.trim().is_empty() {
let lower_email = public.email.to_lowercase();
let existing_email = user_emails::Entity::find()
.filter(user_emails::Column::UserId.eq(public.user_id))
.filter(user_emails::Column::IsPrimary.eq(true))
.one(db)
.await?;
match existing_email {
Some(email_row) => {
let mut am: user_emails::ActiveModel = email_row.into();
am.email = Set(public.email.clone());
am.lower_email = Set(lower_email);
am.is_activated = Set(public.email_verified);
am.updated_at = Set(now);
am.update(db).await?;
}
None => {
user_emails::ActiveModel {
id: Set(uuid::Uuid::now_v7()),
user_id: Set(public.user_id),
email: Set(public.email.clone()),
lower_email: Set(lower_email),
is_activated: Set(public.email_verified),
is_primary: Set(true),
created_at: Set(now),
updated_at: Set(now),
activated_at: Set(public.email_verified.then_some(now)),
deleted_at: Set(None),
}
.insert(db)
.await?;
}
}
}
Ok(row)
}