]> Untitled Git - lemmy.git/commitdiff
Let community announce posts
authorFelix <me@nutomic.com>
Wed, 6 May 2020 17:10:36 +0000 (19:10 +0200)
committerFelix Ableitner <me@nutomic.com>
Thu, 28 May 2020 11:15:51 +0000 (13:15 +0200)
docker/dev/docker-compose.yml
server/src/apub/community.rs
server/src/apub/community_inbox.rs
server/src/apub/post.rs

index 3c52d1e54b28160f34c5e286240e16c7e6b20e4b..556c67bd97341d86b57a4291c7b283f69651db0a 100644 (file)
@@ -22,7 +22,7 @@ services:
       - RUST_LOG=debug
     volumes:
       - ../lemmy.hjson:/config/config.hjson
-    depends_on: 
+    depends_on:
       - postgres
       - pictshare
       - iframely
index bc92449242e9d2f61c2f3bbccb2027a1af41edc1..1ba41da427a3b95a3fcb428148017c8e6a4f8652 100644 (file)
@@ -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(),
index 2ae2e0ebc01c2231946b3ebc79d79f05b9cad8a7..09aecd899e9d28a75662664794010004b783c2cd 100644 (file)
@@ -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::<Follow>()?,
       ),
+      _ => todo!()
     }
   }
 }
@@ -49,13 +58,20 @@ pub async fn community_inbox(
   input: web::Json<CommunityAcceptedObjects>,
   path: web::Path<String>,
   db: DbPoolParam,
-  _chat_server: ChatServerParam,
+  chat_server: ChatServerParam,
 ) -> Result<HttpResponse, Error> {
   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<remove> or undo<delete>, 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<A>(
+  activity: A,
+  _request: &HttpRequest,
+  community: &Community,
+  conn: &PgConnection,
+  _chat_server: ChatServerParam,
+) -> Result<HttpResponse, Error>
+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())
+}
index 9ee0429808ae44c64d94f225a75b8432fc3cfea9..d91cf4720d2bea160849cb03b37b82d22c4fb800 100644 (file)
@@ -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(())
   }
 }