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