From 787eb7f3992e43e7a149288f3378c90dd4fe4bf8 Mon Sep 17 00:00:00 2001 From: Baptiste Gelez Date: Sun, 28 Apr 2019 18:01:41 +0100 Subject: [PATCH] Federate user deletion (#551) * Federate user deletion - When someone deletes their account - When a local user is banned Fixes #509 * cargo fmt --- Cargo.lock | 26 +++++++++++----------- plume-models/src/inbox.rs | 29 ++++++++++++++++++++++++ plume-models/src/users.rs | 46 ++++++++++++++++++++++++++++++++++++--- po/plume/ar.po | 4 ++-- po/plume/bg.po | 4 ++-- po/plume/ca.po | 4 ++-- po/plume/cs.po | 6 +++-- po/plume/de.po | 4 ++-- po/plume/en.po | 4 ++-- po/plume/eo.po | 4 ++-- po/plume/es.po | 4 ++-- po/plume/fr.po | 4 ++-- po/plume/gl.po | 4 ++-- po/plume/hi.po | 4 ++-- po/plume/hr.po | 4 ++-- po/plume/it.po | 4 ++-- po/plume/ja.po | 4 ++-- po/plume/nb.po | 4 ++-- po/plume/pl.po | 5 +++-- po/plume/plume.pot | 4 ++-- po/plume/pt.po | 4 ++-- po/plume/ro.po | 4 ++-- po/plume/ru.po | 4 ++-- po/plume/sk.po | 6 +++-- po/plume/sr.po | 4 ++-- po/plume/sv.po | 4 ++-- src/routes/instance.rs | 25 ++++++++++++--------- src/routes/user.rs | 6 +++++ 28 files changed, 157 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c6357a..037deb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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)", diff --git a/plume-models/src/inbox.rs b/plume-models/src/inbox.rs index adcdb77..56758ed 100644 --- a/plume-models/src/inbox.rs +++ b/plume-models/src/inbox.rs @@ -53,6 +53,7 @@ pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result() .with::() .with::() + .with::() .with::() .with::() .with::() @@ -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(); diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 2d44dcc..098da31 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -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 { + 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 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; diff --git a/po/plume/ar.po b/po/plume/ar.po index c8cba9e..ccf949c 100644 --- a/po/plume/ar.po +++ b/po/plume/ar.po @@ -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" diff --git a/po/plume/bg.po b/po/plume/bg.po index df34776..494c7f8 100644 --- a/po/plume/bg.po +++ b/po/plume/bg.po @@ -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" diff --git a/po/plume/ca.po b/po/plume/ca.po index 2dc59ca..5fac995 100644 --- a/po/plume/ca.po +++ b/po/plume/ca.po @@ -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" diff --git a/po/plume/cs.po b/po/plume/cs.po index f604d99..19bbcca 100644 --- a/po/plume/cs.po +++ b/po/plume/cs.po @@ -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" diff --git a/po/plume/de.po b/po/plume/de.po index 75921f4..a88425f 100644 --- a/po/plume/de.po +++ b/po/plume/de.po @@ -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" diff --git a/po/plume/en.po b/po/plume/en.po index b985cae..eb62313 100644 --- a/po/plume/en.po +++ b/po/plume/en.po @@ -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" diff --git a/po/plume/eo.po b/po/plume/eo.po index 9df5ca1..d444f47 100644 --- a/po/plume/eo.po +++ b/po/plume/eo.po @@ -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" diff --git a/po/plume/es.po b/po/plume/es.po index 653301f..87beeb7 100644 --- a/po/plume/es.po +++ b/po/plume/es.po @@ -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" diff --git a/po/plume/fr.po b/po/plume/fr.po index 5145485..b0a8a0b 100644 --- a/po/plume/fr.po +++ b/po/plume/fr.po @@ -265,10 +265,10 @@ msgid "Follow {}" msgstr "S’abonner" #, 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" diff --git a/po/plume/gl.po b/po/plume/gl.po index 5ba05f2..68e0f42 100644 --- a/po/plume/gl.po +++ b/po/plume/gl.po @@ -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" diff --git a/po/plume/hi.po b/po/plume/hi.po index be5ec8d..3109b81 100644 --- a/po/plume/hi.po +++ b/po/plume/hi.po @@ -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" diff --git a/po/plume/hr.po b/po/plume/hr.po index a037dc7..fec23c5 100644 --- a/po/plume/hr.po +++ b/po/plume/hr.po @@ -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" diff --git a/po/plume/it.po b/po/plume/it.po index 223934e..e51927c 100644 --- a/po/plume/it.po +++ b/po/plume/it.po @@ -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" diff --git a/po/plume/ja.po b/po/plume/ja.po index 96b916c..c312c72 100644 --- a/po/plume/ja.po +++ b/po/plume/ja.po @@ -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" diff --git a/po/plume/nb.po b/po/plume/nb.po index 486f935..a0c428b 100644 --- a/po/plume/nb.po +++ b/po/plume/nb.po @@ -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" diff --git a/po/plume/pl.po b/po/plume/pl.po index b15fabf..682ebc3 100644 --- a/po/plume/pl.po +++ b/po/plume/pl.po @@ -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" diff --git a/po/plume/plume.pot b/po/plume/plume.pot index cf375e7..d9d10d7 100644 --- a/po/plume/plume.pot +++ b/po/plume/plume.pot @@ -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" diff --git a/po/plume/pt.po b/po/plume/pt.po index f51c5c0..97cfc0c 100644 --- a/po/plume/pt.po +++ b/po/plume/pt.po @@ -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" diff --git a/po/plume/ro.po b/po/plume/ro.po index 9226d07..6303b57 100644 --- a/po/plume/ro.po +++ b/po/plume/ro.po @@ -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" diff --git a/po/plume/ru.po b/po/plume/ru.po index 4a747a0..59e9516 100644 --- a/po/plume/ru.po +++ b/po/plume/ru.po @@ -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" diff --git a/po/plume/sk.po b/po/plume/sk.po index 2adf850..3946487 100644 --- a/po/plume/sk.po +++ b/po/plume/sk.po @@ -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" diff --git a/po/plume/sr.po b/po/plume/sr.po index 686cb70..a40889e 100644 --- a/po/plume/sr.po +++ b/po/plume/sr.po @@ -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" diff --git a/po/plume/sv.po b/po/plume/sv.po index 348258d..4a5c136 100644 --- a/po/plume/sv.po +++ b/po/plume/sv.po @@ -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" diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 2b8823f..240f092 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -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, intl: I18n) -> Result { @@ -197,14 +196,20 @@ pub fn admin_users( } #[post("/admin/users//ban")] -pub fn ban( - _admin: Admin, - conn: DbConn, - id: i32, - searcher: Searcher, -) -> Result { - if let Ok(u) = User::get(&*conn, id) { - u.delete(&*conn, &searcher)?; +pub fn ban(_admin: Admin, id: i32, rockets: PlumeRocket) -> Result { + 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 = _))) } diff --git a/src/routes/user.rs b/src/routes/user.rs index dbc9534..ae2aaa4 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -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); }