]> Untitled Git - lemmy.git/blob - crates/websocket/src/handlers.rs
30cd9639b0c875acef030b678d126995230e0777
[lemmy.git] / crates / websocket / src / handlers.rs
1 use crate::{
2   chat_server::{ChatServer, SessionInfo},
3   messages::*,
4 };
5 use actix::{Actor, Context, Handler, ResponseFuture};
6 use lemmy_db_schema::naive_now;
7 use lemmy_utils::ConnectionId;
8 use log::{error, info};
9 use rand::Rng;
10 use serde::Serialize;
11
12 /// Make actor from `ChatServer`
13 impl Actor for ChatServer {
14   /// We are going to use simple Context, we just need ability to communicate
15   /// with other actors.
16   type Context = Context<Self>;
17 }
18
19 /// Handler for Connect message.
20 ///
21 /// Register new session and assign unique id to this session
22 impl Handler<Connect> for ChatServer {
23   type Result = ConnectionId;
24
25   fn handle(&mut self, msg: Connect, _ctx: &mut Context<Self>) -> Self::Result {
26     // register session with random id
27     let id = self.rng.gen::<usize>();
28     info!("{} joined", &msg.ip);
29
30     self.sessions.insert(
31       id,
32       SessionInfo {
33         addr: msg.addr,
34         ip: msg.ip,
35       },
36     );
37
38     id
39   }
40 }
41
42 /// Handler for Disconnect message.
43 impl Handler<Disconnect> for ChatServer {
44   type Result = ();
45
46   fn handle(&mut self, msg: Disconnect, _: &mut Context<Self>) {
47     // Remove connections from sessions and all 3 scopes
48     if self.sessions.remove(&msg.id).is_some() {
49       for sessions in self.user_rooms.values_mut() {
50         sessions.remove(&msg.id);
51       }
52
53       for sessions in self.post_rooms.values_mut() {
54         sessions.remove(&msg.id);
55       }
56
57       for sessions in self.community_rooms.values_mut() {
58         sessions.remove(&msg.id);
59       }
60     }
61   }
62 }
63
64 /// Handler for Message message.
65 impl Handler<StandardMessage> for ChatServer {
66   type Result = ResponseFuture<Result<String, std::convert::Infallible>>;
67
68   fn handle(&mut self, msg: StandardMessage, ctx: &mut Context<Self>) -> Self::Result {
69     let fut = self.parse_json_message(msg, ctx);
70     Box::pin(async move {
71       match fut.await {
72         Ok(m) => {
73           // info!("Message Sent: {}", m);
74           Ok(m)
75         }
76         Err(e) => {
77           error!("Error during message handling {}", e);
78           Ok(e.to_string())
79         }
80       }
81     })
82   }
83 }
84
85 impl<Response> Handler<SendAllMessage<Response>> for ChatServer
86 where
87   Response: Serialize,
88 {
89   type Result = ();
90
91   fn handle(&mut self, msg: SendAllMessage<Response>, _: &mut Context<Self>) {
92     self
93       .send_all_message(&msg.op, &msg.response, msg.websocket_id)
94       .ok();
95   }
96 }
97
98 impl<Response> Handler<SendUserRoomMessage<Response>> for ChatServer
99 where
100   Response: Serialize,
101 {
102   type Result = ();
103
104   fn handle(&mut self, msg: SendUserRoomMessage<Response>, _: &mut Context<Self>) {
105     self
106       .send_user_room_message(
107         &msg.op,
108         &msg.response,
109         msg.local_recipient_id,
110         msg.websocket_id,
111       )
112       .ok();
113   }
114 }
115
116 impl<Response> Handler<SendCommunityRoomMessage<Response>> for ChatServer
117 where
118   Response: Serialize,
119 {
120   type Result = ();
121
122   fn handle(&mut self, msg: SendCommunityRoomMessage<Response>, _: &mut Context<Self>) {
123     self
124       .send_community_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id)
125       .ok();
126   }
127 }
128
129 impl<Response> Handler<SendModRoomMessage<Response>> for ChatServer
130 where
131   Response: Serialize,
132 {
133   type Result = ();
134
135   fn handle(&mut self, msg: SendModRoomMessage<Response>, _: &mut Context<Self>) {
136     self
137       .send_mod_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id)
138       .ok();
139   }
140 }
141
142 impl Handler<SendPost> for ChatServer {
143   type Result = ();
144
145   fn handle(&mut self, msg: SendPost, _: &mut Context<Self>) {
146     self.send_post(&msg.op, &msg.post, msg.websocket_id).ok();
147   }
148 }
149
150 impl Handler<SendComment> for ChatServer {
151   type Result = ();
152
153   fn handle(&mut self, msg: SendComment, _: &mut Context<Self>) {
154     self
155       .send_comment(&msg.op, &msg.comment, msg.websocket_id)
156       .ok();
157   }
158 }
159
160 impl Handler<JoinUserRoom> for ChatServer {
161   type Result = ();
162
163   fn handle(&mut self, msg: JoinUserRoom, _: &mut Context<Self>) {
164     self.join_user_room(msg.local_user_id, msg.id).ok();
165   }
166 }
167
168 impl Handler<JoinCommunityRoom> for ChatServer {
169   type Result = ();
170
171   fn handle(&mut self, msg: JoinCommunityRoom, _: &mut Context<Self>) {
172     self.join_community_room(msg.community_id, msg.id).ok();
173   }
174 }
175
176 impl Handler<JoinModRoom> for ChatServer {
177   type Result = ();
178
179   fn handle(&mut self, msg: JoinModRoom, _: &mut Context<Self>) {
180     self.join_mod_room(msg.community_id, msg.id).ok();
181   }
182 }
183
184 impl Handler<JoinPostRoom> for ChatServer {
185   type Result = ();
186
187   fn handle(&mut self, msg: JoinPostRoom, _: &mut Context<Self>) {
188     self.join_post_room(msg.post_id, msg.id).ok();
189   }
190 }
191
192 impl Handler<GetUsersOnline> for ChatServer {
193   type Result = usize;
194
195   fn handle(&mut self, _msg: GetUsersOnline, _: &mut Context<Self>) -> Self::Result {
196     self.sessions.len()
197   }
198 }
199
200 impl Handler<GetPostUsersOnline> for ChatServer {
201   type Result = usize;
202
203   fn handle(&mut self, msg: GetPostUsersOnline, _: &mut Context<Self>) -> Self::Result {
204     if let Some(users) = self.post_rooms.get(&msg.post_id) {
205       users.len()
206     } else {
207       0
208     }
209   }
210 }
211
212 impl Handler<GetCommunityUsersOnline> for ChatServer {
213   type Result = usize;
214
215   fn handle(&mut self, msg: GetCommunityUsersOnline, _: &mut Context<Self>) -> Self::Result {
216     if let Some(users) = self.community_rooms.get(&msg.community_id) {
217       users.len()
218     } else {
219       0
220     }
221   }
222 }
223
224 impl Handler<CaptchaItem> for ChatServer {
225   type Result = ();
226
227   fn handle(&mut self, msg: CaptchaItem, _: &mut Context<Self>) {
228     self.captchas.push(msg);
229   }
230 }
231
232 impl Handler<CheckCaptcha> for ChatServer {
233   type Result = bool;
234
235   fn handle(&mut self, msg: CheckCaptcha, _: &mut Context<Self>) -> Self::Result {
236     // Remove all the ones that are past the expire time
237     self.captchas.retain(|x| x.expires.gt(&naive_now()));
238
239     let check = self
240       .captchas
241       .iter()
242       .any(|r| r.uuid == msg.uuid && r.answer == msg.answer);
243
244     // Remove this uuid so it can't be re-checked (Checks only work once)
245     self.captchas.retain(|x| x.uuid != msg.uuid);
246
247     check
248   }
249 }