]> Untitled Git - lemmy.git/blob - crates/apub/src/http/routes.rs
a57290e4b9023bbfcf7aa51bd3daa492fa64ad9b
[lemmy.git] / crates / apub / src / http / routes.rs
1 use crate::http::{
2   comment::get_apub_comment,
3   community::{
4     community_inbox,
5     get_apub_community_followers,
6     get_apub_community_http,
7     get_apub_community_moderators,
8     get_apub_community_outbox,
9   },
10   get_activity,
11   person::{get_apub_person_http, get_apub_person_outbox, person_inbox},
12   post::get_apub_post,
13   shared_inbox,
14 };
15 use actix_web::{
16   guard::{Guard, GuardContext},
17   http::{header, Method},
18   web,
19 };
20 use http_signature_normalization_actix::digest::middleware::VerifyDigest;
21 use lemmy_utils::settings::structs::Settings;
22 use sha2::{Digest, Sha256};
23
24 pub fn config(cfg: &mut web::ServiceConfig, settings: &Settings) {
25   if settings.federation.enabled {
26     println!("federation enabled, host is {}", settings.hostname);
27
28     cfg
29       .route(
30         "/c/{community_name}",
31         web::get().to(get_apub_community_http),
32       )
33       .route(
34         "/c/{community_name}/followers",
35         web::get().to(get_apub_community_followers),
36       )
37       .route(
38         "/c/{community_name}/outbox",
39         web::get().to(get_apub_community_outbox),
40       )
41       .route(
42         "/c/{community_name}/moderators",
43         web::get().to(get_apub_community_moderators),
44       )
45       .route("/u/{user_name}", web::get().to(get_apub_person_http))
46       .route(
47         "/u/{user_name}/outbox",
48         web::get().to(get_apub_person_outbox),
49       )
50       .route("/post/{post_id}", web::get().to(get_apub_post))
51       .route("/comment/{comment_id}", web::get().to(get_apub_comment))
52       .route("/activities/{type_}/{id}", web::get().to(get_activity));
53
54     cfg.service(
55       web::scope("")
56         .wrap(VerifyDigest::new(Sha256::new()))
57         .guard(InboxRequestGuard)
58         .route("/c/{community_name}/inbox", web::post().to(community_inbox))
59         .route("/u/{user_name}/inbox", web::post().to(person_inbox))
60         .route("/inbox", web::post().to(shared_inbox)),
61     );
62   }
63 }
64
65 /// Without this, things like webfinger or RSS feeds stop working, as all requests seem to get
66 /// routed into the inbox service (because it covers the root path). So we filter out anything that
67 /// definitely can't be an inbox request (based on Accept header and request method).
68 struct InboxRequestGuard;
69
70 impl Guard for InboxRequestGuard {
71   fn check(&self, ctx: &GuardContext) -> bool {
72     if ctx.head().method != Method::POST {
73       return false;
74     }
75     if let Some(val) = ctx.head().headers.get(header::CONTENT_TYPE) {
76       return val.as_bytes().starts_with(b"application/");
77     }
78     false
79   }
80 }