]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/objects/instance.rs
Diesel 2.0.0 upgrade (#2452)
[lemmy.git] / crates / apub / src / objects / instance.rs
index af75812dacfc406e79da3c21d30eabe92e840d69..dbf2f9f3a05fdd362139c58c42052c49d627d2ed 100644 (file)
@@ -1,24 +1,29 @@
 use crate::{
-  check_is_apub_id_valid,
-  objects::{read_from_string_or_source_opt, verify_image_domain_matches},
-  protocol::{objects::instance::Instance, ImageObject, SourceCompat},
+  check_apub_id_valid_with_strictness,
+  local_instance,
+  objects::read_from_string_or_source_opt,
+  protocol::{
+    objects::instance::{Instance, InstanceType},
+    ImageObject,
+    Source,
+  },
+  ActorType,
 };
-use activitystreams_kinds::actor::ServiceType;
-use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  object_id::ObjectId,
-  traits::{ActorType, ApubObject},
-  values::MediaTypeHtml,
-  verify::verify_domains_match,
+use activitypub_federation::{
+  core::object_id::ObjectId,
+  deser::values::MediaTypeHtml,
+  traits::{Actor, ApubObject},
+  utils::verify_domains_match,
 };
+use chrono::NaiveDateTime;
+use lemmy_api_common::utils::blocking;
 use lemmy_db_schema::{
-  naive_now,
   source::site::{Site, SiteForm},
+  utils::{naive_now, DbPool},
 };
 use lemmy_utils::{
+  error::LemmyError,
   utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html},
-  LemmyError,
 };
 use lemmy_websocket::LemmyContext;
 use std::ops::Deref;
@@ -46,7 +51,7 @@ impl ApubObject for ApubSite {
   type DataType = LemmyContext;
   type ApubType = Instance;
   type DbType = Site;
-  type TombstoneType = ();
+  type Error = LemmyError;
 
   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
     Some(self.last_refreshed_at)
@@ -73,28 +78,24 @@ impl ApubObject for ApubSite {
   #[tracing::instrument(skip_all)]
   async fn into_apub(self, _data: &Self::DataType) -> Result<Self::ApubType, LemmyError> {
     let instance = Instance {
-      kind: ServiceType::Service,
+      kind: InstanceType::Service,
       id: ObjectId::new(self.actor_id()),
       name: self.name.clone(),
       content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
-      source: self.sidebar.clone().map(SourceCompat::new),
+      source: self.sidebar.clone().map(Source::new),
       summary: self.description.clone(),
       media_type: self.sidebar.as_ref().map(|_| MediaTypeHtml::Html),
       icon: self.icon.clone().map(ImageObject::new),
       image: self.banner.clone().map(ImageObject::new),
       inbox: self.inbox_url.clone().into(),
       outbox: Url::parse(&format!("{}/site_outbox", self.actor_id))?,
-      public_key: self.get_public_key()?,
+      public_key: self.get_public_key(),
       published: convert_datetime(self.published),
       updated: self.updated.map(convert_datetime),
     };
     Ok(instance)
   }
 
-  fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError> {
-    unimplemented!()
-  }
-
   #[tracing::instrument(skip_all)]
   async fn verify(
     apub: &Self::ApubType,
@@ -102,10 +103,8 @@ impl ApubObject for ApubSite {
     data: &Self::DataType,
     _request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    check_is_apub_id_valid(apub.id.inner(), true, &data.settings())?;
+    check_apub_id_valid_with_strictness(apub.id.inner(), true, data.settings())?;
     verify_domains_match(expected_domain, apub.id.inner())?;
-    verify_image_domain_matches(expected_domain, &apub.icon)?;
-    verify_image_domain_matches(expected_domain, &apub.image)?;
 
     let slur_regex = &data.settings().slur_regex();
     check_slurs(&apub.name, slur_regex)?;
@@ -121,7 +120,11 @@ impl ApubObject for ApubSite {
   ) -> Result<Self, LemmyError> {
     let site_form = SiteForm {
       name: apub.name.clone(),
-      sidebar: Some(read_from_string_or_source_opt(&apub.content, &apub.source)),
+      sidebar: Some(read_from_string_or_source_opt(
+        &apub.content,
+        &None,
+        &apub.source,
+      )),
       updated: apub.updated.map(|u| u.clone().naive_local()),
       icon: Some(apub.icon.clone().map(|i| i.url.into())),
       banner: Some(apub.image.clone().map(|i| i.url.into())),
@@ -141,19 +144,18 @@ impl ActorType for ApubSite {
   fn actor_id(&self) -> Url {
     self.actor_id.to_owned().into()
   }
-  fn public_key(&self) -> String {
-    self.public_key.to_owned()
-  }
   fn private_key(&self) -> Option<String> {
     self.private_key.to_owned()
   }
+}
 
-  fn inbox_url(&self) -> Url {
-    self.inbox_url.clone().into()
+impl Actor for ApubSite {
+  fn public_key(&self) -> &str {
+    &self.public_key
   }
 
-  fn shared_inbox_url(&self) -> Option<Url> {
-    None
+  fn inbox(&self) -> Url {
+    self.inbox_url.clone().into()
   }
 }
 
@@ -175,13 +177,23 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object(
   // try to fetch the instance actor (to make things like instance rules available)
   let instance_id = instance_actor_id_from_url(object_id);
   let site = ObjectId::<ApubSite>::new(instance_id.clone())
-    .dereference(context, context.client(), request_counter)
+    .dereference(context, local_instance(context), request_counter)
     .await;
   if let Err(e) = site {
     debug!("Failed to dereference site for {}: {}", instance_id, e);
   }
 }
 
+pub(crate) async fn remote_instance_inboxes(pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
+  Ok(
+    blocking(pool, Site::read_remote_sites)
+      .await??
+      .into_iter()
+      .map(|s| ApubSite::from(s).shared_inbox_or_inbox())
+      .collect(),
+  )
+}
+
 #[cfg(test)]
 pub(crate) mod tests {
   use super::*;
@@ -207,11 +219,12 @@ pub(crate) mod tests {
   #[serial]
   async fn test_parse_lemmy_instance() {
     let context = init_context();
+    let conn = &mut context.pool().get().unwrap();
     let site = parse_lemmy_instance(&context).await;
 
     assert_eq!(site.name, "Enterprise");
     assert_eq!(site.description.as_ref().unwrap().len(), 15);
 
-    Site::delete(&*context.pool().get().unwrap(), site.id).unwrap();
+    Site::delete(conn, site.id).unwrap();
   }
 }