2 objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson},
4 activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
5 objects::{group::Group, instance::Instance},
9 use activitypub_federation::{
11 fetch::object_id::ObjectId,
12 traits::{Actor, Object},
14 use chrono::NaiveDateTime;
15 use lemmy_api_common::{
16 community::{BanFromCommunity, BanFromCommunityResponse},
17 context::LemmyContext,
18 person::{BanPerson, BanPersonResponse},
19 utils::local_user_view_from_jwt,
21 use lemmy_db_schema::{
22 source::{community::Community, person::Person, site::Site},
26 use lemmy_db_views::structs::SiteView;
27 use lemmy_utils::{error::LemmyError, utils::time::naive_from_unix};
28 use serde::Deserialize;
32 pub mod undo_block_user;
34 #[derive(Clone, Debug)]
35 pub enum SiteOrCommunity {
37 Community(ApubCommunity),
40 #[derive(Deserialize)]
42 pub enum InstanceOrGroup {
47 #[async_trait::async_trait]
48 impl Object for SiteOrCommunity {
49 type DataType = LemmyContext;
50 type Kind = InstanceOrGroup;
51 type Error = LemmyError;
53 #[tracing::instrument(skip_all)]
54 fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
56 SiteOrCommunity::Site(i) => i.last_refreshed_at,
57 SiteOrCommunity::Community(c) => c.last_refreshed_at,
61 #[tracing::instrument(skip_all)]
62 async fn read_from_id(
64 data: &Data<Self::DataType>,
65 ) -> Result<Option<Self>, LemmyError>
69 let site = ApubSite::read_from_id(object_id.clone(), data).await?;
71 Some(o) => Some(SiteOrCommunity::Site(o)),
72 None => ApubCommunity::read_from_id(object_id, data)
74 .map(SiteOrCommunity::Community),
78 async fn delete(self, _data: &Data<Self::DataType>) -> Result<(), LemmyError> {
82 async fn into_json(self, _data: &Data<Self::DataType>) -> Result<Self::Kind, LemmyError> {
86 #[tracing::instrument(skip_all)]
89 expected_domain: &Url,
90 data: &Data<Self::DataType>,
91 ) -> Result<(), LemmyError> {
93 InstanceOrGroup::Instance(i) => ApubSite::verify(i, expected_domain, data).await,
94 InstanceOrGroup::Group(g) => ApubCommunity::verify(g, expected_domain, data).await,
98 #[tracing::instrument(skip_all)]
99 async fn from_json(apub: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, LemmyError>
104 InstanceOrGroup::Instance(p) => SiteOrCommunity::Site(ApubSite::from_json(p, data).await?),
105 InstanceOrGroup::Group(n) => {
106 SiteOrCommunity::Community(ApubCommunity::from_json(n, data).await?)
112 impl SiteOrCommunity {
113 fn id(&self) -> ObjectId<SiteOrCommunity> {
115 SiteOrCommunity::Site(s) => ObjectId::from(s.actor_id.clone()),
116 SiteOrCommunity::Community(c) => ObjectId::from(c.actor_id.clone()),
121 async fn generate_cc(
122 target: &SiteOrCommunity,
123 pool: &mut DbPool<'_>,
124 ) -> Result<Vec<Url>, LemmyError> {
126 SiteOrCommunity::Site(_) => Site::read_remote_sites(pool)
129 .map(|s| s.actor_id.into())
131 SiteOrCommunity::Community(c) => vec![c.id()],
135 #[async_trait::async_trait]
136 impl SendActivity for BanPerson {
137 type Response = BanPersonResponse;
139 async fn send_activity(
141 _response: &Self::Response,
142 context: &Data<LemmyContext>,
143 ) -> Result<(), LemmyError> {
144 let local_user_view = local_user_view_from_jwt(&request.auth, context).await?;
145 let person = Person::read(&mut context.pool(), request.person_id).await?;
146 let site = SiteOrCommunity::Site(SiteView::read_local(&mut context.pool()).await?.site.into());
147 let expires = request.expires.map(naive_from_unix);
149 // if the action affects a local user, federate to other instances
155 &local_user_view.person.into(),
156 request.remove_data.unwrap_or(false),
157 request.reason.clone(),
166 &local_user_view.person.into(),
167 request.reason.clone(),
178 #[async_trait::async_trait]
179 impl SendActivity for BanFromCommunity {
180 type Response = BanFromCommunityResponse;
182 async fn send_activity(
184 _response: &Self::Response,
185 context: &Data<LemmyContext>,
186 ) -> Result<(), LemmyError> {
187 let local_user_view = local_user_view_from_jwt(&request.auth, context).await?;
188 let community: ApubCommunity = Community::read(&mut context.pool(), request.community_id)
191 let banned_person: ApubPerson = Person::read(&mut context.pool(), request.person_id)
194 let expires = request.expires.map(naive_from_unix);
198 &SiteOrCommunity::Community(community),
200 &local_user_view.person.clone().into(),
201 request.remove_data.unwrap_or(false),
202 request.reason.clone(),
209 &SiteOrCommunity::Community(community),
211 &local_user_view.person.clone().into(),
212 request.reason.clone(),