lemmy/crates/apub/src/protocol/objects/group.rs
Nutomic e8a52d3a5c
Rewrite images to use local proxy (#4035)
* Add markdown rule to add rel=nofollow for all links

* Add markdown image rule to add local image proxy (fixes #1036)

* comments

* rewrite markdown image links working

* add comment

* perform markdown image processing in api/apub receivers

* clippy

* add db table to validate proxied links

* rewrite link fields for avatar, banner etc

* sql fmt

* proxy links received over federation

* add config option

* undo post.url rewriting, move http route definition

* add tests

* proxy images through pictrs

* testing

* cleanup request.rs file

* more cleanup (fixes #2611)

* include url content type when sending post over apub (fixes #2611)

* store post url content type in db

* should be media_type

* get rid of cache_remote_thumbnails setting, instead automatically
take thumbnail from federation data if available.

* fix tests

* add setting disable_external_link_previews

* federate post url as image depending on mime type

* change setting again

* machete

* invert

* support custom emoji

* clippy

* update defaults

* add image proxy test, fix test

* fix test

* clippy

* revert accidental changes

* address review

* clippy

* Markdown link rule-dess (#4356)

* Extracting opengraph_data to its own type.

* A few additions for markdown-link-rule.

---------

Co-authored-by: Nutomic <me@nutomic.com>

* fix setting

* use enum for image proxy setting

* fix test configs

* add config backwards compat

* clippy

* machete

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
2024-01-25 09:22:11 -05:00

93 lines
3 KiB
Rust

use crate::{
check_apub_id_valid_with_strictness,
collections::{
community_featured::ApubCommunityFeatured,
community_follower::ApubCommunityFollower,
community_moderators::ApubCommunityModerators,
community_outbox::ApubCommunityOutbox,
},
local_site_data_cached,
objects::{community::ApubCommunity, read_from_string_or_source_opt},
protocol::{
objects::{Endpoints, LanguageTag},
ImageObject,
Source,
},
};
use activitypub_federation::{
fetch::{collection_id::CollectionId, object_id::ObjectId},
kinds::actor::GroupType,
protocol::{
helpers::deserialize_skip_error,
public_key::PublicKey,
verification::verify_domains_match,
},
};
use chrono::{DateTime, Utc};
use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex};
use lemmy_utils::{
error::LemmyError,
utils::slurs::{check_slurs, check_slurs_opt},
};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::fmt::Debug;
use url::Url;
#[skip_serializing_none]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Group {
#[serde(rename = "type")]
pub(crate) kind: GroupType,
pub(crate) id: ObjectId<ApubCommunity>,
/// username, set at account creation and usually fixed after that
pub(crate) preferred_username: String,
pub(crate) inbox: Url,
pub(crate) followers: CollectionId<ApubCommunityFollower>,
pub(crate) public_key: PublicKey,
/// title
pub(crate) name: Option<String>,
pub(crate) summary: Option<String>,
#[serde(deserialize_with = "deserialize_skip_error", default)]
pub(crate) source: Option<Source>,
#[serde(deserialize_with = "deserialize_skip_error", default)]
pub(crate) icon: Option<ImageObject>,
/// banner
pub(crate) image: Option<ImageObject>,
// lemmy extension
pub(crate) sensitive: Option<bool>,
#[serde(deserialize_with = "deserialize_skip_error", default)]
pub(crate) attributed_to: Option<CollectionId<ApubCommunityModerators>>,
// lemmy extension
pub(crate) posting_restricted_to_mods: Option<bool>,
pub(crate) outbox: CollectionId<ApubCommunityOutbox>,
pub(crate) endpoints: Option<Endpoints>,
pub(crate) featured: Option<CollectionId<ApubCommunityFeatured>>,
#[serde(default)]
pub(crate) language: Vec<LanguageTag>,
pub(crate) published: Option<DateTime<Utc>>,
pub(crate) updated: Option<DateTime<Utc>>,
}
impl Group {
pub(crate) async fn verify(
&self,
expected_domain: &Url,
context: &LemmyContext,
) -> Result<(), LemmyError> {
check_apub_id_valid_with_strictness(self.id.inner(), true, context).await?;
verify_domains_match(expected_domain, self.id.inner())?;
let local_site_data = local_site_data_cached(&mut context.pool()).await?;
let slur_regex = &local_site_opt_to_slur_regex(&local_site_data.local_site);
check_slurs(&self.preferred_username, slur_regex)?;
check_slurs_opt(&self.name, slur_regex)?;
let description = read_from_string_or_source_opt(&self.summary, &None, &self.source);
check_slurs_opt(&description, slur_regex)?;
Ok(())
}
}