]> Untitled Git - lemmy.git/blob - src/routes/api.rs
Move websocket code into workspace (#107)
[lemmy.git] / src / routes / api.rs
1 use actix_web::{error::ErrorBadRequest, *};
2 use lemmy_api::Perform;
3 use lemmy_rate_limit::RateLimit;
4 use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*};
5 use lemmy_websocket::LemmyContext;
6 use serde::Deserialize;
7
8 pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
9   cfg.service(
10     web::scope("/api/v1")
11       // Websockets
12       .service(web::resource("/ws").to(super::websocket::chat_route))
13       // Site
14       .service(
15         web::scope("/site")
16           .wrap(rate_limit.message())
17           .route("", web::get().to(route_get::<GetSite>))
18           // Admin Actions
19           .route("", web::post().to(route_post::<CreateSite>))
20           .route("", web::put().to(route_post::<EditSite>))
21           .route("/transfer", web::post().to(route_post::<TransferSite>))
22           .route("/config", web::get().to(route_get::<GetSiteConfig>))
23           .route("/config", web::put().to(route_post::<SaveSiteConfig>)),
24       )
25       .service(
26         web::resource("/categories")
27           .wrap(rate_limit.message())
28           .route(web::get().to(route_get::<ListCategories>)),
29       )
30       .service(
31         web::resource("/modlog")
32           .wrap(rate_limit.message())
33           .route(web::get().to(route_get::<GetModlog>)),
34       )
35       .service(
36         web::resource("/search")
37           .wrap(rate_limit.message())
38           .route(web::get().to(route_get::<Search>)),
39       )
40       // Community
41       .service(
42         web::resource("/community")
43           .guard(guard::Post())
44           .wrap(rate_limit.register())
45           .route(web::post().to(route_post::<CreateCommunity>)),
46       )
47       .service(
48         web::scope("/community")
49           .wrap(rate_limit.message())
50           .route("", web::get().to(route_get::<GetCommunity>))
51           .route("", web::put().to(route_post::<EditCommunity>))
52           .route("/list", web::get().to(route_get::<ListCommunities>))
53           .route("/follow", web::post().to(route_post::<FollowCommunity>))
54           .route("/delete", web::post().to(route_post::<DeleteCommunity>))
55           // Mod Actions
56           .route("/remove", web::post().to(route_post::<RemoveCommunity>))
57           .route("/transfer", web::post().to(route_post::<TransferCommunity>))
58           .route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
59           .route("/mod", web::post().to(route_post::<AddModToCommunity>))
60           .route("/join", web::post().to(route_post::<CommunityJoin>)),
61       )
62       // Post
63       .service(
64         // Handle POST to /post separately to add the post() rate limitter
65         web::resource("/post")
66           .guard(guard::Post())
67           .wrap(rate_limit.post())
68           .route(web::post().to(route_post::<CreatePost>)),
69       )
70       .service(
71         web::scope("/post")
72           .wrap(rate_limit.message())
73           .route("", web::get().to(route_get::<GetPost>))
74           .route("", web::put().to(route_post::<EditPost>))
75           .route("/delete", web::post().to(route_post::<DeletePost>))
76           .route("/remove", web::post().to(route_post::<RemovePost>))
77           .route("/lock", web::post().to(route_post::<LockPost>))
78           .route("/sticky", web::post().to(route_post::<StickyPost>))
79           .route("/list", web::get().to(route_get::<GetPosts>))
80           .route("/like", web::post().to(route_post::<CreatePostLike>))
81           .route("/save", web::put().to(route_post::<SavePost>))
82           .route("/join", web::post().to(route_post::<PostJoin>)),
83       )
84       // Comment
85       .service(
86         web::scope("/comment")
87           .wrap(rate_limit.message())
88           .route("", web::post().to(route_post::<CreateComment>))
89           .route("", web::put().to(route_post::<EditComment>))
90           .route("/delete", web::post().to(route_post::<DeleteComment>))
91           .route("/remove", web::post().to(route_post::<RemoveComment>))
92           .route(
93             "/mark_as_read",
94             web::post().to(route_post::<MarkCommentAsRead>),
95           )
96           .route("/like", web::post().to(route_post::<CreateCommentLike>))
97           .route("/save", web::put().to(route_post::<SaveComment>))
98           .route("/list", web::get().to(route_get::<GetComments>)),
99       )
100       // Private Message
101       .service(
102         web::scope("/private_message")
103           .wrap(rate_limit.message())
104           .route("/list", web::get().to(route_get::<GetPrivateMessages>))
105           .route("", web::post().to(route_post::<CreatePrivateMessage>))
106           .route("", web::put().to(route_post::<EditPrivateMessage>))
107           .route(
108             "/delete",
109             web::post().to(route_post::<DeletePrivateMessage>),
110           )
111           .route(
112             "/mark_as_read",
113             web::post().to(route_post::<MarkPrivateMessageAsRead>),
114           ),
115       )
116       // User
117       .service(
118         // Account action, I don't like that it's in /user maybe /accounts
119         // Handle /user/register separately to add the register() rate limitter
120         web::resource("/user/register")
121           .guard(guard::Post())
122           .wrap(rate_limit.register())
123           .route(web::post().to(route_post::<Register>)),
124       )
125       // User actions
126       .service(
127         web::scope("/user")
128           .wrap(rate_limit.message())
129           .route("", web::get().to(route_get::<GetUserDetails>))
130           .route("/mention", web::get().to(route_get::<GetUserMentions>))
131           .route(
132             "/mention/mark_as_read",
133             web::post().to(route_post::<MarkUserMentionAsRead>),
134           )
135           .route("/replies", web::get().to(route_get::<GetReplies>))
136           .route(
137             "/followed_communities",
138             web::get().to(route_get::<GetFollowedCommunities>),
139           )
140           .route("/join", web::post().to(route_post::<UserJoin>))
141           // Admin action. I don't like that it's in /user
142           .route("/ban", web::post().to(route_post::<BanUser>))
143           // Account actions. I don't like that they're in /user maybe /accounts
144           .route("/login", web::post().to(route_post::<Login>))
145           .route("/get_captcha", web::get().to(route_get::<GetCaptcha>))
146           .route(
147             "/delete_account",
148             web::post().to(route_post::<DeleteAccount>),
149           )
150           .route(
151             "/password_reset",
152             web::post().to(route_post::<PasswordReset>),
153           )
154           .route(
155             "/password_change",
156             web::post().to(route_post::<PasswordChange>),
157           )
158           // mark_all_as_read feels off being in this section as well
159           .route(
160             "/mark_all_as_read",
161             web::post().to(route_post::<MarkAllAsRead>),
162           )
163           .route(
164             "/save_user_settings",
165             web::put().to(route_post::<SaveUserSettings>),
166           ),
167       )
168       // Admin Actions
169       .service(
170         web::resource("/admin/add")
171           .wrap(rate_limit.message())
172           .route(web::post().to(route_post::<AddAdmin>)),
173       ),
174   );
175 }
176
177 async fn perform<Request>(
178   data: Request,
179   context: web::Data<LemmyContext>,
180 ) -> Result<HttpResponse, Error>
181 where
182   Request: Perform,
183   Request: Send + 'static,
184 {
185   let res = data
186     .perform(&context, None)
187     .await
188     .map(|json| HttpResponse::Ok().json(json))
189     .map_err(ErrorBadRequest)?;
190   Ok(res)
191 }
192
193 async fn route_get<'a, Data>(
194   data: web::Query<Data>,
195   context: web::Data<LemmyContext>,
196 ) -> Result<HttpResponse, Error>
197 where
198   Data: Deserialize<'a> + Send + 'static + Perform,
199 {
200   perform::<Data>(data.0, context).await
201 }
202
203 async fn route_post<'a, Data>(
204   data: web::Json<Data>,
205   context: web::Data<LemmyContext>,
206 ) -> Result<HttpResponse, Error>
207 where
208   Data: Deserialize<'a> + Send + 'static + Perform,
209 {
210   perform::<Data>(data.0, context).await
211 }