]> Untitled Git - lemmy.git/blob - src/api_routes.rs
006140262f73fc34e197eeae8ae30aa7f31b99e1
[lemmy.git] / src / api_routes.rs
1 use actix_web::*;
2 use lemmy_api::Perform;
3 use lemmy_api_common::{
4   comment::*,
5   community::*,
6   person::*,
7   post::*,
8   private_message::*,
9   site::*,
10   websocket::*,
11 };
12 use lemmy_api_crud::PerformCrud;
13 use lemmy_utils::rate_limit::RateLimit;
14 use lemmy_websocket::{routes::chat_route, LemmyContext};
15 use serde::Deserialize;
16
17 pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
18   cfg.service(
19     web::scope("/api/v3")
20       // Websocket
21       .service(web::resource("/ws").to(chat_route))
22       // Site
23       .service(
24         web::scope("/site")
25           .wrap(rate_limit.message())
26           .route("", web::get().to(route_get_crud::<GetSite>))
27           // Admin Actions
28           .route("", web::post().to(route_post_crud::<CreateSite>))
29           .route("", web::put().to(route_post_crud::<EditSite>)),
30       )
31       .service(
32         web::resource("/modlog")
33           .wrap(rate_limit.message())
34           .route(web::get().to(route_get::<GetModlog>)),
35       )
36       .service(
37         web::resource("/search")
38           .wrap(rate_limit.search())
39           .route(web::get().to(route_get::<Search>)),
40       )
41       .service(
42         web::resource("/resolve_object")
43           .wrap(rate_limit.message())
44           .route(web::get().to(route_get::<ResolveObject>)),
45       )
46       // Community
47       .service(
48         web::resource("/community")
49           .guard(guard::Post())
50           .wrap(rate_limit.register())
51           .route(web::post().to(route_post_crud::<CreateCommunity>)),
52       )
53       .service(
54         web::scope("/community")
55           .wrap(rate_limit.message())
56           .route("", web::get().to(route_get_crud::<GetCommunity>))
57           .route("", web::put().to(route_post_crud::<EditCommunity>))
58           .route("/hide", web::put().to(route_post::<HideCommunity>))
59           .route("/list", web::get().to(route_get_crud::<ListCommunities>))
60           .route("/follow", web::post().to(route_post::<FollowCommunity>))
61           .route("/block", web::post().to(route_post::<BlockCommunity>))
62           .route(
63             "/delete",
64             web::post().to(route_post_crud::<DeleteCommunity>),
65           )
66           // Mod Actions
67           .route(
68             "/remove",
69             web::post().to(route_post_crud::<RemoveCommunity>),
70           )
71           .route("/transfer", web::post().to(route_post::<TransferCommunity>))
72           .route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
73           .route("/mod", web::post().to(route_post::<AddModToCommunity>))
74           .route("/join", web::post().to(route_post::<CommunityJoin>))
75           .route("/mod/join", web::post().to(route_post::<ModJoin>)),
76       )
77       // Post
78       .service(
79         // Handle POST to /post separately to add the post() rate limitter
80         web::resource("/post")
81           .guard(guard::Post())
82           .wrap(rate_limit.post())
83           .route(web::post().to(route_post_crud::<CreatePost>)),
84       )
85       .service(
86         web::scope("/post")
87           .wrap(rate_limit.message())
88           .route("", web::get().to(route_get_crud::<GetPost>))
89           .route("", web::put().to(route_post_crud::<EditPost>))
90           .route("/delete", web::post().to(route_post_crud::<DeletePost>))
91           .route("/remove", web::post().to(route_post_crud::<RemovePost>))
92           .route(
93             "/mark_as_read",
94             web::post().to(route_post::<MarkPostAsRead>),
95           )
96           .route("/lock", web::post().to(route_post::<LockPost>))
97           .route("/sticky", web::post().to(route_post::<StickyPost>))
98           .route("/list", web::get().to(route_get_crud::<GetPosts>))
99           .route("/like", web::post().to(route_post::<CreatePostLike>))
100           .route("/save", web::put().to(route_post::<SavePost>))
101           .route("/join", web::post().to(route_post::<PostJoin>))
102           .route("/report", web::post().to(route_post::<CreatePostReport>))
103           .route(
104             "/report/resolve",
105             web::put().to(route_post::<ResolvePostReport>),
106           )
107           .route("/report/list", web::get().to(route_get::<ListPostReports>))
108           .route(
109             "/site_metadata",
110             web::get().to(route_get::<GetSiteMetadata>),
111           ),
112       )
113       // Comment
114       .service(
115         // Handle POST to /comment separately to add the comment() rate limitter
116         web::resource("/comment")
117           .guard(guard::Post())
118           .wrap(rate_limit.comment())
119           .route(web::post().to(route_post_crud::<CreateComment>)),
120       )
121       .service(
122         web::scope("/comment")
123           .wrap(rate_limit.message())
124           .route("", web::get().to(route_get_crud::<GetComment>))
125           .route("", web::put().to(route_post_crud::<EditComment>))
126           .route("/delete", web::post().to(route_post_crud::<DeleteComment>))
127           .route("/remove", web::post().to(route_post_crud::<RemoveComment>))
128           .route(
129             "/mark_as_read",
130             web::post().to(route_post::<MarkCommentReplyAsRead>),
131           )
132           .route("/like", web::post().to(route_post::<CreateCommentLike>))
133           .route("/save", web::put().to(route_post::<SaveComment>))
134           .route("/list", web::get().to(route_get_crud::<GetComments>))
135           .route("/report", web::post().to(route_post::<CreateCommentReport>))
136           .route(
137             "/report/resolve",
138             web::put().to(route_post::<ResolveCommentReport>),
139           )
140           .route(
141             "/report/list",
142             web::get().to(route_get::<ListCommentReports>),
143           ),
144       )
145       // Private Message
146       .service(
147         web::scope("/private_message")
148           .wrap(rate_limit.message())
149           .route("/list", web::get().to(route_get_crud::<GetPrivateMessages>))
150           .route("", web::post().to(route_post_crud::<CreatePrivateMessage>))
151           .route("", web::put().to(route_post_crud::<EditPrivateMessage>))
152           .route(
153             "/delete",
154             web::post().to(route_post_crud::<DeletePrivateMessage>),
155           )
156           .route(
157             "/mark_as_read",
158             web::post().to(route_post::<MarkPrivateMessageAsRead>),
159           )
160           .route(
161             "/report",
162             web::post().to(route_post::<CreatePrivateMessageReport>),
163           )
164           .route(
165             "/report/resolve",
166             web::put().to(route_post::<ResolvePrivateMessageReport>),
167           )
168           .route(
169             "/report/list",
170             web::get().to(route_get::<ListPrivateMessageReports>),
171           ),
172       )
173       // User
174       .service(
175         // Account action, I don't like that it's in /user maybe /accounts
176         // Handle /user/register separately to add the register() rate limitter
177         web::resource("/user/register")
178           .guard(guard::Post())
179           .wrap(rate_limit.register())
180           .route(web::post().to(route_post_crud::<Register>)),
181       )
182       .service(
183         // Handle captcha separately
184         web::resource("/user/get_captcha")
185           .wrap(rate_limit.post())
186           .route(web::get().to(route_get::<GetCaptcha>)),
187       )
188       // User actions
189       .service(
190         web::scope("/user")
191           .wrap(rate_limit.message())
192           .route("", web::get().to(route_get_crud::<GetPersonDetails>))
193           .route("/mention", web::get().to(route_get::<GetPersonMentions>))
194           .route(
195             "/mention/mark_as_read",
196             web::post().to(route_post::<MarkPersonMentionAsRead>),
197           )
198           .route("/replies", web::get().to(route_get::<GetReplies>))
199           .route("/join", web::post().to(route_post::<UserJoin>))
200           // Admin action. I don't like that it's in /user
201           .route("/ban", web::post().to(route_post::<BanPerson>))
202           .route("/banned", web::get().to(route_get::<GetBannedPersons>))
203           .route("/block", web::post().to(route_post::<BlockPerson>))
204           // Account actions. I don't like that they're in /user maybe /accounts
205           .route("/login", web::post().to(route_post::<Login>))
206           .route(
207             "/delete_account",
208             web::post().to(route_post_crud::<DeleteAccount>),
209           )
210           .route(
211             "/password_reset",
212             web::post().to(route_post::<PasswordReset>),
213           )
214           .route(
215             "/password_change",
216             web::post().to(route_post::<PasswordChangeAfterReset>),
217           )
218           // mark_all_as_read feels off being in this section as well
219           .route(
220             "/mark_all_as_read",
221             web::post().to(route_post::<MarkAllAsRead>),
222           )
223           .route(
224             "/save_user_settings",
225             web::put().to(route_post::<SaveUserSettings>),
226           )
227           .route(
228             "/change_password",
229             web::put().to(route_post::<ChangePassword>),
230           )
231           .route("/report_count", web::get().to(route_get::<GetReportCount>))
232           .route("/unread_count", web::get().to(route_get::<GetUnreadCount>))
233           .route("/verify_email", web::post().to(route_post::<VerifyEmail>))
234           .route("/leave_admin", web::post().to(route_post::<LeaveAdmin>)),
235       )
236       // Admin Actions
237       .service(
238         web::scope("/admin")
239           .wrap(rate_limit.message())
240           .route("/add", web::post().to(route_post::<AddAdmin>))
241           .route(
242             "/registration_application/count",
243             web::get().to(route_get::<GetUnreadRegistrationApplicationCount>),
244           )
245           .route(
246             "/registration_application/list",
247             web::get().to(route_get::<ListRegistrationApplications>),
248           )
249           .route(
250             "/registration_application/approve",
251             web::put().to(route_post::<ApproveRegistrationApplication>),
252           ),
253       )
254       .service(
255         web::scope("/admin/purge")
256           .wrap(rate_limit.message())
257           .route("/person", web::post().to(route_post::<PurgePerson>))
258           .route("/community", web::post().to(route_post::<PurgeCommunity>))
259           .route("/post", web::post().to(route_post::<PurgePost>))
260           .route("/comment", web::post().to(route_post::<PurgeComment>)),
261       ),
262   );
263 }
264
265 async fn perform<Request>(
266   data: Request,
267   context: web::Data<LemmyContext>,
268 ) -> Result<HttpResponse, Error>
269 where
270   Request: Perform,
271   Request: Send + 'static,
272 {
273   let res = data
274     .perform(&context, None)
275     .await
276     .map(|json| HttpResponse::Ok().json(json))?;
277   Ok(res)
278 }
279
280 async fn route_get<'a, Data>(
281   data: web::Query<Data>,
282   context: web::Data<LemmyContext>,
283 ) -> Result<HttpResponse, Error>
284 where
285   Data: Deserialize<'a> + Send + 'static + Perform,
286 {
287   perform::<Data>(data.0, context).await
288 }
289
290 async fn route_post<'a, Data>(
291   data: web::Json<Data>,
292   context: web::Data<LemmyContext>,
293 ) -> Result<HttpResponse, Error>
294 where
295   Data: Deserialize<'a> + Send + 'static + Perform,
296 {
297   perform::<Data>(data.0, context).await
298 }
299
300 async fn perform_crud<Request>(
301   data: Request,
302   context: web::Data<LemmyContext>,
303 ) -> Result<HttpResponse, Error>
304 where
305   Request: PerformCrud,
306   Request: Send + 'static,
307 {
308   let res = data
309     .perform(&context, None)
310     .await
311     .map(|json| HttpResponse::Ok().json(json))?;
312   Ok(res)
313 }
314
315 async fn route_get_crud<'a, Data>(
316   data: web::Query<Data>,
317   context: web::Data<LemmyContext>,
318 ) -> Result<HttpResponse, Error>
319 where
320   Data: Deserialize<'a> + Send + 'static + PerformCrud,
321 {
322   perform_crud::<Data>(data.0, context).await
323 }
324
325 async fn route_post_crud<'a, Data>(
326   data: web::Json<Data>,
327   context: web::Data<LemmyContext>,
328 ) -> Result<HttpResponse, Error>
329 where
330   Data: Deserialize<'a> + Send + 'static + PerformCrud,
331 {
332   perform_crud::<Data>(data.0, context).await
333 }