2 objects::{community::ApubCommunity, instance::ApubSite},
4 activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
5 objects::{group::Group, instance::Instance},
8 use activitypub_federation::{
10 fetch::object_id::ObjectId,
11 traits::{Actor, Object},
13 use chrono::NaiveDateTime;
14 use lemmy_api_common::{community::BanFromCommunity, context::LemmyContext, person::BanPerson};
15 use lemmy_db_schema::{
16 newtypes::CommunityId,
17 source::{community::Community, person::Person, site::Site},
21 use lemmy_db_views::structs::SiteView;
23 error::{LemmyError, LemmyResult},
24 utils::time::naive_from_unix,
26 use serde::Deserialize;
30 pub mod undo_block_user;
32 #[derive(Clone, Debug)]
33 pub enum SiteOrCommunity {
35 Community(ApubCommunity),
38 #[derive(Deserialize)]
40 pub enum InstanceOrGroup {
45 #[async_trait::async_trait]
46 impl Object for SiteOrCommunity {
47 type DataType = LemmyContext;
48 type Kind = InstanceOrGroup;
49 type Error = LemmyError;
51 #[tracing::instrument(skip_all)]
52 fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
54 SiteOrCommunity::Site(i) => i.last_refreshed_at,
55 SiteOrCommunity::Community(c) => c.last_refreshed_at,
59 #[tracing::instrument(skip_all)]
60 async fn read_from_id(
62 data: &Data<Self::DataType>,
63 ) -> Result<Option<Self>, LemmyError>
67 let site = ApubSite::read_from_id(object_id.clone(), data).await?;
69 Some(o) => Some(SiteOrCommunity::Site(o)),
70 None => ApubCommunity::read_from_id(object_id, data)
72 .map(SiteOrCommunity::Community),
76 async fn delete(self, _data: &Data<Self::DataType>) -> Result<(), LemmyError> {
80 async fn into_json(self, _data: &Data<Self::DataType>) -> Result<Self::Kind, LemmyError> {
84 #[tracing::instrument(skip_all)]
87 expected_domain: &Url,
88 data: &Data<Self::DataType>,
89 ) -> Result<(), LemmyError> {
91 InstanceOrGroup::Instance(i) => ApubSite::verify(i, expected_domain, data).await,
92 InstanceOrGroup::Group(g) => ApubCommunity::verify(g, expected_domain, data).await,
96 #[tracing::instrument(skip_all)]
97 async fn from_json(apub: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, LemmyError>
102 InstanceOrGroup::Instance(p) => SiteOrCommunity::Site(ApubSite::from_json(p, data).await?),
103 InstanceOrGroup::Group(n) => {
104 SiteOrCommunity::Community(ApubCommunity::from_json(n, data).await?)
110 impl SiteOrCommunity {
111 fn id(&self) -> ObjectId<SiteOrCommunity> {
113 SiteOrCommunity::Site(s) => ObjectId::from(s.actor_id.clone()),
114 SiteOrCommunity::Community(c) => ObjectId::from(c.actor_id.clone()),
119 async fn generate_cc(
120 target: &SiteOrCommunity,
121 pool: &mut DbPool<'_>,
122 ) -> Result<Vec<Url>, LemmyError> {
124 SiteOrCommunity::Site(_) => Site::read_remote_sites(pool)
127 .map(|s| s.actor_id.into())
129 SiteOrCommunity::Community(c) => vec![c.id()],
133 pub(crate) async fn send_ban_from_site(
137 context: Data<LemmyContext>,
138 ) -> Result<(), LemmyError> {
139 let site = SiteOrCommunity::Site(SiteView::read_local(&mut context.pool()).await?.site.into());
140 let expires = data.expires.map(naive_from_unix);
142 // if the action affects a local user, federate to other instances
143 if banned_user.local {
149 data.remove_data.unwrap_or(false),
170 pub(crate) async fn send_ban_from_community(
172 community_id: CommunityId,
173 banned_person: Person,
174 data: BanFromCommunity,
175 context: Data<LemmyContext>,
176 ) -> LemmyResult<()> {
177 let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
180 let expires = data.expires.map(naive_from_unix);
184 &SiteOrCommunity::Community(community),
185 &banned_person.into(),
187 data.remove_data.unwrap_or(false),
195 &SiteOrCommunity::Community(community),
196 &banned_person.into(),