diff options
author | Felix <me@nutomic.com> | 2020-04-29 16:51:25 +0200 |
---|---|---|
committer | Felix <me@nutomic.com> | 2020-04-29 16:51:25 +0200 |
commit | c43f06124a00f3af8559d849541c2b84d3383f13 (patch) | |
tree | 0f850596a52cdfa77bff0eb620056432558af8b0 /server/src/apub | |
parent | 0c0c68398609d549a757a9c3a26ce2311075fa38 (diff) |
Address comments, implement delete for posts and comments
Diffstat (limited to 'server/src/apub')
-rw-r--r-- | server/src/apub/comment.rs | 46 | ||||
-rw-r--r-- | server/src/apub/community.rs | 36 | ||||
-rw-r--r-- | server/src/apub/mod.rs | 58 | ||||
-rw-r--r-- | server/src/apub/post.rs | 50 | ||||
-rw-r--r-- | server/src/apub/shared_inbox.rs | 1 | ||||
-rw-r--r-- | server/src/apub/user.rs | 6 |
6 files changed, 140 insertions, 57 deletions
diff --git a/server/src/apub/comment.rs b/server/src/apub/comment.rs index 9fa5731b..4a5f18b7 100644 --- a/server/src/apub/comment.rs +++ b/server/src/apub/comment.rs @@ -3,7 +3,7 @@ use super::*; impl ToApub for Comment { type Response = Note; - fn to_apub(&self, conn: &PgConnection) -> Result<ResponseOrTombstone<Note>, Error> { + fn to_apub(&self, conn: &PgConnection) -> Result<Note, Error> { let mut comment = Note::default(); let oprops: &mut ObjectProperties = comment.as_mut(); let creator = User_::read(&conn, self.creator_id)?; @@ -33,7 +33,13 @@ impl ToApub for Comment { oprops.set_updated(convert_datetime(u))?; } - Ok(ResponseOrTombstone::Response(comment)) + Ok(comment) + } +} + +impl ToTombstone for Comment { + fn to_tombstone(&self) -> Result<Tombstone, Error> { + create_tombstone(self.deleted, &self.ap_id, self.published, self.updated) } } @@ -102,7 +108,7 @@ impl ApubObjectType for Comment { create .create_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(note.as_response()?.to_owned())?; + .set_object_base_box(note)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -138,7 +144,7 @@ impl ApubObjectType for Comment { update .update_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(note.as_response()?.to_owned())?; + .set_object_base_box(note)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -157,6 +163,34 @@ impl ApubObjectType for Comment { )?; Ok(()) } + + // TODO: this code is literally copied from post.rs + fn send_delete(&self, actor: &User_, conn: &PgConnection) -> Result<(), Error> { + let mut delete = Delete::default(); + delete + .delete_props + .set_actor_xsd_any_uri(actor.actor_id.to_owned())? + .set_object_base_box(BaseBox::from_concrete(self.to_tombstone()?)?)?; + + // Insert the sent activity into the activity table + let activity_form = activity::ActivityForm { + user_id: self.creator_id, + data: serde_json::to_value(&delete)?, + local: true, + updated: None, + }; + activity::Activity::create(&conn, &activity_form)?; + + let post = Post::read(conn, self.post_id)?; + let community = Community::read(conn, post.community_id)?; + send_activity( + &delete, + &actor.private_key.to_owned().unwrap(), + &actor.actor_id, + community.get_follower_inboxes(&conn)?, + )?; + Ok(()) + } } impl ApubLikeableType for Comment { @@ -171,7 +205,7 @@ impl ApubLikeableType for Comment { like .like_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(note.as_response()?.to_owned())?; + .set_object_base_box(note)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -206,7 +240,7 @@ impl ApubLikeableType for Comment { dislike .dislike_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(note.as_response()?.to_owned())?; + .set_object_base_box(note)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index ee319995..36e33c89 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -9,17 +9,7 @@ impl ToApub for Community { type Response = GroupExt; // Turn a Lemmy Community into an ActivityPub group that can be sent out over the network. - fn to_apub(&self, conn: &PgConnection) -> Result<ResponseOrTombstone<GroupExt>, Error> { - if self.deleted || self.removed { - let mut tombstone = Tombstone::default(); - // TODO: might want to include updated/deleted times as well - tombstone - .object_props - .set_id(self.actor_id.to_owned())? - .set_published(convert_datetime(self.published))?; - return Ok(ResponseOrTombstone::Tombstone(Box::new(tombstone))); - } - + fn to_apub(&self, conn: &PgConnection) -> Result<GroupExt, Error> { let mut group = Group::default(); let oprops: &mut ObjectProperties = group.as_mut(); @@ -53,9 +43,13 @@ impl ToApub for Community { .set_endpoints(endpoint_props)? .set_followers(self.get_followers_url())?; - Ok(ResponseOrTombstone::Response( - group.extend(actor_props).extend(self.get_public_key_ext()), - )) + Ok(group.extend(actor_props).extend(self.get_public_key_ext())) + } +} + +impl ToTombstone for Community { + fn to_tombstone(&self) -> Result<Tombstone, Error> { + create_tombstone(self.deleted, &self.actor_id, self.published, self.updated) } } @@ -107,14 +101,11 @@ impl ActorType for Community { } fn send_delete(&self, conn: &PgConnection) -> Result<(), Error> { - let community = self.to_apub(conn)?; let mut delete = Delete::default(); delete .delete_props .set_actor_xsd_any_uri(self.actor_id.to_owned())? - .set_object_base_box(BaseBox::from_concrete( - community.as_tombstone()?.to_owned(), - )?)?; + .set_object_base_box(BaseBox::from_concrete(self.to_tombstone()?)?)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -208,8 +199,13 @@ pub async fn get_apub_community_http( db: DbPoolParam, ) -> Result<HttpResponse<Body>, Error> { let community = Community::read_from_name(&&db.get()?, &info.community_name)?; - let c = community.to_apub(&db.get().unwrap())?; - Ok(create_apub_response(&c)) + if !community.deleted { + Ok(create_apub_response( + &community.to_apub(&db.get().unwrap())?, + )) + } else { + Ok(create_apub_tombstone_response(&community.to_tombstone()?)) + } } /// Returns an empty followers collection, only populating the siz (for privacy). diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index 9232c2d7..9d312cc3 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -60,6 +60,7 @@ use crate::websocket::{ use crate::{convert_datetime, naive_now, Settings}; use activities::{populate_object_props, send_activity}; +use chrono::NaiveDateTime; use fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}; use signatures::verify; use signatures::{sign, PublicKey, PublicKeyExtension}; @@ -86,6 +87,14 @@ where .content_type(APUB_JSON_CONTENT_TYPE) .json(data) } +fn create_apub_tombstone_response<T>(data: &T) -> HttpResponse<Body> +where + T: Serialize, +{ + HttpResponse::Gone() + .content_type(APUB_JSON_CONTENT_TYPE) + .json(data) +} /// Generates the ActivityPub ID for a given object type and name. /// @@ -138,31 +147,40 @@ fn is_apub_id_valid(apub_id: &Url) -> bool { } } -#[derive(Serialize)] -pub enum ResponseOrTombstone<Response> { - Response(Response), - Tombstone(Box<Tombstone>), +// TODO Not sure good names for these +pub trait ToApub { + type Response; + fn to_apub(&self, conn: &PgConnection) -> Result<Self::Response, Error>; } -impl<Response> ResponseOrTombstone<Response> { - fn as_response(&self) -> Result<&Response, Error> { - match self { - ResponseOrTombstone::Response(r) => Ok(r), - ResponseOrTombstone::Tombstone(_t) => Err(format_err!("Value is a tombstone")), - } - } - fn as_tombstone(&self) -> Result<&Tombstone, Error> { - match self { - ResponseOrTombstone::Tombstone(t) => Ok(t), - ResponseOrTombstone::Response(_r) => Err(format_err!("Value is a response")), +fn create_tombstone( + deleted: bool, + object_id: &str, + published: NaiveDateTime, + updated: Option<NaiveDateTime>, +) -> Result<Tombstone, Error> { + if deleted { + let mut tombstone = Tombstone::default(); + // TODO: might want to include deleted time as well + tombstone + .object_props + .set_id(object_id)? + .set_published(convert_datetime(published))?; + if let Some(updated) = updated { + tombstone + .object_props + .set_updated(convert_datetime(updated))?; } + Ok(tombstone) + } else { + Err(format_err!( + "Cant convert object to tombstone if it wasnt deleted" + )) } } -// TODO Not sure good names for these -pub trait ToApub { - type Response; - fn to_apub(&self, conn: &PgConnection) -> Result<ResponseOrTombstone<Self::Response>, Error>; +pub trait ToTombstone { + fn to_tombstone(&self) -> Result<Tombstone, Error>; } pub trait FromApub { @@ -175,7 +193,7 @@ pub trait FromApub { pub trait ApubObjectType { fn send_create(&self, creator: &User_, conn: &PgConnection) -> Result<(), Error>; fn send_update(&self, creator: &User_, conn: &PgConnection) -> Result<(), Error>; - //fn send_delete(&self, creator: &User_, conn: &PgConnection) -> Result<(), Error>; + fn send_delete(&self, actor: &User_, conn: &PgConnection) -> Result<(), Error>; } pub trait ApubLikeableType { diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index 381ba3c6..77f8d984 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -12,14 +12,18 @@ pub async fn get_apub_post( ) -> Result<HttpResponse<Body>, Error> { let id = info.post_id.parse::<i32>()?; let post = Post::read(&&db.get()?, id)?; - Ok(create_apub_response(&post.to_apub(&db.get().unwrap())?)) + if !post.deleted { + Ok(create_apub_response(&post.to_apub(&db.get().unwrap())?)) + } else { + Ok(create_apub_tombstone_response(&post.to_tombstone()?)) + } } impl ToApub for Post { type Response = Page; // Turn a Lemmy post into an ActivityPub page that can be sent out over the network. - fn to_apub(&self, conn: &PgConnection) -> Result<ResponseOrTombstone<Page>, Error> { + fn to_apub(&self, conn: &PgConnection) -> Result<Page, Error> { let mut page = Page::default(); let oprops: &mut ObjectProperties = page.as_mut(); let creator = User_::read(conn, self.creator_id)?; @@ -51,7 +55,13 @@ impl ToApub for Post { oprops.set_updated(convert_datetime(u))?; } - Ok(ResponseOrTombstone::Response(page)) + Ok(page) + } +} + +impl ToTombstone for Post { + fn to_tombstone(&self) -> Result<Tombstone, Error> { + create_tombstone(self.deleted, &self.ap_id, self.published, self.updated) } } @@ -109,7 +119,7 @@ impl ApubObjectType for Post { create .create_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(page.as_response()?.to_owned())?; + .set_object_base_box(page)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -144,7 +154,7 @@ impl ApubObjectType for Post { update .update_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(page.as_response()?.to_owned())?; + .set_object_base_box(page)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -163,6 +173,32 @@ impl ApubObjectType for Post { )?; Ok(()) } + + fn send_delete(&self, actor: &User_, conn: &PgConnection) -> Result<(), Error> { + let mut delete = Delete::default(); + delete + .delete_props + .set_actor_xsd_any_uri(actor.actor_id.to_owned())? + .set_object_base_box(BaseBox::from_concrete(self.to_tombstone()?)?)?; + + // Insert the sent activity into the activity table + let activity_form = activity::ActivityForm { + user_id: self.creator_id, + data: serde_json::to_value(&delete)?, + local: true, + updated: None, + }; + activity::Activity::create(&conn, &activity_form)?; + + let community = Community::read(conn, self.community_id)?; + send_activity( + &delete, + &actor.private_key.to_owned().unwrap(), + &actor.actor_id, + community.get_follower_inboxes(&conn)?, + )?; + Ok(()) + } } impl ApubLikeableType for Post { @@ -176,7 +212,7 @@ impl ApubLikeableType for Post { like .like_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(page.as_response()?.to_owned())?; + .set_object_base_box(page)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { @@ -210,7 +246,7 @@ impl ApubLikeableType for Post { dislike .dislike_props .set_actor_xsd_any_uri(creator.actor_id.to_owned())? - .set_object_base_box(page.as_response()?.to_owned())?; + .set_object_base_box(page)?; // Insert the sent activity into the activity table let activity_form = activity::ActivityForm { diff --git a/server/src/apub/shared_inbox.rs b/server/src/apub/shared_inbox.rs index 10ed1122..28cb71e2 100644 --- a/server/src/apub/shared_inbox.rs +++ b/server/src/apub/shared_inbox.rs @@ -66,6 +66,7 @@ pub async fn shared_inbox( receive_dislike_comment(&d, &request, &conn, chat_server) } (SharedAcceptedObjects::Delete(d), Some("Tombstone")) => { + // TODO: is this deleting a community, post, comment or what? receive_delete_community(&d, &request, &conn, chat_server) } _ => Err(format_err!("Unknown incoming activity type.")), diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 36147f7a..7426efd5 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -9,7 +9,7 @@ impl ToApub for User_ { type Response = PersonExt; // Turn a Lemmy Community into an ActivityPub group that can be sent out over the network. - fn to_apub(&self, _conn: &PgConnection) -> Result<ResponseOrTombstone<PersonExt>, Error> { + fn to_apub(&self, _conn: &PgConnection) -> Result<PersonExt, Error> { // TODO go through all these to_string and to_owned() let mut person = Person::default(); let oprops: &mut ObjectProperties = person.as_mut(); @@ -41,9 +41,7 @@ impl ToApub for User_ { .set_following(self.get_following_url())? .set_liked(self.get_liked_url())?; - Ok(ResponseOrTombstone::Response( - person.extend(actor_props).extend(self.get_public_key_ext()), - )) + Ok(person.extend(actor_props).extend(self.get_public_key_ext())) } } |