2 objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson},
4 activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
5 objects::{group::Group, instance::Instance},
10 use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject};
11 use chrono::NaiveDateTime;
12 use lemmy_api_common::{
13 community::{BanFromCommunity, BanFromCommunityResponse},
14 context::LemmyContext,
15 person::{BanPerson, BanPersonResponse},
16 utils::get_local_user_view_from_jwt,
18 use lemmy_db_schema::{
19 source::{community::Community, person::Person, site::Site},
23 use lemmy_db_views::structs::SiteView;
24 use lemmy_utils::{error::LemmyError, utils::time::naive_from_unix};
25 use serde::Deserialize;
29 pub mod undo_block_user;
31 #[derive(Clone, Debug)]
32 pub enum SiteOrCommunity {
34 Community(ApubCommunity),
37 #[derive(Deserialize)]
39 pub enum InstanceOrGroup {
44 #[async_trait::async_trait(?Send)]
45 impl ApubObject for SiteOrCommunity {
46 type DataType = LemmyContext;
47 type ApubType = 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_apub_id(
62 data: &Self::DataType,
63 ) -> Result<Option<Self>, LemmyError>
67 let site = ApubSite::read_from_apub_id(object_id.clone(), data).await?;
69 Some(o) => Some(SiteOrCommunity::Site(o)),
70 None => ApubCommunity::read_from_apub_id(object_id, data)
72 .map(SiteOrCommunity::Community),
76 async fn delete(self, _data: &Self::DataType) -> Result<(), LemmyError> {
80 async fn into_apub(self, _data: &Self::DataType) -> Result<Self::ApubType, LemmyError> {
84 #[tracing::instrument(skip_all)]
86 apub: &Self::ApubType,
87 expected_domain: &Url,
88 data: &Self::DataType,
89 request_counter: &mut i32,
90 ) -> Result<(), LemmyError> {
92 InstanceOrGroup::Instance(i) => {
93 ApubSite::verify(i, expected_domain, data, request_counter).await
95 InstanceOrGroup::Group(g) => {
96 ApubCommunity::verify(g, expected_domain, data, request_counter).await
101 #[tracing::instrument(skip_all)]
103 apub: Self::ApubType,
104 data: &Self::DataType,
105 request_counter: &mut i32,
106 ) -> Result<Self, LemmyError>
111 InstanceOrGroup::Instance(p) => {
112 SiteOrCommunity::Site(ApubSite::from_apub(p, data, request_counter).await?)
114 InstanceOrGroup::Group(n) => {
115 SiteOrCommunity::Community(ApubCommunity::from_apub(n, data, request_counter).await?)
121 impl SiteOrCommunity {
122 fn id(&self) -> ObjectId<SiteOrCommunity> {
124 SiteOrCommunity::Site(s) => ObjectId::new(s.actor_id.clone()),
125 SiteOrCommunity::Community(c) => ObjectId::new(c.actor_id.clone()),
130 async fn generate_cc(target: &SiteOrCommunity, pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
132 SiteOrCommunity::Site(_) => Site::read_remote_sites(pool)
135 .map(|s| s.actor_id.into())
137 SiteOrCommunity::Community(c) => vec![c.actor_id()],
141 #[async_trait::async_trait(?Send)]
142 impl SendActivity for BanPerson {
143 type Response = BanPersonResponse;
145 async fn send_activity(
147 _response: &Self::Response,
148 context: &LemmyContext,
149 ) -> Result<(), LemmyError> {
150 let local_user_view =
151 get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
152 let person = Person::read(context.pool(), request.person_id).await?;
153 let site = SiteOrCommunity::Site(SiteView::read_local(context.pool()).await?.site.into());
154 let expires = request.expires.map(naive_from_unix);
156 // if the action affects a local user, federate to other instances
162 &local_user_view.person.into(),
163 request.remove_data.unwrap_or(false),
164 request.reason.clone(),
173 &local_user_view.person.into(),
174 request.reason.clone(),
185 #[async_trait::async_trait(?Send)]
186 impl SendActivity for BanFromCommunity {
187 type Response = BanFromCommunityResponse;
189 async fn send_activity(
191 _response: &Self::Response,
192 context: &LemmyContext,
193 ) -> Result<(), LemmyError> {
194 let local_user_view =
195 get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
196 let community: ApubCommunity = Community::read(context.pool(), request.community_id)
199 let banned_person: ApubPerson = Person::read(context.pool(), request.person_id)
202 let expires = request.expires.map(naive_from_unix);
206 &SiteOrCommunity::Community(community),
208 &local_user_view.person.clone().into(),
209 request.remove_data.unwrap_or(false),
210 request.reason.clone(),
217 &SiteOrCommunity::Community(community),
219 &local_user_view.person.clone().into(),
220 request.reason.clone(),