]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/send/user.rs
Use Url type for ap_id fields in database (fixes #1364) (#1371)
[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 actor_id(&self) -> Url {
29     self.actor_id.to_owned().into_inner()
30   }
31
32   fn public_key(&self) -> Option<String> {
33     self.public_key.to_owned()
34   }
35
36   fn private_key(&self) -> Option<String> {
37     self.private_key.to_owned()
38   }
39
40   /// As a given local user, send out a follow request to a remote community.
41   async fn send_follow(
42     &self,
43     follow_actor_id: &Url,
44     context: &LemmyContext,
45   ) -> Result<(), LemmyError> {
46     let follow_actor_id = follow_actor_id.to_owned();
47     let community = blocking(context.pool(), move |conn| {
48       Community::read_from_apub_id(conn, &follow_actor_id.into())
49     })
50     .await??;
51
52     let community_follower_form = CommunityFollowerForm {
53       community_id: community.id,
54       user_id: self.id,
55       pending: true,
56     };
57     blocking(&context.pool(), move |conn| {
58       CommunityFollower::follow(conn, &community_follower_form).ok()
59     })
60     .await?;
61
62     let mut follow = Follow::new(self.actor_id.to_owned().into_inner(), community.actor_id());
63     follow
64       .set_many_contexts(lemmy_context()?)
65       .set_id(generate_activity_id(FollowType::Follow)?)
66       .set_to(community.actor_id());
67
68     send_activity_single_dest(follow, self, community.get_inbox_url()?, context).await?;
69     Ok(())
70   }
71
72   async fn send_unfollow(
73     &self,
74     follow_actor_id: &Url,
75     context: &LemmyContext,
76   ) -> Result<(), LemmyError> {
77     let follow_actor_id = follow_actor_id.to_owned();
78     let community = blocking(context.pool(), move |conn| {
79       Community::read_from_apub_id(conn, &follow_actor_id.into())
80     })
81     .await??;
82
83     let mut follow = Follow::new(self.actor_id.to_owned().into_inner(), community.actor_id());
84     follow
85       .set_many_contexts(lemmy_context()?)
86       .set_id(generate_activity_id(FollowType::Follow)?)
87       .set_to(community.actor_id());
88
89     // Undo that fake activity
90     let mut undo = Undo::new(
91       self.actor_id.to_owned().into_inner(),
92       follow.into_any_base()?,
93     );
94     undo
95       .set_many_contexts(lemmy_context()?)
96       .set_id(generate_activity_id(UndoType::Undo)?)
97       .set_to(community.actor_id());
98
99     send_activity_single_dest(undo, self, community.get_inbox_url()?, context).await?;
100     Ok(())
101   }
102
103   async fn send_accept_follow(
104     &self,
105     _follow: Follow,
106     _context: &LemmyContext,
107   ) -> Result<(), LemmyError> {
108     unimplemented!()
109   }
110
111   async fn send_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
112     unimplemented!()
113   }
114
115   async fn send_undo_delete(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
116     unimplemented!()
117   }
118
119   async fn send_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
120     unimplemented!()
121   }
122
123   async fn send_undo_remove(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
124     unimplemented!()
125   }
126
127   async fn send_announce(
128     &self,
129     _activity: AnyBase,
130     _context: &LemmyContext,
131   ) -> Result<(), LemmyError> {
132     unimplemented!()
133   }
134
135   async fn get_follower_inboxes(&self, _pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
136     unimplemented!()
137   }
138 }