mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-01 16:51:21 +00:00
avoid duplicate writing of new user languages
This commit is contained in:
parent
f9d6384e7a
commit
130b803240
17 changed files with 86 additions and 75 deletions
|
@ -6,10 +6,7 @@ use lemmy_api_common::{
|
||||||
person::GenerateTotpSecretResponse,
|
person::GenerateTotpSecretResponse,
|
||||||
sensitive::Sensitive,
|
sensitive::Sensitive,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::source::local_user::{LocalUser, LocalUserUpdateForm};
|
||||||
source::local_user::{LocalUser, LocalUserUpdateForm},
|
|
||||||
traits::Crud,
|
|
||||||
};
|
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{UpdateTotp, UpdateTotpResponse},
|
person::{UpdateTotp, UpdateTotpResponse},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::source::local_user::{LocalUser, LocalUserUpdateForm};
|
||||||
source::local_user::{LocalUser, LocalUserUpdateForm},
|
|
||||||
traits::Crud,
|
|
||||||
};
|
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,9 @@ mod tests {
|
||||||
.password_encrypted("123456".to_string())
|
.password_encrypted("123456".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_local_user = LocalUser::create(pool, &local_user_form).await.unwrap();
|
let inserted_local_user = LocalUser::create(pool, &local_user_form, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let req = TestRequest::default().to_http_request();
|
let req = TestRequest::default().to_http_request();
|
||||||
let jwt = Claims::generate(inserted_local_user.id, req, &context)
|
let jwt = Claims::generate(inserted_local_user.id, req, &context)
|
||||||
|
|
|
@ -19,7 +19,6 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::PersonAggregates,
|
aggregates::structs::PersonAggregates,
|
||||||
source::{
|
source::{
|
||||||
actor_language::LocalUserLanguage,
|
|
||||||
captcha_answer::{CaptchaAnswer, CheckCaptchaAnswer},
|
captcha_answer::{CaptchaAnswer, CheckCaptchaAnswer},
|
||||||
language::Language,
|
language::Language,
|
||||||
local_user::{LocalUser, LocalUserInsertForm},
|
local_user::{LocalUser, LocalUserInsertForm},
|
||||||
|
@ -155,8 +154,6 @@ pub async fn register(
|
||||||
.admin(Some(!local_site.site_setup))
|
.admin(Some(!local_site.site_setup))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_local_user = LocalUser::create(&mut context.pool(), &local_user_form).await?;
|
|
||||||
|
|
||||||
let all_languages = Language::read_all(&mut context.pool()).await?;
|
let all_languages = Language::read_all(&mut context.pool()).await?;
|
||||||
// use hashset to avoid duplicates
|
// use hashset to avoid duplicates
|
||||||
let mut language_ids = HashSet::new();
|
let mut language_ids = HashSet::new();
|
||||||
|
@ -166,7 +163,9 @@ pub async fn register(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let language_ids = language_ids.into_iter().collect();
|
let language_ids = language_ids.into_iter().collect();
|
||||||
LocalUserLanguage::update(&mut context.pool(), language_ids, inserted_local_user.id).await?;
|
|
||||||
|
let inserted_local_user =
|
||||||
|
LocalUser::create(&mut context.pool(), &local_user_form, language_ids).await?;
|
||||||
|
|
||||||
if local_site.site_setup && require_registration_application {
|
if local_site.site_setup && require_registration_application {
|
||||||
// Create the registration application
|
// Create the registration application
|
||||||
|
|
|
@ -361,7 +361,7 @@ mod tests {
|
||||||
.person_id(person.id)
|
.person_id(person.id)
|
||||||
.password_encrypted("pass".to_string())
|
.password_encrypted("pass".to_string())
|
||||||
.build();
|
.build();
|
||||||
let local_user = LocalUser::create(&mut context.pool(), &user_form).await?;
|
let local_user = LocalUser::create(&mut context.pool(), &user_form, vec![]).await?;
|
||||||
|
|
||||||
Ok(LocalUserView::read(&mut context.pool(), local_user.id).await?)
|
Ok(LocalUserView::read(&mut context.pool(), local_user.id).await?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,7 +535,9 @@ mod tests {
|
||||||
.password_encrypted("my_pw".to_string())
|
.password_encrypted("my_pw".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let local_user = LocalUser::create(pool, &local_user_form).await.unwrap();
|
let local_user = LocalUser::create(pool, &local_user_form, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let local_user_langs1 = LocalUserLanguage::read(pool, local_user.id).await.unwrap();
|
let local_user_langs1 = LocalUserLanguage::read(pool, local_user.id).await.unwrap();
|
||||||
|
|
||||||
// new user should be initialized with all languages
|
// new user should be initialized with all languages
|
||||||
|
@ -648,7 +650,9 @@ mod tests {
|
||||||
.person_id(person.id)
|
.person_id(person.id)
|
||||||
.password_encrypted("my_pw".to_string())
|
.password_encrypted("my_pw".to_string())
|
||||||
.build();
|
.build();
|
||||||
let local_user = LocalUser::create(pool, &local_user_form).await.unwrap();
|
let local_user = LocalUser::create(pool, &local_user_form, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
LocalUserLanguage::update(pool, test_langs2, local_user.id)
|
LocalUserLanguage::update(pool, test_langs2, local_user.id)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
newtypes::{DbUrl, LocalUserId, PersonId},
|
newtypes::{DbUrl, LanguageId, LocalUserId, PersonId},
|
||||||
schema::{local_user, person, registration_application},
|
schema::{local_user, person, registration_application},
|
||||||
source::{
|
source::{
|
||||||
actor_language::LocalUserLanguage,
|
actor_language::LocalUserLanguage,
|
||||||
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
||||||
local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm},
|
local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
|
||||||
utils::{
|
utils::{
|
||||||
functions::{coalesce, lower},
|
functions::{coalesce, lower},
|
||||||
get_conn,
|
get_conn,
|
||||||
|
@ -25,6 +24,52 @@ use diesel::{
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
impl LocalUser {
|
impl LocalUser {
|
||||||
|
pub async fn create(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
form: &LocalUserInsertForm,
|
||||||
|
languages: Vec<LanguageId>,
|
||||||
|
) -> Result<LocalUser, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
let mut form_with_encrypted_password = form.clone();
|
||||||
|
let password_hash =
|
||||||
|
hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
|
||||||
|
form_with_encrypted_password.password_encrypted = password_hash;
|
||||||
|
|
||||||
|
let local_user_ = insert_into(local_user::table)
|
||||||
|
.values(form_with_encrypted_password)
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
LocalUserLanguage::update(pool, languages, local_user_.id).await?;
|
||||||
|
|
||||||
|
// Create their vote_display_modes
|
||||||
|
let vote_display_mode_form = LocalUserVoteDisplayModeInsertForm::builder()
|
||||||
|
.local_user_id(local_user_.id)
|
||||||
|
.build();
|
||||||
|
LocalUserVoteDisplayMode::create(pool, &vote_display_mode_form).await?;
|
||||||
|
|
||||||
|
Ok(local_user_)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
local_user_id: LocalUserId,
|
||||||
|
form: &LocalUserUpdateForm,
|
||||||
|
) -> Result<LocalUser, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
diesel::update(local_user::table.find(local_user_id))
|
||||||
|
.set(form)
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete(pool: &mut DbPool<'_>, id: LocalUserId) -> Result<usize, Error> {
|
||||||
|
let conn = &mut *get_conn(pool).await?;
|
||||||
|
diesel::delete(local_user::table.find(id))
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_password(
|
pub async fn update_password(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
local_user_id: LocalUserId,
|
local_user_id: LocalUserId,
|
||||||
|
@ -183,47 +228,3 @@ pub struct UserBackupLists {
|
||||||
pub blocked_users: Vec<DbUrl>,
|
pub blocked_users: Vec<DbUrl>,
|
||||||
pub blocked_instances: Vec<String>,
|
pub blocked_instances: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl Crud for LocalUser {
|
|
||||||
type InsertForm = LocalUserInsertForm;
|
|
||||||
type UpdateForm = LocalUserUpdateForm;
|
|
||||||
type IdType = LocalUserId;
|
|
||||||
|
|
||||||
async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
let mut form_with_encrypted_password = form.clone();
|
|
||||||
let password_hash =
|
|
||||||
hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
|
|
||||||
form_with_encrypted_password.password_encrypted = password_hash;
|
|
||||||
|
|
||||||
let local_user_ = insert_into(local_user::table)
|
|
||||||
.values(form_with_encrypted_password)
|
|
||||||
.get_result::<Self>(conn)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// TODO: this is necessary for tests, but causes unnecessary db writes in production as languages
|
|
||||||
// are set from accept-language header immediately after. would be good if final languages
|
|
||||||
// could be passed in directly.
|
|
||||||
LocalUserLanguage::update(pool, vec![], local_user_.id).await?;
|
|
||||||
|
|
||||||
// Create their vote_display_modes
|
|
||||||
let vote_display_mode_form = LocalUserVoteDisplayModeInsertForm::builder()
|
|
||||||
.local_user_id(local_user_.id)
|
|
||||||
.build();
|
|
||||||
LocalUserVoteDisplayMode::create(pool, &vote_display_mode_form).await?;
|
|
||||||
|
|
||||||
Ok(local_user_)
|
|
||||||
}
|
|
||||||
async fn update(
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
local_user_id: LocalUserId,
|
|
||||||
form: &Self::UpdateForm,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
diesel::update(local_user::table.find(local_user_id))
|
|
||||||
.set(form)
|
|
||||||
.get_result::<Self>(conn)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -121,7 +121,9 @@ mod tests {
|
||||||
.password_encrypted("pass".to_string())
|
.password_encrypted("pass".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
|
let inserted_local_user = LocalUser::create(pool, &new_local_user, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let token = "nope";
|
let token = "nope";
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,9 @@ mod tests {
|
||||||
.person_id(inserted_timmy.id)
|
.person_id(inserted_timmy.id)
|
||||||
.password_encrypted("123".to_string())
|
.password_encrypted("123".to_string())
|
||||||
.build();
|
.build();
|
||||||
let timmy_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
|
let timmy_local_user = LocalUser::create(pool, &new_local_user, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let timmy_view = LocalUserView {
|
let timmy_view = LocalUserView {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
local_user_vote_display_mode: LocalUserVoteDisplayMode::default(),
|
local_user_vote_display_mode: LocalUserVoteDisplayMode::default(),
|
||||||
|
|
|
@ -481,7 +481,7 @@ mod tests {
|
||||||
.admin(Some(true))
|
.admin(Some(true))
|
||||||
.password_encrypted(String::new())
|
.password_encrypted(String::new())
|
||||||
.build();
|
.build();
|
||||||
let inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form)
|
let inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form, vec![])
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -330,7 +330,9 @@ mod tests {
|
||||||
.person_id(inserted_timmy.id)
|
.person_id(inserted_timmy.id)
|
||||||
.password_encrypted("123".to_string())
|
.password_encrypted("123".to_string())
|
||||||
.build();
|
.build();
|
||||||
let timmy_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
|
let timmy_local_user = LocalUser::create(pool, &new_local_user, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let timmy_view = LocalUserView {
|
let timmy_view = LocalUserView {
|
||||||
local_user: timmy_local_user,
|
local_user: timmy_local_user,
|
||||||
local_user_vote_display_mode: LocalUserVoteDisplayMode::default(),
|
local_user_vote_display_mode: LocalUserVoteDisplayMode::default(),
|
||||||
|
|
|
@ -807,7 +807,7 @@ mod tests {
|
||||||
admin: Some(true),
|
admin: Some(true),
|
||||||
..LocalUserInsertForm::test_form(inserted_person.id)
|
..LocalUserInsertForm::test_form(inserted_person.id)
|
||||||
};
|
};
|
||||||
let inserted_local_user = LocalUser::create(pool, &local_user_form).await?;
|
let inserted_local_user = LocalUser::create(pool, &local_user_form, vec![]).await?;
|
||||||
|
|
||||||
let new_bot = PersonInsertForm {
|
let new_bot = PersonInsertForm {
|
||||||
bot_account: Some(true),
|
bot_account: Some(true),
|
||||||
|
@ -833,6 +833,7 @@ mod tests {
|
||||||
let inserted_blocked_local_user = LocalUser::create(
|
let inserted_blocked_local_user = LocalUser::create(
|
||||||
pool,
|
pool,
|
||||||
&LocalUserInsertForm::test_form(inserted_blocked_person.id),
|
&LocalUserInsertForm::test_form(inserted_blocked_person.id),
|
||||||
|
vec![],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ mod tests {
|
||||||
.admin(Some(true))
|
.admin(Some(true))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let _inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form)
|
let _inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form, vec![])
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ mod tests {
|
||||||
.password_encrypted("nada".to_string())
|
.password_encrypted("nada".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_sara_local_user = LocalUser::create(pool, &sara_local_user_form)
|
let inserted_sara_local_user = LocalUser::create(pool, &sara_local_user_form, vec![])
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ mod tests {
|
||||||
.password_encrypted("nada".to_string())
|
.password_encrypted("nada".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_jess_local_user = LocalUser::create(pool, &jess_local_user_form)
|
let inserted_jess_local_user = LocalUser::create(pool, &jess_local_user_form, vec![])
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,9 @@ mod tests {
|
||||||
.person_id(inserted_person.id)
|
.person_id(inserted_person.id)
|
||||||
.password_encrypted(String::new())
|
.password_encrypted(String::new())
|
||||||
.build();
|
.build();
|
||||||
let local_user = LocalUser::create(pool, &local_user_form).await.unwrap();
|
let local_user = LocalUser::create(pool, &local_user_form, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let new_community = CommunityInsertForm::builder()
|
let new_community = CommunityInsertForm::builder()
|
||||||
.name("test_community_3".to_string())
|
.name("test_community_3".to_string())
|
||||||
|
|
|
@ -204,7 +204,7 @@ mod tests {
|
||||||
.person_id(alice.id)
|
.person_id(alice.id)
|
||||||
.password_encrypted(String::new())
|
.password_encrypted(String::new())
|
||||||
.build();
|
.build();
|
||||||
let alice_local_user = LocalUser::create(pool, &alice_local_user_form).await?;
|
let alice_local_user = LocalUser::create(pool, &alice_local_user_form, vec![]).await?;
|
||||||
|
|
||||||
let bob_form = PersonInsertForm::builder()
|
let bob_form = PersonInsertForm::builder()
|
||||||
.name("bob".to_string())
|
.name("bob".to_string())
|
||||||
|
@ -218,7 +218,7 @@ mod tests {
|
||||||
.person_id(bob.id)
|
.person_id(bob.id)
|
||||||
.password_encrypted(String::new())
|
.password_encrypted(String::new())
|
||||||
.build();
|
.build();
|
||||||
let bob_local_user = LocalUser::create(pool, &bob_local_user_form).await?;
|
let bob_local_user = LocalUser::create(pool, &bob_local_user_form, vec![]).await?;
|
||||||
|
|
||||||
Ok(Data {
|
Ok(Data {
|
||||||
alice,
|
alice,
|
||||||
|
|
|
@ -475,7 +475,7 @@ async fn initialize_local_site_2022_10_10(
|
||||||
.email(setup.admin_email.clone())
|
.email(setup.admin_email.clone())
|
||||||
.admin(Some(true))
|
.admin(Some(true))
|
||||||
.build();
|
.build();
|
||||||
LocalUser::create(pool, &local_user_form).await?;
|
LocalUser::create(pool, &local_user_form, vec![]).await?;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add an entry for the site table
|
// Add an entry for the site table
|
||||||
|
|
|
@ -155,7 +155,9 @@ mod tests {
|
||||||
.password_encrypted("123456".to_string())
|
.password_encrypted("123456".to_string())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let inserted_local_user = LocalUser::create(pool, &local_user_form).await.unwrap();
|
let inserted_local_user = LocalUser::create(pool, &local_user_form, vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let req = TestRequest::default().to_http_request();
|
let req = TestRequest::default().to_http_request();
|
||||||
let jwt = Claims::generate(inserted_local_user.id, req, &context)
|
let jwt = Claims::generate(inserted_local_user.id, req, &context)
|
||||||
|
|
Loading…
Reference in a new issue