summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdocker/federation/run-federation-test.bash3
-rw-r--r--server/src/apub/activities.rs26
-rw-r--r--server/src/apub/community_inbox.rs53
-rw-r--r--server/src/apub/inbox.rs101
-rw-r--r--server/src/apub/mod.rs3
-rw-r--r--server/src/apub/user_inbox.rs64
-rw-r--r--server/src/routes/federation.rs7
7 files changed, 135 insertions, 122 deletions
diff --git a/docker/federation/run-federation-test.bash b/docker/federation/run-federation-test.bash
index 62bc1e8b..2c8b681c 100755
--- a/docker/federation/run-federation-test.bash
+++ b/docker/federation/run-federation-test.bash
@@ -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
diff --git a/server/src/apub/activities.rs b/server/src/apub/activities.rs
index a1707267..2e35400d 100644
--- a/server/src/apub/activities.rs
+++ b/server/src/apub/activities.rs
@@ -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
index 00000000..0fe3fd70
--- /dev/null
+++ b/server/src/apub/community_inbox.rs
@@ -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
index a2db335a..00000000
--- a/server/src/apub/inbox.rs
+++ /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),
-}
diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs
index b2d157ae..11b513be 100644
--- a/server/src/apub/mod.rs
+++ b/server/src/apub/mod.rs
@@ -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
index 00000000..02517afe
--- /dev/null
+++ b/server/src/apub/user_inbox.rs
@@ -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())
+}
diff --git a/server/src/routes/federation.rs b/server/src/routes/federation.rs
index 2798e7a9..6c7cce8a 100644
--- a/server/src/routes/federation.rs
+++ b/server/src/routes/federation.rs
@@ -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}",