From 1ed7c5949178aec31776ac78ad59dcda5a45f14a Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 23 Jul 2020 16:36:45 +0200 Subject: [PATCH 1/5] Refactor inbox, simplify and split into multiple files --- server/src/api/comment.rs | 9 +- server/src/apub/community.rs | 10 +- server/src/apub/fetcher.rs | 23 +- server/src/apub/inbox/activities/announce.rs | 56 + server/src/apub/inbox/activities/create.rs | 124 ++ server/src/apub/inbox/activities/delete.rs | 222 +++ server/src/apub/inbox/activities/dislike.rs | 132 ++ server/src/apub/inbox/activities/like.rs | 132 ++ server/src/apub/inbox/activities/mod.rs | 8 + server/src/apub/inbox/activities/remove.rs | 221 +++ server/src/apub/inbox/activities/undo.rs | 550 ++++++ server/src/apub/inbox/activities/update.rs | 128 ++ .../src/apub/{ => inbox}/community_inbox.rs | 0 server/src/apub/inbox/mod.rs | 4 + server/src/apub/inbox/shared_inbox.rs | 136 ++ server/src/apub/{ => inbox}/user_inbox.rs | 0 server/src/apub/mod.rs | 7 +- server/src/apub/shared_inbox.rs | 1514 ----------------- server/src/apub/user.rs | 4 + server/src/routes/federation.rs | 6 +- 20 files changed, 1758 insertions(+), 1528 deletions(-) create mode 100644 server/src/apub/inbox/activities/announce.rs create mode 100644 server/src/apub/inbox/activities/create.rs create mode 100644 server/src/apub/inbox/activities/delete.rs create mode 100644 server/src/apub/inbox/activities/dislike.rs create mode 100644 server/src/apub/inbox/activities/like.rs create mode 100644 server/src/apub/inbox/activities/mod.rs create mode 100644 server/src/apub/inbox/activities/remove.rs create mode 100644 server/src/apub/inbox/activities/undo.rs create mode 100644 server/src/apub/inbox/activities/update.rs rename server/src/apub/{ => inbox}/community_inbox.rs (100%) create mode 100644 server/src/apub/inbox/mod.rs create mode 100644 server/src/apub/inbox/shared_inbox.rs rename server/src/apub/{ => inbox}/user_inbox.rs (100%) delete mode 100644 server/src/apub/shared_inbox.rs diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs index f8bdf5d5b..d0dfa7a7c 100644 --- a/server/src/api/comment.rs +++ b/server/src/api/comment.rs @@ -176,7 +176,7 @@ impl Perform for Oper { // Scan the comment for user mentions, add those rows let mentions = scrape_text_for_mentions(&comment_form.content); let recipient_ids = - send_local_notifs(mentions, updated_comment.clone(), user.clone(), post, pool).await?; + send_local_notifs(mentions, updated_comment.clone(), &user, post, pool).await?; // You like your own comment by default let like_form = CommentLikeForm { @@ -407,7 +407,7 @@ impl Perform for Oper { let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??; let mentions = scrape_text_for_mentions(&comment_form.content); - let recipient_ids = send_local_notifs(mentions, updated_comment, user, post, pool).await?; + let recipient_ids = send_local_notifs(mentions, updated_comment, &user, post, pool).await?; let edit_id = data.edit_id; let comment_view = blocking(pool, move |conn| { @@ -672,12 +672,13 @@ impl Perform for Oper { pub async fn send_local_notifs( mentions: Vec, comment: Comment, - user: User_, + user: &User_, post: Post, pool: &DbPool, ) -> Result, LemmyError> { + let user2 = user.clone(); let ids = blocking(pool, move |conn| { - do_send_local_notifs(conn, &mentions, &comment, &user, &post) + do_send_local_notifs(conn, &mentions, &comment, &user2, &post) }) .await?; diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index f84e6508d..a3f58f5d4 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -318,6 +318,10 @@ impl ActorType for Community { ) -> Result<(), LemmyError> { unimplemented!() } + + fn user_id(&self) -> i32 { + self.creator_id + } } #[async_trait::async_trait(?Send)] @@ -427,10 +431,10 @@ pub async fn get_apub_community_followers( pub async fn do_announce( activity: AnyBase, community: &Community, - sender: &dyn ActorType, + sender: &User_, client: &Client, pool: &DbPool, -) -> Result { +) -> Result<(), LemmyError> { let id = format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4()); let mut announce = Announce::new(community.actor_id.to_owned(), activity); announce @@ -450,5 +454,5 @@ pub async fn do_announce( send_activity(client, &announce.into_any_base()?, community, to).await?; - Ok(HttpResponse::Ok().finish()) + Ok(()) } diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index d224b7cd0..5fd394157 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -1,6 +1,14 @@ use crate::{ api::site::SearchResponse, - apub::{is_apub_id_valid, FromApub, GroupExt, PageExt, PersonExt, APUB_JSON_CONTENT_TYPE}, + apub::{ + is_apub_id_valid, + ActorType, + FromApub, + GroupExt, + PageExt, + PersonExt, + APUB_JSON_CONTENT_TYPE, + }, blocking, request::{retry, RecvError}, routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}, @@ -192,6 +200,19 @@ pub async fn search_by_apub_id( Ok(response) } +pub async fn get_or_fetch_and_upsert_remote_actor( + apub_id: &Url, + client: &Client, + pool: &DbPool, +) -> Result, LemmyError> { + let user = get_or_fetch_and_upsert_remote_user(apub_id, client, pool).await; + let actor: Box = match user { + Ok(u) => Box::new(u), + Err(_) => Box::new(get_or_fetch_and_upsert_remote_community(apub_id, client, pool).await?), + }; + Ok(actor) +} + /// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user. pub async fn get_or_fetch_and_upsert_remote_user( apub_id: &Url, diff --git a/server/src/apub/inbox/activities/announce.rs b/server/src/apub/inbox/activities/announce.rs new file mode 100644 index 000000000..9564555a6 --- /dev/null +++ b/server/src/apub/inbox/activities/announce.rs @@ -0,0 +1,56 @@ +use crate::{ + apub::{ + inbox::activities::{ + create::receive_create, + delete::receive_delete, + dislike::receive_dislike, + like::receive_like, + remove::receive_remove, + undo::receive_undo, + update::receive_update, + }, + inbox::shared_inbox::receive_unhandled_activity, + }, + routes::ChatServerParam, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::*, prelude::ExtendsExt}; +use actix_web::{client::Client, HttpResponse}; +use activitystreams_new::base::AnyBase; + +pub async fn receive_announce( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let announce = Announce::from_any_base(activity)?.unwrap(); + let kind = announce.object().as_single_kind_str(); + let object = announce.object(); + let object2 = object.clone().one().unwrap(); + match kind { + Some("Create") => { + receive_create(object2, client, pool, chat_server).await + } + Some("Update") => { + receive_update(object2, client, pool, chat_server).await + } + Some("Like") => { + receive_like(object2, client, pool, chat_server).await + } + Some("Dislike") => { + receive_dislike(object2, client, pool, chat_server).await + } + Some("Delete") => { + receive_delete(object2, client, pool, chat_server).await + } + Some("Remove") => { + receive_remove(object2, client, pool, chat_server).await + } + Some("Undo") => { + receive_undo(object2, client, pool, chat_server).await + } + _ => receive_unhandled_activity(announce), + } +} diff --git a/server/src/apub/inbox/activities/create.rs b/server/src/apub/inbox/activities/create.rs new file mode 100644 index 000000000..413a2977b --- /dev/null +++ b/server/src/apub/inbox/activities/create.rs @@ -0,0 +1,124 @@ +use crate::{ + api::{ + comment::{send_local_notifs, CommentResponse}, + post::PostResponse, + }, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + ActorType, + FromApub, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::Create, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{Comment, CommentForm}, + comment_view::CommentView, + post::{Post, PostForm}, + post_view::PostView, + Crud, +}; +use lemmy_utils::scrape_text_for_mentions; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::{announce_if_community_is_local}; + +pub async fn receive_create( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let create = Create::from_any_base(activity)?.unwrap(); + dbg!(create.object().as_single_kind_str()); + match create.object().as_single_kind_str() { + Some("Page") => receive_create_post(create, client, pool, chat_server).await, + Some("Note") => receive_create_comment(create, client, pool, chat_server).await, + _ => receive_unhandled_activity(create), + } +} + +async fn receive_create_post( + create: Create, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&create, client, pool).await?; + let page = PageExt::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); + + let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + + let inserted_post = blocking(pool, move |conn| Post::create(conn, &post)).await??; + + // Refetch the view + let inserted_post_id = inserted_post.id; + let post_view = blocking(pool, move |conn| { + PostView::read(conn, inserted_post_id, None) + }) + .await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::CreatePost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(create, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_create_comment( + create: Create, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&create, client, pool).await?; + let note = Note::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); + + let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + + let inserted_comment = blocking(pool, move |conn| Comment::create(conn, &comment)).await??; + + let post_id = inserted_comment.post_id; + let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??; + + // Note: + // Although mentions could be gotten from the post tags (they are included there), or the ccs, + // Its much easier to scrape them from the comment body, since the API has to do that + // anyway. + let mentions = scrape_text_for_mentions(&inserted_comment.content); + let recipient_ids = + send_local_notifs(mentions, inserted_comment.clone(), &user, post, pool).await?; + + // Refetch the view + let comment_view = blocking(pool, move |conn| { + CommentView::read(conn, inserted_comment.id, None) + }) + .await??; + + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::CreateComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(create, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/delete.rs b/server/src/apub/inbox/activities/delete.rs new file mode 100644 index 000000000..9c0d146fb --- /dev/null +++ b/server/src/apub/inbox/activities/delete.rs @@ -0,0 +1,222 @@ +use crate::{ + api::{comment::CommentResponse, community::CommunityResponse, post::PostResponse}, + apub::inbox:: + shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + GroupExt, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendCommunityRoomMessage, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::Delete, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{Comment, CommentForm}, + comment_view::CommentView, + community::{Community, CommunityForm}, + community_view::CommunityView, + naive_now, + post::{Post, PostForm}, + post_view::PostView, + Crud, +}; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_delete( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let delete = Delete::from_any_base(activity)?.unwrap(); + match delete.object().as_single_kind_str() { + Some("Page") => receive_delete_post(delete, client, pool, chat_server).await, + Some("Note") => receive_delete_comment(delete, client, pool, chat_server).await, + Some("Group") => receive_delete_community(delete, client, pool, chat_server).await, + _ => receive_unhandled_activity(delete), + } +} + +async fn receive_delete_post( + delete: Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&delete, client, pool).await?; + let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + + let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) + .await? + .get_ap_id()?; + + let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; + + let post_form = PostForm { + name: post.name.to_owned(), + url: post.url.to_owned(), + body: post.body.to_owned(), + creator_id: post.creator_id.to_owned(), + community_id: post.community_id, + removed: None, + deleted: Some(true), + nsfw: post.nsfw, + locked: None, + stickied: None, + updated: Some(naive_now()), + embed_title: post.embed_title, + embed_description: post.embed_description, + embed_html: post.embed_html, + thumbnail_url: post.thumbnail_url, + ap_id: post.ap_id, + local: post.local, + published: None, + }; + let post_id = post.id; + blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; + + // Refetch the view + let post_id = post.id; + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::EditPost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(delete, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_delete_comment( + delete: Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&delete, client, pool).await?; + let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + + let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) + .await? + .get_ap_id()?; + + let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; + + let comment_form = CommentForm { + content: comment.content.to_owned(), + parent_id: comment.parent_id, + post_id: comment.post_id, + creator_id: comment.creator_id, + removed: None, + deleted: Some(true), + read: None, + published: None, + updated: Some(naive_now()), + ap_id: comment.ap_id, + local: comment.local, + }; + let comment_id = comment.id; + blocking(pool, move |conn| { + Comment::update(conn, comment_id, &comment_form) + }) + .await??; + + // Refetch the view + let comment_id = comment.id; + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::EditComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(delete, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_delete_community( + delete: Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + let user = get_user_from_activity(&delete, client, pool).await?; + + let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) + .await? + .actor_id; + + let community = blocking(pool, move |conn| { + Community::read_from_actor_id(conn, &community_actor_id) + }) + .await??; + + let community_form = CommunityForm { + name: community.name.to_owned(), + title: community.title.to_owned(), + description: community.description.to_owned(), + category_id: community.category_id, // Note: need to keep this due to foreign key constraint + creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint + removed: None, + published: None, + updated: Some(naive_now()), + deleted: Some(true), + nsfw: community.nsfw, + actor_id: community.actor_id, + local: community.local, + private_key: community.private_key, + public_key: community.public_key, + last_refreshed_at: None, + }; + + let community_id = community.id; + blocking(pool, move |conn| { + Community::update(conn, community_id, &community_form) + }) + .await??; + + let community_id = community.id; + let res = CommunityResponse { + community: blocking(pool, move |conn| { + CommunityView::read(conn, community_id, None) + }) + .await??, + }; + + let community_id = res.community.id; + + chat_server.do_send(SendCommunityRoomMessage { + op: UserOperation::EditCommunity, + response: res, + community_id, + my_id: None, + }); + + announce_if_community_is_local(delete, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/dislike.rs b/server/src/apub/inbox/activities/dislike.rs new file mode 100644 index 000000000..2b887c55e --- /dev/null +++ b/server/src/apub/inbox/activities/dislike.rs @@ -0,0 +1,132 @@ +use crate::{ + api::{comment::CommentResponse, post::PostResponse}, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::Dislike, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{CommentForm, CommentLike, CommentLikeForm}, + comment_view::CommentView, + post::{PostForm, PostLike, PostLikeForm}, + post_view::PostView, + Likeable, +}; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_dislike( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let dislike = Dislike::from_any_base(activity)?.unwrap(); + match dislike.object().as_single_kind_str() { + Some("Page") => receive_dislike_post(dislike, client, pool, chat_server).await, + Some("Note") => receive_dislike_comment(dislike, client, pool, chat_server).await, + _ => receive_unhandled_activity(dislike), + } +} + +async fn receive_dislike_post( + dislike: Dislike, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&dislike, client, pool).await?; + let page = PageExt::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); + + let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + + let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = PostLikeForm { + post_id, + user_id: user.id, + score: -1, + }; + blocking(pool, move |conn| { + PostLike::remove(conn, &like_form)?; + PostLike::like(conn, &like_form) + }) + .await??; + + // Refetch the view + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::CreatePostLike, + post: res, + my_id: None, + }); + + announce_if_community_is_local(dislike, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_dislike_comment( + dislike: Dislike, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let note = Note::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); + let user = get_user_from_activity(&dislike, client, pool).await?; + + let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + + let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = CommentLikeForm { + comment_id, + post_id: comment.post_id, + user_id: user.id, + score: -1, + }; + blocking(pool, move |conn| { + CommentLike::remove(conn, &like_form)?; + CommentLike::like(conn, &like_form) + }) + .await??; + + // Refetch the view + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::CreateCommentLike, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(dislike, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/like.rs b/server/src/apub/inbox/activities/like.rs new file mode 100644 index 000000000..51a7d0333 --- /dev/null +++ b/server/src/apub/inbox/activities/like.rs @@ -0,0 +1,132 @@ +use crate::{ + api::{comment::CommentResponse, post::PostResponse}, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::Like, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{CommentForm, CommentLike, CommentLikeForm}, + comment_view::CommentView, + post::{PostForm, PostLike, PostLikeForm}, + post_view::PostView, + Likeable, +}; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_like( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let like = Like::from_any_base(activity)?.unwrap(); + match like.object().as_single_kind_str() { + Some("Page") => receive_like_post(like, client, pool, chat_server).await, + Some("Note") => receive_like_comment(like, client, pool, chat_server).await, + _ => receive_unhandled_activity(like), + } +} + +async fn receive_like_post( + like: Like, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&like, client, pool).await?; + let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); + + let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + + let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = PostLikeForm { + post_id, + user_id: user.id, + score: 1, + }; + blocking(pool, move |conn| { + PostLike::remove(conn, &like_form)?; + PostLike::like(conn, &like_form) + }) + .await??; + + // Refetch the view + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::CreatePostLike, + post: res, + my_id: None, + }); + + announce_if_community_is_local(like, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_like_comment( + like: Like, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); + let user = get_user_from_activity(&like, client, pool).await?; + + let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + + let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = CommentLikeForm { + comment_id, + post_id: comment.post_id, + user_id: user.id, + score: 1, + }; + blocking(pool, move |conn| { + CommentLike::remove(conn, &like_form)?; + CommentLike::like(conn, &like_form) + }) + .await??; + + // Refetch the view + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::CreateCommentLike, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(like, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/mod.rs b/server/src/apub/inbox/activities/mod.rs new file mode 100644 index 000000000..aa50cd116 --- /dev/null +++ b/server/src/apub/inbox/activities/mod.rs @@ -0,0 +1,8 @@ +pub mod announce; +pub mod create; +pub mod delete; +pub mod dislike; +pub mod like; +pub mod remove; +pub mod undo; +pub mod update; diff --git a/server/src/apub/inbox/activities/remove.rs b/server/src/apub/inbox/activities/remove.rs new file mode 100644 index 000000000..a056b898e --- /dev/null +++ b/server/src/apub/inbox/activities/remove.rs @@ -0,0 +1,221 @@ +use crate::{ + api::{comment::CommentResponse, community::CommunityResponse, post::PostResponse}, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + GroupExt, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendCommunityRoomMessage, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::Remove, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{Comment, CommentForm}, + comment_view::CommentView, + community::{Community, CommunityForm}, + community_view::CommunityView, + naive_now, + post::{Post, PostForm}, + post_view::PostView, + Crud, +}; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_remove( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let remove = Remove::from_any_base(activity)?.unwrap(); + match remove.object().as_single_kind_str() { + Some("Page") => receive_remove_post(remove, client, pool, chat_server).await, + Some("Note") => receive_remove_comment(remove, client, pool, chat_server).await, + Some("Group") => receive_remove_community(remove, client, pool, chat_server).await, + _ => receive_unhandled_activity(remove), + } +} + +async fn receive_remove_post( + remove: Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(&remove, client, pool).await?; + let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) + .await? + .get_ap_id()?; + + let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; + + let post_form = PostForm { + name: post.name.to_owned(), + url: post.url.to_owned(), + body: post.body.to_owned(), + creator_id: post.creator_id.to_owned(), + community_id: post.community_id, + removed: Some(true), + deleted: None, + nsfw: post.nsfw, + locked: None, + stickied: None, + updated: Some(naive_now()), + embed_title: post.embed_title, + embed_description: post.embed_description, + embed_html: post.embed_html, + thumbnail_url: post.thumbnail_url, + ap_id: post.ap_id, + local: post.local, + published: None, + }; + let post_id = post.id; + blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; + + // Refetch the view + let post_id = post.id; + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::EditPost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(remove, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_remove_comment( + remove: Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(&remove, client, pool).await?; + let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) + .await? + .get_ap_id()?; + + let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; + + let comment_form = CommentForm { + content: comment.content.to_owned(), + parent_id: comment.parent_id, + post_id: comment.post_id, + creator_id: comment.creator_id, + removed: Some(true), + deleted: None, + read: None, + published: None, + updated: Some(naive_now()), + ap_id: comment.ap_id, + local: comment.local, + }; + let comment_id = comment.id; + blocking(pool, move |conn| { + Comment::update(conn, comment_id, &comment_form) + }) + .await??; + + // Refetch the view + let comment_id = comment.id; + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::EditComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(remove, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_remove_community( + remove: Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(&remove, client, pool).await?; + let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) + .await? + .actor_id; + + let community = blocking(pool, move |conn| { + Community::read_from_actor_id(conn, &community_actor_id) + }) + .await??; + + let community_form = CommunityForm { + name: community.name.to_owned(), + title: community.title.to_owned(), + description: community.description.to_owned(), + category_id: community.category_id, // Note: need to keep this due to foreign key constraint + creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint + removed: Some(true), + published: None, + updated: Some(naive_now()), + deleted: None, + nsfw: community.nsfw, + actor_id: community.actor_id, + local: community.local, + private_key: community.private_key, + public_key: community.public_key, + last_refreshed_at: None, + }; + + let community_id = community.id; + blocking(pool, move |conn| { + Community::update(conn, community_id, &community_form) + }) + .await??; + + let community_id = community.id; + let res = CommunityResponse { + community: blocking(pool, move |conn| { + CommunityView::read(conn, community_id, None) + }) + .await??, + }; + + let community_id = res.community.id; + + chat_server.do_send(SendCommunityRoomMessage { + op: UserOperation::EditCommunity, + response: res, + community_id, + my_id: None, + }); + + announce_if_community_is_local(remove, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/undo.rs b/server/src/apub/inbox/activities/undo.rs new file mode 100644 index 000000000..a08472261 --- /dev/null +++ b/server/src/apub/inbox/activities/undo.rs @@ -0,0 +1,550 @@ +use crate::{ + api::{comment::CommentResponse, community::CommunityResponse, post::PostResponse}, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + GroupExt, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendCommunityRoomMessage, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{activity::*, object::Note, prelude::*}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, + comment_view::CommentView, + community::{Community, CommunityForm}, + community_view::CommunityView, + naive_now, + post::{Post, PostForm, PostLike, PostLikeForm}, + post_view::PostView, + Crud, + Likeable, +}; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_undo( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let undo = Undo::from_any_base(activity)?.unwrap(); + match undo.object().as_single_kind_str() { + Some("Delete") => receive_undo_delete(undo, client, pool, chat_server).await, + Some("Remove") => receive_undo_remove(undo, client, pool, chat_server).await, + Some("Like") => receive_undo_like(undo, client, pool, chat_server).await, + Some("Dislike") => receive_undo_dislike(undo, client, pool, chat_server).await, + // TODO: handle undo_dislike? + _ => receive_unhandled_activity(undo), + } +} + +async fn receive_undo_delete( + undo: Undo, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let delete = Delete::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); + let type_ = delete.object().as_single_kind_str().unwrap(); + match type_ { + "Note" => receive_undo_delete_comment(undo, &delete, client, pool, chat_server).await, + "Page" => receive_undo_delete_post(undo, &delete, client, pool, chat_server).await, + "Group" => receive_undo_delete_community(undo, &delete, client, pool, chat_server).await, + d => Err(format_err!("Undo Delete type {} not supported", d).into()), + } +} + +async fn receive_undo_remove( + undo: Undo, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let remove = Remove::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); + + let type_ = remove.object().as_single_kind_str().unwrap(); + match type_ { + "Note" => receive_undo_remove_comment(undo, &remove, client, pool, chat_server).await, + "Page" => receive_undo_remove_post(undo, &remove, client, pool, chat_server).await, + "Group" => receive_undo_remove_community(undo, &remove, client, pool, chat_server).await, + d => Err(format_err!("Undo Delete type {} not supported", d).into()), + } +} + +async fn receive_undo_like( + undo: Undo, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let like = Like::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); + + let type_ = like.object().as_single_kind_str().unwrap(); + match type_ { + "Note" => receive_undo_like_comment(undo, &like, client, pool, chat_server).await, + "Page" => receive_undo_like_post(undo, &like, client, pool, chat_server).await, + d => Err(format_err!("Undo Delete type {} not supported", d).into()), + } +} + +async fn receive_undo_dislike( + undo: Undo, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let dislike = Dislike::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); + + let type_ = dislike.object().as_single_kind_str().unwrap(); + match type_ { + // TODO: handle dislike + d => Err(format_err!("Undo Delete type {} not supported", d).into()), + } +} + +async fn receive_undo_delete_comment( + undo: Undo, + delete: &Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(delete, client, pool).await?; + let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + + let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) + .await? + .get_ap_id()?; + + let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; + + let comment_form = CommentForm { + content: comment.content.to_owned(), + parent_id: comment.parent_id, + post_id: comment.post_id, + creator_id: comment.creator_id, + removed: None, + deleted: Some(false), + read: None, + published: None, + updated: Some(naive_now()), + ap_id: comment.ap_id, + local: comment.local, + }; + let comment_id = comment.id; + blocking(pool, move |conn| { + Comment::update(conn, comment_id, &comment_form) + }) + .await??; + + // Refetch the view + let comment_id = comment.id; + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::EditComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_remove_comment( + undo: Undo, + remove: &Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(remove, client, pool).await?; + let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) + .await? + .get_ap_id()?; + + let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; + + let comment_form = CommentForm { + content: comment.content.to_owned(), + parent_id: comment.parent_id, + post_id: comment.post_id, + creator_id: comment.creator_id, + removed: Some(false), + deleted: None, + read: None, + published: None, + updated: Some(naive_now()), + ap_id: comment.ap_id, + local: comment.local, + }; + let comment_id = comment.id; + blocking(pool, move |conn| { + Comment::update(conn, comment_id, &comment_form) + }) + .await??; + + // Refetch the view + let comment_id = comment.id; + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::EditComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_delete_post( + undo: Undo, + delete: &Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(delete, client, pool).await?; + let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + + let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) + .await? + .get_ap_id()?; + + let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; + + let post_form = PostForm { + name: post.name.to_owned(), + url: post.url.to_owned(), + body: post.body.to_owned(), + creator_id: post.creator_id.to_owned(), + community_id: post.community_id, + removed: None, + deleted: Some(false), + nsfw: post.nsfw, + locked: None, + stickied: None, + updated: Some(naive_now()), + embed_title: post.embed_title, + embed_description: post.embed_description, + embed_html: post.embed_html, + thumbnail_url: post.thumbnail_url, + ap_id: post.ap_id, + local: post.local, + published: None, + }; + let post_id = post.id; + blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; + + // Refetch the view + let post_id = post.id; + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::EditPost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_remove_post( + undo: Undo, + remove: &Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(remove, client, pool).await?; + let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) + .await? + .get_ap_id()?; + + let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; + + let post_form = PostForm { + name: post.name.to_owned(), + url: post.url.to_owned(), + body: post.body.to_owned(), + creator_id: post.creator_id.to_owned(), + community_id: post.community_id, + removed: Some(false), + deleted: None, + nsfw: post.nsfw, + locked: None, + stickied: None, + updated: Some(naive_now()), + embed_title: post.embed_title, + embed_description: post.embed_description, + embed_html: post.embed_html, + thumbnail_url: post.thumbnail_url, + ap_id: post.ap_id, + local: post.local, + published: None, + }; + let post_id = post.id; + blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; + + // Refetch the view + let post_id = post.id; + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::EditPost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_delete_community( + undo: Undo, + delete: &Delete, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(delete, client, pool).await?; + let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); + + let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) + .await? + .actor_id; + + let community = blocking(pool, move |conn| { + Community::read_from_actor_id(conn, &community_actor_id) + }) + .await??; + + let community_form = CommunityForm { + name: community.name.to_owned(), + title: community.title.to_owned(), + description: community.description.to_owned(), + category_id: community.category_id, // Note: need to keep this due to foreign key constraint + creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint + removed: None, + published: None, + updated: Some(naive_now()), + deleted: Some(false), + nsfw: community.nsfw, + actor_id: community.actor_id, + local: community.local, + private_key: community.private_key, + public_key: community.public_key, + last_refreshed_at: None, + }; + + let community_id = community.id; + blocking(pool, move |conn| { + Community::update(conn, community_id, &community_form) + }) + .await??; + + let community_id = community.id; + let res = CommunityResponse { + community: blocking(pool, move |conn| { + CommunityView::read(conn, community_id, None) + }) + .await??, + }; + + let community_id = res.community.id; + + chat_server.do_send(SendCommunityRoomMessage { + op: UserOperation::EditCommunity, + response: res, + community_id, + my_id: None, + }); + + announce_if_community_is_local(undo, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_remove_community( + undo: Undo, + remove: &Remove, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let mod_ = get_user_from_activity(remove, client, pool).await?; + let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); + + let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) + .await? + .actor_id; + + let community = blocking(pool, move |conn| { + Community::read_from_actor_id(conn, &community_actor_id) + }) + .await??; + + let community_form = CommunityForm { + name: community.name.to_owned(), + title: community.title.to_owned(), + description: community.description.to_owned(), + category_id: community.category_id, // Note: need to keep this due to foreign key constraint + creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint + removed: Some(false), + published: None, + updated: Some(naive_now()), + deleted: None, + nsfw: community.nsfw, + actor_id: community.actor_id, + local: community.local, + private_key: community.private_key, + public_key: community.public_key, + last_refreshed_at: None, + }; + + let community_id = community.id; + blocking(pool, move |conn| { + Community::update(conn, community_id, &community_form) + }) + .await??; + + let community_id = community.id; + let res = CommunityResponse { + community: blocking(pool, move |conn| { + CommunityView::read(conn, community_id, None) + }) + .await??, + }; + + let community_id = res.community.id; + + chat_server.do_send(SendCommunityRoomMessage { + op: UserOperation::EditCommunity, + response: res, + community_id, + my_id: None, + }); + + announce_if_community_is_local(undo, &mod_, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_like_comment( + undo: Undo, + like: &Like, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(like, client, pool).await?; + let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); + + let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + + let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = CommentLikeForm { + comment_id, + post_id: comment.post_id, + user_id: user.id, + score: 0, + }; + blocking(pool, move |conn| CommentLike::remove(conn, &like_form)).await??; + + // Refetch the view + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + // TODO get those recipient actor ids from somewhere + let recipient_ids = vec![]; + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::CreateCommentLike, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_undo_like_post( + undo: Undo, + like: &Like, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(like, client, pool).await?; + let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); + + let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + + let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) + .await? + .id; + + let like_form = PostLikeForm { + post_id, + user_id: user.id, + score: 1, + }; + blocking(pool, move |conn| PostLike::remove(conn, &like_form)).await??; + + // Refetch the view + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::CreatePostLike, + post: res, + my_id: None, + }); + + announce_if_community_is_local(undo, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/inbox/activities/update.rs b/server/src/apub/inbox/activities/update.rs new file mode 100644 index 000000000..96e0efac6 --- /dev/null +++ b/server/src/apub/inbox/activities/update.rs @@ -0,0 +1,128 @@ +use crate::{ + api::{ + comment::{send_local_notifs, CommentResponse}, + post::PostResponse, + }, + apub::inbox::shared_inbox::{get_user_from_activity, receive_unhandled_activity}, + apub::{ + fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, + ActorType, + FromApub, + PageExt, + }, + blocking, + routes::ChatServerParam, + websocket::{ + server::{SendComment, SendPost}, + UserOperation, + }, + DbPool, + LemmyError, +}; +use activitystreams_new::{ + activity::{Update}, + object::Note, + prelude::*, +}; +use actix_web::{client::Client, HttpResponse}; +use lemmy_db::{ + comment::{Comment, CommentForm}, + comment_view::CommentView, + post::{Post, PostForm}, + post_view::PostView, + Crud, +}; +use lemmy_utils::scrape_text_for_mentions; +use activitystreams_new::base::AnyBase; +use crate::apub::inbox::shared_inbox::announce_if_community_is_local; + +pub async fn receive_update( + activity: AnyBase, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let update = Update::from_any_base(activity)?.unwrap(); + match update.object().as_single_kind_str() { + Some("Page") => receive_update_post(update, client, pool, chat_server).await, + Some("Note") => receive_update_comment(update, client, pool, chat_server).await, + _ => receive_unhandled_activity(update), + } +} + +async fn receive_update_post( + update: Update, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let user = get_user_from_activity(&update, client, pool).await?; + let page = PageExt::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); + + let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + + let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) + .await? + .id; + + blocking(pool, move |conn| Post::update(conn, post_id, &post)).await??; + + // Refetch the view + let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; + + let res = PostResponse { post: post_view }; + + chat_server.do_send(SendPost { + op: UserOperation::EditPost, + post: res, + my_id: None, + }); + + announce_if_community_is_local(update, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} + +async fn receive_update_comment( + update: Update, + client: &Client, + pool: &DbPool, + chat_server: ChatServerParam, +) -> Result { + let note = Note::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); + let user = get_user_from_activity(&update, client, pool).await?; + + let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + + let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) + .await? + .id; + + let updated_comment = blocking(pool, move |conn| { + Comment::update(conn, comment_id, &comment) + }) + .await??; + + let post_id = updated_comment.post_id; + let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??; + + let mentions = scrape_text_for_mentions(&updated_comment.content); + let recipient_ids = send_local_notifs(mentions, updated_comment, &user, post, pool).await?; + + // Refetch the view + let comment_view = + blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; + + let res = CommentResponse { + comment: comment_view, + recipient_ids, + }; + + chat_server.do_send(SendComment { + op: UserOperation::EditComment, + comment: res, + my_id: None, + }); + + announce_if_community_is_local(update, &user, client, pool).await?; + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/community_inbox.rs b/server/src/apub/inbox/community_inbox.rs similarity index 100% rename from server/src/apub/community_inbox.rs rename to server/src/apub/inbox/community_inbox.rs diff --git a/server/src/apub/inbox/mod.rs b/server/src/apub/inbox/mod.rs new file mode 100644 index 000000000..d7b7b7433 --- /dev/null +++ b/server/src/apub/inbox/mod.rs @@ -0,0 +1,4 @@ +pub mod activities; +pub mod community_inbox; +pub mod shared_inbox; +pub mod user_inbox; \ No newline at end of file diff --git a/server/src/apub/inbox/shared_inbox.rs b/server/src/apub/inbox/shared_inbox.rs new file mode 100644 index 000000000..2a51d98ae --- /dev/null +++ b/server/src/apub/inbox/shared_inbox.rs @@ -0,0 +1,136 @@ +use crate::{ + apub::{ + extensions::signatures::verify, + fetcher::{ + get_or_fetch_and_upsert_remote_actor, + get_or_fetch_and_upsert_remote_user, + }, + inbox::activities::{ + announce::receive_announce, + create::receive_create, + delete::receive_delete, + dislike::receive_dislike, + like::receive_like, + remove::receive_remove, + undo::receive_undo, + update::receive_update, + }, + insert_activity, + }, + routes::{ChatServerParam, DbPoolParam}, + DbPool, + LemmyError, +}; +use activitystreams_new::{ + activity::{ActorAndObject, ActorAndObjectRef}, + base::{AsBase}, + prelude::*, +}; +use actix_web::{client::Client, web, HttpRequest, HttpResponse}; +use lemmy_db::{user::User_}; +use log::debug; +use std::fmt::Debug; +use crate::apub::fetcher::get_or_fetch_and_upsert_remote_community; +use activitystreams_new::object::AsObject; +use crate::apub::community::do_announce; +use activitystreams_new::base::Extends; +use serde::Serialize; + +#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "PascalCase")] +pub enum ValidTypes { + Create, + Update, + Like, + Dislike, + Delete, + Undo, + Remove, + Announce, +} + +// TODO: this isnt entirely correct, cause some of these activities are not ActorAndObject, +// but it might still work due to the anybase conversion +pub type AcceptedActivities = ActorAndObject; + +/// Handler for all incoming activities to user inboxes. +pub async fn shared_inbox( + request: HttpRequest, + input: web::Json, + client: web::Data, + pool: DbPoolParam, + chat_server: ChatServerParam, +) -> Result { + let activity = input.into_inner(); + + let json = serde_json::to_string(&activity)?; + debug!("Shared inbox received activity: {}", json); + + let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap(); + + // TODO: pass this actor in instead of using get_user_from_activity() + let actor = get_or_fetch_and_upsert_remote_actor(sender, &client, &pool).await?; + verify(&request, actor.as_ref())?; + + insert_activity(actor.user_id(), activity.clone(), false, &pool).await?; + + let any_base = activity.clone().into_any_base()?; + let kind = activity.kind().unwrap(); + dbg!(kind); + match kind { + ValidTypes::Announce => { + receive_announce(any_base, &client, &pool, chat_server).await + } + ValidTypes::Create => receive_create(any_base, &client, &pool, chat_server).await, + ValidTypes::Update => receive_update(any_base, &client, &pool, chat_server).await, + ValidTypes::Like => receive_like(any_base, &client, &pool, chat_server).await, + ValidTypes::Dislike => receive_dislike(any_base, &client, &pool, chat_server).await, + ValidTypes::Remove => receive_remove(any_base, &client, &pool, chat_server).await, + ValidTypes::Delete => receive_delete(any_base, &client, &pool, chat_server).await, + ValidTypes::Undo => receive_undo(any_base, &client, &pool, chat_server).await, + } +} + +pub(in crate::apub::inbox) fn receive_unhandled_activity(activity: A) -> Result +where + A: Debug, +{ + debug!("received unhandled activity type: {:?}", activity); + Ok(HttpResponse::NotImplemented().finish()) +} + +pub(in crate::apub::inbox) async fn get_user_from_activity( + activity: &T, + client: &Client, + pool: &DbPool, +) -> Result + where + T: AsBase + ActorAndObjectRef, +{ + let actor = activity.actor()?; + let user_uri = actor.as_single_xsd_any_uri().unwrap(); + get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await +} + +pub(in crate::apub::inbox) async fn announce_if_community_is_local( + activity: T, + user: &User_, + client: &Client, + pool: &DbPool, +) -> Result<(), LemmyError> + where + T: AsObject, + T: Extends, + Kind: Serialize, + >::Error: From + Send + Sync + 'static, +{ + let cc = activity.cc().unwrap(); + let cc = cc.as_many().unwrap(); + let community_uri = cc.first().unwrap().as_xsd_any_uri().unwrap(); + let community = get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?; + + if community.local { + do_announce(activity.into_any_base()?, &community, &user, client, pool).await?; + } + Ok(()) +} diff --git a/server/src/apub/user_inbox.rs b/server/src/apub/inbox/user_inbox.rs similarity index 100% rename from server/src/apub/user_inbox.rs rename to server/src/apub/inbox/user_inbox.rs diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index 4e65d9e72..d27dc97cc 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -1,14 +1,12 @@ pub mod activities; pub mod comment; pub mod community; -pub mod community_inbox; pub mod extensions; pub mod fetcher; +pub mod inbox; pub mod post; pub mod private_message; -pub mod shared_inbox; pub mod user; -pub mod user_inbox; use crate::{ apub::extensions::{ @@ -219,6 +217,9 @@ pub trait ActorType { fn public_key(&self) -> String; fn private_key(&self) -> String; + /// numeric id in the database, used for insert_activity + fn user_id(&self) -> i32; + // These two have default impls, since currently a community can't follow anything, // and a user can't be followed (yet) #[allow(unused_variables)] diff --git a/server/src/apub/shared_inbox.rs b/server/src/apub/shared_inbox.rs deleted file mode 100644 index 8d6b255d3..000000000 --- a/server/src/apub/shared_inbox.rs +++ /dev/null @@ -1,1514 +0,0 @@ -use crate::{ - api::{ - comment::{send_local_notifs, CommentResponse}, - community::CommunityResponse, - post::PostResponse, - }, - apub::{ - community::do_announce, - extensions::signatures::verify, - fetcher::{ - get_or_fetch_and_insert_remote_comment, - get_or_fetch_and_insert_remote_post, - get_or_fetch_and_upsert_remote_community, - get_or_fetch_and_upsert_remote_user, - }, - insert_activity, - ActorType, - FromApub, - GroupExt, - PageExt, - }, - blocking, - routes::{ChatServerParam, DbPoolParam}, - websocket::{ - server::{SendComment, SendCommunityRoomMessage, SendPost}, - UserOperation, - }, - DbPool, - LemmyError, -}; -use activitystreams_new::{ - activity::{ActorAndObjectRef, Announce, Create, Delete, Dislike, Like, Remove, Undo, Update}, - base::{AnyBase, AsBase}, - error::DomainError, - object::Note, - prelude::{ExtendsExt, *}, -}; -use actix_web::{client::Client, web, HttpRequest, HttpResponse}; -use lemmy_db::{ - comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, - comment_view::CommentView, - community::{Community, CommunityForm}, - community_view::CommunityView, - naive_now, - post::{Post, PostForm, PostLike, PostLikeForm}, - post_view::PostView, - user::User_, - Crud, - Likeable, -}; -use lemmy_utils::scrape_text_for_mentions; -use log::debug; -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; -use url::Url; - -#[serde(untagged)] -#[derive(Serialize, Deserialize, Debug, Clone)] -pub enum SharedAcceptedObjects { - Create(Box), - Update(Box), - Like(Box), - Dislike(Box), - Delete(Box), - Undo(Box), - Remove(Box), - Announce(Box), -} - -impl SharedAcceptedObjects { - // TODO: these shouldnt be necessary anymore - // https://git.asonix.dog/asonix/ap-relay/src/branch/main/src/apub.rs - fn object(&self) -> Option { - match self { - SharedAcceptedObjects::Create(c) => c.object().to_owned().one(), - SharedAcceptedObjects::Update(u) => u.object().to_owned().one(), - SharedAcceptedObjects::Like(l) => l.object().to_owned().one(), - SharedAcceptedObjects::Dislike(d) => d.object().to_owned().one(), - SharedAcceptedObjects::Delete(d) => d.object().to_owned().one(), - SharedAcceptedObjects::Undo(d) => d.object().to_owned().one(), - SharedAcceptedObjects::Remove(r) => r.object().to_owned().one(), - SharedAcceptedObjects::Announce(a) => a.object().to_owned().one(), - } - } - fn sender(&self) -> Result<&Url, DomainError> { - let uri = match self { - SharedAcceptedObjects::Create(c) => c.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Update(u) => u.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Like(l) => l.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Dislike(d) => d.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Delete(d) => d.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Undo(d) => d.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Remove(r) => r.actor()?.as_single_xsd_any_uri(), - SharedAcceptedObjects::Announce(a) => a.actor()?.as_single_xsd_any_uri(), - }; - Ok(uri.unwrap()) - } - fn cc(&self) -> String { - let cc = match self { - SharedAcceptedObjects::Create(c) => c.cc().to_owned(), - SharedAcceptedObjects::Update(u) => u.cc().to_owned(), - SharedAcceptedObjects::Like(l) => l.cc().to_owned(), - SharedAcceptedObjects::Dislike(d) => d.cc().to_owned(), - SharedAcceptedObjects::Delete(d) => d.cc().to_owned(), - SharedAcceptedObjects::Undo(d) => d.cc().to_owned(), - SharedAcceptedObjects::Remove(r) => r.cc().to_owned(), - SharedAcceptedObjects::Announce(a) => a.cc().to_owned(), - }; - cc.unwrap() - .clone() - .many() - .unwrap() - .first() - .unwrap() - .as_xsd_any_uri() - .unwrap() - .to_string() - } -} - -/// Handler for all incoming activities to user inboxes. -pub async fn shared_inbox( - request: HttpRequest, - input: web::Json, - client: web::Data, - pool: DbPoolParam, - chat_server: ChatServerParam, -) -> Result { - let activity = input.into_inner(); - let pool = &pool; - let client = &client; - - let json = serde_json::to_string(&activity)?; - debug!("Shared inbox received activity: {}", json); - - let sender = &activity.sender()?.clone(); - let cc = activity.to_owned().cc(); - // TODO: this is hacky, we should probably send the community id directly somehow - let to = cc.replace("/followers", ""); - - // TODO: this is ugly - match get_or_fetch_and_upsert_remote_user(sender, &client, pool).await { - Ok(u) => verify(&request, &u)?, - Err(_) => { - let c = get_or_fetch_and_upsert_remote_community(sender, &client, pool).await?; - verify(&request, &c)?; - } - } - - let object = activity.object().unwrap(); - match (activity, object.kind_str()) { - (SharedAcceptedObjects::Create(c), Some("Page")) => { - receive_create_post((*c).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(c.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Update(u), Some("Page")) => { - receive_update_post((*u).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(u.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Like(l), Some("Page")) => { - receive_like_post((*l).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(l.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Dislike(d), Some("Page")) => { - receive_dislike_post((*d).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(d.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Delete(d), Some("Page")) => { - receive_delete_post((*d).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(d.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Remove(r), Some("Page")) => { - receive_remove_post((*r).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(r.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Create(c), Some("Note")) => { - receive_create_comment((*c).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(c.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Update(u), Some("Note")) => { - receive_update_comment((*u).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(u.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Like(l), Some("Note")) => { - receive_like_comment((*l).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(l.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Dislike(d), Some("Note")) => { - receive_dislike_comment((*d).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(d.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Delete(d), Some("Note")) => { - receive_delete_comment((*d).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(d.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Remove(r), Some("Note")) => { - receive_remove_comment((*r).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(r.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Delete(d), Some("Group")) => { - receive_delete_community((*d).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(d.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Remove(r), Some("Group")) => { - receive_remove_community((*r).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(r.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Undo(u), Some("Delete")) => { - receive_undo_delete((*u).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(u.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Undo(u), Some("Remove")) => { - receive_undo_remove((*u).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(u.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Undo(u), Some("Like")) => { - receive_undo_like((*u).clone(), client, pool, chat_server).await?; - announce_activity_if_valid(u.into_any_base()?, &to, sender, client, pool).await - } - (SharedAcceptedObjects::Announce(a), _) => receive_announce(a, client, pool, chat_server).await, - (a, _) => receive_unhandled_activity(a), - } -} - -// TODO: should pass in sender as ActorType, but thats a bit tricky in shared_inbox() -async fn announce_activity_if_valid( - activity: AnyBase, - community_uri: &str, - sender: &Url, - client: &Client, - pool: &DbPool, -) -> Result { - let community_uri = community_uri.to_owned(); - let community = blocking(pool, move |conn| { - Community::read_from_actor_id(conn, &community_uri) - }) - .await??; - - if community.local { - let sending_user = get_or_fetch_and_upsert_remote_user(sender, client, pool).await?; - - do_announce(activity, &community, &sending_user, client, pool).await - } else { - Ok(HttpResponse::NotFound().finish()) - } -} - -async fn receive_announce( - announce: Box, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let object = announce.to_owned().object().clone().one().unwrap(); - // TODO: too much copy paste - match object.kind_str() { - Some("Create") => { - let create = Create::from_any_base(object)?.unwrap(); - match create.object().as_single_kind_str() { - Some("Page") => receive_create_post(create, client, pool, chat_server).await, - Some("Note") => receive_create_comment(create, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Update") => { - let update = Update::from_any_base(object)?.unwrap(); - match update.object().as_single_kind_str() { - Some("Page") => receive_update_post(update, client, pool, chat_server).await, - Some("Note") => receive_update_comment(update, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Like") => { - let like = Like::from_any_base(object)?.unwrap(); - match like.object().as_single_kind_str() { - Some("Page") => receive_like_post(like, client, pool, chat_server).await, - Some("Note") => receive_like_comment(like, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Dislike") => { - let dislike = Dislike::from_any_base(object)?.unwrap(); - match dislike.object().as_single_kind_str() { - Some("Page") => receive_dislike_post(dislike, client, pool, chat_server).await, - Some("Note") => receive_dislike_comment(dislike, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Delete") => { - let delete = Delete::from_any_base(object)?.unwrap(); - match delete.object().as_single_kind_str() { - Some("Page") => receive_delete_post(delete, client, pool, chat_server).await, - Some("Note") => receive_delete_comment(delete, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Remove") => { - let remove = Remove::from_any_base(object)?.unwrap(); - match remove.object().as_single_kind_str() { - Some("Page") => receive_remove_post(remove, client, pool, chat_server).await, - Some("Note") => receive_remove_comment(remove, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - Some("Undo") => { - let undo = Undo::from_any_base(object)?.unwrap(); - match undo.object().as_single_kind_str() { - Some("Delete") => receive_undo_delete(undo, client, pool, chat_server).await, - Some("Remove") => receive_undo_remove(undo, client, pool, chat_server).await, - Some("Like") => receive_undo_like(undo, client, pool, chat_server).await, - _ => receive_unhandled_activity(announce), - } - } - _ => receive_unhandled_activity(announce), - } -} - -fn receive_unhandled_activity(activity: A) -> Result -where - A: Debug, -{ - debug!("received unhandled activity type: {:?}", activity); - Ok(HttpResponse::NotImplemented().finish()) -} - -async fn get_user_from_activity( - activity: &T, - client: &Client, - pool: &DbPool, -) -> Result -where - T: AsBase + ActorAndObjectRef, -{ - let actor = activity.actor()?; - let user_uri = actor.as_single_xsd_any_uri().unwrap(); - get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await -} - -async fn receive_create_post( - create: Create, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&create, client, pool).await?; - let page = PageExt::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, create, false, pool).await?; - - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; - - let inserted_post = blocking(pool, move |conn| Post::create(conn, &post)).await??; - - // Refetch the view - let inserted_post_id = inserted_post.id; - let post_view = blocking(pool, move |conn| { - PostView::read(conn, inserted_post_id, None) - }) - .await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::CreatePost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_create_comment( - create: Create, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&create, client, pool).await?; - let note = Note::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, create, false, pool).await?; - - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; - - let inserted_comment = blocking(pool, move |conn| Comment::create(conn, &comment)).await??; - - let post_id = inserted_comment.post_id; - let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??; - - // Note: - // Although mentions could be gotten from the post tags (they are included there), or the ccs, - // Its much easier to scrape them from the comment body, since the API has to do that - // anyway. - let mentions = scrape_text_for_mentions(&inserted_comment.content); - let recipient_ids = - send_local_notifs(mentions, inserted_comment.clone(), user, post, pool).await?; - - // Refetch the view - let comment_view = blocking(pool, move |conn| { - CommentView::read(conn, inserted_comment.id, None) - }) - .await??; - - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::CreateComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_update_post( - update: Update, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&update, client, pool).await?; - let page = PageExt::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, update, false, pool).await?; - - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; - - let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) - .await? - .id; - - blocking(pool, move |conn| Post::update(conn, post_id, &post)).await??; - - // Refetch the view - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::EditPost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_like_post( - like: Like, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&like, client, pool).await?; - let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, like, false, pool).await?; - - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; - - let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = PostLikeForm { - post_id, - user_id: user.id, - score: 1, - }; - blocking(pool, move |conn| { - PostLike::remove(conn, &like_form)?; - PostLike::like(conn, &like_form) - }) - .await??; - - // Refetch the view - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::CreatePostLike, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_dislike_post( - dislike: Dislike, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&dislike, client, pool).await?; - let page = PageExt::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, dislike, false, pool).await?; - - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; - - let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = PostLikeForm { - post_id, - user_id: user.id, - score: -1, - }; - blocking(pool, move |conn| { - PostLike::remove(conn, &like_form)?; - PostLike::like(conn, &like_form) - }) - .await??; - - // Refetch the view - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::CreatePostLike, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_update_comment( - update: Update, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let note = Note::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); - let user = get_user_from_activity(&update, client, pool).await?; - - insert_activity(user.id, update, false, pool).await?; - - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; - - let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) - .await? - .id; - - let updated_comment = blocking(pool, move |conn| { - Comment::update(conn, comment_id, &comment) - }) - .await??; - - let post_id = updated_comment.post_id; - let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??; - - let mentions = scrape_text_for_mentions(&updated_comment.content); - let recipient_ids = send_local_notifs(mentions, updated_comment, user, post, pool).await?; - - // Refetch the view - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::EditComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_like_comment( - like: Like, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - let user = get_user_from_activity(&like, client, pool).await?; - - insert_activity(user.id, like, false, pool).await?; - - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; - - let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = CommentLikeForm { - comment_id, - post_id: comment.post_id, - user_id: user.id, - score: 1, - }; - blocking(pool, move |conn| { - CommentLike::remove(conn, &like_form)?; - CommentLike::like(conn, &like_form) - }) - .await??; - - // Refetch the view - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::CreateCommentLike, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_dislike_comment( - dislike: Dislike, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let note = Note::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); - let user = get_user_from_activity(&dislike, client, pool).await?; - - insert_activity(user.id, dislike, false, pool).await?; - - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; - - let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = CommentLikeForm { - comment_id, - post_id: comment.post_id, - user_id: user.id, - score: -1, - }; - blocking(pool, move |conn| { - CommentLike::remove(conn, &like_form)?; - CommentLike::like(conn, &like_form) - }) - .await??; - - // Refetch the view - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::CreateCommentLike, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_delete_community( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let user = get_user_from_activity(&delete, client, pool).await?; - - insert_activity(user.id, delete, false, pool).await?; - - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) - .await? - .actor_id; - - let community = blocking(pool, move |conn| { - Community::read_from_actor_id(conn, &community_actor_id) - }) - .await??; - - let community_form = CommunityForm { - name: community.name.to_owned(), - title: community.title.to_owned(), - description: community.description.to_owned(), - category_id: community.category_id, // Note: need to keep this due to foreign key constraint - creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint - removed: None, - published: None, - updated: Some(naive_now()), - deleted: Some(true), - nsfw: community.nsfw, - actor_id: community.actor_id, - local: community.local, - private_key: community.private_key, - public_key: community.public_key, - last_refreshed_at: None, - }; - - let community_id = community.id; - blocking(pool, move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await??; - - let community_id = community.id; - let res = CommunityResponse { - community: blocking(pool, move |conn| { - CommunityView::read(conn, community_id, None) - }) - .await??, - }; - - let community_id = res.community.id; - - chat_server.do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, - response: res, - community_id, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_remove_community( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) - .await? - .actor_id; - - let community = blocking(pool, move |conn| { - Community::read_from_actor_id(conn, &community_actor_id) - }) - .await??; - - let community_form = CommunityForm { - name: community.name.to_owned(), - title: community.title.to_owned(), - description: community.description.to_owned(), - category_id: community.category_id, // Note: need to keep this due to foreign key constraint - creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint - removed: Some(true), - published: None, - updated: Some(naive_now()), - deleted: None, - nsfw: community.nsfw, - actor_id: community.actor_id, - local: community.local, - private_key: community.private_key, - public_key: community.public_key, - last_refreshed_at: None, - }; - - let community_id = community.id; - blocking(pool, move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await??; - - let community_id = community.id; - let res = CommunityResponse { - community: blocking(pool, move |conn| { - CommunityView::read(conn, community_id, None) - }) - .await??, - }; - - let community_id = res.community.id; - - chat_server.do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, - response: res, - community_id, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_delete_post( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&delete, client, pool).await?; - let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, delete, false, pool).await?; - - let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) - .await? - .get_ap_id()?; - - let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; - - let post_form = PostForm { - name: post.name.to_owned(), - url: post.url.to_owned(), - body: post.body.to_owned(), - creator_id: post.creator_id.to_owned(), - community_id: post.community_id, - removed: None, - deleted: Some(true), - nsfw: post.nsfw, - locked: None, - stickied: None, - updated: Some(naive_now()), - embed_title: post.embed_title, - embed_description: post.embed_description, - embed_html: post.embed_html, - thumbnail_url: post.thumbnail_url, - ap_id: post.ap_id, - local: post.local, - published: None, - }; - let post_id = post.id; - blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; - - // Refetch the view - let post_id = post.id; - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::EditPost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_remove_post( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) - .await? - .get_ap_id()?; - - let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; - - let post_form = PostForm { - name: post.name.to_owned(), - url: post.url.to_owned(), - body: post.body.to_owned(), - creator_id: post.creator_id.to_owned(), - community_id: post.community_id, - removed: Some(true), - deleted: None, - nsfw: post.nsfw, - locked: None, - stickied: None, - updated: Some(naive_now()), - embed_title: post.embed_title, - embed_description: post.embed_description, - embed_html: post.embed_html, - thumbnail_url: post.thumbnail_url, - ap_id: post.ap_id, - local: post.local, - published: None, - }; - let post_id = post.id; - blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; - - // Refetch the view - let post_id = post.id; - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::EditPost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_delete_comment( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&delete, client, pool).await?; - let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, delete, false, pool).await?; - - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) - .await? - .get_ap_id()?; - - let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; - - let comment_form = CommentForm { - content: comment.content.to_owned(), - parent_id: comment.parent_id, - post_id: comment.post_id, - creator_id: comment.creator_id, - removed: None, - deleted: Some(true), - read: None, - published: None, - updated: Some(naive_now()), - ap_id: comment.ap_id, - local: comment.local, - }; - let comment_id = comment.id; - blocking(pool, move |conn| { - Comment::update(conn, comment_id, &comment_form) - }) - .await??; - - // Refetch the view - let comment_id = comment.id; - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::EditComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_remove_comment( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) - .await? - .get_ap_id()?; - - let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; - - let comment_form = CommentForm { - content: comment.content.to_owned(), - parent_id: comment.parent_id, - post_id: comment.post_id, - creator_id: comment.creator_id, - removed: Some(true), - deleted: None, - read: None, - published: None, - updated: Some(naive_now()), - ap_id: comment.ap_id, - local: comment.local, - }; - let comment_id = comment.id; - blocking(pool, move |conn| { - Comment::update(conn, comment_id, &comment_form) - }) - .await??; - - // Refetch the view - let comment_id = comment.id; - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::EditComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_delete( - undo: Undo, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let delete = Delete::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); - - let type_ = delete.object().as_single_kind_str().unwrap(); - match type_ { - "Note" => receive_undo_delete_comment(delete, client, pool, chat_server).await, - "Page" => receive_undo_delete_post(delete, client, pool, chat_server).await, - "Group" => receive_undo_delete_community(delete, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), - } -} - -async fn receive_undo_remove( - undo: Undo, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let remove = Remove::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); - - let type_ = remove.object().as_single_kind_str().unwrap(); - match type_ { - "Note" => receive_undo_remove_comment(remove, client, pool, chat_server).await, - "Page" => receive_undo_remove_post(remove, client, pool, chat_server).await, - "Group" => receive_undo_remove_community(remove, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), - } -} - -async fn receive_undo_delete_comment( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&delete, client, pool).await?; - let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, delete, false, pool).await?; - - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) - .await? - .get_ap_id()?; - - let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; - - let comment_form = CommentForm { - content: comment.content.to_owned(), - parent_id: comment.parent_id, - post_id: comment.post_id, - creator_id: comment.creator_id, - removed: None, - deleted: Some(false), - read: None, - published: None, - updated: Some(naive_now()), - ap_id: comment.ap_id, - local: comment.local, - }; - let comment_id = comment.id; - blocking(pool, move |conn| { - Comment::update(conn, comment_id, &comment_form) - }) - .await??; - - // Refetch the view - let comment_id = comment.id; - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::EditComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_remove_comment( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) - .await? - .get_ap_id()?; - - let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; - - let comment_form = CommentForm { - content: comment.content.to_owned(), - parent_id: comment.parent_id, - post_id: comment.post_id, - creator_id: comment.creator_id, - removed: Some(false), - deleted: None, - read: None, - published: None, - updated: Some(naive_now()), - ap_id: comment.ap_id, - local: comment.local, - }; - let comment_id = comment.id; - blocking(pool, move |conn| { - Comment::update(conn, comment_id, &comment_form) - }) - .await??; - - // Refetch the view - let comment_id = comment.id; - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::EditComment, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_delete_post( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&delete, client, pool).await?; - let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, delete, false, pool).await?; - - let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) - .await? - .get_ap_id()?; - - let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; - - let post_form = PostForm { - name: post.name.to_owned(), - url: post.url.to_owned(), - body: post.body.to_owned(), - creator_id: post.creator_id.to_owned(), - community_id: post.community_id, - removed: None, - deleted: Some(false), - nsfw: post.nsfw, - locked: None, - stickied: None, - updated: Some(naive_now()), - embed_title: post.embed_title, - embed_description: post.embed_description, - embed_html: post.embed_html, - thumbnail_url: post.thumbnail_url, - ap_id: post.ap_id, - local: post.local, - published: None, - }; - let post_id = post.id; - blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; - - // Refetch the view - let post_id = post.id; - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::EditPost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_remove_post( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) - .await? - .get_ap_id()?; - - let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; - - let post_form = PostForm { - name: post.name.to_owned(), - url: post.url.to_owned(), - body: post.body.to_owned(), - creator_id: post.creator_id.to_owned(), - community_id: post.community_id, - removed: Some(false), - deleted: None, - nsfw: post.nsfw, - locked: None, - stickied: None, - updated: Some(naive_now()), - embed_title: post.embed_title, - embed_description: post.embed_description, - embed_html: post.embed_html, - thumbnail_url: post.thumbnail_url, - ap_id: post.ap_id, - local: post.local, - published: None, - }; - let post_id = post.id; - blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??; - - // Refetch the view - let post_id = post.id; - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::EditPost, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_delete_community( - delete: Delete, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&delete, client, pool).await?; - let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, delete, false, pool).await?; - - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) - .await? - .actor_id; - - let community = blocking(pool, move |conn| { - Community::read_from_actor_id(conn, &community_actor_id) - }) - .await??; - - let community_form = CommunityForm { - name: community.name.to_owned(), - title: community.title.to_owned(), - description: community.description.to_owned(), - category_id: community.category_id, // Note: need to keep this due to foreign key constraint - creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint - removed: None, - published: None, - updated: Some(naive_now()), - deleted: Some(false), - nsfw: community.nsfw, - actor_id: community.actor_id, - local: community.local, - private_key: community.private_key, - public_key: community.public_key, - last_refreshed_at: None, - }; - - let community_id = community.id; - blocking(pool, move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await??; - - let community_id = community.id; - let res = CommunityResponse { - community: blocking(pool, move |conn| { - CommunityView::read(conn, community_id, None) - }) - .await??, - }; - - let community_id = res.community.id; - - chat_server.do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, - response: res, - community_id, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_remove_community( - remove: Remove, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let mod_ = get_user_from_activity(&remove, client, pool).await?; - let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(mod_.id, remove, false, pool).await?; - - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) - .await? - .actor_id; - - let community = blocking(pool, move |conn| { - Community::read_from_actor_id(conn, &community_actor_id) - }) - .await??; - - let community_form = CommunityForm { - name: community.name.to_owned(), - title: community.title.to_owned(), - description: community.description.to_owned(), - category_id: community.category_id, // Note: need to keep this due to foreign key constraint - creator_id: community.creator_id, // Note: need to keep this due to foreign key constraint - removed: Some(false), - published: None, - updated: Some(naive_now()), - deleted: None, - nsfw: community.nsfw, - actor_id: community.actor_id, - local: community.local, - private_key: community.private_key, - public_key: community.public_key, - last_refreshed_at: None, - }; - - let community_id = community.id; - blocking(pool, move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await??; - - let community_id = community.id; - let res = CommunityResponse { - community: blocking(pool, move |conn| { - CommunityView::read(conn, community_id, None) - }) - .await??, - }; - - let community_id = res.community.id; - - chat_server.do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, - response: res, - community_id, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_like( - undo: Undo, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let like = Like::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); - - let type_ = like.object().as_single_kind_str().unwrap(); - match type_ { - "Note" => receive_undo_like_comment(like, client, pool, chat_server).await, - "Page" => receive_undo_like_post(like, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), - } -} - -async fn receive_undo_like_comment( - like: Like, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&like, client, pool).await?; - let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, like, false, pool).await?; - - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; - - let comment_id = get_or_fetch_and_insert_remote_comment(&comment.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = CommentLikeForm { - comment_id, - post_id: comment.post_id, - user_id: user.id, - score: 0, - }; - blocking(pool, move |conn| CommentLike::remove(conn, &like_form)).await??; - - // Refetch the view - let comment_view = - blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??; - - // TODO get those recipient actor ids from somewhere - let recipient_ids = vec![]; - let res = CommentResponse { - comment: comment_view, - recipient_ids, - }; - - chat_server.do_send(SendComment { - op: UserOperation::CreateCommentLike, - comment: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} - -async fn receive_undo_like_post( - like: Like, - client: &Client, - pool: &DbPool, - chat_server: ChatServerParam, -) -> Result { - let user = get_user_from_activity(&like, client, pool).await?; - let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - - insert_activity(user.id, like, false, pool).await?; - - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; - - let post_id = get_or_fetch_and_insert_remote_post(&post.get_ap_id()?, client, pool) - .await? - .id; - - let like_form = PostLikeForm { - post_id, - user_id: user.id, - score: 1, - }; - blocking(pool, move |conn| PostLike::remove(conn, &like_form)).await??; - - // Refetch the view - let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??; - - let res = PostResponse { post: post_view }; - - chat_server.do_send(SendPost { - op: UserOperation::CreatePostLike, - post: res, - my_id: None, - }); - - Ok(HttpResponse::Ok().finish()) -} diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 2a98670ce..e60e469a9 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -186,6 +186,10 @@ impl ActorType for User_ { async fn get_follower_inboxes(&self, _pool: &DbPool) -> Result, LemmyError> { unimplemented!() } + + fn user_id(&self) -> i32 { + self.id + } } #[async_trait::async_trait(?Send)] diff --git a/server/src/routes/federation.rs b/server/src/routes/federation.rs index cd4c47803..2d12f99fd 100644 --- a/server/src/routes/federation.rs +++ b/server/src/routes/federation.rs @@ -1,11 +1,11 @@ use crate::apub::{ comment::get_apub_comment, community::*, - community_inbox::community_inbox, + inbox::community_inbox::community_inbox, post::get_apub_post, - shared_inbox::shared_inbox, + inbox::shared_inbox::shared_inbox, user::*, - user_inbox::user_inbox, + inbox::user_inbox::user_inbox, APUB_JSON_CONTENT_TYPE, }; use actix_web::*; From 494fcfdb8fb2a6db18872005ce2061bc7ee6876b Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Tue, 28 Jul 2020 18:47:26 +0200 Subject: [PATCH 2/5] Add helper function to generate proper activity IDs --- server/src/apub/activities.rs | 26 +++++-- server/src/apub/comment.rs | 72 ++++++-------------- server/src/apub/community.rs | 56 +++++---------- server/src/apub/fetcher.rs | 15 +--- server/src/apub/inbox/activities/announce.rs | 12 +--- server/src/apub/inbox/activities/create.rs | 11 +-- server/src/apub/inbox/activities/delete.rs | 12 +--- server/src/apub/inbox/activities/dislike.rs | 11 +-- server/src/apub/inbox/activities/like.rs | 11 +-- server/src/apub/inbox/activities/remove.rs | 12 +--- server/src/apub/inbox/activities/undo.rs | 15 ++-- server/src/apub/inbox/activities/update.rs | 11 +-- server/src/apub/inbox/community_inbox.rs | 3 +- server/src/apub/inbox/shared_inbox.rs | 15 ++-- server/src/apub/inbox/user_inbox.rs | 9 +-- server/src/apub/mod.rs | 14 ++-- server/src/apub/post.rs | 71 ++++++------------- server/src/apub/private_message.rs | 39 ++++------- server/src/apub/user.rs | 33 +++++---- 19 files changed, 152 insertions(+), 296 deletions(-) diff --git a/server/src/apub/activities.rs b/server/src/apub/activities.rs index a14e6ec37..9cc20af80 100644 --- a/server/src/apub/activities.rs +++ b/server/src/apub/activities.rs @@ -1,20 +1,18 @@ use crate::{ apub::{ - community::do_announce, - extensions::signatures::sign, - insert_activity, - is_apub_id_valid, + community::do_announce, extensions::signatures::sign, insert_activity, is_apub_id_valid, ActorType, }, request::retry_custom, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::base::AnyBase; use actix_web::client::Client; use lemmy_db::{community::Community, user::User_}; +use lemmy_utils::{get_apub_protocol_string, settings::Settings}; use log::debug; -use url::Url; +use url::{ParseError, Url}; +use uuid::Uuid; pub async fn send_activity_to_community( creator: &User_, @@ -68,3 +66,17 @@ pub async fn send_activity( Ok(()) } + +pub(in crate::apub) fn generate_activity_id(kind: T) -> Result +where + T: ToString, +{ + let id = format!( + "{}://{}/activities/{}/{}", + get_apub_protocol_string(), + Settings::get().hostname, + kind.to_string().to_lowercase(), + Uuid::new_v4() + ); + Url::parse(&id) +} diff --git a/server/src/apub/comment.rs b/server/src/apub/comment.rs index 774abba6b..61a1d15e4 100644 --- a/server/src/apub/comment.rs +++ b/server/src/apub/comment.rs @@ -1,28 +1,22 @@ use crate::{ apub::{ - activities::send_activity_to_community, - create_apub_response, - create_apub_tombstone_response, - create_tombstone, - fetch_webfinger_url, + activities::{generate_activity_id, send_activity_to_community}, + create_apub_response, create_apub_tombstone_response, create_tombstone, fetch_webfinger_url, fetcher::{ - get_or_fetch_and_insert_remote_comment, - get_or_fetch_and_insert_remote_post, + get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post, get_or_fetch_and_upsert_remote_user, }, - ActorType, - ApubLikeableType, - ApubObjectType, - FromApub, - ToApub, + ActorType, ApubLikeableType, ApubObjectType, FromApub, ToApub, }, blocking, routes::DbPoolParam, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{ - activity::{Create, Delete, Dislike, Like, Remove, Undo, Update}, + activity::{ + kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, + Create, Delete, Dislike, Like, Remove, Undo, Update, + }, base::AnyBase, context, link::Mention, @@ -109,12 +103,7 @@ impl ToApub for Comment { } fn to_tombstone(&self) -> Result { - create_tombstone( - self.deleted, - &self.ap_id, - self.updated, - NoteType::Note.to_string(), - ) + create_tombstone(self.deleted, &self.ap_id, self.updated, NoteType::Note) } } @@ -204,11 +193,10 @@ impl ApubObjectType for Comment { let maa = collect_non_local_mentions_and_addresses(&self.content, &community, client, pool).await?; - let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4()); let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?); create .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(CreateType::Create)?) .set_to(public()) .set_many_ccs(maa.addressed_ccs.to_owned()) // Set the mention tags @@ -244,11 +232,10 @@ impl ApubObjectType for Comment { let maa = collect_non_local_mentions_and_addresses(&self.content, &community, client, pool).await?; - let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4()); let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?); update .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(UpdateType::Update)?) .set_to(public()) .set_many_ccs(maa.addressed_ccs.to_owned()) // Set the mention tags @@ -280,11 +267,10 @@ impl ApubObjectType for Comment { let community_id = post.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -315,21 +301,18 @@ impl ApubObjectType for Comment { let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; // Generate a fake delete activity, with the correct object - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -359,11 +342,10 @@ impl ApubObjectType for Comment { let community_id = post.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -394,20 +376,18 @@ impl ApubObjectType for Comment { let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; // Generate a fake delete activity, with the correct object - let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); // Undo that fake activity - let undo_id = format!("{}/undo/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -440,12 +420,10 @@ impl ApubLikeableType for Comment { let community_id = post.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?); like .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(LikeType::Like)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -475,12 +453,10 @@ impl ApubLikeableType for Comment { let community_id = post.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut dislike = Dislike::new(creator.actor_id.to_owned(), note.into_any_base()?); dislike .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DislikeType::Dislike)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -510,22 +486,18 @@ impl ApubLikeableType for Comment { let community_id = post.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?); like .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DislikeType::Dislike)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/like/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index a3f58f5d4..16d13711e 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -1,26 +1,21 @@ use crate::{ apub::{ - activities::send_activity, - create_apub_response, - create_apub_tombstone_response, - create_tombstone, + activities::{generate_activity_id, send_activity}, + create_apub_response, create_apub_tombstone_response, create_tombstone, extensions::group_extensions::GroupExtension, fetcher::get_or_fetch_and_upsert_remote_user, - get_shared_inbox, - insert_activity, - ActorType, - FromApub, - GroupExt, - ToApub, + get_shared_inbox, insert_activity, ActorType, FromApub, GroupExt, ToApub, }, blocking, routes::DbPoolParam, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_ext::Ext2; use activitystreams_new::{ - activity::{Accept, Announce, Delete, Follow, Remove, Undo}, + activity::{ + kind::{AcceptType, AnnounceType, DeleteType, LikeType, RemoveType, UndoType}, + Accept, Announce, Delete, Follow, Remove, Undo, + }, actor::{kind::GroupType, ApActor, Endpoints, Group}, base::{AnyBase, BaseExt}, collection::UnorderedCollection, @@ -107,12 +102,7 @@ impl ToApub for Community { } fn to_tombstone(&self) -> Result { - create_tombstone( - self.deleted, - &self.actor_id, - self.updated, - GroupType::Group.to_string(), - ) + create_tombstone(self.deleted, &self.actor_id, self.updated, GroupType::Group) } } @@ -137,13 +127,12 @@ impl ActorType for Community { pool: &DbPool, ) -> Result<(), LemmyError> { let actor_uri = follow.actor()?.as_single_xsd_any_uri().unwrap().to_string(); - let id = format!("{}/accept/{}", self.actor_id, uuid::Uuid::new_v4()); let mut accept = Accept::new(self.actor_id.to_owned(), follow.into_any_base()?); let to = format!("{}/inbox", actor_uri); accept .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(AcceptType::Accept)?) .set_to(to.clone()); insert_activity(self.creator_id, accept.clone(), true, pool).await?; @@ -160,12 +149,10 @@ impl ActorType for Community { ) -> Result<(), LemmyError> { let group = self.to_apub(pool).await?; - let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4()); - let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); @@ -188,22 +175,19 @@ impl ActorType for Community { ) -> Result<(), LemmyError> { let group = self.to_apub(pool).await?; - let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4()); - let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); // TODO // Undo that fake activity - let undo_id = format!("{}/undo/delete/{}", self.actor_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); @@ -226,12 +210,10 @@ impl ActorType for Community { ) -> Result<(), LemmyError> { let group = self.to_apub(pool).await?; - let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4()); - let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); @@ -254,21 +236,18 @@ impl ActorType for Community { ) -> Result<(), LemmyError> { let group = self.to_apub(pool).await?; - let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4()); - let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); // Undo that fake activity - let undo_id = format!("{}/undo/remove/{}", self.actor_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(LikeType::Like)?) .set_to(public()) .set_many_ccs(vec![self.get_followers_url()]); @@ -435,11 +414,10 @@ pub async fn do_announce( client: &Client, pool: &DbPool, ) -> Result<(), LemmyError> { - let id = format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4()); let mut announce = Announce::new(community.actor_id.to_owned(), activity); announce .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(AnnounceType::Announce)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index 5fd394157..cf1986365 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -1,19 +1,12 @@ use crate::{ api::site::SearchResponse, apub::{ - is_apub_id_valid, - ActorType, - FromApub, - GroupExt, - PageExt, - PersonExt, - APUB_JSON_CONTENT_TYPE, + is_apub_id_valid, ActorType, FromApub, GroupExt, PageExt, PersonExt, APUB_JSON_CONTENT_TYPE, }, blocking, request::{retry, RecvError}, routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{base::BaseExt, object::Note, prelude::*}; use actix_web::client::Client; @@ -29,9 +22,7 @@ use lemmy_db::{ post_view::PostView, user::{UserForm, User_}, user_view::UserView, - Crud, - Joinable, - SearchType, + Crud, Joinable, SearchType, }; use lemmy_utils::get_apub_protocol_string; use log::debug; diff --git a/server/src/apub/inbox/activities/announce.rs b/server/src/apub/inbox/activities/announce.rs index 78a005fb1..ae1351836 100644 --- a/server/src/apub/inbox/activities/announce.rs +++ b/server/src/apub/inbox/activities/announce.rs @@ -1,19 +1,13 @@ use crate::{ apub::inbox::{ activities::{ - create::receive_create, - delete::receive_delete, - dislike::receive_dislike, - like::receive_like, - remove::receive_remove, - undo::receive_undo, - update::receive_update, + create::receive_create, delete::receive_delete, dislike::receive_dislike, like::receive_like, + remove::receive_remove, undo::receive_undo, update::receive_update, }, shared_inbox::receive_unhandled_activity, }, routes::ChatServerParam, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::*, base::AnyBase, prelude::ExtendsExt}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/create.rs b/server/src/apub/inbox/activities/create.rs index da90bea53..4390b1a82 100644 --- a/server/src/apub/inbox/activities/create.rs +++ b/server/src/apub/inbox/activities/create.rs @@ -5,13 +5,9 @@ use crate::{ }, apub::{ inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - PageExt, + ActorType, FromApub, PageExt, }, blocking, routes::ChatServerParam, @@ -19,8 +15,7 @@ use crate::{ server::{SendComment, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Create, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/delete.rs b/server/src/apub/inbox/activities/delete.rs index 4b072ebdd..820786539 100644 --- a/server/src/apub/inbox/activities/delete.rs +++ b/server/src/apub/inbox/activities/delete.rs @@ -3,14 +3,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - GroupExt, - PageExt, + ActorType, FromApub, GroupExt, PageExt, }, blocking, routes::ChatServerParam, @@ -18,8 +13,7 @@ use crate::{ server::{SendComment, SendCommunityRoomMessage, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Delete, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/dislike.rs b/server/src/apub/inbox/activities/dislike.rs index 94790220c..bbb868e7d 100644 --- a/server/src/apub/inbox/activities/dislike.rs +++ b/server/src/apub/inbox/activities/dislike.rs @@ -3,13 +3,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - PageExt, + ActorType, FromApub, PageExt, }, blocking, routes::ChatServerParam, @@ -17,8 +13,7 @@ use crate::{ server::{SendComment, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Dislike, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/like.rs b/server/src/apub/inbox/activities/like.rs index 1df20a056..893b68c31 100644 --- a/server/src/apub/inbox/activities/like.rs +++ b/server/src/apub/inbox/activities/like.rs @@ -3,13 +3,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - PageExt, + ActorType, FromApub, PageExt, }, blocking, routes::ChatServerParam, @@ -17,8 +13,7 @@ use crate::{ server::{SendComment, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Like, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/remove.rs b/server/src/apub/inbox/activities/remove.rs index cb2a1292b..8b1630d80 100644 --- a/server/src/apub/inbox/activities/remove.rs +++ b/server/src/apub/inbox/activities/remove.rs @@ -3,14 +3,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - GroupExt, - PageExt, + ActorType, FromApub, GroupExt, PageExt, }, blocking, routes::ChatServerParam, @@ -18,8 +13,7 @@ use crate::{ server::{SendComment, SendCommunityRoomMessage, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Remove, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/activities/undo.rs b/server/src/apub/inbox/activities/undo.rs index 3c5bdb68b..ad62a8f6e 100644 --- a/server/src/apub/inbox/activities/undo.rs +++ b/server/src/apub/inbox/activities/undo.rs @@ -3,14 +3,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - GroupExt, - PageExt, + ActorType, FromApub, GroupExt, PageExt, }, blocking, routes::ChatServerParam, @@ -18,8 +13,7 @@ use crate::{ server::{SendComment, SendCommunityRoomMessage, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::*, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; @@ -31,8 +25,7 @@ use lemmy_db::{ naive_now, post::{Post, PostForm, PostLike, PostLikeForm}, post_view::PostView, - Crud, - Likeable, + Crud, Likeable, }; pub async fn receive_undo( diff --git a/server/src/apub/inbox/activities/update.rs b/server/src/apub/inbox/activities/update.rs index f46c7ff78..306d8ef71 100644 --- a/server/src/apub/inbox/activities/update.rs +++ b/server/src/apub/inbox/activities/update.rs @@ -6,13 +6,9 @@ use crate::{ apub::{ fetcher::{get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post}, inbox::shared_inbox::{ - announce_if_community_is_local, - get_user_from_activity, - receive_unhandled_activity, + announce_if_community_is_local, get_user_from_activity, receive_unhandled_activity, }, - ActorType, - FromApub, - PageExt, + ActorType, FromApub, PageExt, }, blocking, routes::ChatServerParam, @@ -20,8 +16,7 @@ use crate::{ server::{SendComment, SendPost}, UserOperation, }, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{activity::Update, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; diff --git a/server/src/apub/inbox/community_inbox.rs b/server/src/apub/inbox/community_inbox.rs index 3b8236749..44a1c949d 100644 --- a/server/src/apub/inbox/community_inbox.rs +++ b/server/src/apub/inbox/community_inbox.rs @@ -2,8 +2,7 @@ use crate::{ apub::{ extensions::signatures::verify, fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}, - insert_activity, - ActorType, + insert_activity, ActorType, }, blocking, routes::{ChatServerParam, DbPoolParam}, diff --git a/server/src/apub/inbox/shared_inbox.rs b/server/src/apub/inbox/shared_inbox.rs index f406d83ac..eb3d521bb 100644 --- a/server/src/apub/inbox/shared_inbox.rs +++ b/server/src/apub/inbox/shared_inbox.rs @@ -3,25 +3,18 @@ use crate::{ community::do_announce, extensions::signatures::verify, fetcher::{ - get_or_fetch_and_upsert_remote_actor, - get_or_fetch_and_upsert_remote_community, + get_or_fetch_and_upsert_remote_actor, get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user, }, inbox::activities::{ - announce::receive_announce, - create::receive_create, - delete::receive_delete, - dislike::receive_dislike, - like::receive_like, - remove::receive_remove, - undo::receive_undo, + announce::receive_announce, create::receive_create, delete::receive_delete, + dislike::receive_dislike, like::receive_like, remove::receive_remove, undo::receive_undo, update::receive_update, }, insert_activity, }, routes::{ChatServerParam, DbPoolParam}, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{ activity::{ActorAndObject, ActorAndObjectRef}, diff --git a/server/src/apub/inbox/user_inbox.rs b/server/src/apub/inbox/user_inbox.rs index 7b589b28c..73916ee2c 100644 --- a/server/src/apub/inbox/user_inbox.rs +++ b/server/src/apub/inbox/user_inbox.rs @@ -3,14 +3,12 @@ use crate::{ apub::{ extensions::signatures::verify, fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}, - insert_activity, - FromApub, + insert_activity, FromApub, }, blocking, routes::{ChatServerParam, DbPoolParam}, websocket::{server::SendUserRoomMessage, UserOperation}, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_new::{ activity::{Accept, Create, Delete, Undo, Update}, @@ -24,8 +22,7 @@ use lemmy_db::{ private_message::{PrivateMessage, PrivateMessageForm}, private_message_view::PrivateMessageView, user::User_, - Crud, - Followable, + Crud, Followable, }; use log::debug; use serde::Deserialize; diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index d27dc97cc..a5d8984c8 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -17,8 +17,7 @@ use crate::{ blocking, request::{retry, RecvError}, routes::webfinger::WebFingerResponse, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_ext::{Ext1, Ext2}; use activitystreams_new::{ @@ -101,17 +100,20 @@ pub trait ToApub { } /// Updated is actually the deletion time -fn create_tombstone( +fn create_tombstone( deleted: bool, object_id: &str, updated: Option, - former_type: String, -) -> Result { + former_type: T, +) -> Result +where + T: ToString, +{ if deleted { if let Some(updated) = updated { let mut tombstone = Tombstone::new(); tombstone.set_id(object_id.parse()?); - tombstone.set_former_type(former_type); + tombstone.set_former_type(former_type.to_string()); tombstone.set_deleted(convert_datetime(updated)); Ok(tombstone) } else { diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index 9575a6c7c..aca2984b3 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -1,26 +1,21 @@ use crate::{ apub::{ - activities::send_activity_to_community, - create_apub_response, - create_apub_tombstone_response, - create_tombstone, + activities::{generate_activity_id, send_activity_to_community}, + create_apub_response, create_apub_tombstone_response, create_tombstone, extensions::page_extension::PageExtension, fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}, - ActorType, - ApubLikeableType, - ApubObjectType, - FromApub, - PageExt, - ToApub, + ActorType, ApubLikeableType, ApubObjectType, FromApub, PageExt, ToApub, }, blocking, routes::DbPoolParam, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_ext::Ext1; use activitystreams_new::{ - activity::{Create, Delete, Dislike, Like, Remove, Undo, Update}, + activity::{ + kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, + Create, Delete, Dislike, Like, Remove, Undo, Update, + }, context, object::{kind::PageType, Image, Page, Tombstone}, prelude::*, @@ -139,12 +134,7 @@ impl ToApub for Post { } fn to_tombstone(&self) -> Result { - create_tombstone( - self.deleted, - &self.ap_id, - self.updated, - PageType::Page.to_string(), - ) + create_tombstone(self.deleted, &self.ap_id, self.updated, PageType::Page) } } @@ -274,12 +264,10 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut create = Create::new(creator.actor_id.to_owned(), page.into_any_base()?); create .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(CreateType::Create)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -307,12 +295,10 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut update = Update::new(creator.actor_id.to_owned(), page.into_any_base()?); update .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(UpdateType::Update)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -339,11 +325,10 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -370,21 +355,18 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -411,11 +393,10 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -442,20 +423,18 @@ impl ApubObjectType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?); remove .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(RemoveType::Remove)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); // Undo that fake activity - let undo_id = format!("{}/undo/remove/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -485,12 +464,10 @@ impl ApubLikeableType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?); like .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(LikeType::Like)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -517,12 +494,10 @@ impl ApubLikeableType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut dislike = Dislike::new(creator.actor_id.to_owned(), page.into_any_base()?); dislike .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DislikeType::Dislike)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); @@ -549,22 +524,18 @@ impl ApubLikeableType for Post { let community_id = self.community_id; let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??; - let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4()); - let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?); like .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(LikeType::Like)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/like/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(public()) .set_many_ccs(vec![community.get_followers_url()]); diff --git a/server/src/apub/private_message.rs b/server/src/apub/private_message.rs index 94cadeec2..b10f87b55 100644 --- a/server/src/apub/private_message.rs +++ b/server/src/apub/private_message.rs @@ -1,19 +1,17 @@ use crate::{ apub::{ - activities::send_activity, + activities::{generate_activity_id, send_activity}, create_tombstone, fetcher::get_or_fetch_and_upsert_remote_user, - insert_activity, - ApubObjectType, - FromApub, - ToApub, + insert_activity, ApubObjectType, FromApub, ToApub, }, - blocking, - DbPool, - LemmyError, + blocking, DbPool, LemmyError, }; use activitystreams_new::{ - activity::{Create, Delete, Undo, Update}, + activity::{ + kind::{CreateType, DeleteType, UndoType, UpdateType}, + Create, Delete, Undo, Update, + }, context, object::{kind::NoteType, Note, Tombstone}, prelude::*, @@ -56,12 +54,7 @@ impl ToApub for PrivateMessage { } fn to_tombstone(&self) -> Result { - create_tombstone( - self.deleted, - &self.ap_id, - self.updated, - NoteType::Note.to_string(), - ) + create_tombstone(self.deleted, &self.ap_id, self.updated, NoteType::Note) } } @@ -118,7 +111,6 @@ impl ApubObjectType for PrivateMessage { pool: &DbPool, ) -> Result<(), LemmyError> { let note = self.to_apub(pool).await?; - let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4()); let recipient_id = self.recipient_id; let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??; @@ -127,7 +119,7 @@ impl ApubObjectType for PrivateMessage { let to = format!("{}/inbox", recipient.actor_id); create .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(CreateType::Create)?) .set_to(to.clone()); insert_activity(creator.id, create.clone(), true, pool).await?; @@ -144,7 +136,6 @@ impl ApubObjectType for PrivateMessage { pool: &DbPool, ) -> Result<(), LemmyError> { let note = self.to_apub(pool).await?; - let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4()); let recipient_id = self.recipient_id; let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??; @@ -153,7 +144,7 @@ impl ApubObjectType for PrivateMessage { let to = format!("{}/inbox", recipient.actor_id); update .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(UpdateType::Update)?) .set_to(to.clone()); insert_activity(creator.id, update.clone(), true, pool).await?; @@ -169,7 +160,6 @@ impl ApubObjectType for PrivateMessage { pool: &DbPool, ) -> Result<(), LemmyError> { let note = self.to_apub(pool).await?; - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let recipient_id = self.recipient_id; let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??; @@ -178,7 +168,7 @@ impl ApubObjectType for PrivateMessage { let to = format!("{}/inbox", recipient.actor_id); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(to.clone()); insert_activity(creator.id, delete.clone(), true, pool).await?; @@ -194,7 +184,6 @@ impl ApubObjectType for PrivateMessage { pool: &DbPool, ) -> Result<(), LemmyError> { let note = self.to_apub(pool).await?; - let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let recipient_id = self.recipient_id; let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??; @@ -203,16 +192,14 @@ impl ApubObjectType for PrivateMessage { let to = format!("{}/inbox", recipient.actor_id); delete .set_context(context()) - .set_id(Url::parse(&id)?) + .set_id(generate_activity_id(DeleteType::Delete)?) .set_to(to.clone()); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/delete/{}", self.ap_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?); undo .set_context(context()) - .set_id(Url::parse(&undo_id)?) + .set_id(generate_activity_id(UndoType::Undo)?) .set_to(to.clone()); insert_activity(creator.id, undo.clone(), true, pool).await?; diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 85ed1846c..8ec972dad 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -1,21 +1,18 @@ use crate::{ apub::{ - activities::send_activity, - create_apub_response, - insert_activity, - ActorType, - FromApub, - PersonExt, - ToApub, + activities::{generate_activity_id, send_activity}, + create_apub_response, insert_activity, ActorType, FromApub, PersonExt, ToApub, }, blocking, routes::DbPoolParam, - DbPool, - LemmyError, + DbPool, LemmyError, }; use activitystreams_ext::Ext1; use activitystreams_new::{ - activity::{Follow, Undo}, + activity::{ + kind::{FollowType, UndoType}, + Follow, Undo, + }, actor::{ApActor, Endpoints, Person}, context, object::{Image, Tombstone}, @@ -102,9 +99,10 @@ impl ActorType for User_ { client: &Client, pool: &DbPool, ) -> Result<(), LemmyError> { - let id = format!("{}/follow/{}", self.actor_id, uuid::Uuid::new_v4()); let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id); - follow.set_context(context()).set_id(id.parse()?); + follow + .set_context(context()) + .set_id(generate_activity_id(FollowType::Follow)?); let to = format!("{}/inbox", follow_actor_id); insert_activity(self.id, follow.clone(), true, pool).await?; @@ -119,17 +117,18 @@ impl ActorType for User_ { client: &Client, pool: &DbPool, ) -> Result<(), LemmyError> { - let id = format!("{}/follow/{}", self.actor_id, uuid::Uuid::new_v4()); let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id); - follow.set_context(context()).set_id(id.parse()?); + follow + .set_context(context()) + .set_id(generate_activity_id(FollowType::Follow)?); let to = format!("{}/inbox", follow_actor_id); - // TODO // Undo that fake activity - let undo_id = format!("{}/undo/follow/{}", self.actor_id, uuid::Uuid::new_v4()); let mut undo = Undo::new(Url::parse(&self.actor_id)?, follow.into_any_base()?); - undo.set_context(context()).set_id(undo_id.parse()?); + undo + .set_context(context()) + .set_id(generate_activity_id(UndoType::Undo)?); insert_activity(self.id, undo.clone(), true, pool).await?; From b2d2553305c2460f373d880c418a9aee97870072 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 28 Jul 2020 19:37:19 -0400 Subject: [PATCH 3/5] Adding a unit test for a federated comment like. --- ui/src/api_tests/api.spec.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ui/src/api_tests/api.spec.ts b/ui/src/api_tests/api.spec.ts index 52ef4fda9..9f498f8b1 100644 --- a/ui/src/api_tests/api.spec.ts +++ b/ui/src/api_tests/api.spec.ts @@ -618,6 +618,37 @@ describe('main', () => { }); }); + describe('federated comment like', () => { + test('/u/lemmy_beta likes a comment from /u/lemmy_alpha, the like is on both instances', async () => { + // Do a like, to test it (its also been unliked, so its at 0) + let likeCommentForm: CommentLikeForm = { + comment_id: 1, + score: 1, + auth: lemmyBetaAuth, + }; + + let likeCommentRes: CommentResponse = await fetch( + `${lemmyBetaApiUrl}/comment/like`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: wrapper(likeCommentForm), + } + ).then(d => d.json()); + + expect(likeCommentRes.comment.score).toBe(1); + + let getPostUrl = `${lemmyAlphaApiUrl}/post?id=2`; + let getPostRes: GetPostResponse = await fetch(getPostUrl, { + method: 'GET', + }).then(d => d.json()); + + expect(getPostRes.comments[2].score).toBe(1); + }); + }); + describe('delete things', () => { test('/u/lemmy_beta deletes and undeletes a federated comment, post, and community, lemmy_alpha sees its deleted.', async () => { // Create a test community From a85873d294171bd6d32ebbdc44fc4ae2fcb231ad Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 29 Jul 2020 13:46:11 +0200 Subject: [PATCH 4/5] Take correct community uri in shared_inbox, rename fetch_remote* methods --- server/src/apub/activities.rs | 8 +++-- server/src/apub/comment.rs | 35 ++++++++++++++------ server/src/apub/community.rs | 25 ++++++++++---- server/src/apub/fetcher.rs | 35 ++++++++++++-------- server/src/apub/inbox/activities/announce.rs | 12 +++++-- server/src/apub/inbox/activities/create.rs | 11 ++++-- server/src/apub/inbox/activities/delete.rs | 18 ++++++---- server/src/apub/inbox/activities/dislike.rs | 17 ++++++---- server/src/apub/inbox/activities/like.rs | 17 ++++++---- server/src/apub/inbox/activities/remove.rs | 18 ++++++---- server/src/apub/inbox/activities/undo.rs | 29 ++++++++++------ server/src/apub/inbox/activities/update.rs | 17 ++++++---- server/src/apub/inbox/community_inbox.rs | 9 ++--- server/src/apub/inbox/shared_inbox.rs | 31 ++++++++++++----- server/src/apub/inbox/user_inbox.rs | 21 +++++++----- server/src/apub/mod.rs | 3 +- server/src/apub/post.rs | 29 +++++++++++----- server/src/apub/private_message.rs | 20 +++++++---- server/src/apub/user.rs | 13 ++++++-- 19 files changed, 250 insertions(+), 118 deletions(-) diff --git a/server/src/apub/activities.rs b/server/src/apub/activities.rs index 9cc20af80..a622c691d 100644 --- a/server/src/apub/activities.rs +++ b/server/src/apub/activities.rs @@ -1,10 +1,14 @@ use crate::{ apub::{ - community::do_announce, extensions::signatures::sign, insert_activity, is_apub_id_valid, + community::do_announce, + extensions::signatures::sign, + insert_activity, + is_apub_id_valid, ActorType, }, request::retry_custom, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_new::base::AnyBase; use actix_web::client::Client; diff --git a/server/src/apub/comment.rs b/server/src/apub/comment.rs index 61a1d15e4..269e7fc25 100644 --- a/server/src/apub/comment.rs +++ b/server/src/apub/comment.rs @@ -1,21 +1,36 @@ use crate::{ apub::{ activities::{generate_activity_id, send_activity_to_community}, - create_apub_response, create_apub_tombstone_response, create_tombstone, fetch_webfinger_url, + create_apub_response, + create_apub_tombstone_response, + create_tombstone, + fetch_webfinger_url, fetcher::{ - get_or_fetch_and_insert_remote_comment, get_or_fetch_and_insert_remote_post, - get_or_fetch_and_upsert_remote_user, + get_or_fetch_and_insert_comment, + get_or_fetch_and_insert_post, + get_or_fetch_and_upsert_user, }, - ActorType, ApubLikeableType, ApubObjectType, FromApub, ToApub, + ActorType, + ApubLikeableType, + ApubObjectType, + FromApub, + ToApub, }, blocking, routes::DbPoolParam, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_new::{ activity::{ kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, - Create, Delete, Dislike, Like, Remove, Undo, Update, + Create, + Delete, + Dislike, + Like, + Remove, + Undo, + Update, }, base::AnyBase, context, @@ -124,7 +139,7 @@ impl FromApub for CommentForm { .as_single_xsd_any_uri() .unwrap(); - let creator = get_or_fetch_and_upsert_remote_user(creator_actor_id, client, pool).await?; + let creator = get_or_fetch_and_upsert_user(creator_actor_id, client, pool).await?; let mut in_reply_tos = note .in_reply_to() @@ -137,7 +152,7 @@ impl FromApub for CommentForm { let post_ap_id = in_reply_tos.next().unwrap(); // This post, or the parent comment might not yet exist on this server yet, fetch them. - let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; + let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?; // The 2nd item, if it exists, is the parent comment apub_id // For deeply nested comments, FromApub automatically gets called recursively @@ -145,7 +160,7 @@ impl FromApub for CommentForm { Some(parent_comment_uri) => { let parent_comment_ap_id = &parent_comment_uri; let parent_comment = - get_or_fetch_and_insert_remote_comment(&parent_comment_ap_id, client, pool).await?; + get_or_fetch_and_insert_comment(&parent_comment_ap_id, client, pool).await?; Some(parent_comment.id) } @@ -558,7 +573,7 @@ async fn collect_non_local_mentions_and_addresses( debug!("mention actor_id: {}", actor_id); addressed_ccs.push(actor_id.to_owned().to_string()); - let mention_user = get_or_fetch_and_upsert_remote_user(&actor_id, client, pool).await?; + let mention_user = get_or_fetch_and_upsert_user(&actor_id, client, pool).await?; let shared_inbox = mention_user.get_shared_inbox_url(); mention_inboxes.push(shared_inbox); diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index 16d13711e..b60059aa3 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -1,20 +1,33 @@ use crate::{ apub::{ activities::{generate_activity_id, send_activity}, - create_apub_response, create_apub_tombstone_response, create_tombstone, + create_apub_response, + create_apub_tombstone_response, + create_tombstone, extensions::group_extensions::GroupExtension, - fetcher::get_or_fetch_and_upsert_remote_user, - get_shared_inbox, insert_activity, ActorType, FromApub, GroupExt, ToApub, + fetcher::get_or_fetch_and_upsert_user, + get_shared_inbox, + insert_activity, + ActorType, + FromApub, + GroupExt, + ToApub, }, blocking, routes::DbPoolParam, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_ext::Ext2; use activitystreams_new::{ activity::{ kind::{AcceptType, AnnounceType, DeleteType, LikeType, RemoveType, UndoType}, - Accept, Announce, Delete, Follow, Remove, Undo, + Accept, + Announce, + Delete, + Follow, + Remove, + Undo, }, actor::{kind::GroupType, ApActor, Endpoints, Group}, base::{AnyBase, BaseExt}, @@ -324,7 +337,7 @@ impl FromApub for CommunityForm { .as_xsd_any_uri() .unwrap(); - let creator = get_or_fetch_and_upsert_remote_user(creator_uri, client, pool).await?; + let creator = get_or_fetch_and_upsert_user(creator_uri, client, pool).await?; Ok(CommunityForm { name: group diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index cf1986365..ff1ec11b7 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -1,12 +1,19 @@ use crate::{ api::site::SearchResponse, apub::{ - is_apub_id_valid, ActorType, FromApub, GroupExt, PageExt, PersonExt, APUB_JSON_CONTENT_TYPE, + is_apub_id_valid, + ActorType, + FromApub, + GroupExt, + PageExt, + PersonExt, + APUB_JSON_CONTENT_TYPE, }, blocking, request::{retry, RecvError}, routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_new::{base::BaseExt, object::Note, prelude::*}; use actix_web::client::Client; @@ -22,7 +29,9 @@ use lemmy_db::{ post_view::PostView, user::{UserForm, User_}, user_view::UserView, - Crud, Joinable, SearchType, + Crud, + Joinable, + SearchType, }; use lemmy_utils::get_apub_protocol_string; use log::debug; @@ -140,7 +149,7 @@ pub async fn search_by_apub_id( SearchAcceptedObjects::Person(p) => { let user_uri = p.inner.id(domain)?.unwrap(); - let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?; + let user = get_or_fetch_and_upsert_user(&user_uri, client, pool).await?; response.users = vec![blocking(pool, move |conn| UserView::read(conn, user.id)).await??]; @@ -149,7 +158,7 @@ pub async fn search_by_apub_id( SearchAcceptedObjects::Group(g) => { let community_uri = g.inner.id(domain)?.unwrap(); - let community = get_or_fetch_and_upsert_remote_community(community_uri, client, pool).await?; + let community = get_or_fetch_and_upsert_community(community_uri, client, pool).await?; // TODO Maybe at some point in the future, fetch all the history of a community // fetch_community_outbox(&c, conn)?; @@ -191,21 +200,21 @@ pub async fn search_by_apub_id( Ok(response) } -pub async fn get_or_fetch_and_upsert_remote_actor( +pub async fn get_or_fetch_and_upsert_actor( apub_id: &Url, client: &Client, pool: &DbPool, ) -> Result, LemmyError> { - let user = get_or_fetch_and_upsert_remote_user(apub_id, client, pool).await; + let user = get_or_fetch_and_upsert_user(apub_id, client, pool).await; let actor: Box = match user { Ok(u) => Box::new(u), - Err(_) => Box::new(get_or_fetch_and_upsert_remote_community(apub_id, client, pool).await?), + Err(_) => Box::new(get_or_fetch_and_upsert_community(apub_id, client, pool).await?), }; Ok(actor) } /// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user. -pub async fn get_or_fetch_and_upsert_remote_user( +pub async fn get_or_fetch_and_upsert_user( apub_id: &Url, client: &Client, pool: &DbPool, @@ -257,7 +266,7 @@ fn should_refetch_actor(last_refreshed: NaiveDateTime) -> bool { } /// Check if a remote community exists, create if not found, if its too old update it.Fetch a community, insert/update it in the database and return the community. -pub async fn get_or_fetch_and_upsert_remote_community( +pub async fn get_or_fetch_and_upsert_community( apub_id: &Url, client: &Client, pool: &DbPool, @@ -299,7 +308,7 @@ pub async fn get_or_fetch_and_upsert_remote_community( let mut creator_and_moderators = Vec::new(); for uri in creator_and_moderator_uris { - let c_or_m = get_or_fetch_and_upsert_remote_user(uri, client, pool).await?; + let c_or_m = get_or_fetch_and_upsert_user(uri, client, pool).await?; creator_and_moderators.push(c_or_m); } @@ -333,7 +342,7 @@ fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result Result( @@ -118,8 +126,13 @@ where { let cc = activity.cc().unwrap(); let cc = cc.as_many().unwrap(); - let community_uri = cc.first().unwrap().as_xsd_any_uri().unwrap(); - let community = get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?; + let community_followers_uri = cc.first().unwrap().as_xsd_any_uri().unwrap(); + // TODO: this is hacky but seems to be the only way to get the community ID + let community_uri = community_followers_uri + .to_string() + .replace("/followers", ""); + let community = + get_or_fetch_and_upsert_community(&Url::parse(&community_uri)?, client, pool).await?; if community.local { do_announce(activity.into_any_base()?, &community, &user, client, pool).await?; diff --git a/server/src/apub/inbox/user_inbox.rs b/server/src/apub/inbox/user_inbox.rs index 73916ee2c..13d974e9a 100644 --- a/server/src/apub/inbox/user_inbox.rs +++ b/server/src/apub/inbox/user_inbox.rs @@ -2,13 +2,15 @@ use crate::{ api::user::PrivateMessageResponse, apub::{ extensions::signatures::verify, - fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}, - insert_activity, FromApub, + fetcher::{get_or_fetch_and_upsert_community, get_or_fetch_and_upsert_user}, + insert_activity, + FromApub, }, blocking, routes::{ChatServerParam, DbPoolParam}, websocket::{server::SendUserRoomMessage, UserOperation}, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_new::{ activity::{Accept, Create, Delete, Undo, Update}, @@ -22,7 +24,8 @@ use lemmy_db::{ private_message::{PrivateMessage, PrivateMessageForm}, private_message_view::PrivateMessageView, user::User_, - Crud, Followable, + Crud, + Followable, }; use log::debug; use serde::Deserialize; @@ -79,7 +82,7 @@ async fn receive_accept( ) -> Result { let community_uri = accept.actor()?.to_owned().single_xsd_any_uri().unwrap(); - let community = get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?; + let community = get_or_fetch_and_upsert_community(&community_uri, client, pool).await?; verify(request, &community)?; let username = username.to_owned(); @@ -113,7 +116,7 @@ async fn receive_create_private_message( let user_uri = &create.actor()?.to_owned().single_xsd_any_uri().unwrap(); let note = Note::from_any_base(create.object().as_one().unwrap().to_owned())?.unwrap(); - let user = get_or_fetch_and_upsert_remote_user(user_uri, client, pool).await?; + let user = get_or_fetch_and_upsert_user(user_uri, client, pool).await?; verify(request, &user)?; insert_activity(user.id, create, false, pool).await?; @@ -154,7 +157,7 @@ async fn receive_update_private_message( let user_uri = &update.actor()?.to_owned().single_xsd_any_uri().unwrap(); let note = Note::from_any_base(update.object().as_one().unwrap().to_owned())?.unwrap(); - let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?; + let user = get_or_fetch_and_upsert_user(&user_uri, client, pool).await?; verify(request, &user)?; insert_activity(user.id, update, false, pool).await?; @@ -203,7 +206,7 @@ async fn receive_delete_private_message( let user_uri = &delete.actor()?.to_owned().single_xsd_any_uri().unwrap(); let note = Note::from_any_base(delete.object().as_one().unwrap().to_owned())?.unwrap(); - let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?; + let user = get_or_fetch_and_upsert_user(&user_uri, client, pool).await?; verify(request, &user)?; insert_activity(user.id, delete, false, pool).await?; @@ -265,7 +268,7 @@ async fn receive_undo_delete_private_message( let note = Note::from_any_base(delete.object().as_one().unwrap().to_owned())?.unwrap(); let user_uri = &delete.actor()?.to_owned().single_xsd_any_uri().unwrap(); - let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?; + let user = get_or_fetch_and_upsert_user(&user_uri, client, pool).await?; verify(request, &user)?; insert_activity(user.id, delete, false, pool).await?; diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index a5d8984c8..47f01e315 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -17,7 +17,8 @@ use crate::{ blocking, request::{retry, RecvError}, routes::webfinger::WebFingerResponse, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_ext::{Ext1, Ext2}; use activitystreams_new::{ diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index 932ff8ce2..a4cf8e4cc 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -1,20 +1,34 @@ use crate::{ apub::{ activities::{generate_activity_id, send_activity_to_community}, - create_apub_response, create_apub_tombstone_response, create_tombstone, + create_apub_response, + create_apub_tombstone_response, + create_tombstone, extensions::page_extension::PageExtension, - fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user}, - ActorType, ApubLikeableType, ApubObjectType, FromApub, PageExt, ToApub, + fetcher::{get_or_fetch_and_upsert_community, get_or_fetch_and_upsert_user}, + ActorType, + ApubLikeableType, + ApubObjectType, + FromApub, + PageExt, + ToApub, }, blocking, routes::DbPoolParam, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_ext::Ext1; use activitystreams_new::{ activity::{ kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, - Create, Delete, Dislike, Like, Remove, Undo, Update, + Create, + Delete, + Dislike, + Like, + Remove, + Undo, + Update, }, context, object::{kind::PageType, Image, Page, Tombstone}, @@ -151,7 +165,7 @@ impl FromApub for PostForm { .as_single_xsd_any_uri() .unwrap(); - let creator = get_or_fetch_and_upsert_remote_user(creator_actor_id, client, pool).await?; + let creator = get_or_fetch_and_upsert_user(creator_actor_id, client, pool).await?; let community_actor_id = page .inner @@ -161,8 +175,7 @@ impl FromApub for PostForm { .as_single_xsd_any_uri() .unwrap(); - let community = - get_or_fetch_and_upsert_remote_community(community_actor_id, client, pool).await?; + let community = get_or_fetch_and_upsert_community(community_actor_id, client, pool).await?; let thumbnail_url = match &page.inner.image() { Some(any_image) => Image::from_any_base(any_image.to_owned().as_one().unwrap().to_owned())? diff --git a/server/src/apub/private_message.rs b/server/src/apub/private_message.rs index b10f87b55..5f8abca8e 100644 --- a/server/src/apub/private_message.rs +++ b/server/src/apub/private_message.rs @@ -2,15 +2,23 @@ use crate::{ apub::{ activities::{generate_activity_id, send_activity}, create_tombstone, - fetcher::get_or_fetch_and_upsert_remote_user, - insert_activity, ApubObjectType, FromApub, ToApub, + fetcher::get_or_fetch_and_upsert_user, + insert_activity, + ApubObjectType, + FromApub, + ToApub, }, - blocking, DbPool, LemmyError, + blocking, + DbPool, + LemmyError, }; use activitystreams_new::{ activity::{ kind::{CreateType, DeleteType, UndoType, UpdateType}, - Create, Delete, Undo, Update, + Create, + Delete, + Undo, + Update, }, context, object::{kind::NoteType, Note, Tombstone}, @@ -76,11 +84,11 @@ impl FromApub for PrivateMessageForm { .single_xsd_any_uri() .unwrap(); - let creator = get_or_fetch_and_upsert_remote_user(&creator_actor_id, client, pool).await?; + let creator = get_or_fetch_and_upsert_user(&creator_actor_id, client, pool).await?; let recipient_actor_id = note.to().unwrap().clone().single_xsd_any_uri().unwrap(); - let recipient = get_or_fetch_and_upsert_remote_user(&recipient_actor_id, client, pool).await?; + let recipient = get_or_fetch_and_upsert_user(&recipient_actor_id, client, pool).await?; Ok(PrivateMessageForm { creator_id: creator.id, diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 8ec972dad..9d8c9167f 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -1,17 +1,24 @@ use crate::{ apub::{ activities::{generate_activity_id, send_activity}, - create_apub_response, insert_activity, ActorType, FromApub, PersonExt, ToApub, + create_apub_response, + insert_activity, + ActorType, + FromApub, + PersonExt, + ToApub, }, blocking, routes::DbPoolParam, - DbPool, LemmyError, + DbPool, + LemmyError, }; use activitystreams_ext::Ext1; use activitystreams_new::{ activity::{ kind::{FollowType, UndoType}, - Follow, Undo, + Follow, + Undo, }, actor::{ApActor, Endpoints, Person}, context, From 8ad43789602db4701e00253aa2e87524d8324b1d Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 29 Jul 2020 13:58:39 +0200 Subject: [PATCH 5/5] Disable ID domain check in FromApub until we figure it out properly --- server/src/apub/comment.rs | 3 +-- server/src/apub/community.rs | 13 ++----------- server/src/apub/fetcher.rs | 18 +++++++++--------- server/src/apub/inbox/activities/create.rs | 5 ++--- server/src/apub/inbox/activities/delete.rs | 7 +++---- server/src/apub/inbox/activities/dislike.rs | 5 ++--- server/src/apub/inbox/activities/like.rs | 5 ++--- server/src/apub/inbox/activities/remove.rs | 7 +++---- server/src/apub/inbox/activities/undo.rs | 17 ++++++++--------- server/src/apub/inbox/activities/update.rs | 5 ++--- server/src/apub/inbox/user_inbox.rs | 8 ++++---- server/src/apub/mod.rs | 1 - server/src/apub/post.rs | 7 +------ server/src/apub/private_message.rs | 3 +-- server/src/apub/user.rs | 9 ++------- 15 files changed, 42 insertions(+), 71 deletions(-) diff --git a/server/src/apub/comment.rs b/server/src/apub/comment.rs index 269e7fc25..650c60577 100644 --- a/server/src/apub/comment.rs +++ b/server/src/apub/comment.rs @@ -131,7 +131,6 @@ impl FromApub for CommentForm { note: &Note, client: &Client, pool: &DbPool, - actor_id: &Url, ) -> Result { let creator_actor_id = ¬e .attributed_to() @@ -182,7 +181,7 @@ impl FromApub for CommentForm { published: note.published().map(|u| u.to_owned().naive_local()), updated: note.updated().map(|u| u.to_owned().naive_local()), deleted: None, - ap_id: note.id(actor_id.domain().unwrap())?.unwrap().to_string(), + ap_id: note.id_unchecked().unwrap().to_string(), local: false, }) } diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index b60059aa3..112b6e851 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -321,12 +321,7 @@ impl FromApub for CommunityForm { type ApubType = GroupExt; /// Parse an ActivityPub group received from another instance into a Lemmy community. - async fn from_apub( - group: &GroupExt, - client: &Client, - pool: &DbPool, - actor_id: &Url, - ) -> Result { + async fn from_apub(group: &GroupExt, client: &Client, pool: &DbPool) -> Result { let creator_and_moderator_uris = group.inner.attributed_to().unwrap(); let creator_uri = creator_and_moderator_uris .as_many() @@ -363,11 +358,7 @@ impl FromApub for CommunityForm { updated: group.inner.updated().map(|u| u.to_owned().naive_local()), deleted: None, nsfw: group.ext_one.sensitive, - actor_id: group - .inner - .id(actor_id.domain().unwrap())? - .unwrap() - .to_string(), + actor_id: group.inner.id_unchecked().unwrap().to_string(), local: false, private_key: None, public_key: Some(group.ext_two.to_owned().public_key.public_key_pem), diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index ff1ec11b7..c10426d14 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -172,7 +172,7 @@ pub async fn search_by_apub_id( response } SearchAcceptedObjects::Page(p) => { - let post_form = PostForm::from_apub(&p, client, pool, &query_url).await?; + let post_form = PostForm::from_apub(&p, client, pool).await?; let p = blocking(pool, move |conn| upsert_post(&post_form, conn)).await??; response.posts = vec![blocking(pool, move |conn| PostView::read(conn, p.id, None)).await??]; @@ -185,8 +185,8 @@ pub async fn search_by_apub_id( // TODO: also fetch parent comments if any let x = post_url.first().unwrap().as_xsd_any_uri().unwrap(); let post = fetch_remote_object(client, x).await?; - let post_form = PostForm::from_apub(&post, client, pool, &query_url).await?; - let comment_form = CommentForm::from_apub(&c, client, pool, &query_url).await?; + let post_form = PostForm::from_apub(&post, client, pool).await?; + let comment_form = CommentForm::from_apub(&c, client, pool).await?; blocking(pool, move |conn| upsert_post(&post_form, conn)).await??; let c = blocking(pool, move |conn| upsert_comment(&comment_form, conn)).await??; @@ -231,7 +231,7 @@ pub async fn get_or_fetch_and_upsert_user( debug!("Fetching and updating from remote user: {}", apub_id); let person = fetch_remote_object::(client, apub_id).await?; - let mut uf = UserForm::from_apub(&person, client, pool, apub_id).await?; + let mut uf = UserForm::from_apub(&person, client, pool).await?; uf.last_refreshed_at = Some(naive_now()); let user = blocking(pool, move |conn| User_::update(conn, u.id, &uf)).await??; @@ -242,7 +242,7 @@ pub async fn get_or_fetch_and_upsert_user( debug!("Fetching and creating remote user: {}", apub_id); let person = fetch_remote_object::(client, apub_id).await?; - let uf = UserForm::from_apub(&person, client, pool, apub_id).await?; + let uf = UserForm::from_apub(&person, client, pool).await?; let user = blocking(pool, move |conn| User_::create(conn, &uf)).await??; Ok(user) @@ -282,7 +282,7 @@ pub async fn get_or_fetch_and_upsert_community( debug!("Fetching and updating from remote community: {}", apub_id); let group = fetch_remote_object::(client, apub_id).await?; - let mut cf = CommunityForm::from_apub(&group, client, pool, apub_id).await?; + let mut cf = CommunityForm::from_apub(&group, client, pool).await?; cf.last_refreshed_at = Some(naive_now()); let community = blocking(pool, move |conn| Community::update(conn, c.id, &cf)).await??; @@ -293,7 +293,7 @@ pub async fn get_or_fetch_and_upsert_community( debug!("Fetching and creating remote community: {}", apub_id); let group = fetch_remote_object::(client, apub_id).await?; - let cf = CommunityForm::from_apub(&group, client, pool, apub_id).await?; + let cf = CommunityForm::from_apub(&group, client, pool).await?; let community = blocking(pool, move |conn| Community::create(conn, &cf)).await??; // Also add the community moderators too @@ -358,7 +358,7 @@ pub async fn get_or_fetch_and_insert_post( Err(NotFound {}) => { debug!("Fetching and creating remote post: {}", post_ap_id); let post = fetch_remote_object::(client, post_ap_id).await?; - let post_form = PostForm::from_apub(&post, client, pool, post_ap_id).await?; + let post_form = PostForm::from_apub(&post, client, pool).await?; let post = blocking(pool, move |conn| Post::create(conn, &post_form)).await??; @@ -396,7 +396,7 @@ pub async fn get_or_fetch_and_insert_comment( comment_ap_id ); let comment = fetch_remote_object::(client, comment_ap_id).await?; - let comment_form = CommentForm::from_apub(&comment, client, pool, comment_ap_id).await?; + let comment_form = CommentForm::from_apub(&comment, client, pool).await?; let comment = blocking(pool, move |conn| Comment::create(conn, &comment_form)).await??; diff --git a/server/src/apub/inbox/activities/create.rs b/server/src/apub/inbox/activities/create.rs index da90bea53..0f5595cd0 100644 --- a/server/src/apub/inbox/activities/create.rs +++ b/server/src/apub/inbox/activities/create.rs @@ -9,7 +9,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, PageExt, }, @@ -57,7 +56,7 @@ async fn receive_create_post( let user = get_user_from_activity(&create, client, pool).await?; let page = PageExt::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + let post = PostForm::from_apub(&page, client, pool).await?; let inserted_post = blocking(pool, move |conn| Post::create(conn, &post)).await??; @@ -89,7 +88,7 @@ async fn receive_create_comment( let user = get_user_from_activity(&create, client, pool).await?; let note = Note::from_any_base(create.object().to_owned().one().unwrap())?.unwrap(); - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + let comment = CommentForm::from_apub(¬e, client, pool).await?; let inserted_comment = blocking(pool, move |conn| Comment::create(conn, &comment)).await??; diff --git a/server/src/apub/inbox/activities/delete.rs b/server/src/apub/inbox/activities/delete.rs index 09df0bc1e..b4fe0de48 100644 --- a/server/src/apub/inbox/activities/delete.rs +++ b/server/src/apub/inbox/activities/delete.rs @@ -7,7 +7,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, GroupExt, PageExt, @@ -58,7 +57,7 @@ async fn receive_delete_post( let user = get_user_from_activity(&delete, client, pool).await?; let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) + let post_ap_id = PostForm::from_apub(&page, client, pool) .await? .get_ap_id()?; @@ -112,7 +111,7 @@ async fn receive_delete_comment( let user = get_user_from_activity(&delete, client, pool).await?; let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) + let comment_ap_id = CommentForm::from_apub(¬e, client, pool) .await? .get_ap_id()?; @@ -169,7 +168,7 @@ async fn receive_delete_community( let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); let user = get_user_from_activity(&delete, client, pool).await?; - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) + let community_actor_id = CommunityForm::from_apub(&group, client, pool) .await? .actor_id; diff --git a/server/src/apub/inbox/activities/dislike.rs b/server/src/apub/inbox/activities/dislike.rs index 7135505e1..cb12724d6 100644 --- a/server/src/apub/inbox/activities/dislike.rs +++ b/server/src/apub/inbox/activities/dislike.rs @@ -7,7 +7,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, PageExt, }, @@ -53,7 +52,7 @@ async fn receive_dislike_post( let user = get_user_from_activity(&dislike, client, pool).await?; let page = PageExt::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + let post = PostForm::from_apub(&page, client, pool).await?; let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool) .await? @@ -94,7 +93,7 @@ async fn receive_dislike_comment( let note = Note::from_any_base(dislike.object().to_owned().one().unwrap())?.unwrap(); let user = get_user_from_activity(&dislike, client, pool).await?; - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + let comment = CommentForm::from_apub(¬e, client, pool).await?; let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool) .await? diff --git a/server/src/apub/inbox/activities/like.rs b/server/src/apub/inbox/activities/like.rs index 36bdbfa8d..da92bbff3 100644 --- a/server/src/apub/inbox/activities/like.rs +++ b/server/src/apub/inbox/activities/like.rs @@ -7,7 +7,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, PageExt, }, @@ -53,7 +52,7 @@ async fn receive_like_post( let user = get_user_from_activity(&like, client, pool).await?; let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + let post = PostForm::from_apub(&page, client, pool).await?; let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool) .await? @@ -94,7 +93,7 @@ async fn receive_like_comment( let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); let user = get_user_from_activity(&like, client, pool).await?; - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + let comment = CommentForm::from_apub(¬e, client, pool).await?; let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool) .await? diff --git a/server/src/apub/inbox/activities/remove.rs b/server/src/apub/inbox/activities/remove.rs index 1ae482d42..af3d144b8 100644 --- a/server/src/apub/inbox/activities/remove.rs +++ b/server/src/apub/inbox/activities/remove.rs @@ -7,7 +7,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, GroupExt, PageExt, @@ -58,7 +57,7 @@ async fn receive_remove_post( let mod_ = get_user_from_activity(&remove, client, pool).await?; let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) + let post_ap_id = PostForm::from_apub(&page, client, pool) .await? .get_ap_id()?; @@ -112,7 +111,7 @@ async fn receive_remove_comment( let mod_ = get_user_from_activity(&remove, client, pool).await?; let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) + let comment_ap_id = CommentForm::from_apub(¬e, client, pool) .await? .get_ap_id()?; @@ -169,7 +168,7 @@ async fn receive_remove_community( let mod_ = get_user_from_activity(&remove, client, pool).await?; let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) + let community_actor_id = CommunityForm::from_apub(&group, client, pool) .await? .actor_id; diff --git a/server/src/apub/inbox/activities/undo.rs b/server/src/apub/inbox/activities/undo.rs index 3634bd44d..332364843 100644 --- a/server/src/apub/inbox/activities/undo.rs +++ b/server/src/apub/inbox/activities/undo.rs @@ -7,7 +7,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, GroupExt, PageExt, @@ -123,7 +122,7 @@ async fn receive_undo_delete_comment( let user = get_user_from_activity(delete, client, pool).await?; let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?) + let comment_ap_id = CommentForm::from_apub(¬e, client, pool) .await? .get_ap_id()?; @@ -181,7 +180,7 @@ async fn receive_undo_remove_comment( let mod_ = get_user_from_activity(remove, client, pool).await?; let note = Note::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let comment_ap_id = CommentForm::from_apub(¬e, client, pool, &mod_.actor_id()?) + let comment_ap_id = CommentForm::from_apub(¬e, client, pool) .await? .get_ap_id()?; @@ -239,7 +238,7 @@ async fn receive_undo_delete_post( let user = get_user_from_activity(delete, client, pool).await?; let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let post_ap_id = PostForm::from_apub(&page, client, pool, &user.actor_id()?) + let post_ap_id = PostForm::from_apub(&page, client, pool) .await? .get_ap_id()?; @@ -294,7 +293,7 @@ async fn receive_undo_remove_post( let mod_ = get_user_from_activity(remove, client, pool).await?; let page = PageExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let post_ap_id = PostForm::from_apub(&page, client, pool, &mod_.actor_id()?) + let post_ap_id = PostForm::from_apub(&page, client, pool) .await? .get_ap_id()?; @@ -349,7 +348,7 @@ async fn receive_undo_delete_community( let user = get_user_from_activity(delete, client, pool).await?; let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap(); - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &user.actor_id()?) + let community_actor_id = CommunityForm::from_apub(&group, client, pool) .await? .actor_id; @@ -413,7 +412,7 @@ async fn receive_undo_remove_community( let mod_ = get_user_from_activity(remove, client, pool).await?; let group = GroupExt::from_any_base(remove.object().to_owned().one().unwrap())?.unwrap(); - let community_actor_id = CommunityForm::from_apub(&group, client, pool, &mod_.actor_id()?) + let community_actor_id = CommunityForm::from_apub(&group, client, pool) .await? .actor_id; @@ -477,7 +476,7 @@ async fn receive_undo_like_comment( let user = get_user_from_activity(like, client, pool).await?; let note = Note::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + let comment = CommentForm::from_apub(¬e, client, pool).await?; let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool) .await? @@ -523,7 +522,7 @@ async fn receive_undo_like_post( let user = get_user_from_activity(like, client, pool).await?; let page = PageExt::from_any_base(like.object().to_owned().one().unwrap())?.unwrap(); - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + let post = PostForm::from_apub(&page, client, pool).await?; let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool) .await? diff --git a/server/src/apub/inbox/activities/update.rs b/server/src/apub/inbox/activities/update.rs index 2d5d06606..5da262e1f 100644 --- a/server/src/apub/inbox/activities/update.rs +++ b/server/src/apub/inbox/activities/update.rs @@ -10,7 +10,6 @@ use crate::{ get_user_from_activity, receive_unhandled_activity, }, - ActorType, FromApub, PageExt, }, @@ -57,7 +56,7 @@ async fn receive_update_post( let user = get_user_from_activity(&update, client, pool).await?; let page = PageExt::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); - let post = PostForm::from_apub(&page, client, pool, &user.actor_id()?).await?; + let post = PostForm::from_apub(&page, client, pool).await?; let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool) .await? @@ -89,7 +88,7 @@ async fn receive_update_comment( let note = Note::from_any_base(update.object().to_owned().one().unwrap())?.unwrap(); let user = get_user_from_activity(&update, client, pool).await?; - let comment = CommentForm::from_apub(¬e, client, pool, &user.actor_id()?).await?; + let comment = CommentForm::from_apub(¬e, client, pool).await?; let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool) .await? diff --git a/server/src/apub/inbox/user_inbox.rs b/server/src/apub/inbox/user_inbox.rs index 13d974e9a..be99d81a0 100644 --- a/server/src/apub/inbox/user_inbox.rs +++ b/server/src/apub/inbox/user_inbox.rs @@ -121,7 +121,7 @@ async fn receive_create_private_message( insert_activity(user.id, create, false, pool).await?; - let private_message = PrivateMessageForm::from_apub(¬e, client, pool, user_uri).await?; + let private_message = PrivateMessageForm::from_apub(¬e, client, pool).await?; let inserted_private_message = blocking(pool, move |conn| { PrivateMessage::create(conn, &private_message) @@ -162,7 +162,7 @@ async fn receive_update_private_message( insert_activity(user.id, update, false, pool).await?; - let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool, user_uri).await?; + let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool).await?; let private_message_ap_id = private_message_form.ap_id.clone(); let private_message = blocking(pool, move |conn| { @@ -211,7 +211,7 @@ async fn receive_delete_private_message( insert_activity(user.id, delete, false, pool).await?; - let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool, user_uri).await?; + let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool).await?; let private_message_ap_id = private_message_form.ap_id; let private_message = blocking(pool, move |conn| { @@ -273,7 +273,7 @@ async fn receive_undo_delete_private_message( insert_activity(user.id, delete, false, pool).await?; - let private_message = PrivateMessageForm::from_apub(¬e, client, pool, user_uri).await?; + let private_message = PrivateMessageForm::from_apub(¬e, client, pool).await?; let private_message_ap_id = private_message.ap_id.clone(); let private_message_id = blocking(pool, move |conn| { diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index 47f01e315..28eb86ac2 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -132,7 +132,6 @@ pub trait FromApub { apub: &Self::ApubType, client: &Client, pool: &DbPool, - actor_id: &Url, ) -> Result where Self: Sized; diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index a4cf8e4cc..39e4faf34 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -154,7 +154,6 @@ impl FromApub for PostForm { page: &PageExt, client: &Client, pool: &DbPool, - actor_id: &Url, ) -> Result { let ext = &page.ext_one; let creator_actor_id = page @@ -246,11 +245,7 @@ impl FromApub for PostForm { embed_description, embed_html, thumbnail_url, - ap_id: page - .inner - .id(actor_id.domain().unwrap())? - .unwrap() - .to_string(), + ap_id: page.inner.id_unchecked().unwrap().to_string(), local: false, }) } diff --git a/server/src/apub/private_message.rs b/server/src/apub/private_message.rs index 5f8abca8e..f58a6bfed 100644 --- a/server/src/apub/private_message.rs +++ b/server/src/apub/private_message.rs @@ -75,7 +75,6 @@ impl FromApub for PrivateMessageForm { note: &Note, client: &Client, pool: &DbPool, - actor_id: &Url, ) -> Result { let creator_actor_id = note .attributed_to() @@ -103,7 +102,7 @@ impl FromApub for PrivateMessageForm { updated: note.updated().map(|u| u.to_owned().naive_local()), deleted: None, read: None, - ap_id: note.id(actor_id.domain().unwrap())?.unwrap().to_string(), + ap_id: note.id_unchecked().unwrap().to_string(), local: false, }) } diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 9d8c9167f..0e90941d6 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -201,12 +201,7 @@ impl ActorType for User_ { impl FromApub for UserForm { type ApubType = PersonExt; /// Parse an ActivityPub person received from another instance into a Lemmy user. - async fn from_apub( - person: &PersonExt, - _: &Client, - _: &DbPool, - actor_id: &Url, - ) -> Result { + async fn from_apub(person: &PersonExt, _: &Client, _: &DbPool) -> Result { let avatar = match person.icon() { Some(any_image) => Image::from_any_base(any_image.as_one().unwrap().clone()) .unwrap() @@ -242,7 +237,7 @@ impl FromApub for UserForm { show_avatars: false, send_notifications_to_email: false, matrix_user_id: None, - actor_id: person.id(actor_id.domain().unwrap())?.unwrap().to_string(), + actor_id: person.id_unchecked().unwrap().to_string(), bio: person .inner .summary()