-/// Common methods provided by ActivityPub actors (community and person). Not all methods are
-/// implemented by all actors.
-trait ActorType {
- fn is_local(&self) -> bool;
- fn actor_id(&self) -> Url;
- fn name(&self) -> String;
-
- // TODO: every actor should have a public key, so this shouldnt be an option (needs to be fixed in db)
- fn public_key(&self) -> Option<String>;
- fn private_key(&self) -> Option<String>;
-
- fn get_shared_inbox_or_inbox_url(&self) -> Url;
-
- /// Outbox URL is not generally used by Lemmy, so it can be generated on the fly (but only for
- /// local actors).
- fn get_outbox_url(&self) -> Result<Url, LemmyError> {
- /* TODO
- if !self.is_local() {
- return Err(anyhow!("get_outbox_url() called for remote actor").into());
- }
- */
- Ok(Url::parse(&format!("{}/outbox", &self.actor_id()))?)
- }
-
- fn get_public_key(&self) -> Result<PublicKey, LemmyError> {
- Ok(PublicKey {
- id: format!("{}#main-key", self.actor_id()),
- owner: self.actor_id(),
- public_key_pem: self.public_key().context(location_info!())?,
- })
- }
-}
-
-#[async_trait::async_trait(?Send)]
-pub trait CommunityType {
- fn followers_url(&self) -> Url;
- async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError>;
-
- async fn send_update(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError>;
-
- async fn send_announce(
- &self,
- activity: AnyBase,
- object: Option<Url>,
- context: &LemmyContext,
- ) -> Result<(), LemmyError>;
-
- async fn send_add_mod(
- &self,
- actor: &Person,
- added_mod: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError>;
- async fn send_remove_mod(
- &self,
- actor: &Person,
- removed_mod: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError>;
-
- async fn send_block_user(
- &self,
- actor: &Person,
- blocked_user: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError>;
- async fn send_undo_block_user(
- &self,
- actor: &Person,
- blocked_user: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError>;
-}
-
-pub enum EndpointType {
- Community,
- Person,
- Post,
- Comment,
- PrivateMessage,
-}
-
-/// Generates an apub endpoint for a given domain, IE xyz.tld
-fn generate_apub_endpoint_for_domain(
- endpoint_type: EndpointType,
- name: &str,
- domain: &str,
-) -> Result<DbUrl, ParseError> {
- let point = match endpoint_type {
- EndpointType::Community => "c",
- EndpointType::Person => "u",
- EndpointType::Post => "post",
- EndpointType::Comment => "comment",
- EndpointType::PrivateMessage => "private_message",
- };
-
- Ok(Url::parse(&format!("{}/{}/{}", domain, point, name))?.into())
-}
-
-/// Generates the ActivityPub ID for a given object type and ID.
-pub fn generate_apub_endpoint(
- endpoint_type: EndpointType,
- name: &str,
-) -> Result<DbUrl, ParseError> {
- generate_apub_endpoint_for_domain(
- endpoint_type,
- name,
- &Settings::get().get_protocol_and_hostname(),
+#[derive(Clone)]
+pub(crate) struct LocalSiteData {
+ local_site: Option<LocalSite>,
+ allowed_instances: Vec<Instance>,
+ blocked_instances: Vec<Instance>,
+}
+
+pub(crate) async fn local_site_data_cached(
+ pool: &mut DbPool<'_>,
+) -> LemmyResult<Arc<LocalSiteData>> {
+ static CACHE: Lazy<Cache<(), Arc<LocalSiteData>>> = Lazy::new(|| {
+ Cache::builder()
+ .max_capacity(1)
+ .time_to_live(BLOCKLIST_CACHE_DURATION)
+ .build()
+ });
+ Ok(
+ CACHE
+ .try_get_with((), async {
+ let (local_site, allowed_instances, blocked_instances) =
+ lemmy_db_schema::try_join_with_pool!(pool => (
+ // LocalSite may be missing
+ |pool| async {
+ Ok(LocalSite::read(pool).await.ok())
+ },
+ Instance::allowlist,
+ Instance::blocklist
+ ))?;
+
+ Ok::<_, diesel::result::Error>(Arc::new(LocalSiteData {
+ local_site,
+ allowed_instances,
+ blocked_instances,
+ }))
+ })
+ .await?,