3 check_is_apub_id_valid,
4 community::do_announce,
5 extensions::signatures::verify,
7 get_or_fetch_and_upsert_actor,
8 get_or_fetch_and_upsert_community,
9 get_or_fetch_and_upsert_user,
12 announce::receive_announce,
13 create::receive_create,
14 delete::receive_delete,
15 dislike::receive_dislike,
17 remove::receive_remove,
19 update::receive_update,
23 routes::{ChatServerParam, DbPoolParam},
27 use activitystreams::{
28 activity::{ActorAndObject, ActorAndObjectRef},
29 base::{AsBase, Extends},
33 use actix_web::{client::Client, web, HttpRequest, HttpResponse};
34 use lemmy_db::user::User_;
36 use serde::{Deserialize, Serialize};
40 #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
41 #[serde(rename_all = "PascalCase")]
53 // TODO: this isnt entirely correct, cause some of these activities are not ActorAndObject,
54 // but it might still work due to the anybase conversion
55 pub type AcceptedActivities = ActorAndObject<ValidTypes>;
57 /// Handler for all incoming activities to user inboxes.
58 pub async fn shared_inbox(
60 input: web::Json<AcceptedActivities>,
61 client: web::Data<Client>,
63 chat_server: ChatServerParam,
64 ) -> Result<HttpResponse, LemmyError> {
65 let activity = input.into_inner();
67 let json = serde_json::to_string(&activity)?;
68 debug!("Shared inbox received activity: {}", json);
70 let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap();
71 let community = get_community_id_from_activity(&activity)?;
73 check_is_apub_id_valid(sender)?;
74 check_is_apub_id_valid(&community)?;
76 let actor = get_or_fetch_and_upsert_actor(sender, &client, &pool).await?;
77 verify(&request, actor.as_ref())?;
79 let any_base = activity.clone().into_any_base()?;
80 let kind = activity.kind().unwrap();
81 let res = match kind {
82 ValidTypes::Announce => receive_announce(any_base, &client, &pool, chat_server).await,
83 ValidTypes::Create => receive_create(any_base, &client, &pool, chat_server).await,
84 ValidTypes::Update => receive_update(any_base, &client, &pool, chat_server).await,
85 ValidTypes::Like => receive_like(any_base, &client, &pool, chat_server).await,
86 ValidTypes::Dislike => receive_dislike(any_base, &client, &pool, chat_server).await,
87 ValidTypes::Remove => receive_remove(any_base, &client, &pool, chat_server).await,
88 ValidTypes::Delete => receive_delete(any_base, &client, &pool, chat_server).await,
89 ValidTypes::Undo => receive_undo(any_base, &client, &pool, chat_server).await,
92 insert_activity(actor.user_id(), activity.clone(), false, &pool).await?;
96 pub(in crate::apub::inbox) fn receive_unhandled_activity<A>(
98 ) -> Result<HttpResponse, LemmyError>
102 debug!("received unhandled activity type: {:?}", activity);
103 Ok(HttpResponse::NotImplemented().finish())
106 pub(in crate::apub::inbox) async fn get_user_from_activity<T, A>(
110 ) -> Result<User_, LemmyError>
112 T: AsBase<A> + ActorAndObjectRef,
114 let actor = activity.actor()?;
115 let user_uri = actor.as_single_xsd_any_uri().unwrap();
116 get_or_fetch_and_upsert_user(&user_uri, client, pool).await
119 pub(in crate::apub::inbox) fn get_community_id_from_activity<T, A>(
121 ) -> Result<Url, LemmyError>
123 T: AsBase<A> + ActorAndObjectRef + AsObject<A>,
125 let cc = activity.cc().unwrap();
126 let cc = cc.as_many().unwrap();
127 Ok(cc.first().unwrap().as_xsd_any_uri().unwrap().to_owned())
130 pub(in crate::apub::inbox) async fn announce_if_community_is_local<T, Kind>(
135 ) -> Result<(), LemmyError>
140 <T as Extends<Kind>>::Error: From<serde_json::Error> + Send + Sync + 'static,
142 let cc = activity.cc().unwrap();
143 let cc = cc.as_many().unwrap();
144 let community_followers_uri = cc.first().unwrap().as_xsd_any_uri().unwrap();
145 // TODO: this is hacky but seems to be the only way to get the community ID
146 let community_uri = community_followers_uri
148 .replace("/followers", "");
150 get_or_fetch_and_upsert_community(&Url::parse(&community_uri)?, client, pool).await?;
153 do_announce(activity.into_any_base()?, &community, &user, client, pool).await?;