Return validation error if upload size exceeds limit
This commit is contained in:
parent
3b56b29785
commit
4dc94ed39b
5 changed files with 30 additions and 24 deletions
|
@ -25,12 +25,11 @@ use mitra::mastodon_api::oauth::views::oauth_api_scope;
|
|||
use mitra::mastodon_api::search::views::search_api_scope;
|
||||
use mitra::mastodon_api::statuses::views::status_api_scope;
|
||||
use mitra::mastodon_api::timelines::views::timeline_api_scope;
|
||||
use mitra::mastodon_api::UPLOAD_MAX_SIZE;
|
||||
use mitra::nodeinfo::views as nodeinfo;
|
||||
use mitra::scheduler;
|
||||
use mitra::webfinger::views as webfinger;
|
||||
|
||||
const MAX_UPLOAD_SIZE: usize = 1024 * 1024 * 10;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let config = parse_config();
|
||||
|
@ -119,8 +118,8 @@ async fn main() -> std::io::Result<()> {
|
|||
}
|
||||
})
|
||||
.wrap(create_auth_error_handler())
|
||||
.app_data(web::PayloadConfig::default().limit(MAX_UPLOAD_SIZE))
|
||||
.app_data(web::JsonConfig::default().limit(MAX_UPLOAD_SIZE))
|
||||
.app_data(web::PayloadConfig::default().limit(UPLOAD_MAX_SIZE * 2))
|
||||
.app_data(web::JsonConfig::default().limit(UPLOAD_MAX_SIZE * 2))
|
||||
.app_data(web::Data::new(config.clone()))
|
||||
.app_data(web::Data::new(db_pool.clone()))
|
||||
.app_data(web::Data::new(maybe_contract_set.clone()))
|
||||
|
|
|
@ -30,7 +30,6 @@ use crate::mastodon_api::oauth::auth::get_current_user;
|
|||
use crate::mastodon_api::pagination::get_paginated_response;
|
||||
use crate::mastodon_api::statuses::helpers::build_status_list;
|
||||
use crate::mastodon_api::statuses::types::Status;
|
||||
use crate::mastodon_api::uploads::UploadError;
|
||||
use crate::models::posts::queries::get_posts_by_author;
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_id,
|
||||
|
@ -194,18 +193,7 @@ async fn update_credentials(
|
|||
¤t_user.profile.identity_proofs.into_inner(),
|
||||
¤t_user.profile.payment_options.into_inner(),
|
||||
&config.media_dir(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
match err {
|
||||
UploadError::Base64DecodingError(_) => {
|
||||
HttpError::ValidationError("base64 decoding error".into())
|
||||
},
|
||||
UploadError::InvalidMediaType => {
|
||||
HttpError::ValidationError("invalid media type".into())
|
||||
},
|
||||
_ => HttpError::InternalError,
|
||||
}
|
||||
})?;
|
||||
)?;
|
||||
profile_data.clean()?;
|
||||
current_user.profile = update_profile(
|
||||
db_client,
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::config::Config;
|
|||
use crate::database::{Pool, get_database_client};
|
||||
use crate::errors::HttpError;
|
||||
use crate::mastodon_api::oauth::auth::get_current_user;
|
||||
use crate::mastodon_api::uploads::{UploadError, save_b64_file};
|
||||
use crate::mastodon_api::uploads::save_b64_file;
|
||||
use crate::models::attachments::queries::create_attachment;
|
||||
use super::types::{AttachmentCreateData, Attachment};
|
||||
|
||||
|
@ -21,12 +21,7 @@ async fn create_attachment_view(
|
|||
let (file_name, media_type) = save_b64_file(
|
||||
&attachment_data.file,
|
||||
&config.media_dir(),
|
||||
).map_err(|err| match err {
|
||||
UploadError::Base64DecodingError(err) => {
|
||||
HttpError::ValidationError(err.to_string())
|
||||
},
|
||||
_ => HttpError::InternalError,
|
||||
})?;
|
||||
)?;
|
||||
let db_attachment = create_attachment(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
|
|
|
@ -12,3 +12,4 @@ pub mod timelines;
|
|||
mod uploads;
|
||||
|
||||
const MASTODON_API_VERSION: &str = "3.0.0";
|
||||
pub use uploads::UPLOAD_MAX_SIZE;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::errors::HttpError;
|
||||
use crate::utils::files::{save_file, sniff_media_type};
|
||||
|
||||
pub const UPLOAD_MAX_SIZE: usize = 1024 * 1024 * 5;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum UploadError {
|
||||
#[error(transparent)]
|
||||
|
@ -10,15 +13,32 @@ pub enum UploadError {
|
|||
#[error("base64 decoding error")]
|
||||
Base64DecodingError(#[from] base64::DecodeError),
|
||||
|
||||
#[error("file is too large")]
|
||||
TooLarge,
|
||||
|
||||
#[error("invalid media type")]
|
||||
InvalidMediaType,
|
||||
}
|
||||
|
||||
impl From<UploadError> for HttpError {
|
||||
fn from(error: UploadError) -> Self {
|
||||
match error {
|
||||
UploadError::WriteError(_) => HttpError::InternalError,
|
||||
other_error => {
|
||||
HttpError::ValidationError(other_error.to_string())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_b64_file(
|
||||
b64data: &str,
|
||||
output_dir: &Path,
|
||||
) -> Result<(String, Option<String>), UploadError> {
|
||||
let data = base64::decode(b64data)?;
|
||||
if data.len() > UPLOAD_MAX_SIZE {
|
||||
return Err(UploadError::TooLarge);
|
||||
};
|
||||
Ok(save_file(data, output_dir, None)?)
|
||||
}
|
||||
|
||||
|
@ -28,6 +48,9 @@ pub fn save_validated_b64_file(
|
|||
media_type_prefix: &str,
|
||||
) -> Result<(String, String), UploadError> {
|
||||
let data = base64::decode(b64data)?;
|
||||
if data.len() > UPLOAD_MAX_SIZE {
|
||||
return Err(UploadError::TooLarge);
|
||||
};
|
||||
let media_type = sniff_media_type(&data)
|
||||
.ok_or(UploadError::InvalidMediaType)?;
|
||||
if !media_type.starts_with(media_type_prefix) {
|
||||
|
|
Loading…
Reference in a new issue