Compare commits
2 commits
main
...
federated-
Author | SHA1 | Date | |
---|---|---|---|
c2adaea5c1 | |||
c986f5961c |
8 changed files with 76 additions and 10 deletions
|
@ -782,9 +782,9 @@ impl Perform for ResolveCommentReport {
|
||||||
let resolved = data.resolved;
|
let resolved = data.resolved;
|
||||||
let resolve_fun = move |conn: &'_ _| {
|
let resolve_fun = move |conn: &'_ _| {
|
||||||
if resolved {
|
if resolved {
|
||||||
CommentReport::resolve(conn, report_id.clone(), user_id)
|
CommentReport::resolve(conn, report_id, user_id)
|
||||||
} else {
|
} else {
|
||||||
CommentReport::unresolve(conn, report_id.clone(), user_id)
|
CommentReport::unresolve(conn, report_id, user_id)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -839,9 +839,9 @@ impl Perform for ResolvePostReport {
|
||||||
let resolved = data.resolved;
|
let resolved = data.resolved;
|
||||||
let resolve_fun = move |conn: &'_ _| {
|
let resolve_fun = move |conn: &'_ _| {
|
||||||
if resolved {
|
if resolved {
|
||||||
PostReport::resolve(conn, report_id.clone(), user_id)
|
PostReport::resolve(conn, report_id, user_id)
|
||||||
} else {
|
} else {
|
||||||
PostReport::unresolve(conn, report_id.clone(), user_id)
|
PostReport::unresolve(conn, report_id, user_id)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use anyhow::Context;
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use captcha::{gen, Difficulty};
|
use captcha::{gen, Difficulty};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use lemmy_apub::ApubObjectType;
|
use lemmy_apub::{ActorType, ApubObjectType};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::*,
|
comment::*,
|
||||||
comment_report::CommentReportView,
|
comment_report::CommentReportView,
|
||||||
|
@ -877,6 +877,9 @@ impl Perform for DeleteAccount {
|
||||||
return Err(APIError::err("password_incorrect").into());
|
return Err(APIError::err("password_incorrect").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send activity to delete user on federated instances
|
||||||
|
user.send_delete(context).await?;
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
|
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
|
||||||
|
@ -890,6 +893,11 @@ impl Perform for DeleteAccount {
|
||||||
return Err(APIError::err("couldnt_update_post").into());
|
return Err(APIError::err("couldnt_update_post").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
User_::delete_account(conn, user_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
Ok(LoginResponse {
|
Ok(LoginResponse {
|
||||||
jwt: data.auth.to_owned(),
|
jwt: data.auth.to_owned(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,13 +5,16 @@ use crate::{
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
activity::{
|
activity::{
|
||||||
kind::{FollowType, UndoType},
|
kind::{DeleteType, FollowType, UndoType},
|
||||||
|
Delete,
|
||||||
Follow,
|
Follow,
|
||||||
Undo,
|
Undo,
|
||||||
},
|
},
|
||||||
base::{AnyBase, BaseExt, ExtendsExt},
|
base::{AnyBase, BaseExt, ExtendsExt},
|
||||||
object::ObjectExt,
|
object::ObjectExt,
|
||||||
|
public,
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
|
@ -105,8 +108,38 @@ impl ActorType for User_ {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
/// The user has deleted their account
|
||||||
unimplemented!()
|
async fn send_delete(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
|
let mut delete = Delete::new(self.actor_id()?, self.actor_id()?);
|
||||||
|
delete
|
||||||
|
.set_context(activitystreams::context())
|
||||||
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
|
.set_to(public())
|
||||||
|
// TODO: who is `cc`? all the communities the user has posted to? our inbox code can only
|
||||||
|
// handle activities for one activity. sending separate activities would work, but
|
||||||
|
// would also create a lot of traffic.
|
||||||
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
|
// TODO: should directly get distinct shared_inboxes from federated communites from db
|
||||||
|
// (once we store that)
|
||||||
|
let distinct_communities = blocking(context.pool(), move |conn| {
|
||||||
|
Community::distinct_federated_communities(conn)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
let shared_inboxes = distinct_communities
|
||||||
|
.iter()
|
||||||
|
.map(|actor_id| Url::parse(actor_id).ok())
|
||||||
|
.flatten()
|
||||||
|
.map(|url| url.host_str().map(|u| u.to_string()))
|
||||||
|
.flatten()
|
||||||
|
.unique()
|
||||||
|
.map(|c| format!("{}/inbox", c))
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
// TODO: maybe we should add a separate function `send_activity_multi_dest()`
|
||||||
|
for s in &shared_inboxes {
|
||||||
|
send_activity_single_dest(delete.to_owned(), self, Url::parse(s)?, context).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
async fn send_undo_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
|
|
|
@ -467,6 +467,7 @@ table! {
|
||||||
public_key -> Nullable<Text>,
|
public_key -> Nullable<Text>,
|
||||||
last_refreshed_at -> Timestamp,
|
last_refreshed_at -> Timestamp,
|
||||||
banner -> Nullable<Text>,
|
banner -> Nullable<Text>,
|
||||||
|
deleted -> Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ pub struct User_ {
|
||||||
pub public_key: Option<String>,
|
pub public_key: Option<String>,
|
||||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
|
pub deleted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset, Clone)]
|
#[derive(Insertable, AsChangeset, Clone)]
|
||||||
|
@ -70,7 +71,10 @@ pub struct UserForm {
|
||||||
|
|
||||||
impl Crud<UserForm> for User_ {
|
impl Crud<UserForm> for User_ {
|
||||||
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
||||||
user_.find(user_id).first::<Self>(conn)
|
user_
|
||||||
|
.filter(deleted.eq(false))
|
||||||
|
.find(user_id)
|
||||||
|
.first::<Self>(conn)
|
||||||
}
|
}
|
||||||
fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
|
fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
|
||||||
diesel::delete(user_.find(user_id)).execute(conn)
|
diesel::delete(user_.find(user_id)).execute(conn)
|
||||||
|
@ -114,6 +118,7 @@ impl User_ {
|
||||||
pub fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<Self, Error> {
|
pub fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<Self, Error> {
|
||||||
user_
|
user_
|
||||||
.filter(local.eq(true))
|
.filter(local.eq(true))
|
||||||
|
.filter(deleted.eq(false))
|
||||||
.filter(name.eq(from_user_name))
|
.filter(name.eq(from_user_name))
|
||||||
.first::<Self>(conn)
|
.first::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
@ -132,7 +137,10 @@ impl User_ {
|
||||||
|
|
||||||
pub fn read_from_actor_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
|
pub fn read_from_actor_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
|
||||||
use crate::schema::user_::dsl::*;
|
use crate::schema::user_::dsl::*;
|
||||||
user_.filter(actor_id.eq(object_id)).first::<Self>(conn)
|
user_
|
||||||
|
.filter(deleted.eq(false))
|
||||||
|
.filter(actor_id.eq(object_id))
|
||||||
|
.first::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_by_email_or_username(
|
pub fn find_by_email_or_username(
|
||||||
|
@ -148,6 +156,7 @@ impl User_ {
|
||||||
|
|
||||||
pub fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error> {
|
pub fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error> {
|
||||||
user_
|
user_
|
||||||
|
.filter(deleted.eq(false))
|
||||||
.filter(local.eq(true))
|
.filter(local.eq(true))
|
||||||
.filter(name.ilike(username))
|
.filter(name.ilike(username))
|
||||||
.first::<User_>(conn)
|
.first::<User_>(conn)
|
||||||
|
@ -155,6 +164,7 @@ impl User_ {
|
||||||
|
|
||||||
pub fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<User_, Error> {
|
pub fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<User_, Error> {
|
||||||
user_
|
user_
|
||||||
|
.filter(deleted.eq(false))
|
||||||
.filter(local.eq(true))
|
.filter(local.eq(true))
|
||||||
.filter(email.eq(from_email))
|
.filter(email.eq(from_email))
|
||||||
.first::<User_>(conn)
|
.first::<User_>(conn)
|
||||||
|
@ -177,6 +187,18 @@ impl User_ {
|
||||||
.set(user_form)
|
.set(user_form)
|
||||||
.get_result::<Self>(conn)
|
.get_result::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_account(conn: &PgConnection, user_id: i32) -> Result<User_, Error> {
|
||||||
|
diesel::update(user_.find(user_id))
|
||||||
|
.set((
|
||||||
|
preferred_username.eq::<Option<String>>(None),
|
||||||
|
email.eq::<Option<String>>(None),
|
||||||
|
matrix_user_id.eq::<Option<String>>(None),
|
||||||
|
deleted.eq(true),
|
||||||
|
updated.eq(naive_now()),
|
||||||
|
))
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
1
migrations/2020-11-26-134531_delete_user/down.sql
Normal file
1
migrations/2020-11-26-134531_delete_user/down.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE user_ DROP COLUMN deleted;
|
1
migrations/2020-11-26-134531_delete_user/up.sql
Normal file
1
migrations/2020-11-26-134531_delete_user/up.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE user_ ADD COLUMN deleted BOOLEAN DEFAULT FALSE NOT NULL;
|
Loading…
Reference in a new issue