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::get_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(target: &SiteOrCommunity, pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
123 SiteOrCommunity::Site(_) => Site::read_remote_sites(pool)
126 .map(|s| s.actor_id.into())
128 SiteOrCommunity::Community(c) => vec![c.id()],
132 #[async_trait::async_trait]
133 impl SendActivity for BanPerson {
134 type Response = BanPersonResponse;
136 async fn send_activity(
138 _response: &Self::Response,
139 context: &Data<LemmyContext>,
140 ) -> Result<(), LemmyError> {
141 let local_user_view =
142 get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
143 let person = Person::read(context.pool(), request.person_id).await?;
144 let site = SiteOrCommunity::Site(SiteView::read_local(context.pool()).await?.site.into());
145 let expires = request.expires.map(naive_from_unix);
147 // if the action affects a local user, federate to other instances
153 &local_user_view.person.into(),
154 request.remove_data.unwrap_or(false),
155 request.reason.clone(),
164 &local_user_view.person.into(),
165 request.reason.clone(),
176 #[async_trait::async_trait]
177 impl SendActivity for BanFromCommunity {
178 type Response = BanFromCommunityResponse;
180 async fn send_activity(
182 _response: &Self::Response,
183 context: &Data<LemmyContext>,
184 ) -> Result<(), LemmyError> {
185 let local_user_view =
186 get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
187 let community: ApubCommunity = Community::read(context.pool(), request.community_id)
190 let banned_person: ApubPerson = Person::read(context.pool(), request.person_id)
193 let expires = request.expires.map(naive_from_unix);
197 &SiteOrCommunity::Community(community),
199 &local_user_view.person.clone().into(),
200 request.remove_data.unwrap_or(false),
201 request.reason.clone(),
208 &SiteOrCommunity::Community(community),
210 &local_user_view.person.clone().into(),
211 request.reason.clone(),