]> Untitled Git - lemmy.git/commitdiff
Send activities to correct inbox, seperate community/user inboxes
authorFelix <me@nutomic.com>
Wed, 15 Apr 2020 18:12:25 +0000 (20:12 +0200)
committerFelix <me@nutomic.com>
Wed, 15 Apr 2020 18:12:25 +0000 (20:12 +0200)
docker/federation/run-federation-test.bash
server/src/apub/activities.rs
server/src/apub/community_inbox.rs [new file with mode: 0644]
server/src/apub/inbox.rs [deleted file]
server/src/apub/mod.rs
server/src/apub/user_inbox.rs [new file with mode: 0644]
server/src/routes/federation.rs

index 62bc1e8bfa92431c7fb8b0a50f68ef034d1c2e93..2c8b681ce3e65e0fe8cdcd3dbc994debffb05903 100755 (executable)
@@ -3,6 +3,7 @@ set -e
 
 if [ "$1" = "-yarn" ]; then
   pushd ../../ui/ || exit
+  yarn
   yarn build
   popd || exit
 fi
@@ -13,4 +14,4 @@ popd || exit
 
 sudo docker build ../../ -f Dockerfile -t lemmy-federation:latest
 
-sudo docker-compose up
\ No newline at end of file
+sudo docker-compose up
index a1707267c2abda47866870f1a5d5345cc4de450e..2e35400d0f351ff03ad5ce0d4676569a790bb4f8 100644 (file)
@@ -1,5 +1,5 @@
-use crate::apub::{get_apub_protocol_string, get_following_instances};
 use crate::db::community::Community;
+use crate::db::community_view::CommunityFollowerView;
 use crate::db::post::Post;
 use crate::db::user::User_;
 use crate::db::Crud;
@@ -46,18 +46,14 @@ where
   Ok(())
 }
 
-fn get_followers(_community: &Community) -> Vec<String> {
-  // TODO: this is wrong, needs to go to the (non-local) followers of the community
-  get_following_instances()
-    .iter()
-    .map(|i| {
-      format!(
-        "{}://{}/federation/inbox",
-        get_apub_protocol_string(),
-        i.domain
-      )
-    })
-    .collect()
+fn get_followers(conn: &PgConnection, community: &Community) -> Result<Vec<String>, Error> {
+  Ok(
+    CommunityFollowerView::for_community(conn, community.id)?
+      .iter()
+      .filter(|c| !c.user_local)
+      .map(|c| format!("{}/inbox", c.user_actor_id.to_owned()))
+      .collect(),
+  )
 }
 
 pub fn post_create(post: &Post, creator: &User_, conn: &PgConnection) -> Result<(), Error> {
@@ -73,7 +69,7 @@ pub fn post_create(post: &Post, creator: &User_, conn: &PgConnection) -> Result<
     .create_props
     .set_actor_xsd_any_uri(creator.actor_id.to_owned())?
     .set_object_base_box(page)?;
-  send_activity(&create, get_followers(&community))?;
+  send_activity(&create, get_followers(conn, &community)?)?;
   Ok(())
 }
 
@@ -90,7 +86,7 @@ pub fn post_update(post: &Post, creator: &User_, conn: &PgConnection) -> Result<
     .update_props
     .set_actor_xsd_any_uri(creator.actor_id.to_owned())?
     .set_object_base_box(page)?;
-  send_activity(&update, get_followers(&community))?;
+  send_activity(&update, get_followers(conn, &community)?)?;
   Ok(())
 }
 
