add server-side filesize check on uploads

This commit is contained in:
Régis Hanol
2013-07-24 00:54:18 +02:00
parent 75491d2cf6
commit be9217d4c8
34 changed files with 114 additions and 97 deletions

View File

@@ -163,41 +163,55 @@ Discourse.Utilities = {
/**
Validate a list of files to be uploaded
@method validateFilesForUpload
@method validateUploadedFiles
@param {Array} files The list of files we want to upload
**/
validateFilesForUpload: function(files) {
validateUploadedFiles: function(files) {
if (!files || files.length === 0) { return false; }
// can only upload one file at a time
if (files.length > 1) {
bootbox.alert(I18n.t('post.errors.too_many_uploads'));
return false;
}
var upload = files[0];
// ensures that new users can upload image/attachment
if (Discourse.Utilities.isUploadForbidden(upload.name)) {
if (Discourse.Utilities.isAnImage(upload.name)) {
bootbox.alert(I18n.t('post.errors.image_upload_not_allowed_for_new_user'));
} else {
bootbox.alert(I18n.t('post.errors.attachment_upload_not_allowed_for_new_user'));
}
return false;
}
// if the image was pasted, sets its name to a default one
// CHROME ONLY: if the image was pasted, sets its name to a default one
if (upload instanceof Blob && !(upload instanceof File) && upload.type === "image/png") { upload.name = "blob.png"; }
return Discourse.Utilities.validateUploadedFile(upload, Discourse.Utilities.isAnImage(upload.name) ? 'image' : 'attachment');
},
/**
Validate a file to be uploaded
@method validateUploadedFile
@param {File} file The file to be uploaded
@param {string} type The type of the file
**/
validateUploadedFile: function(file, type) {
// check that the uploaded file is authorized
if (!Discourse.Utilities.isAuthorizedUpload(upload)) {
if (!Discourse.Utilities.isAuthorizedUpload(file)) {
var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
bootbox.alert(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
return false;
}
// check file size
var fileSizeKB = upload.size / 1024;
var maxSizeKB = Discourse.Utilities.maxUploadSizeInKB(upload.name);
if (fileSizeKB > maxSizeKB) {
bootbox.alert(I18n.t('post.errors.upload_too_large', { max_size_kb: maxSizeKB }));
// ensures that new users can upload a file
if (Discourse.User.current('trust_level') === 0 && Discourse.SiteSettings['newuser_max_' + type + 's'] === 0) {
bootbox.alert(I18n.t('post.errors.' + type + '_upload_not_allowed_for_new_user'));
return false;
}
// check file size
var fileSizeKB = file.size / 1024;
var maxSizeKB = Discourse.SiteSettings['max_' + type + '_size_kb'];
if (fileSizeKB > maxSizeKB) {
bootbox.alert(I18n.t('post.errors.' + type + '_too_large', { max_size_kb: maxSizeKB }));
return false;
}
// everything went fine
return true;
},
@@ -238,27 +252,6 @@ Discourse.Utilities = {
return path && path.match(/\.(png|jpg|jpeg|gif|bmp|tif|tiff)$/i);
},
/**
Retrieve max upload size in KB depending on the file is an image or not
@method maxUploadSizeInKB
@param {String} path The path
**/
maxUploadSizeInKB: function(path) {
return Discourse.Utilities.isAnImage(path) ? Discourse.SiteSettings.max_image_size_kb : Discourse.SiteSettings.max_attachment_size_kb;
},
/**
Test whether an upload is forbidden or not
@method isUploadForbidden
@param {String} path The path
**/
isUploadForbidden: function(path) {
if (Discourse.User.current('trust_level') > 0) { return false; }
return Discourse.Utilities.isAnImage(path) ? Discourse.SiteSettings.newuser_max_images === 0 : Discourse.SiteSettings.newuser_max_attachments === 0;
},
/**
Determines whether we allow attachments or not

View File

@@ -252,7 +252,7 @@ Discourse.ComposerView = Discourse.View.extend({
// submit - this event is triggered for each upload
$uploadTarget.on('fileuploadsubmit', function (e, data) {
var result = Discourse.Utilities.validateFilesForUpload(data.files);
var result = Discourse.Utilities.validateUploadedFiles(data.files);
// reset upload status when everything is ok
if (result) composerView.setProperties({ uploadProgress: 0, isUploading: true });
return result;
@@ -300,10 +300,11 @@ Discourse.ComposerView = Discourse.View.extend({
switch (data.jqXHR.status) {
// 0 == cancel from the user
case 0: return;
// 413 == entity too large, returned usually from nginx
// 413 == entity too large, usually returned from the web server
case 413:
var maxSizeKB = Discourse.Utilities.maxUploadSizeInKB(data.files[0].name);
bootbox.alert(I18n.t('post.errors.upload_too_large', { max_size_kb: maxSizeKB }));
var type = Discourse.Utilities.isAnImage(data.files[0].name) ? "image" : "attachment";
var maxSizeKB = Discourse.SiteSettings['max_' + type + '_size_kb'];
bootbox.alert(I18n.t('post.errors.' + type + '_too_large', { max_size_kb: maxSizeKB }));
return;
// 415 == media type not authorized
case 415: