Support signed fetch for federation (fixes #868) (#4125)

* Support signed fetch for federation (fixes #868)

* taplo
This commit is contained in:
Nutomic 2023-11-06 22:02:01 +01:00 committed by GitHub
parent cf788334aa
commit 8c85f35b19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 28 additions and 41 deletions

View file

@ -492,29 +492,13 @@ mod tests {
site_registration_mode: RegistrationMode, site_registration_mode: RegistrationMode,
) -> LocalSite { ) -> LocalSite {
LocalSite { LocalSite {
id: Default::default(),
site_id: Default::default(),
site_setup, site_setup,
enable_downvotes: false,
enable_nsfw: false,
community_creation_admin_only: false,
require_email_verification: false,
application_question: site_application_question, application_question: site_application_question,
private_instance: site_is_private, private_instance: site_is_private,
default_theme: String::new(),
default_post_listing_type: ListingType::All,
legal_information: None,
hide_modlog_mod_names: false,
application_email_admins: false,
slur_filter_regex: site_slur_filter_regex, slur_filter_regex: site_slur_filter_regex,
actor_name_max_length: 0,
federation_enabled: site_is_federated, federation_enabled: site_is_federated,
captcha_enabled: false,
captcha_difficulty: String::new(),
published: Default::default(),
updated: None,
registration_mode: site_registration_mode, registration_mode: site_registration_mode,
reports_email_admins: false, ..Default::default()
} }
} }

View file

@ -491,29 +491,12 @@ mod tests {
site_registration_mode: RegistrationMode, site_registration_mode: RegistrationMode,
) -> LocalSite { ) -> LocalSite {
LocalSite { LocalSite {
id: Default::default(),
site_id: Default::default(),
site_setup: true,
enable_downvotes: false,
enable_nsfw: false,
community_creation_admin_only: false,
require_email_verification: false,
application_question: site_application_question, application_question: site_application_question,
private_instance: site_is_private, private_instance: site_is_private,
default_theme: String::new(),
default_post_listing_type: ListingType::All,
legal_information: None,
hide_modlog_mod_names: false,
application_email_admins: false,
slur_filter_regex: site_slur_filter_regex, slur_filter_regex: site_slur_filter_regex,
actor_name_max_length: 0,
federation_enabled: site_is_federated, federation_enabled: site_is_federated,
captcha_enabled: false,
captcha_difficulty: String::new(),
published: Default::default(),
updated: None,
registration_mode: site_registration_mode, registration_mode: site_registration_mode,
reports_email_admins: false, ..Default::default()
} }
} }

View file

@ -114,7 +114,9 @@ pub enum ListingType {
ModeratorView, ModeratorView,
} }
#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] #[derive(
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default,
)]
#[cfg_attr(feature = "full", derive(DbEnum, TS))] #[cfg_attr(feature = "full", derive(DbEnum, TS))]
#[cfg_attr( #[cfg_attr(
feature = "full", feature = "full",
@ -129,6 +131,7 @@ pub enum RegistrationMode {
/// Open, but pending approval of a registration application. /// Open, but pending approval of a registration application.
RequireApplication, RequireApplication,
/// Open to all. /// Open to all.
#[default]
Open, Open,
} }

View file

@ -385,6 +385,7 @@ diesel::table! {
updated -> Nullable<Timestamptz>, updated -> Nullable<Timestamptz>,
registration_mode -> RegistrationModeEnum, registration_mode -> RegistrationModeEnum,
reports_email_admins -> Bool, reports_email_admins -> Bool,
federation_signed_fetch -> Bool,
} }
} }

View file

@ -13,7 +13,7 @@ use ts_rs::TS;
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
#[skip_serializing_none] #[skip_serializing_none]
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)] #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "full", derive(Queryable, Identifiable, TS))] #[cfg_attr(feature = "full", derive(Queryable, Identifiable, TS))]
#[cfg_attr(feature = "full", diesel(table_name = local_site))] #[cfg_attr(feature = "full", diesel(table_name = local_site))]
#[cfg_attr(feature = "full", diesel(belongs_to(crate::source::site::Site)))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::site::Site)))]
@ -60,6 +60,9 @@ pub struct LocalSite {
pub registration_mode: RegistrationMode, pub registration_mode: RegistrationMode,
/// Whether to email admins on new reports. /// Whether to email admins on new reports.
pub reports_email_admins: bool, pub reports_email_admins: bool,
/// Whether to sign outgoing Activitypub fetches with private key of local instance. Some
/// Fediverse instances and platforms require this.
pub federation_signed_fetch: bool,
} }
#[derive(Clone, TypedBuilder)] #[derive(Clone, TypedBuilder)]
@ -88,6 +91,7 @@ pub struct LocalSiteInsertForm {
pub captcha_difficulty: Option<String>, pub captcha_difficulty: Option<String>,
pub registration_mode: Option<RegistrationMode>, pub registration_mode: Option<RegistrationMode>,
pub reports_email_admins: Option<bool>, pub reports_email_admins: Option<bool>,
pub federation_signed_fetch: Option<bool>,
} }
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -114,4 +118,5 @@ pub struct LocalSiteUpdateForm {
pub registration_mode: Option<RegistrationMode>, pub registration_mode: Option<RegistrationMode>,
pub reports_email_admins: Option<bool>, pub reports_email_admins: Option<bool>,
pub updated: Option<Option<DateTime<Utc>>>, pub updated: Option<Option<DateTime<Utc>>>,
pub federation_signed_fetch: Option<bool>,
} }

View file

@ -0,0 +1,3 @@
ALTER TABLE local_site
DROP COLUMN federation_signed_fetch;

View file

@ -0,0 +1,3 @@
ALTER TABLE local_site
ADD COLUMN federation_signed_fetch boolean NOT NULL DEFAULT FALSE;

View file

@ -36,6 +36,7 @@ use lemmy_api_common::{
}; };
use lemmy_apub::{ use lemmy_apub::{
activities::{handle_outgoing_activities, match_outgoing_activities}, activities::{handle_outgoing_activities, match_outgoing_activities},
objects::instance::ApubSite,
VerifyUrlData, VerifyUrlData,
FEDERATION_HTTP_FETCH_LIMIT, FEDERATION_HTTP_FETCH_LIMIT,
}; };
@ -164,16 +165,20 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
serve_prometheus(prometheus, context.clone())?; serve_prometheus(prometheus, context.clone())?;
} }
let federation_config = FederationConfig::builder() let mut federation_config = FederationConfig::builder();
federation_config
.domain(SETTINGS.hostname.clone()) .domain(SETTINGS.hostname.clone())
.app_data(context.clone()) .app_data(context.clone())
.client(client.clone()) .client(client.clone())
.http_fetch_limit(FEDERATION_HTTP_FETCH_LIMIT) .http_fetch_limit(FEDERATION_HTTP_FETCH_LIMIT)
.debug(cfg!(debug_assertions)) .debug(cfg!(debug_assertions))
.http_signature_compat(true) .http_signature_compat(true)
.url_verifier(Box::new(VerifyUrlData(context.inner_pool().clone()))) .url_verifier(Box::new(VerifyUrlData(context.inner_pool().clone())));
.build() if local_site.federation_signed_fetch {
.await?; let site: ApubSite = site_view.site.into();
federation_config.signed_fetch_actor(&site);
}
let federation_config = federation_config.build().await?;
MATCH_OUTGOING_ACTIVITIES MATCH_OUTGOING_ACTIVITIES
.set(Box::new(move |d, c| { .set(Box::new(move |d, c| {