]> Untitled Git - lemmy.git/blob - server/src/apub/inbox.rs
Merge branch 'dev' into federation
[lemmy.git] / server / src / apub / inbox.rs
1 use crate::apub::activities::accept_follow;
2 use crate::apub::fetcher::fetch_remote_user;
3 use crate::db::community::{Community, CommunityFollower, CommunityFollowerForm};
4 use crate::db::post::{Post, PostForm};
5 use crate::db::Crud;
6 use crate::db::Followable;
7 use activitystreams::activity::{Accept, Create, Follow, Update};
8 use activitystreams::object::Page;
9 use actix_web::{web, HttpResponse};
10 use diesel::r2d2::{ConnectionManager, Pool};
11 use diesel::PgConnection;
12 use failure::Error;
13 use url::Url;
14
15 // TODO: need a proper actor that has this inbox
16
17 pub async fn inbox(
18   input: web::Json<AcceptedObjects>,
19   db: web::Data<Pool<ConnectionManager<PgConnection>>>,
20 ) -> Result<HttpResponse, Error> {
21   // TODO: make sure that things are received in the correct inbox
22   //      (by using seperate handler functions and checking the user/community name in the path)
23   let input = input.into_inner();
24   let conn = &db.get().unwrap();
25   match input {
26     AcceptedObjects::Create(c) => handle_create(&c, conn),
27     AcceptedObjects::Update(u) => handle_update(&u, conn),
28     AcceptedObjects::Follow(f) => handle_follow(&f, conn),
29     AcceptedObjects::Accept(a) => handle_accept(&a, conn),
30   }
31 }
32
33 fn handle_create(create: &Create, conn: &PgConnection) -> Result<HttpResponse, Error> {
34   let page = create
35     .create_props
36     .get_object_base_box()
37     .to_owned()
38     .unwrap()
39     .to_owned()
40     .to_concrete::<Page>()?;
41   let post = PostForm::from_page(&page, conn)?;
42   Post::create(conn, &post)?;
43   // TODO: send the new post out via websocket
44   Ok(HttpResponse::Ok().finish())
45 }
46
47 fn handle_update(update: &Update, conn: &PgConnection) -> Result<HttpResponse, Error> {
48   let page = update
49     .update_props
50     .get_object_base_box()
51     .to_owned()
52     .unwrap()
53     .to_owned()
54     .to_concrete::<Page>()?;
55   let post = PostForm::from_page(&page, conn)?;
56   let id = Post::read_from_apub_id(conn, &post.ap_id)?.id;
57   Post::update(conn, id, &post)?;
58   // TODO: send the new post out via websocket
59   Ok(HttpResponse::Ok().finish())
60 }
61
62 fn handle_follow(follow: &Follow, conn: &PgConnection) -> Result<HttpResponse, Error> {
63   println!("received follow: {:?}", &follow);
64
65   // TODO: make sure this is a local community
66   let community_uri = follow
67     .follow_props
68     .get_object_xsd_any_uri()
69     .unwrap()
70     .to_string();
71   let community = Community::read_from_actor_id(conn, &community_uri)?;
72   let user_uri = follow
73     .follow_props
74     .get_actor_xsd_any_uri()
75     .unwrap()
76     .to_string();
77   let user = fetch_remote_user(&Url::parse(&user_uri)?, conn)?;
78   // TODO: insert ID of the user into follows of the community
79   let community_follower_form = CommunityFollowerForm {
80     community_id: community.id,
81     user_id: user.id,
82   };
83   CommunityFollower::follow(&conn, &community_follower_form)?;
84   accept_follow(&follow)?;
85   Ok(HttpResponse::Ok().finish())
86 }
87
88 fn handle_accept(accept: &Accept, _conn: &PgConnection) -> Result<HttpResponse, Error> {
89   println!("received accept: {:?}", &accept);
90   // TODO: at this point, indicate to the user that they are following the community
91   Ok(HttpResponse::Ok().finish())
92 }
93
94 #[serde(untagged)]
95 #[derive(serde::Deserialize)]
96 pub enum AcceptedObjects {
97   Create(Create),
98   Update(Update),
99   Follow(Follow),
100   Accept(Accept),
101 }