if [ "$1" = "-yarn" ]; then
pushd ../../ui/ || exit
+ yarn
yarn build
popd || exit
fi
sudo docker build ../../ -f Dockerfile -t lemmy-federation:latest
-sudo docker-compose up
\ No newline at end of file
+sudo docker-compose up
-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;
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> {
.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(())
}
.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(())
}
--- /dev/null
+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())
+}
+++ /dev/null
-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),
-}
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};
--- /dev/null
+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())
+}
"/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}",