From: Felix Date: Wed, 6 May 2020 17:10:36 +0000 (+0200) Subject: Let community announce posts X-Git-Url: http://these/git/%7B%60%24%7BwebArchiveUrl%7D/%22%7B%7D/readmes/%7B%7D/%22%7Burl%7D/%24%7Bargs.pageFn.jump%20n%7D?a=commitdiff_plain;h=5753c4feaa93c6a6bfa0f0cf5a87ba756d559ce0;p=lemmy.git Let community announce posts --- diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 3c52d1e5..556c67bd 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -22,7 +22,7 @@ services: - RUST_LOG=debug volumes: - ../lemmy.hjson:/config/config.hjson - depends_on: + depends_on: - postgres - pictshare - iframely diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index bc924492..1ba41da4 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -283,19 +283,7 @@ impl ActorType for Community { Ok( CommunityFollowerView::for_community(conn, self.id)? .into_iter() - // TODO eventually this will have to use the inbox or shared_inbox column, meaning that view - // will have to change - .map(|c| { - // If the user is local, but the community isn't, get the community shared inbox - // and vice versa - if c.user_local && !c.community_local { - get_shared_inbox(&c.community_actor_id) - } else if !c.user_local && c.community_local { - get_shared_inbox(&c.user_actor_id) - } else { - "".to_string() - } - }) + .map(|c| get_shared_inbox(&c.user_actor_id)) .filter(|s| !s.is_empty()) .unique() .collect(), diff --git a/server/src/apub/community_inbox.rs b/server/src/apub/community_inbox.rs index 2ae2e0eb..09aecd89 100644 --- a/server/src/apub/community_inbox.rs +++ b/server/src/apub/community_inbox.rs @@ -12,18 +12,26 @@ use crate::{ }, routes::{ChatServerParam, DbPoolParam}, }; -use activitystreams::activity::{Follow, Undo}; +use activitystreams::activity::{Follow, Undo, Update, Create, Delete, Remove}; use actix_web::{web, HttpRequest, HttpResponse, Result}; use diesel::PgConnection; use failure::{Error, _core::fmt::Debug}; use log::debug; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; +use activitystreams::activity::{Activity, Announce}; +use activitystreams::Base; +use crate::apub::activities::{populate_object_props, send_activity}; +use activitystreams::BaseBox; #[serde(untagged)] #[derive(Deserialize, Debug)] pub enum CommunityAcceptedObjects { Follow(Follow), Undo(Undo), + Create(Create), + Update(Update), + Delete(Delete), + Remove(Remove), } impl CommunityAcceptedObjects { @@ -38,6 +46,7 @@ impl CommunityAcceptedObjects { .to_owned() .into_concrete::()?, ), + _ => todo!() } } } @@ -49,13 +58,20 @@ pub async fn community_inbox( input: web::Json, path: web::Path, db: DbPoolParam, - _chat_server: ChatServerParam, + chat_server: ChatServerParam, ) -> Result { let input = input.into_inner(); - let community_name = path.into_inner(); + let conn = db.get()?; + let community = Community::read_from_name(&conn, &path.into_inner())?; + if !community.local { + return Err(format_err!( + "Received activity is addressed to remote community {}", + &community.actor_id + )); + } debug!( "Community {} received activity {:?}", - &community_name, &input + &community.name, &input ); let follow = input.follow()?; let user_uri = follow @@ -77,8 +93,27 @@ pub async fn community_inbox( verify(&request, &user)?; match input { - CommunityAcceptedObjects::Follow(f) => handle_follow(&f, &user, &community, &conn), - CommunityAcceptedObjects::Undo(u) => handle_undo_follow(&u, &user, &community, &conn), + CommunityAcceptedObjects::Follow(f) => { + handle_follow(&f, &user, &community, &conn) + } + CommunityAcceptedObjects::Undo(u) => { + // TODO: if this is an undo or undo, we need to announce it instead + handle_undo_follow(&u, &user, &community, &conn) + } + // TODO: we should be able to handle all this with a single wildcard match, but i dont see how + // to get the value from that + CommunityAcceptedObjects::Create(c) => { + do_announce(c, &request, &community, &conn, chat_server) + } + CommunityAcceptedObjects::Update(u) => { + do_announce(u, &request, &community, &conn, chat_server) + } + CommunityAcceptedObjects::Delete(d) => { + do_announce(d, &request, &community, &conn, chat_server) + } + CommunityAcceptedObjects::Remove(r) => { + do_announce(r, &request, &community, &conn, chat_server) + } } } @@ -122,3 +157,50 @@ fn handle_undo_follow( Ok(HttpResponse::Ok().finish()) } + +fn do_announce( + activity: A, + _request: &HttpRequest, + community: &Community, + conn: &PgConnection, + _chat_server: ChatServerParam, +) -> Result +where + A: Activity + Base + Serialize, +{ + // TODO: checking the signature needs a lot of boilerplate, unless this gets implemented + // https://git.asonix.dog/Aardwolf/activitystreams/issues/4 + /* + let user_uri = activity + .follow_props + .get_actor_xsd_any_uri() + .unwrap() + .to_string(); + let user = get_or_fetch_and_upsert_remote_user(&user_uri, &conn)?; + verify(&request, &user.public_key.unwrap())?; + */ + + insert_activity(&conn, -1, &activity, false)?; + + // TODO: handle the sending in community.rs + let mut announce = Announce::default(); + populate_object_props( + &mut announce.object_props, + vec!(community.get_followers_url()), + &format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4()), + )?; + announce + .announce_props + .set_actor_xsd_any_uri(community.actor_id.to_owned())? + .set_object_base_box(BaseBox::from_concrete(activity)?)?; + + insert_activity(&conn, -1, &announce, true)?; + + send_activity( + &announce, + community, + community.get_follower_inboxes(&conn)?, + )?; + + Ok(HttpResponse::Ok().finish()) +} diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index 9ee04298..d91cf472 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -241,7 +241,7 @@ impl ApubObjectType for Post { insert_activity(&conn, creator.id, &create, true)?; - send_activity(&create, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&create, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -264,7 +264,7 @@ impl ApubObjectType for Post { insert_activity(&conn, creator.id, &update, true)?; - send_activity(&update, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&update, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -288,7 +288,7 @@ impl ApubObjectType for Post { insert_activity(&conn, self.creator_id, &delete, true)?; let community = Community::read(conn, self.community_id)?; - send_activity(&delete, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&delete, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -328,7 +328,7 @@ impl ApubObjectType for Post { insert_activity(&conn, self.creator_id, &undo, true)?; let community = Community::read(conn, self.community_id)?; - send_activity(&undo, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&undo, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -352,7 +352,7 @@ impl ApubObjectType for Post { insert_activity(&conn, mod_.id, &remove, true)?; let community = Community::read(conn, self.community_id)?; - send_activity(&remove, mod_, community.get_follower_inboxes(&conn)?)?; + send_activity(&remove, mod_, vec!(community.get_inbox_url()))?; Ok(()) } fn send_undo_remove(&self, mod_: &User_, conn: &PgConnection) -> Result<(), Error> { @@ -390,7 +390,7 @@ impl ApubObjectType for Post { insert_activity(&conn, mod_.id, &undo, true)?; let community = Community::read(conn, self.community_id)?; - send_activity(&undo, mod_, community.get_follower_inboxes(&conn)?)?; + send_activity(&undo, mod_, vec!(community.get_inbox_url()))?; Ok(()) } } @@ -414,7 +414,7 @@ impl ApubLikeableType for Post { insert_activity(&conn, creator.id, &like, true)?; - send_activity(&like, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&like, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -436,7 +436,7 @@ impl ApubLikeableType for Post { insert_activity(&conn, creator.id, &dislike, true)?; - send_activity(&dislike, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&dislike, creator, vec!(community.get_inbox_url()))?; Ok(()) } @@ -474,7 +474,7 @@ impl ApubLikeableType for Post { insert_activity(&conn, creator.id, &undo, true)?; - send_activity(&undo, creator, community.get_follower_inboxes(&conn)?)?; + send_activity(&undo, creator, vec!(community.get_inbox_url()))?; Ok(()) } }