]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/send/user.rs
1847ec5c571ca65af8ce265db3af2e89d32c1e4d
[lemmy.git] / crates / apub / src / activities / send / user.rs
1 use crate::{
2   activities::send::generate_activity_id,
3   activity_queue::send_activity_single_dest,
4   extensions::context::lemmy_context,
5   ActorType,
6 };
7 use activitystreams::{
8   activity::{
9     kind::{FollowType, UndoType},
10     Follow,
11     Undo,
12   },
13   base::{AnyBase, BaseExt, ExtendsExt},
14   object::ObjectExt,
15 };
16 use lemmy_db_queries::{ApubObject, DbPool, Followable};
17 use lemmy_db_schema::source::{
18   community::{Community, CommunityFollower, CommunityFollowerForm},
19   user::User_,
20 };
21 use lemmy_structs::blocking;
22 use lemmy_utils::LemmyError;
23 use lemmy_websocket::LemmyContext;
24 use url::Url;
25
26 #[async_trait::async_trait(?Send)]
27 impl ActorType for User_ {
28   fn is_local(&self) -> bool {
29     self.local
30   }
31   fn actor_id(&self) -> Url {
32     self.actor_id.to_owned().into_inner()
33   }
34
35   fn public_key(&self) -> Option<String> {
36     self.public_key.to_owned()
37   }
38
39   fn private_key(&self) -> Option<String> {
40     self.private_key.to_owned()
41   }
42
43   fn get_shared_inbox_or_inbox_url(&self) -> Url {
44     self
45       .shared_inbox_url
46       .clone()
47       .unwrap_or_else(|| self.inbox_url.to_owned())
48       .into()
49   }
50
51   /// As a given local user, send out a follow request to a remote community.
52   async fn send_follow(
53     &self,
54     follow_actor_id: &Url,
55     context: &LemmyContext,
56   ) -> Result<(), LemmyError> {
57     let follow_actor_id = follow_actor_id.to_owned();
58     let community = blocking(context.pool(), move |conn| {
59       Community::read_from_apub_id(conn, &follow_actor_id.into())
60     })
61     .await??;
62
63     let community_follower_form = CommunityFollowerForm {
64       community_id: community.id,
65       user_id: self.id,
66       pending: true,
67     };
68     blocking(&context.pool(), move |conn| {
69       CommunityFollower::follow(conn, &community_follower_form).ok()
70     })
71     .await?;
72
73     let mut follow = Follow::new(self.actor_id.to_owned().into_inner(), community.actor_id());
74     follow
75       .set_many_contexts(lemmy_context()?)
76       .set_id(generate_activity_id(FollowType::Follow)?)
77       .set_to(community.actor_id());
78
79     send_activity_single_dest(follow, self, community.inbox_url.into(), context).await?;
80     Ok(())
81   }
82
83   async fn send_unfollow(
84     &self,
85     follow_actor_id: &Url,
86     context: &LemmyContext,
87   ) -> Result<(), LemmyError> {
88     let follow_actor_id = follow_actor_id.to_owned();
89     let community = blocking(context.pool(), move |conn| {
90       Community::read_from_apub_id(conn, &follow_actor_id.into())
91     })
92     .await??;
93
94     let mut follow = Follow::new(self.actor_id.to_owned().into_inner(), community.actor_id());
95     follow
96       .set_many_contexts(lemmy_context()?)
97       .set_id(generate_activity_id(FollowType::Follow)?)
98       .set_to(community.actor_id());
99
100     // Undo that fake activity
101     let mut undo = Undo::new(
102       self.actor_id.to_owned().into_inner(),
103       follow.into_any_base()?,
104     );
105     undo
106       .set_many_contexts(lemmy_context()?)
107       .set_id(generate_activity_id(UndoType::Undo)?)
108       .set_to(community.actor_id());
109
110     send_activity_single_dest(undo, self, community.inbox_url.into(), context).await?;
111     Ok(())
112   }
113
114   async fn send_accept_follow(
115     &self,
116     _follow: Follow,
117     _context: &LemmyContext,
118   ) -> Result<(), LemmyError> {
119     unimplemented!()
120   }
121
122   async fn send_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
123     unimplemented!()
124   }
125
126   async fn send_undo_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
127     unimplemented!()
128   }
129
130   async fn send_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
131     unimplemented!()
132   }
133
134   async fn send_undo_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
135     unimplemented!()
136   }
137
138   async fn send_announce(
139     &self,
140     _activity: AnyBase,
141     _context: &LemmyContext,
142   ) -> Result<(), LemmyError> {
143     unimplemented!()
144   }
145
146   async fn get_follower_inboxes(&self, _pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
147     unimplemented!()
148   }
149 }