mirror of
https://github.com/LemmyNet/lemmy
synced 2024-11-14 00:37:07 +00:00
* Deleting denied local_users older than a week. Fixes #4434 * Addressing PR comments. * Upping rust to 1.76 * Delete the person rows also.
This commit is contained in:
parent
3f7cc07b02
commit
890565ca14
4 changed files with 82 additions and 48 deletions
|
@ -2,7 +2,7 @@
|
||||||
# See https://github.com/woodpecker-ci/woodpecker/issues/1677
|
# See https://github.com/woodpecker-ci/woodpecker/issues/1677
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
- &rust_image "rust:1.75"
|
- &rust_image "rust:1.76"
|
||||||
- &install_pnpm "corepack enable pnpm"
|
- &install_pnpm "corepack enable pnpm"
|
||||||
- &slow_check_paths
|
- &slow_check_paths
|
||||||
- path:
|
- path:
|
||||||
|
|
|
@ -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())),
|
lower(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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# syntax=docker/dockerfile:1.6
|
# syntax=docker/dockerfile:1.6
|
||||||
ARG RUST_VERSION=1.75
|
ARG RUST_VERSION=1.76
|
||||||
ARG CARGO_BUILD_FEATURES=default
|
ARG CARGO_BUILD_FEATURES=default
|
||||||
ARG RUST_RELEASE_MODE=debug
|
ARG RUST_RELEASE_MODE=debug
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,10 @@ use lemmy_db_schema::{
|
||||||
received_activity,
|
received_activity,
|
||||||
sent_activity,
|
sent_activity,
|
||||||
},
|
},
|
||||||
source::instance::{Instance, InstanceForm},
|
source::{
|
||||||
|
instance::{Instance, InstanceForm},
|
||||||
|
local_user::LocalUser,
|
||||||
|
},
|
||||||
utils::{get_conn, naive_now, now, DbPool, DELETED_REPLACEMENT_TEXT},
|
utils::{get_conn, naive_now, now, DbPool, DELETED_REPLACEMENT_TEXT},
|
||||||
};
|
};
|
||||||
use lemmy_routes::nodeinfo::NodeInfo;
|
use lemmy_routes::nodeinfo::NodeInfo;
|
||||||
|
@ -79,24 +82,19 @@ pub async fn setup(context: LemmyContext) -> Result<(), LemmyError> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let context_1 = context.clone();
|
let context_1 = context.clone();
|
||||||
// Overwrite deleted & removed posts and comments every day
|
// Daily tasks:
|
||||||
|
// - Overwrite deleted & removed posts and comments every day
|
||||||
|
// - Delete old denied users
|
||||||
|
// - Update instance software
|
||||||
scheduler.every(CTimeUnits::days(1)).run(move || {
|
scheduler.every(CTimeUnits::days(1)).run(move || {
|
||||||
let context = context_1.clone();
|
let context = context_1.clone();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
overwrite_deleted_posts_and_comments(&mut context.pool()).await;
|
overwrite_deleted_posts_and_comments(&mut context.pool()).await;
|
||||||
}
|
delete_old_denied_users(&mut context.pool()).await;
|
||||||
});
|
|
||||||
|
|
||||||
let context_1 = context.clone();
|
|
||||||
// Update the Instance Software
|
|
||||||
scheduler.every(CTimeUnits::days(1)).run(move || {
|
|
||||||
let context = context_1.clone();
|
|
||||||
|
|
||||||
async move {
|
|
||||||
update_instance_software(&mut context.pool(), context.client())
|
update_instance_software(&mut context.pool(), context.client())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| warn!("Failed to update instance software: {e}"))
|
.inspect_err(|e| warn!("Failed to update instance software: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -115,6 +113,7 @@ async fn startup_jobs(pool: &mut DbPool<'_>) {
|
||||||
update_banned_when_expired(pool).await;
|
update_banned_when_expired(pool).await;
|
||||||
clear_old_activities(pool).await;
|
clear_old_activities(pool).await;
|
||||||
overwrite_deleted_posts_and_comments(pool).await;
|
overwrite_deleted_posts_and_comments(pool).await;
|
||||||
|
delete_old_denied_users(pool).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the hot_rank columns for the aggregates tables
|
/// Update the hot_rank columns for the aggregates tables
|
||||||
|
@ -277,10 +276,10 @@ async fn delete_expired_captcha_answers(pool: &mut DbPool<'_>) {
|
||||||
)
|
)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map(|_| {
|
.inspect(|_| {
|
||||||
info!("Done.");
|
info!("Done.");
|
||||||
})
|
})
|
||||||
.map_err(|e| error!("Failed to clear old captcha answers: {e}"))
|
.inspect_err(|e| error!("Failed to clear old captcha answers: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -301,7 +300,7 @@ async fn clear_old_activities(pool: &mut DbPool<'_>) {
|
||||||
)
|
)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Failed to clear old sent activities: {e}"))
|
.inspect_err(|e| error!("Failed to clear old sent activities: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
diesel::delete(
|
diesel::delete(
|
||||||
|
@ -310,8 +309,8 @@ async fn clear_old_activities(pool: &mut DbPool<'_>) {
|
||||||
)
|
)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map(|_| info!("Done."))
|
.inspect(|_| info!("Done."))
|
||||||
.map_err(|e| error!("Failed to clear old received activities: {e}"))
|
.inspect_err(|e| error!("Failed to clear old received activities: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -320,6 +319,16 @@ async fn clear_old_activities(pool: &mut DbPool<'_>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn delete_old_denied_users(pool: &mut DbPool<'_>) {
|
||||||
|
LocalUser::delete_old_denied_local_users(pool)
|
||||||
|
.await
|
||||||
|
.inspect(|_| {
|
||||||
|
info!("Done.");
|
||||||
|
})
|
||||||
|
.inspect(|e| error!("Failed to deleted old denied users: {e}"))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
/// overwrite posts and comments 30d after deletion
|
/// overwrite posts and comments 30d after deletion
|
||||||
async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) {
|
async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) {
|
||||||
info!("Overwriting deleted posts...");
|
info!("Overwriting deleted posts...");
|
||||||
|
@ -339,10 +348,10 @@ async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) {
|
||||||
))
|
))
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map(|_| {
|
.inspect(|_| {
|
||||||
info!("Done.");
|
info!("Done.");
|
||||||
})
|
})
|
||||||
.map_err(|e| error!("Failed to overwrite deleted posts: {e}"))
|
.inspect_err(|e| error!("Failed to overwrite deleted posts: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
info!("Overwriting deleted comments...");
|
info!("Overwriting deleted comments...");
|
||||||
|
@ -355,10 +364,10 @@ async fn overwrite_deleted_posts_and_comments(pool: &mut DbPool<'_>) {
|
||||||
.set(comment::content.eq(DELETED_REPLACEMENT_TEXT))
|
.set(comment::content.eq(DELETED_REPLACEMENT_TEXT))
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map(|_| {
|
.inspect(|_| {
|
||||||
info!("Done.");
|
info!("Done.");
|
||||||
})
|
})
|
||||||
.map_err(|e| error!("Failed to overwrite deleted comments: {e}"))
|
.inspect_err(|e| error!("Failed to overwrite deleted comments: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -390,14 +399,14 @@ async fn active_counts(pool: &mut DbPool<'_>) {
|
||||||
sql_query(update_site_stmt)
|
sql_query(update_site_stmt)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Failed to update site stats: {e}"))
|
.inspect_err(|e| error!("Failed to update site stats: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
let update_community_stmt = format!("update community_aggregates ca set users_active_{} = mv.count_ from community_aggregates_activity('{}') mv where ca.community_id = mv.community_id_", i.1, i.0);
|
let update_community_stmt = format!("update community_aggregates ca set users_active_{} = mv.count_ from community_aggregates_activity('{}') mv where ca.community_id = mv.community_id_", i.1, i.0);
|
||||||
sql_query(update_community_stmt)
|
sql_query(update_community_stmt)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Failed to update community stats: {e}"))
|
.inspect_err(|e| error!("Failed to update community stats: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +433,7 @@ async fn update_banned_when_expired(pool: &mut DbPool<'_>) {
|
||||||
.set(person::banned.eq(false))
|
.set(person::banned.eq(false))
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Failed to update person.banned when expires: {e}"))
|
.inspect_err(|e| error!("Failed to update person.banned when expires: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
diesel::delete(
|
diesel::delete(
|
||||||
|
@ -432,7 +441,7 @@ async fn update_banned_when_expired(pool: &mut DbPool<'_>) {
|
||||||
)
|
)
|
||||||
.execute(&mut conn)
|
.execute(&mut conn)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error!("Failed to remove community_ban expired rows: {e}"))
|
.inspect_err(|e| error!("Failed to remove community_ban expired rows: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
Loading…
Reference in a new issue