diff --git a/server/src/apub/community_inbox.rs b/server/src/apub/community_inbox.rs
new file mode 100644 (file)
index 0000000..0fe3fd7
--- /dev/null
@@ -0,0 +1,53 @@
+use crate::apub::activities::accept_follow;
+use crate::apub::fetcher::fetch_remote_user;
+use crate::db::community::{Community, CommunityFollower, CommunityFollowerForm};
+use crate::db::Followable;
+use activitystreams::activity::Follow;
+use actix_web::{web, HttpResponse};
+use diesel::r2d2::{ConnectionManager, Pool};
+use diesel::PgConnection;
+use failure::Error;
+use url::Url;
+
+#[serde(untagged)]
+#[derive(serde::Deserialize)]
+pub enum CommunityAcceptedObjects {
+  Follow(Follow),
+}
+
+pub async fn community_inbox(
+  input: web::Json<CommunityAcceptedObjects>,
+  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
+) -> Result<HttpResponse, Error> {
+  let input = input.into_inner();
+  let conn = &db.get().unwrap();
+  match input {
+    CommunityAcceptedObjects::Follow(f) => handle_follow(&f, conn),
+  }
+}
+
+fn handle_follow(follow: &Follow, conn: &PgConnection) -> Result<HttpResponse, Error> {
+  println!("received follow: {:?}", &follow);
+
+  // TODO: make sure this is a local community
+  let community_uri = follow
+    .follow_props
+    .get_object_xsd_any_uri()
+    .unwrap()
+    .to_string();
+  let community = Community::read_from_actor_id(conn, &community_uri)?;
+  let user_uri = follow
+    .follow_props
+    .get_actor_xsd_any_uri()
+    .unwrap()
+    .to_string();
+  let user = fetch_remote_user(&Url::parse(&user_uri)?, conn)?;
+  // TODO: insert ID of the user into follows of the community
+  let community_follower_form = CommunityFollowerForm {
+    community_id: community.id,
+    user_id: user.id,
+  };
+  CommunityFollower::follow(&conn, &community_follower_form)?;
+  accept_follow(&follow)?;
+  Ok(HttpResponse::Ok().finish())
+}
diff --git a/server/src/apub/inbox.rs b/server/src/apub/inbox.rs
deleted file mode 100644 (file)
index a2db335..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-use crate::apub::activities::accept_follow;
-use crate::apub::fetcher::fetch_remote_user;
-use crate::db::community::{Community, CommunityFollower, CommunityFollowerForm};
-use crate::db::post::{Post, PostForm};
-use crate::db::Crud;
-use crate::db::Followable;
-use activitystreams::activity::{Accept, Create, Follow, Update};
-use activitystreams::object::Page;
-use actix_web::{web, HttpResponse};
-use diesel::r2d2::{ConnectionManager, Pool};
-use diesel::PgConnection;
-use failure::Error;
-use url::Url;
-
-// TODO: need a proper actor that has this inbox
-
-pub async fn inbox(
-  input: web::Json<AcceptedObjects>,
-  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
-) -> Result<HttpResponse, Error> {
-  // TODO: make sure that things are received in the correct inbox
-  //      (by using seperate handler functions and checking the user/community name in the path)
-  let input = input.into_inner();
-  let conn = &db.get().unwrap();
-  match input {
-    AcceptedObjects::Create(c) => handle_create(&c, conn),
-    AcceptedObjects::Update(u) => handle_update(&u, conn),
-    AcceptedObjects::Follow(f) => handle_follow(&f, conn),
-    AcceptedObjects::Accept(a) => handle_accept(&a, conn),
-  }
-}
-
-fn handle_create(create: &Create, conn: &PgConnection) -> Result<HttpResponse, Error> {
-  let page = create
-    .create_props
-    .get_object_base_box()
-    .to_owned()
-    .unwrap()
-    .to_owned()
-    .to_concrete::<Page>()?;
-  let post = PostForm::from_page(&page, conn)?;
-  Post::create(conn, &post)?;
-  // TODO: send the new post out via websocket
-  Ok(HttpResponse::Ok().finish())
-}
-
-fn handle_update(update: &Update, conn: &PgConnection) -> Result<HttpResponse, Error> {
-  let page = update
-    .update_props
-    .get_object_base_box()
-    .to_owned()
-    .unwrap()
-    .to_owned()
-    .to_concrete::<Page>()?;
-  let post = PostForm::from_page(&page, conn)?;
-  let id = Post::read_from_apub_id(conn, &post.ap_id)?.id;
-  Post::update(conn, id, &post)?;
-  // TODO: send the new post out via websocket
-  Ok(HttpResponse::Ok().finish())
-}
-
-fn handle_follow(follow: &Follow, conn: &PgConnection) -> Result<HttpResponse, Error> {
-  println!("received follow: {:?}", &follow);
-
-  // TODO: make sure this is a local community
-  let community_uri = follow
-    .follow_props
-    .get_object_xsd_any_uri()
-    .unwrap()
-    .to_string();
-  let community = Community::read_from_actor_id(conn, &community_uri)?;
-  let user_uri = follow
-    .follow_props
-    .get_actor_xsd_any_uri()
-    .unwrap()
-    .to_string();
-  let user = fetch_remote_user(&Url::parse(&user_uri)?, conn)?;
-  // TODO: insert ID of the user into follows of the community
-  let community_follower_form = CommunityFollowerForm {
-    community_id: community.id,
-    user_id: user.id,
-  };
-  CommunityFollower::follow(&conn, &community_follower_form)?;
-  accept_follow(&follow)?;
-  Ok(HttpResponse::Ok().finish())
-}
-
-fn handle_accept(accept: &Accept, _conn: &PgConnection) -> Result<HttpResponse, Error> {
-  println!("received accept: {:?}", &accept);
-  // TODO: at this point, indicate to the user that they are following the community
-  Ok(HttpResponse::Ok().finish())
-}
-
-#[serde(untagged)]
-#[derive(serde::Deserialize)]
-pub enum AcceptedObjects {
-  Create(Create),
-  Update(Update),
-  Follow(Follow),
-  Accept(Accept),
-}
index b2d157ae8e0c153d8a123f002d768432c6a7d595..11b513bebf9bca008185b6bfd27c93b589bff33b 100644 (file)
@@ -1,10 +1,11 @@
 pub mod activities;
 pub mod community;
