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