Federate user deletion (#551)

* Federate user deletion

- When someone deletes their account
- When a local user is banned

Fixes #509

* cargo fmt
fix-mobile-margin
Baptiste Gelez 5 years ago committed by GitHub
parent 85aa0883c8
commit 787eb7f399
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

26
Cargo.lock generated

@ -1777,7 +1777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plume"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1797,9 +1797,9 @@ dependencies = [
"lettre_email 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)",
"multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plume-api 0.2.0",
"plume-common 0.2.0",
"plume-models 0.2.0",
"plume-api 0.3.0",
"plume-common 0.3.0",
"plume-models 0.3.0",
"rocket 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_contrib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=4a72ea2ec716cb0b26188fb00bccf2ef7d1e031c)",
@ -1819,7 +1819,7 @@ dependencies = [
[[package]]
name = "plume-api"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"canapi 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1828,18 +1828,18 @@ dependencies = [
[[package]]
name = "plume-cli"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plume-models 0.2.0",
"plume-models 0.3.0",
"rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "plume-common"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1861,7 +1861,7 @@ dependencies = [
[[package]]
name = "plume-front"
version = "0.1.0"
version = "0.3.0"
dependencies = [
"gettext 0.3.0 (git+https://github.com/Plume-org/gettext/?rev=294c54d74c699fbc66502b480a37cc66c1daa7f3)",
"gettext-macros 0.4.0 (git+https://github.com/Plume-org/gettext-macros/?rev=a7c605f7edd6bfbfbfe7778026bfefd88d82db10)",
@ -1872,7 +1872,7 @@ dependencies = [
[[package]]
name = "plume-models"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ammonia 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1885,10 +1885,10 @@ dependencies = [
"guid-create 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)",
"plume-api 0.2.0",
"plume-common 0.2.0",
"plume-api 0.3.0",
"plume-common 0.3.0",
"reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_i18n 0.4.0 (git+https://github.com/Plume-org/rocket_i18n?rev=e922afa7c366038b3433278c03b1456b346074f2)",

@ -53,6 +53,7 @@ pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result<InboxResult, E
.with::<User, Create, Post>()
.with::<User, Delete, Comment>()
.with::<User, Delete, Post>()
.with::<User, Delete, User>()
.with::<User, Follow, User>()
.with::<User, Like, Post>()
.with::<User, Undo, Reshare>()
@ -286,6 +287,34 @@ pub(crate) mod tests {
});
}
#[test]
fn delete_user() {
let r = rockets();
let conn = &*r.conn;
conn.test_transaction::<_, (), _>(|| {
let (_, users, _) = fill_database(&r);
let fail_act = json!({
"id": "https://plu.me/@/Admin#delete",
"actor": users[1].ap_url, // Not the same account
"object": users[0].ap_url,
"type": "Delete",
});
assert!(super::inbox(&r, fail_act).is_err());
let ok_act = json!({
"id": "https://plu.me/@/Admin#delete",
"actor": users[0].ap_url,
"object": users[0].ap_url,
"type": "Delete",
});
assert!(super::inbox(&r, ok_act).is_ok());
assert!(crate::users::User::get(conn, users[0].id).is_err());
Ok(())
});
}
#[test]
fn follow() {
let r = rockets();

@ -1,5 +1,9 @@
use activitypub::{
actor::Person, collection::OrderedCollection, object::Image, Activity, CustomObject, Endpoint,
activity::Delete,
actor::Person,
collection::OrderedCollection,
object::{Image, Tombstone},
Activity, CustomObject, Endpoint,
};
use bcrypt;
use chrono::{NaiveDateTime, Utc};
@ -12,9 +16,9 @@ use openssl::{
};
use plume_common::activity_pub::{
ap_accept_header,
inbox::{AsActor, FromId},
inbox::{AsActor, AsObject, FromId},
sign::{gen_keypair, Signer},
ActivityStream, ApSignature, Id, IntoId, PublicKey,
ActivityStream, ApSignature, Id, IntoId, PublicKey, PUBLIC_VISIBILITY,
};
use plume_common::utils;
use reqwest::{
@ -632,6 +636,29 @@ impl User {
Ok(CustomPerson::new(actor, ap_signature))
}
pub fn delete_activity(&self, conn: &Connection) -> Result<Delete> {
let mut del = Delete::default();
let mut tombstone = Tombstone::default();
tombstone.object_props.set_id_string(self.ap_url.clone())?;
del.delete_props
.set_actor_link(Id::new(self.ap_url.clone()))?;
del.delete_props.set_object_object(tombstone)?;
del.object_props
.set_id_string(format!("{}#delete", self.ap_url))?;
del.object_props
.set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?;
del.object_props.set_cc_link_vec(
self.get_followers(conn)?
.into_iter()
.map(|f| Id::new(f.ap_url))
.collect(),
)?;
Ok(del)
}
pub fn avatar_url(&self, conn: &Connection) -> String {
self.avatar_id
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
@ -832,6 +859,19 @@ impl AsActor<&PlumeRocket> for User {
}
}
impl AsObject<User, Delete, &PlumeRocket> for User {
type Error = Error;
type Output = ();
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
if self.id == actor.id {
self.delete(&c.conn, &c.searcher).map(|_| ())
} else {
Err(Error::Unauthorized)
}
}
}
impl Signer for User {
type Error = Error;

@ -265,10 +265,10 @@ msgid "Follow {}"
msgstr "اتبع"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "قم بتسجيل الدخول قصد مشاركته"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -262,10 +262,10 @@ msgstr "Писти Pluma {0}"
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -262,10 +262,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,12 @@ msgstr "Beží na Plume {0}"
msgid "Follow {}"
msgstr "Následovat {}"
msgid "Login to follow"
#, fuzzy
msgid "Log in to follow"
msgstr "Pro následování se přihlášte"
msgid "Enter your full username to follow"
#, fuzzy
msgid "Enter your full username handle to follow"
msgstr "Pro následovaní zadejte své úplné uživatelské jméno"
msgid "Edit your account"

@ -264,10 +264,10 @@ msgid "Follow {}"
msgstr "Folgen"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Um zu boosten, musst du eingeloggt sein"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -262,10 +262,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -262,10 +262,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,10 @@ msgid "Follow {}"
msgstr "Seguir"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Dejar de seguir"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -265,10 +265,10 @@ msgid "Follow {}"
msgstr "Sabonner"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Connectez-vous pour partager"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -265,10 +265,10 @@ msgid "Follow {}"
msgstr "Seguir"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Conéctese para promover"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,10 @@ msgstr "Plume {0} का इस्तेमाल कर रहे हैं"
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -263,10 +263,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,10 @@ msgid "Follow {}"
msgstr "Segui"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Accedi per boostare"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -267,10 +267,10 @@ msgid "Follow {}"
msgstr "フォロー"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "ブーストするにはログインしてください"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -274,10 +274,10 @@ msgid "Follow {}"
msgstr "Følg"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Logg inn"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,11 @@ msgstr "Działa na Plume {0}"
msgid "Follow {}"
msgstr "Obserwuj {}"
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
#, fuzzy
msgid "Enter your full username handle to follow"
msgstr "Wpisz swoją pełną nazwę użytkownika, do naśladowania"
msgid "Edit your account"

@ -256,10 +256,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -266,10 +266,10 @@ msgid "Follow {}"
msgstr "Seguir"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Entrar para gostar"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -263,10 +263,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -266,10 +266,10 @@ msgid "Follow {}"
msgstr "Подписаться"
#, fuzzy
msgid "Login to follow"
msgid "Log in to follow"
msgstr "Войдите, чтобы продвигать посты"
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -264,10 +264,12 @@ msgstr "Beží na Plume {0}"
msgid "Follow {}"
msgstr "Následuj {}"
msgid "Login to follow"
#, fuzzy
msgid "Log in to follow"
msgstr "Pre následovanie sa prihlás"
msgid "Enter your full username to follow"
#, fuzzy
msgid "Enter your full username handle to follow"
msgstr "Zadaj svoju prezývku v úplnosti, aby si následoval/a"
msgid "Edit your account"

@ -263,10 +263,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -262,10 +262,10 @@ msgstr ""
msgid "Follow {}"
msgstr ""
msgid "Login to follow"
msgid "Log in to follow"
msgstr ""
msgid "Enter your full username to follow"
msgid "Enter your full username handle to follow"
msgstr ""
msgid "Edit your account"

@ -8,14 +8,13 @@ use serde_json;
use validator::{Validate, ValidationErrors};
use inbox;
use plume_common::activity_pub::inbox::FromId;
use plume_common::activity_pub::{broadcast, inbox::FromId};
use plume_models::{
admin::Admin, comments::Comment, db_conn::DbConn, headers::Headers, instance::*, posts::Post,
safe_string::SafeString, users::User, Error, PlumeRocket, CONFIG,
};
use routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page};
use template_utils::Ructe;
use Searcher;
#[get("/")]
pub fn index(conn: DbConn, user: Option<User>, intl: I18n) -> Result<Ructe, ErrorPage> {
@ -197,14 +196,20 @@ pub fn admin_users(
}
#[post("/admin/users/<id>/ban")]
pub fn ban(
_admin: Admin,
conn: DbConn,
id: i32,
searcher: Searcher,
) -> Result<Redirect, ErrorPage> {
if let Ok(u) = User::get(&*conn, id) {
u.delete(&*conn, &searcher)?;
pub fn ban(_admin: Admin, id: i32, rockets: PlumeRocket) -> Result<Redirect, ErrorPage> {
if let Ok(u) = User::get(&*rockets.conn, id) {
u.delete(&*rockets.conn, &rockets.searcher)?;
if Instance::get_local(&*rockets.conn)
.map(|i| u.instance_id == i.id)
.unwrap_or(false)
{
let target = User::one_by_instance(&*rockets.conn)?;
let delete_act = u.delete_activity(&*rockets.conn)?;
rockets
.worker
.execute(move || broadcast(&u, delete_act, target));
}
}
Ok(Redirect::to(uri!(admin_users: page = _)))
}

@ -394,6 +394,12 @@ pub fn delete(
if user.id == account.id {
account.delete(&*rockets.conn, &rockets.searcher)?;
let target = User::one_by_instance(&*rockets.conn)?;
let delete_act = account.delete_activity(&*rockets.conn)?;
rockets
.worker
.execute(move || broadcast(&account, delete_act, target));
if let Some(cookie) = cookies.get_private(AUTH_COOKIE) {
cookies.remove_private(cookie);
}

Loading…
Cancel
Save