+pub mod community_inbox;
 pub mod fetcher;
-pub mod inbox;
 pub mod post;
 pub mod signatures;
 pub mod user;
+pub mod user_inbox;
 use crate::apub::signatures::PublicKeyExtension;
 use crate::Settings;
 use activitystreams::actor::{properties::ApActorProperties, Group, Person};
diff --git a/server/src/apub/user_inbox.rs b/server/src/apub/user_inbox.rs
new file mode 100644 (file)
index 0000000..02517af
--- /dev/null
@@ -0,0 +1,64 @@
+use crate::db::post::{Post, PostForm};
+use crate::db::Crud;
+use activitystreams::activity::{Accept, Create, Update};
+use activitystreams::object::Page;
+use actix_web::{web, HttpResponse};
+use diesel::r2d2::{ConnectionManager, Pool};
+use diesel::PgConnection;
+use failure::Error;
+
+#[serde(untagged)]
+#[derive(serde::Deserialize)]
+pub enum UserAcceptedObjects {
+  Create(Create),
+  Update(Update),
+  Accept(Accept),
+}
+
+pub async fn user_inbox(
+  input: web::Json<UserAcceptedObjects>,
+  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
+) -> Result<HttpResponse, Error> {
+  let input = input.into_inner();
+  let conn = &db.get().unwrap();
+  match input {
+    UserAcceptedObjects::Create(c) => handle_create(&c, conn),
+    UserAcceptedObjects::Update(u) => handle_update(&u, conn),
+    UserAcceptedObjects::Accept(a) => handle_accept(&a, conn),
+  }
+}
+
+fn handle_create(create: &Create, conn: &PgConnection) -> Result<HttpResponse, Error> {
+  let page = create
+    .create_props
+    .get_object_base_box()
+    .to_owned()
+    .unwrap()
+    .to_owned()
+    .to_concrete::<Page>()?;
+  let post = PostForm::from_page(&page, conn)?;
+  Post::create(conn, &post)?;
+  // TODO: send the new post out via websocket
+  Ok(HttpResponse::Ok().finish())
+}
+
+fn handle_update(update: &Update, conn: &PgConnection) -> Result<HttpResponse, Error> {
+  let page = update
+    .update_props
+    .get_object_base_box()
+    .to_owned()
+    .unwrap()
+    .to_owned()
+    .to_concrete::<Page>()?;
+  let post = PostForm::from_page(&page, conn)?;
+  let id = Post::read_from_apub_id(conn, &post.ap_id)?.id;
+  Post::update(conn, id, &post)?;
+  // TODO: send the new post out via websocket
+  Ok(HttpResponse::Ok().finish())
+}
+
+fn handle_accept(accept: &Accept, _conn: &PgConnection) -> Result<HttpResponse, Error> {
+  println!("received accept: {:?}", &accept);
+  // TODO: at this point, indicate to the user that they are following the community
+  Ok(HttpResponse::Ok().finish())
+}
index 2798e7a9526a168e0260daf359bc52f9a0447a50..6c7cce8a8c06d46b40e6e47307ed5ff8138bdb33 100644 (file)
@@ -10,15 +10,14 @@ pub fn config(cfg: &mut web::ServiceConfig) {
         "/federation/communities",
         web::get().to(apub::community::get_apub_community_list),
       )
-      // TODO: this needs to be moved to the actors (eg /federation/u/{}/inbox)
-      .route("/federation/inbox", web::post().to(apub::inbox::inbox))
+      // TODO: check the user/community params for these
       .route(
         "/federation/c/{_}/inbox",
-        web::post().to(apub::inbox::inbox),
+        web::post().to(apub::community_inbox::community_inbox),
       )
       .route(
         "/federation/u/{_}/inbox",
-        web::post().to(apub::inbox::inbox),
+        web::post().to(apub::user_inbox::user_inbox),
       )
       .route(
         "/federation/c/{community_name}",