mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-22 19:01:32 +00:00
Split image endpoints into API v3 and v4
This commit is contained in:
parent
8a5daeec97
commit
56ab67f804
3 changed files with 286 additions and 289 deletions
|
@ -18,27 +18,13 @@ use lemmy_db_schema::source::{
|
|||
local_site::LocalSite,
|
||||
};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::{error::LemmyResult, rate_limit::RateLimitCell, REQWEST_TIMEOUT};
|
||||
use lemmy_utils::{error::LemmyResult, REQWEST_TIMEOUT};
|
||||
use reqwest::Body;
|
||||
use reqwest_middleware::{ClientWithMiddleware, RequestBuilder};
|
||||
use reqwest_middleware::RequestBuilder;
|
||||
use serde::Deserialize;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
pub fn config(cfg: &mut ServiceConfig, client: ClientWithMiddleware, rate_limit: &RateLimitCell) {
|
||||
cfg
|
||||
.app_data(Data::new(client))
|
||||
.service(
|
||||
resource("/pictrs/image")
|
||||
.wrap(rate_limit.image())
|
||||
.route(post().to(upload)),
|
||||
)
|
||||
// This has optional query params: /image/{filename}?format=jpg&thumbnail=256
|
||||
.service(resource("/pictrs/image/{filename}").route(get().to(full_res)))
|
||||
.service(resource("/pictrs/image/delete/{token}/{filename}").route(get().to(delete)))
|
||||
.service(resource("/pictrs/healthz").route(get().to(healthz)));
|
||||
}
|
||||
|
||||
trait ProcessUrl {
|
||||
/// If thumbnail or format is given, this uses the pictrs process endpoint.
|
||||
/// Otherwise, it uses the normal pictrs url (IE image/original).
|
||||
|
@ -46,7 +32,7 @@ trait ProcessUrl {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct PictrsGetParams {
|
||||
pub struct PictrsGetParams {
|
||||
format: Option<String>,
|
||||
thumbnail: Option<i32>,
|
||||
}
|
||||
|
@ -99,15 +85,12 @@ impl ProcessUrl for ImageProxyParams {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn adapt_request(
|
||||
request: &HttpRequest,
|
||||
client: &ClientWithMiddleware,
|
||||
url: String,
|
||||
) -> RequestBuilder {
|
||||
fn adapt_request(request: &HttpRequest, context: &LemmyContext, url: String) -> RequestBuilder {
|
||||
// remove accept-encoding header so that pictrs doesn't compress the response
|
||||
const INVALID_HEADERS: &[HeaderName] = &[ACCEPT_ENCODING, HOST];
|
||||
|
||||
let client_request = client
|
||||
let client_request = context
|
||||
.client()
|
||||
.request(convert_method(request.method()), url)
|
||||
.timeout(REQWEST_TIMEOUT);
|
||||
|
||||
|
@ -124,19 +107,17 @@ fn adapt_request(
|
|||
})
|
||||
}
|
||||
|
||||
async fn upload(
|
||||
pub async fn upload_image(
|
||||
req: HttpRequest,
|
||||
body: Payload,
|
||||
// require login
|
||||
local_user_view: LocalUserView,
|
||||
client: Data<ClientWithMiddleware>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<HttpResponse> {
|
||||
// TODO: check rate limit here
|
||||
let pictrs_config = context.settings().pictrs_config()?;
|
||||
let image_url = format!("{}image", pictrs_config.url);
|
||||
|
||||
let mut client_req = adapt_request(&req, &client, image_url);
|
||||
let mut client_req = adapt_request(&req, &context, image_url);
|
||||
|
||||
if let Some(addr) = req.head().peer_addr {
|
||||
client_req = client_req.header("X-Forwarded-For", addr.to_string())
|
||||
|
@ -169,11 +150,10 @@ async fn upload(
|
|||
Ok(HttpResponse::build(convert_status(status)).json(images))
|
||||
}
|
||||
|
||||
async fn full_res(
|
||||
pub async fn get_full_res_image(
|
||||
filename: Path<String>,
|
||||
Query(params): Query<PictrsGetParams>,
|
||||
req: HttpRequest,
|
||||
client: Data<ClientWithMiddleware>,
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: Option<LocalUserView>,
|
||||
) -> LemmyResult<HttpResponse> {
|
||||
|
@ -189,15 +169,11 @@ async fn full_res(
|
|||
|
||||
let processed_url = params.process_url(name, &pictrs_config.url);
|
||||
|
||||
image(processed_url, req, &client).await
|
||||
image(processed_url, req, &context).await
|
||||
}
|
||||
|
||||
async fn image(
|
||||
url: String,
|
||||
req: HttpRequest,
|
||||
client: &ClientWithMiddleware,
|
||||
) -> LemmyResult<HttpResponse> {
|
||||
let mut client_req = adapt_request(&req, client, url);
|
||||
async fn image(url: String, req: HttpRequest, context: &LemmyContext) -> LemmyResult<HttpResponse> {
|
||||
let mut client_req = adapt_request(&req, context, url);
|
||||
|
||||
if let Some(addr) = req.head().peer_addr {
|
||||
client_req = client_req.header("X-Forwarded-For", addr.to_string());
|
||||
|
@ -222,10 +198,9 @@ async fn image(
|
|||
Ok(client_res.body(BodyStream::new(res.bytes_stream())))
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
pub async fn delete_image(
|
||||
components: Path<(String, String)>,
|
||||
req: HttpRequest,
|
||||
client: Data<ClientWithMiddleware>,
|
||||
context: Data<LemmyContext>,
|
||||
// require login
|
||||
_local_user_view: LocalUserView,
|
||||
|
@ -235,7 +210,7 @@ async fn delete(
|
|||
let pictrs_config = context.settings().pictrs_config()?;
|
||||
let url = format!("{}image/delete/{}/{}", pictrs_config.url, &token, &file);
|
||||
|
||||
let mut client_req = adapt_request(&req, &client, url);
|
||||
let mut client_req = adapt_request(&req, &context, url);
|
||||
|
||||
if let Some(addr) = req.head().peer_addr {
|
||||
client_req = client_req.header("X-Forwarded-For", addr.to_string());
|
||||
|
@ -248,15 +223,11 @@ async fn delete(
|
|||
Ok(HttpResponse::build(convert_status(res.status())).body(BodyStream::new(res.bytes_stream())))
|
||||
}
|
||||
|
||||
async fn healthz(
|
||||
req: HttpRequest,
|
||||
client: Data<ClientWithMiddleware>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<HttpResponse> {
|
||||
pub async fn pictrs_healthz(req: HttpRequest, context: Data<LemmyContext>) -> LemmyResult<HttpResponse> {
|
||||
let pictrs_config = context.settings().pictrs_config()?;
|
||||
let url = format!("{}healthz", pictrs_config.url);
|
||||
|
||||
let mut client_req = adapt_request(&req, &client, url);
|
||||
let mut client_req = adapt_request(&req, &context, url);
|
||||
|
||||
if let Some(addr) = req.head().peer_addr {
|
||||
client_req = client_req.header("X-Forwarded-For", addr.to_string());
|
||||
|
@ -270,7 +241,6 @@ async fn healthz(
|
|||
pub async fn image_proxy(
|
||||
Query(params): Query<ImageProxyParams>,
|
||||
req: HttpRequest,
|
||||
client: Data<ClientWithMiddleware>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Either<HttpResponse<()>, HttpResponse<BoxBody>>> {
|
||||
let url = Url::parse(¶ms.url)?;
|
||||
|
@ -291,7 +261,7 @@ pub async fn image_proxy(
|
|||
Ok(Either::Left(Redirect::to(url.to_string()).respond_to(&req)))
|
||||
} else {
|
||||
// Proxy the image data through Lemmy
|
||||
Ok(Either::Right(image(processed_url, req, &client).await?))
|
||||
Ok(Either::Right(image(processed_url, req, &context).await?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,252 +134,262 @@ use lemmy_apub::api::{
|
|||
search::search,
|
||||
user_settings_backup::{export_settings, import_settings},
|
||||
};
|
||||
use lemmy_routes::images::image_proxy;
|
||||
use lemmy_routes::images::{delete_image, get_full_res_image, image_proxy, pictrs_healthz, upload_image};
|
||||
use lemmy_utils::rate_limit::RateLimitCell;
|
||||
|
||||
// Deprecated, use api v4 instead.
|
||||
// When removing api v3, we also need to rewrite all links in database with
|
||||
// `/api/v3/image_proxy` to use `/api/v4/image_proxy` instead.
|
||||
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
||||
cfg.service(
|
||||
scope("/api/v3")
|
||||
.route("/image_proxy", get().to(image_proxy))
|
||||
// Site
|
||||
.service(
|
||||
scope("/site")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_site_v3))
|
||||
// Admin Actions
|
||||
.route("", post().to(create_site))
|
||||
.route("", put().to(update_site))
|
||||
.route("/block", post().to(user_block_instance)),
|
||||
)
|
||||
.service(
|
||||
resource("/modlog")
|
||||
.wrap(rate_limit.message())
|
||||
.route(get().to(get_mod_log)),
|
||||
)
|
||||
.service(
|
||||
resource("/search")
|
||||
.wrap(rate_limit.search())
|
||||
.route(get().to(search)),
|
||||
)
|
||||
.service(
|
||||
resource("/resolve_object")
|
||||
.wrap(rate_limit.message())
|
||||
.route(get().to(resolve_object)),
|
||||
)
|
||||
// Community
|
||||
.service(
|
||||
resource("/community")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(create_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/community")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/block", post().to(user_block_community))
|
||||
.route("/delete", post().to(delete_community))
|
||||
// Mod Actions
|
||||
.route("/remove", post().to(remove_community))
|
||||
.route("/transfer", post().to(transfer_community))
|
||||
.route("/ban_user", post().to(ban_from_community))
|
||||
.route("/mod", post().to(add_mod_to_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/federated_instances")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_federated_instances)),
|
||||
)
|
||||
// Post
|
||||
.service(
|
||||
// Handle POST to /post separately to add the post() rate limitter
|
||||
resource("/post")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.post())
|
||||
.route(post().to(create_post)),
|
||||
)
|
||||
.service(
|
||||
scope("/post")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_post))
|
||||
.route("", put().to(update_post))
|
||||
.route("/delete", post().to(delete_post))
|
||||
.route("/remove", post().to(remove_post))
|
||||
.route("/mark_as_read", post().to(mark_post_as_read))
|
||||
.route("/hide", post().to(hide_post))
|
||||
.route("/lock", post().to(lock_post))
|
||||
.route("/feature", post().to(feature_post))
|
||||
.route("/list", get().to(list_posts))
|
||||
.route("/like", post().to(like_post))
|
||||
.route("/like/list", get().to(list_post_likes))
|
||||
.route("/save", put().to(save_post))
|
||||
.route("/report", post().to(create_post_report))
|
||||
.route("/report/resolve", put().to(resolve_post_report))
|
||||
.route("/report/list", get().to(list_post_reports))
|
||||
.route("/site_metadata", get().to(get_link_metadata)),
|
||||
)
|
||||
// Comment
|
||||
.service(
|
||||
// Handle POST to /comment separately to add the comment() rate limitter
|
||||
resource("/comment")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.comment())
|
||||
.route(post().to(create_comment)),
|
||||
)
|
||||
.service(
|
||||
scope("/comment")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_comment))
|
||||
.route("", put().to(update_comment))
|
||||
.route("/delete", post().to(delete_comment))
|
||||
.route("/remove", post().to(remove_comment))
|
||||
.route("/mark_as_read", post().to(mark_reply_as_read))
|
||||
.route("/distinguish", post().to(distinguish_comment))
|
||||
.route("/like", post().to(like_comment))
|
||||
.route("/like/list", get().to(list_comment_likes))
|
||||
.route("/save", put().to(save_comment))
|
||||
.route("/list", get().to(list_comments))
|
||||
.route("/report", post().to(create_comment_report))
|
||||
.route("/report/resolve", put().to(resolve_comment_report))
|
||||
.route("/report/list", get().to(list_comment_reports)),
|
||||
)
|
||||
// Private Message
|
||||
.service(
|
||||
scope("/private_message")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/list", get().to(get_private_message))
|
||||
.route("", post().to(create_private_message))
|
||||
.route("", put().to(update_private_message))
|
||||
.route("/delete", post().to(delete_private_message))
|
||||
.route("/mark_as_read", post().to(mark_pm_as_read))
|
||||
.route("/report", post().to(create_pm_report))
|
||||
.route("/report/resolve", put().to(resolve_pm_report))
|
||||
.route("/report/list", get().to(list_pm_reports)),
|
||||
)
|
||||
// User
|
||||
.service(
|
||||
// Account action, I don't like that it's in /user maybe /accounts
|
||||
// Handle /user/register separately to add the register() rate limiter
|
||||
resource("/user/register")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(register)),
|
||||
)
|
||||
// User
|
||||
.service(
|
||||
// Handle /user/login separately to add the register() rate limiter
|
||||
// TODO: pretty annoying way to apply rate limits for register and login, we should
|
||||
// group them under a common path so that rate limit is only applied once (eg under
|
||||
// /account).
|
||||
resource("/user/login")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(login)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/password_reset")
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(reset_password)),
|
||||
)
|
||||
.service(
|
||||
// Handle captcha separately
|
||||
resource("/user/get_captcha")
|
||||
.wrap(rate_limit.post())
|
||||
.route(get().to(get_captcha)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/export_settings")
|
||||
.wrap(rate_limit.import_user_settings())
|
||||
.route(get().to(export_settings)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/import_settings")
|
||||
.wrap(rate_limit.import_user_settings())
|
||||
.route(post().to(import_settings)),
|
||||
)
|
||||
// TODO, all the current account related actions under /user need to get moved here eventually
|
||||
.service(
|
||||
scope("/account")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/list_media", get().to(list_media)),
|
||||
)
|
||||
// User actions
|
||||
.service(
|
||||
scope("/user")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(read_person))
|
||||
.route("/mention", get().to(list_mentions))
|
||||
.route(
|
||||
"/mention/mark_as_read",
|
||||
post().to(mark_person_mention_as_read),
|
||||
)
|
||||
.route("/replies", get().to(list_replies))
|
||||
// Admin action. I don't like that it's in /user
|
||||
.route("/ban", post().to(ban_from_site))
|
||||
.route("/banned", get().to(list_banned_users))
|
||||
.route("/block", post().to(user_block_person))
|
||||
// TODO Account actions. I don't like that they're in /user maybe /accounts
|
||||
.route("/logout", post().to(logout))
|
||||
.route("/delete_account", post().to(delete_account))
|
||||
.route("/password_change", post().to(change_password_after_reset))
|
||||
// TODO mark_all_as_read feels off being in this section as well
|
||||
.route("/mark_all_as_read", post().to(mark_all_notifications_read))
|
||||
.route("/save_user_settings", put().to(save_user_settings))
|
||||
.route("/change_password", put().to(change_password))
|
||||
.route("/report_count", get().to(report_count))
|
||||
.route("/unread_count", get().to(unread_count))
|
||||
.route("/verify_email", post().to(verify_email))
|
||||
.route("/leave_admin", post().to(leave_admin))
|
||||
.route("/totp/generate", post().to(generate_totp_secret))
|
||||
.route("/totp/update", post().to(update_totp))
|
||||
.route("/list_logins", get().to(list_logins))
|
||||
.route("/validate_auth", get().to(validate_auth)),
|
||||
)
|
||||
// Admin Actions
|
||||
.service(
|
||||
scope("/admin")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/add", post().to(add_admin))
|
||||
.route(
|
||||
"/registration_application/count",
|
||||
get().to(get_unread_registration_application_count),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/list",
|
||||
get().to(list_registration_applications),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/approve",
|
||||
put().to(approve_registration_application),
|
||||
)
|
||||
.route(
|
||||
"/registration_application",
|
||||
get().to(get_registration_application),
|
||||
)
|
||||
.route("/list_all_media", get().to(list_all_media))
|
||||
.service(
|
||||
scope("/purge")
|
||||
.route("/person", post().to(purge_person))
|
||||
.route("/community", post().to(purge_community))
|
||||
.route("/post", post().to(purge_post))
|
||||
.route("/comment", post().to(purge_comment)),
|
||||
),
|
||||
)
|
||||
.service(
|
||||
scope("/custom_emoji")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", post().to(create_custom_emoji))
|
||||
.route("", put().to(update_custom_emoji))
|
||||
.route("/delete", post().to(delete_custom_emoji)),
|
||||
),
|
||||
);
|
||||
cfg
|
||||
.service(
|
||||
resource("/pictrs/image")
|
||||
.wrap(rate_limit.image())
|
||||
.route(post().to(upload_image)),
|
||||
)
|
||||
.service(resource("/pictrs/image/{filename}").route(get().to(get_full_res_image)))
|
||||
.service(resource("/pictrs/image/delete/{token}/{filename}").route(get().to(delete_image)))
|
||||
.service(resource("/pictrs/healthz").route(get().to(pictrs_healthz)))
|
||||
.service(
|
||||
scope("/api/v3")
|
||||
.route("/image_proxy", get().to(image_proxy))
|
||||
// Site
|
||||
.service(
|
||||
scope("/site")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_site_v3))
|
||||
// Admin Actions
|
||||
.route("", post().to(create_site))
|
||||
.route("", put().to(update_site))
|
||||
.route("/block", post().to(user_block_instance)),
|
||||
)
|
||||
.service(
|
||||
resource("/modlog")
|
||||
.wrap(rate_limit.message())
|
||||
.route(get().to(get_mod_log)),
|
||||
)
|
||||
.service(
|
||||
resource("/search")
|
||||
.wrap(rate_limit.search())
|
||||
.route(get().to(search)),
|
||||
)
|
||||
.service(
|
||||
resource("/resolve_object")
|
||||
.wrap(rate_limit.message())
|
||||
.route(get().to(resolve_object)),
|
||||
)
|
||||
// Community
|
||||
.service(
|
||||
resource("/community")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(create_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/community")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/block", post().to(user_block_community))
|
||||
.route("/delete", post().to(delete_community))
|
||||
// Mod Actions
|
||||
.route("/remove", post().to(remove_community))
|
||||
.route("/transfer", post().to(transfer_community))
|
||||
.route("/ban_user", post().to(ban_from_community))
|
||||
.route("/mod", post().to(add_mod_to_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/federated_instances")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_federated_instances)),
|
||||
)
|
||||
// Post
|
||||
.service(
|
||||
// Handle POST to /post separately to add the post() rate limitter
|
||||
resource("/post")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.post())
|
||||
.route(post().to(create_post)),
|
||||
)
|
||||
.service(
|
||||
scope("/post")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_post))
|
||||
.route("", put().to(update_post))
|
||||
.route("/delete", post().to(delete_post))
|
||||
.route("/remove", post().to(remove_post))
|
||||
.route("/mark_as_read", post().to(mark_post_as_read))
|
||||
.route("/hide", post().to(hide_post))
|
||||
.route("/lock", post().to(lock_post))
|
||||
.route("/feature", post().to(feature_post))
|
||||
.route("/list", get().to(list_posts))
|
||||
.route("/like", post().to(like_post))
|
||||
.route("/like/list", get().to(list_post_likes))
|
||||
.route("/save", put().to(save_post))
|
||||
.route("/report", post().to(create_post_report))
|
||||
.route("/report/resolve", put().to(resolve_post_report))
|
||||
.route("/report/list", get().to(list_post_reports))
|
||||
.route("/site_metadata", get().to(get_link_metadata)),
|
||||
)
|
||||
// Comment
|
||||
.service(
|
||||
// Handle POST to /comment separately to add the comment() rate limitter
|
||||
resource("/comment")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.comment())
|
||||
.route(post().to(create_comment)),
|
||||
)
|
||||
.service(
|
||||
scope("/comment")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_comment))
|
||||
.route("", put().to(update_comment))
|
||||
.route("/delete", post().to(delete_comment))
|
||||
.route("/remove", post().to(remove_comment))
|
||||
.route("/mark_as_read", post().to(mark_reply_as_read))
|
||||
.route("/distinguish", post().to(distinguish_comment))
|
||||
.route("/like", post().to(like_comment))
|
||||
.route("/like/list", get().to(list_comment_likes))
|
||||
.route("/save", put().to(save_comment))
|
||||
.route("/list", get().to(list_comments))
|
||||
.route("/report", post().to(create_comment_report))
|
||||
.route("/report/resolve", put().to(resolve_comment_report))
|
||||
.route("/report/list", get().to(list_comment_reports)),
|
||||
)
|
||||
// Private Message
|
||||
.service(
|
||||
scope("/private_message")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/list", get().to(get_private_message))
|
||||
.route("", post().to(create_private_message))
|
||||
.route("", put().to(update_private_message))
|
||||
.route("/delete", post().to(delete_private_message))
|
||||
.route("/mark_as_read", post().to(mark_pm_as_read))
|
||||
.route("/report", post().to(create_pm_report))
|
||||
.route("/report/resolve", put().to(resolve_pm_report))
|
||||
.route("/report/list", get().to(list_pm_reports)),
|
||||
)
|
||||
// User
|
||||
.service(
|
||||
// Account action, I don't like that it's in /user maybe /accounts
|
||||
// Handle /user/register separately to add the register() rate limiter
|
||||
resource("/user/register")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(register)),
|
||||
)
|
||||
// User
|
||||
.service(
|
||||
// Handle /user/login separately to add the register() rate limiter
|
||||
// TODO: pretty annoying way to apply rate limits for register and login, we should
|
||||
// group them under a common path so that rate limit is only applied once (eg under
|
||||
// /account).
|
||||
resource("/user/login")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(login)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/password_reset")
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(reset_password)),
|
||||
)
|
||||
.service(
|
||||
// Handle captcha separately
|
||||
resource("/user/get_captcha")
|
||||
.wrap(rate_limit.post())
|
||||
.route(get().to(get_captcha)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/export_settings")
|
||||
.wrap(rate_limit.import_user_settings())
|
||||
.route(get().to(export_settings)),
|
||||
)
|
||||
.service(
|
||||
resource("/user/import_settings")
|
||||
.wrap(rate_limit.import_user_settings())
|
||||
.route(post().to(import_settings)),
|
||||
)
|
||||
// TODO, all the current account related actions under /user need to get moved here
|
||||
// eventually
|
||||
.service(
|
||||
scope("/account")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/list_media", get().to(list_media)),
|
||||
)
|
||||
// User actions
|
||||
.service(
|
||||
scope("/user")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(read_person))
|
||||
.route("/mention", get().to(list_mentions))
|
||||
.route(
|
||||
"/mention/mark_as_read",
|
||||
post().to(mark_person_mention_as_read),
|
||||
)
|
||||
.route("/replies", get().to(list_replies))
|
||||
// Admin action. I don't like that it's in /user
|
||||
.route("/ban", post().to(ban_from_site))
|
||||
.route("/banned", get().to(list_banned_users))
|
||||
.route("/block", post().to(user_block_person))
|
||||
// TODO Account actions. I don't like that they're in /user maybe /accounts
|
||||
.route("/logout", post().to(logout))
|
||||
.route("/delete_account", post().to(delete_account))
|
||||
.route("/password_change", post().to(change_password_after_reset))
|
||||
// TODO mark_all_as_read feels off being in this section as well
|
||||
.route("/mark_all_as_read", post().to(mark_all_notifications_read))
|
||||
.route("/save_user_settings", put().to(save_user_settings))
|
||||
.route("/change_password", put().to(change_password))
|
||||
.route("/report_count", get().to(report_count))
|
||||
.route("/unread_count", get().to(unread_count))
|
||||
.route("/verify_email", post().to(verify_email))
|
||||
.route("/leave_admin", post().to(leave_admin))
|
||||
.route("/totp/generate", post().to(generate_totp_secret))
|
||||
.route("/totp/update", post().to(update_totp))
|
||||
.route("/list_logins", get().to(list_logins))
|
||||
.route("/validate_auth", get().to(validate_auth)),
|
||||
)
|
||||
// Admin Actions
|
||||
.service(
|
||||
scope("/admin")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/add", post().to(add_admin))
|
||||
.route(
|
||||
"/registration_application/count",
|
||||
get().to(get_unread_registration_application_count),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/list",
|
||||
get().to(list_registration_applications),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/approve",
|
||||
put().to(approve_registration_application),
|
||||
)
|
||||
.route(
|
||||
"/registration_application",
|
||||
get().to(get_registration_application),
|
||||
)
|
||||
.route("/list_all_media", get().to(list_all_media))
|
||||
.service(
|
||||
scope("/purge")
|
||||
.route("/person", post().to(purge_person))
|
||||
.route("/community", post().to(purge_community))
|
||||
.route("/post", post().to(purge_post))
|
||||
.route("/comment", post().to(purge_comment)),
|
||||
),
|
||||
)
|
||||
.service(
|
||||
scope("/custom_emoji")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", post().to(create_custom_emoji))
|
||||
.route("", put().to(update_custom_emoji))
|
||||
.route("/delete", post().to(delete_custom_emoji)),
|
||||
),
|
||||
);
|
||||
cfg.service(
|
||||
scope("/sitemap.xml")
|
||||
.wrap(rate_limit.message())
|
||||
|
|
|
@ -159,7 +159,13 @@ use lemmy_apub::api::{
|
|||
search::search,
|
||||
user_settings_backup::{export_settings, import_settings},
|
||||
};
|
||||
use lemmy_routes::images::image_proxy;
|
||||
use lemmy_routes::images::{
|
||||
delete_image,
|
||||
get_full_res_image,
|
||||
image_proxy,
|
||||
pictrs_healthz,
|
||||
upload_image,
|
||||
};
|
||||
use lemmy_utils::rate_limit::RateLimitCell;
|
||||
|
||||
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
||||
|
@ -387,6 +393,17 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.wrap(rate_limit.register())
|
||||
.route("/authenticate", post().to(authenticate_with_oauth)),
|
||||
)
|
||||
.route("/sitemap.xml", get().to(get_sitemap)),
|
||||
.route("/sitemap.xml", get().to(get_sitemap))
|
||||
.service(
|
||||
scope("/image")
|
||||
.service(
|
||||
resource("")
|
||||
.wrap(rate_limit.image())
|
||||
.route(post().to(upload_image)),
|
||||
)
|
||||
.route("/{filename}", get().to(get_full_res_image))
|
||||
.route("{token}/{filename}", delete().to(delete_image))
|
||||
.route("/healthz", get().to(pictrs_healthz)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue