@ -1,12 +1,6 @@
use crate ::{
use crate ::{
newtypes ::{ DbUrl , LocalUserId , PersonId } ,
newtypes ::{ DbUrl , LocalUserId , PersonId } ,
schema ::local_user ::dsl ::{
schema ::{ local_user , person , registration_application } ,
accepted_application ,
email ,
email_verified ,
local_user ,
password_encrypted ,
} ,
source ::{
source ::{
actor_language ::{ LocalUserLanguage , SiteLanguage } ,
actor_language ::{ LocalUserLanguage , SiteLanguage } ,
local_user ::{ LocalUser , LocalUserInsertForm , LocalUserUpdateForm } ,
local_user ::{ LocalUser , LocalUserInsertForm , LocalUserUpdateForm } ,
@ -15,11 +9,18 @@ use crate::{
utils ::{
utils ::{
functions ::{ coalesce , lower } ,
functions ::{ coalesce , lower } ,
get_conn ,
get_conn ,
now ,
DbPool ,
DbPool ,
} ,
} ,
} ;
} ;
use bcrypt ::{ hash , DEFAULT_COST } ;
use bcrypt ::{ hash , DEFAULT_COST } ;
use diesel ::{ dsl ::insert_into , result ::Error , ExpressionMethods , JoinOnDsl , QueryDsl } ;
use diesel ::{
dsl ::{ insert_into , not , IntervalDsl } ,
result ::Error ,
ExpressionMethods ,
JoinOnDsl ,
QueryDsl ,
} ;
use diesel_async ::RunQueryDsl ;
use diesel_async ::RunQueryDsl ;
impl LocalUser {
impl LocalUser {
@ -31,16 +32,16 @@ impl LocalUser {
let conn = & mut get_conn ( pool ) . await ? ;
let conn = & mut get_conn ( pool ) . await ? ;
let password_hash = hash ( new_password , DEFAULT_COST ) . expect ( "Couldn't hash password" ) ;
let password_hash = hash ( new_password , DEFAULT_COST ) . expect ( "Couldn't hash password" ) ;
diesel ::update ( local_user . find ( local_user_id ) )
diesel ::update ( local_user ::table . find ( local_user_id ) )
. set ( ( password_encrypted. eq ( password_hash ) , ) )
. set ( ( local_user:: password_encrypted. eq ( password_hash ) , ) )
. get_result ::< Self > ( conn )
. get_result ::< Self > ( conn )
. await
. await
}
}
pub async fn set_all_users_email_verified ( pool : & mut DbPool < ' _ > ) -> Result < Vec < Self > , Error > {
pub async fn set_all_users_email_verified ( pool : & mut DbPool < ' _ > ) -> Result < Vec < Self > , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
let conn = & mut get_conn ( pool ) . await ? ;
diesel ::update ( local_user )
diesel ::update ( local_user ::table )
. set ( email_verified. eq ( true ) )
. set ( local_user:: email_verified. eq ( true ) )
. get_results ::< Self > ( conn )
. get_results ::< Self > ( conn )
. await
. await
}
}
@ -49,18 +50,43 @@ impl LocalUser {
pool : & mut DbPool < ' _ > ,
pool : & mut DbPool < ' _ > ,
) -> Result < Vec < Self > , Error > {
) -> Result < Vec < Self > , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
let conn = & mut get_conn ( pool ) . await ? ;
diesel ::update ( local_user )
diesel ::update ( local_user ::table )
. set ( accepted_application. eq ( true ) )
. set ( local_user:: accepted_application. eq ( true ) )
. get_results ::< Self > ( conn )
. get_results ::< Self > ( conn )
. await
. await
}
}
pub async fn is_email_taken ( pool : & mut DbPool < ' _ > , email_ : & str ) -> Result < bool , Error > {
pub async fn delete_old_denied_local_users ( pool : & mut DbPool < ' _ > ) -> Result < usize , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
// Make sure:
// - The deny reason exists
// - The app is older than a week
// - The accepted_application is false
let old_denied_registrations = registration_application ::table
. filter ( registration_application ::deny_reason . is_not_null ( ) )
. filter ( registration_application ::published . lt ( now ( ) - 1. week ( ) ) )
. select ( registration_application ::local_user_id ) ;
// Delete based on join logic is here:
// https://stackoverflow.com/questions/60836040/how-do-i-perform-a-delete-with-sub-query-in-diesel-against-a-postgres-database
let local_users = local_user ::table
. filter ( local_user ::id . eq_any ( old_denied_registrations ) )
. filter ( not ( local_user ::accepted_application ) )
. select ( local_user ::person_id ) ;
// Delete the person rows, which should automatically clear the local_user ones
let persons = person ::table . filter ( person ::id . eq_any ( local_users ) ) ;
diesel ::delete ( persons ) . execute ( conn ) . await
}
pub async fn is_email_taken ( pool : & mut DbPool < ' _ > , email : & str ) -> Result < bool , Error > {
use diesel ::dsl ::{ exists , select } ;
use diesel ::dsl ::{ exists , select } ;
let conn = & mut get_conn ( pool ) . await ? ;
let conn = & mut get_conn ( pool ) . await ? ;
select ( exists (
select ( exists ( local_user ::table . filter (
local_user . filter ( lower ( coalesce ( email , "" ) ) . eq ( email_ . to_lowercase ( ) ) ) ,
lo wer( coalesce ( local_user :: email , "" ) ) . eq ( email . to_lowercase ( ) ) ,
) )
) ) )
. get_result ( conn )
. get_result ( conn )
. await
. await
}
}
@ -78,7 +104,6 @@ impl LocalUser {
community_follower ,
community_follower ,
instance ,
instance ,
instance_block ,
instance_block ,
person ,
person_block ,
person_block ,
post ,
post ,
post_saved ,
post_saved ,
@ -171,7 +196,7 @@ impl Crud for LocalUser {
hash ( & form . password_encrypted , DEFAULT_COST ) . expect ( "Couldn't hash password" ) ;
hash ( & form . password_encrypted , DEFAULT_COST ) . expect ( "Couldn't hash password" ) ;
form_with_encrypted_password . password_encrypted = password_hash ;
form_with_encrypted_password . password_encrypted = password_hash ;
let local_user_ = insert_into ( local_user )
let local_user_ = insert_into ( local_user ::table )
. values ( form_with_encrypted_password )
. values ( form_with_encrypted_password )
. get_result ::< Self > ( conn )
. get_result ::< Self > ( conn )
. await ? ;
. await ? ;
@ -194,7 +219,7 @@ impl Crud for LocalUser {
form : & Self ::UpdateForm ,
form : & Self ::UpdateForm ,
) -> Result < Self , Error > {
) -> Result < Self , Error > {
let conn = & mut get_conn ( pool ) . await ? ;
let conn = & mut get_conn ( pool ) . await ? ;
diesel ::update ( local_user . find ( local_user_id ) )
diesel ::update ( local_user ::table . find ( local_user_id ) )
. set ( form )
. set ( form )
. get_result ::< Self > ( conn )
. get_result ::< Self > ( conn )
. await
. await