add client IP logging to media requests
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
d036d8adcb
commit
93e7cf461d
1 changed files with 43 additions and 17 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::{io::Cursor, sync::Arc, time::Duration};
|
use std::{io::Cursor, sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduit::{debug, error, utils::math::ruma_from_usize, warn};
|
use conduit::{debug, error, utils::math::ruma_from_usize, warn};
|
||||||
use image::io::Reader as ImgReader;
|
use image::io::Reader as ImgReader;
|
||||||
use ipaddress::IPAddress;
|
use ipaddress::IPAddress;
|
||||||
|
@ -64,18 +65,22 @@ pub(crate) async fn get_media_config_v1_route(
|
||||||
/// # `GET /_matrix/media/v3/preview_url`
|
/// # `GET /_matrix/media/v3/preview_url`
|
||||||
///
|
///
|
||||||
/// Returns URL preview.
|
/// Returns URL preview.
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "url_preview")]
|
||||||
pub(crate) async fn get_media_preview_route(
|
pub(crate) async fn get_media_preview_route(
|
||||||
body: Ruma<get_media_preview::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_media_preview::v3::Request>,
|
||||||
) -> Result<get_media_preview::v3::Response> {
|
) -> Result<get_media_preview::v3::Response> {
|
||||||
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let url = &body.url;
|
let url = &body.url;
|
||||||
if !url_preview_allowed(url) {
|
if !url_preview_allowed(url) {
|
||||||
|
warn!(%sender_user, "URL is not allowed to be previewed: {url}");
|
||||||
return Err(Error::BadRequest(ErrorKind::forbidden(), "URL is not allowed to be previewed"));
|
return Err(Error::BadRequest(ErrorKind::forbidden(), "URL is not allowed to be previewed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
match get_url_preview(url).await {
|
match get_url_preview(url).await {
|
||||||
Ok(preview) => {
|
Ok(preview) => {
|
||||||
let res = serde_json::value::to_raw_value(&preview).map_err(|e| {
|
let res = serde_json::value::to_raw_value(&preview).map_err(|e| {
|
||||||
error!("Failed to convert UrlPreviewData into a serde json value: {}", e);
|
error!(%sender_user, "Failed to convert UrlPreviewData into a serde json value: {e}");
|
||||||
Error::BadRequest(
|
Error::BadRequest(
|
||||||
ErrorKind::LimitExceeded {
|
ErrorKind::LimitExceeded {
|
||||||
retry_after: Some(RetryAfter::Delay(Duration::from_secs(5))),
|
retry_after: Some(RetryAfter::Delay(Duration::from_secs(5))),
|
||||||
|
@ -87,7 +92,7 @@ pub(crate) async fn get_media_preview_route(
|
||||||
Ok(get_media_preview::v3::Response::from_raw_value(res))
|
Ok(get_media_preview::v3::Response::from_raw_value(res))
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Failed to generate a URL preview: {e}");
|
warn!(%sender_user, "Failed to generate a URL preview: {e}");
|
||||||
|
|
||||||
// there doesn't seem to be an agreed-upon error code in the spec.
|
// there doesn't seem to be an agreed-upon error code in the spec.
|
||||||
// the only response codes in the preview_url spec page are 200 and 429.
|
// the only response codes in the preview_url spec page are 200 and 429.
|
||||||
|
@ -108,10 +113,13 @@ pub(crate) async fn get_media_preview_route(
|
||||||
/// See <https://spec.matrix.org/legacy/legacy/#id27>
|
/// See <https://spec.matrix.org/legacy/legacy/#id27>
|
||||||
///
|
///
|
||||||
/// Returns URL preview.
|
/// Returns URL preview.
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "url_preview")]
|
||||||
pub(crate) async fn get_media_preview_v1_route(
|
pub(crate) async fn get_media_preview_v1_route(
|
||||||
body: Ruma<get_media_preview::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_media_preview::v3::Request>,
|
||||||
) -> Result<RumaResponse<get_media_preview::v3::Response>> {
|
) -> Result<RumaResponse<get_media_preview::v3::Response>> {
|
||||||
get_media_preview_route(body).await.map(RumaResponse)
|
get_media_preview_route(InsecureClientIp(client), body)
|
||||||
|
.await
|
||||||
|
.map(RumaResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # `POST /_matrix/media/v3/upload`
|
/// # `POST /_matrix/media/v3/upload`
|
||||||
|
@ -120,8 +128,9 @@ pub(crate) async fn get_media_preview_v1_route(
|
||||||
///
|
///
|
||||||
/// - Some metadata will be saved in the database
|
/// - Some metadata will be saved in the database
|
||||||
/// - Media will be saved in the media/ directory
|
/// - Media will be saved in the media/ directory
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_upload")]
|
||||||
pub(crate) async fn create_content_route(
|
pub(crate) async fn create_content_route(
|
||||||
body: Ruma<create_content::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<create_content::v3::Request>,
|
||||||
) -> Result<create_content::v3::Response> {
|
) -> Result<create_content::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
|
@ -167,10 +176,13 @@ pub(crate) async fn create_content_route(
|
||||||
///
|
///
|
||||||
/// - Some metadata will be saved in the database
|
/// - Some metadata will be saved in the database
|
||||||
/// - Media will be saved in the media/ directory
|
/// - Media will be saved in the media/ directory
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_upload")]
|
||||||
pub(crate) async fn create_content_v1_route(
|
pub(crate) async fn create_content_v1_route(
|
||||||
body: Ruma<create_content::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<create_content::v3::Request>,
|
||||||
) -> Result<RumaResponse<create_content::v3::Response>> {
|
) -> Result<RumaResponse<create_content::v3::Response>> {
|
||||||
create_content_route(body).await.map(RumaResponse)
|
create_content_route(InsecureClientIp(client), body)
|
||||||
|
.await
|
||||||
|
.map(RumaResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # `GET /_matrix/media/v3/download/{serverName}/{mediaId}`
|
/// # `GET /_matrix/media/v3/download/{serverName}/{mediaId}`
|
||||||
|
@ -181,7 +193,10 @@ pub(crate) async fn create_content_v1_route(
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
pub(crate) async fn get_content_route(body: Ruma<get_content::v3::Request>) -> Result<get_content::v3::Response> {
|
#[tracing::instrument(skip_all, fields(%client), name = "media_get")]
|
||||||
|
pub(crate) async fn get_content_route(
|
||||||
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content::v3::Request>,
|
||||||
|
) -> Result<get_content::v3::Response> {
|
||||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||||
|
|
||||||
if let Some(FileMeta {
|
if let Some(FileMeta {
|
||||||
|
@ -243,10 +258,13 @@ pub(crate) async fn get_content_route(body: Ruma<get_content::v3::Request>) -> R
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_get")]
|
||||||
pub(crate) async fn get_content_v1_route(
|
pub(crate) async fn get_content_v1_route(
|
||||||
body: Ruma<get_content::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content::v3::Request>,
|
||||||
) -> Result<RumaResponse<get_content::v3::Response>> {
|
) -> Result<RumaResponse<get_content::v3::Response>> {
|
||||||
get_content_route(body).await.map(RumaResponse)
|
get_content_route(InsecureClientIp(client), body)
|
||||||
|
.await
|
||||||
|
.map(RumaResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # `GET /_matrix/media/v3/download/{serverName}/{mediaId}/{fileName}`
|
/// # `GET /_matrix/media/v3/download/{serverName}/{mediaId}/{fileName}`
|
||||||
|
@ -257,8 +275,9 @@ pub(crate) async fn get_content_v1_route(
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_get")]
|
||||||
pub(crate) async fn get_content_as_filename_route(
|
pub(crate) async fn get_content_as_filename_route(
|
||||||
body: Ruma<get_content_as_filename::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content_as_filename::v3::Request>,
|
||||||
) -> Result<get_content_as_filename::v3::Response> {
|
) -> Result<get_content_as_filename::v3::Response> {
|
||||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||||
|
|
||||||
|
@ -328,10 +347,13 @@ pub(crate) async fn get_content_as_filename_route(
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_get")]
|
||||||
pub(crate) async fn get_content_as_filename_v1_route(
|
pub(crate) async fn get_content_as_filename_v1_route(
|
||||||
body: Ruma<get_content_as_filename::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content_as_filename::v3::Request>,
|
||||||
) -> Result<RumaResponse<get_content_as_filename::v3::Response>> {
|
) -> Result<RumaResponse<get_content_as_filename::v3::Response>> {
|
||||||
get_content_as_filename_route(body).await.map(RumaResponse)
|
get_content_as_filename_route(InsecureClientIp(client), body)
|
||||||
|
.await
|
||||||
|
.map(RumaResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # `GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId}`
|
/// # `GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId}`
|
||||||
|
@ -342,8 +364,9 @@ pub(crate) async fn get_content_as_filename_v1_route(
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_thumbnail_get")]
|
||||||
pub(crate) async fn get_content_thumbnail_route(
|
pub(crate) async fn get_content_thumbnail_route(
|
||||||
body: Ruma<get_content_thumbnail::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content_thumbnail::v3::Request>,
|
||||||
) -> Result<get_content_thumbnail::v3::Response> {
|
) -> Result<get_content_thumbnail::v3::Response> {
|
||||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||||
|
|
||||||
|
@ -453,10 +476,13 @@ pub(crate) async fn get_content_thumbnail_route(
|
||||||
/// - Only redirects if `allow_redirect` is true
|
/// - Only redirects if `allow_redirect` is true
|
||||||
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
/// - Uses client-provided `timeout_ms` if available, else defaults to 20
|
||||||
/// seconds
|
/// seconds
|
||||||
|
#[tracing::instrument(skip_all, fields(%client), name = "media_thumbnail_get")]
|
||||||
pub(crate) async fn get_content_thumbnail_v1_route(
|
pub(crate) async fn get_content_thumbnail_v1_route(
|
||||||
body: Ruma<get_content_thumbnail::v3::Request>,
|
InsecureClientIp(client): InsecureClientIp, body: Ruma<get_content_thumbnail::v3::Request>,
|
||||||
) -> Result<RumaResponse<get_content_thumbnail::v3::Response>> {
|
) -> Result<RumaResponse<get_content_thumbnail::v3::Response>> {
|
||||||
get_content_thumbnail_route(body).await.map(RumaResponse)
|
get_content_thumbnail_route(InsecureClientIp(client), body)
|
||||||
|
.await
|
||||||
|
.map(RumaResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_remote_content(
|
async fn get_remote_content(
|
||||||
|
|
Loading…
Add table
Reference in a new issue