Federate user deletion (#551)
* Federate user deletion - When someone deletes their account - When a local user is banned Fixes #509 * cargo fmt
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user