summaryrefslogtreecommitdiffstats
path: root/server/src/apub
diff options
context:
space:
mode:
authorFelix <me@nutomic.com>2020-04-29 16:51:25 +0200
committerFelix <me@nutomic.com>2020-04-29 16:51:25 +0200
commitc43f06124a00f3af8559d849541c2b84d3383f13 (patch)
tree0f850596a52cdfa77bff0eb620056432558af8b0 /server/src/apub
parent0c0c68398609d549a757a9c3a26ce2311075fa38 (diff)
Address comments, implement delete for posts and comments
Diffstat (limited to 'server/src/apub')
-rw-r--r--server/src/apub/comment.rs46
-rw-r--r--server/src/apub/community.rs36
-rw-r--r--server/src/apub/mod.rs58
-rw-r--r--server/src/apub/post.rs50
-rw-r--r--server/src/apub/shared_inbox.rs1
-rw-r--r--server/src/apub/user.rs6
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()))
}
}