fix: delete user follows when deleting user

This commit is contained in:
trisua 2025-04-17 21:48:45 -04:00
parent f161e0b176
commit bc57782bfe
5 changed files with 79 additions and 15 deletions

View file

@ -20,7 +20,7 @@ pub async fn follow_request(
if let Ok(userfollow) = data.get_userfollow_by_initiator_receiver(user.id, id).await {
// delete
match data.delete_userfollow(userfollow.id, &user).await {
match data.delete_userfollow(userfollow.id, &user, false).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "User unfollowed".to_string(),
@ -164,7 +164,7 @@ pub async fn block_request(
if let Ok(userfollow) = data.get_userfollow_by_initiator_receiver(user.id, id).await
{
// automatically unfollow
match data.delete_userfollow(userfollow.id, &user).await {
match data.delete_userfollow(userfollow.id, &user, false).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "User blocked".to_string(),
@ -176,7 +176,7 @@ pub async fn block_request(
data.get_userfollow_by_receiver_initiator(user.id, id).await
{
// automatically unfollow
match data.delete_userfollow(userfollow.id, &user).await {
match data.delete_userfollow(userfollow.id, &user, false).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "User blocked".to_string(),

View file

@ -226,6 +226,39 @@ impl DataManager {
return Err(Error::DatabaseError(e.to_string()));
}
// delete requests
let res = execute!(
&conn,
"DELETE FROM requests WHERE owner = $1",
&[&(id as i64)]
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
// delete warnings
let res = execute!(
&conn,
"DELETE FROM user_warnings WHERE receiver = $1",
&[&(id as i64)]
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
// delete blocks
let res = execute!(
&conn,
"DELETE FROM userblocks WHERE initiator = $1 OR receiver = $1",
&[&(id as i64)]
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
// delete reactions
// reactions counts will remain the same :)
let res = execute!(
@ -245,6 +278,15 @@ impl DataManager {
return Err(Error::DatabaseError(e.to_string()));
}
// delete user follows... individually since it requires updating user counts
for follow in self.get_userfollows_by_receiver_all(id).await? {
self.delete_userfollow(follow.id, &user, true).await?;
}
for follow in self.get_userfollows_by_initiator_all(id).await? {
self.delete_userfollow(follow.id, &user, true).await?;
}
// remove images
let avatar = PathBufD::current().extend(&[
self.0.dirs.media.as_str(),

View file

@ -26,7 +26,7 @@ impl DataManager {
}
}
auto_method!(get_user_warning_by_ip(&str)@get_user_warning_from_row -> "SELECT * FROM user_warning WHERE ip = $1" --name="user warning" --returns=UserWarning --cache-key-tmpl="atto.user_warning:{}");
auto_method!(get_user_warning_by_ip(&str)@get_user_warning_from_row -> "SELECT * FROM user_warnings WHERE ip = $1" --name="user warning" --returns=UserWarning --cache-key-tmpl="atto.user_warning:{}");
/// Get all user warnings by user (paginated).
///

View file

@ -196,7 +196,13 @@ impl DataManager {
for userfollow in userfollows {
let receiver = userfollow.receiver;
out.push((userfollow, self.get_user_by_id(receiver).await?));
out.push((
userfollow,
match self.get_user_by_id(receiver).await {
Ok(u) => u,
Err(_) => continue,
},
));
}
Ok(out)
@ -211,7 +217,13 @@ impl DataManager {
for userfollow in userfollows {
let initiator = userfollow.initiator;
out.push((userfollow, self.get_user_by_id(initiator).await?));
out.push((
userfollow,
match self.get_user_by_id(initiator).await {
Ok(u) => u,
Err(_) => continue,
},
));
}
Ok(out)
@ -272,12 +284,18 @@ impl DataManager {
Ok(FollowResult::Followed)
}
pub async fn delete_userfollow(&self, id: usize, user: &User) -> Result<()> {
pub async fn delete_userfollow(
&self,
id: usize,
user: &User,
is_deleting_user: bool,
) -> Result<()> {
let follow = self.get_userfollow_by_id(id).await?;
if (user.id != follow.initiator)
&& (user.id != follow.receiver)
&& !user.permissions.check(FinePermission::MANAGE_FOLLOWS)
&& !is_deleting_user
{
return Err(Error::NotAllowed);
}
@ -299,14 +317,18 @@ impl DataManager {
self.2.remove(format!("atto.userfollow:{}", id)).await;
// decr counts
self.decr_user_following_count(follow.initiator)
.await
.unwrap();
// decr counts (if we aren't deleting the user OR the user id isn't the deleted user id)
if !is_deleting_user | (follow.initiator != user.id) {
self.decr_user_following_count(follow.initiator)
.await
.unwrap();
}
self.decr_user_follower_count(follow.receiver)
.await
.unwrap();
if !is_deleting_user | (follow.receiver != user.id) {
self.decr_user_follower_count(follow.receiver)
.await
.unwrap();
}
// return
Ok(())

View file

@ -299,7 +299,7 @@ impl Notification {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub struct UserFollow {
pub id: usize,
pub created: usize,