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:

View file

@ -4,21 +4,28 @@ class UploadsController < ApplicationController
def create
file = params[:file] || params[:files].first
# check if the extension is allowed
unless SiteSetting.authorized_upload?(file)
text = I18n.t("upload.unauthorized", authorized_extensions: SiteSetting.authorized_extensions.gsub("|", ", "))
return render status: 415, text: text
end
upload = Upload.create_for(current_user.id, file)
# check the file size (note: this might also be done in the web server)
filesize = File.size(file.tempfile)
type = SiteSetting.authorized_image?(file) ? "image" : "attachment"
max_size_kb = SiteSetting.send("max_#{type}_size_kb") * 1024
return render status: 413, text: I18n.t("upload.#{type}s.too_large", max_size_kb: max_size_kb) if filesize > max_size_kb
upload = Upload.create_for(current_user.id, file, filesize)
render_serialized(upload, UploadSerializer, root: false)
rescue FastImage::ImageFetchFailure
render status: 422, text: I18n.t("upload.image.fetch_failure")
render status: 422, text: I18n.t("upload.images.fetch_failure")
rescue FastImage::UnknownImageType
render status: 422, text: I18n.t("upload.image.unknown_image_type")
render status: 422, text: I18n.t("upload.images.unknown_image_type")
rescue FastImage::SizeNotFound
render status: 422, text: I18n.t("upload.image.size_not_found")
render status: 422, text: I18n.t("upload.images.size_not_found")
end
end

View file

@ -43,7 +43,7 @@ class Upload < ActiveRecord::Base
end
end
def self.create_for(user_id, file)
def self.create_for(user_id, file, filesize)
# compute the sha
sha1 = Digest::SHA1.file(file.tempfile).hexdigest
# check if the file has already been uploaded
@ -61,7 +61,7 @@ class Upload < ActiveRecord::Base
upload = Upload.create!({
user_id: user_id,
original_filename: file.original_filename,
filesize: File.size(file.tempfile),
filesize: filesize,
sha1: sha1,
url: "",
width: width,

View file

@ -788,7 +788,7 @@ cs:
create: "Bohužel nastala chyba při vytváření příspěvku. Prosím zkuste to znovu."
edit: "Bohužel nastala chyba při editaci příspěvku. Prosím zkuste to znovu."
upload: "Bohužel nastala chyba při nahrávání příspěvku. Prosím zkuste to znovu."
upload_too_large: "Soubor, který se snažíte nahrát je bohužel příliš velký (maximální velikost je {{max_size_kb}}kb). Prosím zmenšete ho zkuste to znovu."
image_too_large: "Soubor, který se snažíte nahrát je bohužel příliš velký (maximální velikost je {{max_size_kb}}kb). Prosím zmenšete ho zkuste to znovu."
too_many_uploads: "Bohužel, najednou smíte nahrát jen jeden soubor."
upload_not_authorized: "Bohužel, soubor, který se snažíte nahrát, není povolený (povolené přípony: {{authorized_extensions}})."
upload_not_allowed_for_new_user: "Bohužel, noví uživatelé nemohou nahrávat obrázky."

View file

@ -762,7 +762,7 @@ de:
create: "Entschuldige, es gab einen Fehler beim Anlegen des Beitrags. Bitte versuche es noch einmal."
edit: "Entschuldige, es gab einen Fehler beim Bearbeiten des Beitrags. Bitte versuche es noch einmal."
upload: "Entschuldige, es gab einen Fehler beim Hochladen der Datei. Bitte versuche es noch einmal."
upload_too_large: "Entschuldige, die Datei die du hochladen wolltest ist zu groß (Maximalgröße {{max_size_kb}}kb), bitte reduziere die Dateigröße und versuche es nochmal."
image_too_large: "Entschuldige, die Datei die du hochladen wolltest ist zu groß (Maximalgröße {{max_size_kb}}kb), bitte reduziere die Dateigröße und versuche es nochmal."
abandon: "Willst Du diesen Beitrag wirklich verwerfen?"

View file

@ -762,7 +762,8 @@ en:
create: "Sorry, there was an error creating your post. Please try again."
edit: "Sorry, there was an error editing your post. Please try again."
upload: "Sorry, there was an error uploading that file. Please try again."
upload_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb), please resize it and try again."
attachment_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb)."
image_too_large: "Sorry, the image you are trying to upload is too big (maximum size is {{max_size_kb}}kb), please resize it and try again."
too_many_uploads: "Sorry, you can only upload one file at a time."
upload_not_authorized: "Sorry, the file you are trying to upload is not authorized (authorized extension: {{authorized_extensions}})."
image_upload_not_allowed_for_new_user: "Sorry, new users can not upload images."

View file

@ -743,7 +743,8 @@ fr:
create: "Désolé, il y a eu une erreur lors de la publication de votre message. Merci de réessayer."
edit: "Désolé, il y a eu une erreur lors de l'édition de votre message. Merci de réessayer."
upload: "Désolé, il y a eu une erreur lors de l'envoi du fichier. Merci de réessayer."
upload_too_large: "Désolé, le fichier que vous êtes en train d'envoyer est trop grand (maximum {{max_size_kb}}Kb). Merci de le redimensionner et de réessayer."
image_too_large: "Désolé, l'image que vous êtes en train d'envoyer est trop grande (taille maximum de {{max_size_kb}} Ko). Merci de le redimensionner et de réessayer."
attachment_too_large: "Désolé, le fichier que vous êtes en train d'envoyer est trop grand (taille maximum de {{max_size_kb}} Ko)."
too_many_uploads: "Désolé, vous ne pouvez envoyer qu'un seul fichier à la fois."
upload_not_authorized: "Désole, le fichier que vous êtes en train d'uploader n'est pas autorisé (extensions autorisées : {{authorized_extensions}})."
image_upload_not_allowed_for_new_user: "Désolé, les nouveaux utilisateurs ne peuvent pas uploader d'image."

View file

@ -660,7 +660,7 @@ it:
create: "Spiacenti, si è verificato un errore durante la creazione del tuo post. Per favore, prova di nuovo."
edit: "Spiacenti, si è verificato un errore durante la modifica del tuo post. Per favore, prova di nuovo."
upload: "Spiacenti, si è verificato un errore durante il caricamento del file. Per favore, prova di nuovo."
upload_too_large: "Spiacenti, il file che stai cercando di caricare è troppo grande (la dimensione massima è {{max_size_kb}}kb), per favore ridimensionalo e prova di nuovo."
image_too_large: "Spiacenti, il file che stai cercando di caricare è troppo grande (la dimensione massima è {{max_size_kb}}kb), per favore ridimensionalo e prova di nuovo."
too_many_uploads: "Spiacenti, puoi caricare un'immagine per volta."
abandon: "Sei sicuro di voler abbandonare il tuo post?"

View file

@ -610,7 +610,7 @@ ko:
create: "죄송합니다, 귀하의 게시물을 만드는 동안 오류가 발생했습니다. 다시 시도하십시오."
edit: "죄송합니다, 귀하의 게시물을 수정하는 중에 오류가 발생했습니다. 다시 시도하십시오."
upload: "죄송합니다, 오류가 업로드하는 파일이 있었다. 다시 시도하십시오."
upload_too_large: "죄송합니다, 당신이 업로드하려는 파일이 너무 큽니다. (최대 크기는 {{max_size_kb}}kb), 사이즈를 조정하고 다시 시도해보세요"
image_too_large: "죄송합니다, 당신이 업로드하려는 파일이 너무 큽니다. (최대 크기는 {{max_size_kb}}kb), 사이즈를 조정하고 다시 시도해보세요"
upload_too_many_images: "죄송합니다, 당신은 한 번에 하나의 이미지를 업로드 할 수 있습니다."
only_images_are_supported: "죄송합니다, 당신은 한 번에 하나의 이미지를 업로드 할 수 있습니다."

View file

@ -680,7 +680,7 @@ nb_NO:
create: "Beklager, det oppstod en feil ved å publisere ditt innlegg. Vennligst prøv igjen."
edit: "Beklager, det oppstod en feil ved redigeringen av ditt innlegg. Vennligst prøv igjen."
upload: "Sorry, there was an error uploading that file. Please try again."
upload_too_large: "Beklager, filen du prøve å laste opp er for stor (maks størrelse er {{max_size_kb}}kb), vennligst reduser størrelsen og prøv igjen."
image_too_large: "Beklager, filen du prøve å laste opp er for stor (maks størrelse er {{max_size_kb}}kb), vennligst reduser størrelsen og prøv igjen."
too_many_uploads: "Beklager, du kan bare laste opp ett bilde om gangen."
abandon: "Er du sikker på at du vil forlate innlegget ditt?"

View file

@ -757,7 +757,7 @@ nl:
create: "Sorry, er is iets misgegaan bij het plaatsen van je bericht. Probeer het nog eens."
edit: "Sorry, er is iets misgegaan bij het bewerken van je bericht. Probeer het nog eens."
upload: "Sorry, er is iets misgegaan bij het uploaden van je bestand. Probeer het nog eens."
upload_too_large: "Sorry, het bestand dat je wil uploaden is te groot (maximum grootte is {{max_size_kb}}kb), verklein het bestand en probeer het opnieuw."
image_too_large: "Sorry, het bestand dat je wil uploaden is te groot (maximum grootte is {{max_size_kb}}kb), verklein het bestand en probeer het opnieuw."
too_many_uploads: "Sorry, je kan maar één afbeelding tegelijk uploaden."
upload_not_authorized: "Sorry, je mag dat type bestand niet uploaden (toegestane extensies: {{authorized_extensions}})."
upload_not_allowed_for_new_user: "Sorry, nieuwe gebruikers mogen nog geen afbeeldingen uploaden."

View file

@ -731,7 +731,7 @@ pseudo:
edit: '[[ Šóřřý, ťĥéřé ŵáš áɳ éřřóř éďíťíɳǧ ýóůř ƿóšť. Рłéášé ťřý áǧáíɳ. ]]'
upload: '[[ Šóřřý, ťĥéřé ŵáš áɳ éřřóř ůƿłóáďíɳǧ ťĥáť ƒíłé. Рłéášé ťřý áǧáíɳ.
]]'
upload_too_large: '[[ Šóřřý, ťĥé ƒíłé ýóů ářé ťřýíɳǧ ťó ůƿłóáď íš ťóó ƀíǧ
image_too_large: '[[ Šóřřý, ťĥé ƒíłé ýóů ářé ťřýíɳǧ ťó ůƿłóáď íš ťóó ƀíǧ
(ɱáхíɱůɱ šížé íš {{max_size_kb}}ǩƀ), ƿłéášé řéšížé íť áɳď ťřý áǧáíɳ. ]]'
too_many_uploads: '[[ Šóřřý, ýóů čáɳ óɳłý ůƿłóáď óɳé ƒíłé áť á ťíɱé. ]]'
upload_not_authorized: '[[ Šóřřý, ťĥé ƒíłé ýóů ářé ťřýíɳǧ ťó ůƿłóáď íš ɳóť

View file

@ -656,7 +656,7 @@ pt_BR:
create: "Desculpe, houve um erro ao criar o seu post. Por favor tenta outra vez."
edit: "Desculpe, houve um erro ao editar o seu post. Por favor tenta outra vez."
upload: "Desculpe, houve um erro ao enviar esse ficheiro. Por favor tenta otura vez."
upload_too_large: "Desculpe, o arquivo que você está tentando enviar é muito grande (o tamanho máximo é {{max_size_kb}}kb), por favor diminua-o e tente novamente."
image_too_large: "Desculpe, o arquivo que você está tentando enviar é muito grande (o tamanho máximo é {{max_size_kb}}kb), por favor diminua-o e tente novamente."
too_many_uploads: "Desculpe, você pode enviar apenas um arquivos por vez."
upload_not_authorized: "Desculpe, o tipo de arquivo que você está tentando enviar não está autorizado (extensões autorizadas: {{authorized_extensions}})."
upload_not_allowed_for_new_user: "Desculpe, novos usuários não podem enviar imagens."

View file

@ -735,7 +735,7 @@ ru:
create: К сожалению, не удалось создать сообщение. Попробуйте еще раз.
edit: К сожалению, не удалось изменить сообщение. Попробуйте еще раз.
upload: К сожалению, не удалось загрузить файл. Попробуйте еще раз.
upload_too_large: 'Превышен допустимый размер ({{max_size_kb}}kb) файла. Уменьшите размер изображения и повторите попытку.'
image_too_large: 'Превышен допустимый размер ({{max_size_kb}}kb) файла. Уменьшите размер изображения и повторите попытку.'
too_many_uploads: К сожалению, за один раз можно загрузить только одно изображение.
upload_not_authorized: 'К сожалению, вы не можете загрузить файл данного типа (список разрешенных типов файлов: {{authorized_extensions}}).'
upload_not_allowed_for_new_user: К сожалению, загрузка изображений недоступна новым пользователям.

View file

@ -578,7 +578,7 @@ sv:
create: "Tyvärr, det uppstod ett fel under skapandet av ditt inlägg. Var god försök igen."
edit: "Tyvärr, det uppstod ett fel under ändringen av ditt inlägg. Var god försök igen."
upload: "Tyvärr, det uppstod ett fel under uppladdandet av den filen. Vad god försök igen."
upload_too_large: "Tyvärr, filen som du försöker ladda upp är för stor (maxstorlek är {{max_size_kb}}kb), var god ändra storlek och försök igen."
image_too_large: "Tyvärr, filen som du försöker ladda upp är för stor (maxstorlek är {{max_size_kb}}kb), var god ändra storlek och försök igen."
too_many_uploads: "Tyvärr, du kan bara ladda upp en bild i taget."
abandon: "Är du säker på att du vill överge ditt inlägg?"

View file

@ -765,7 +765,7 @@ zh_CN:
create: "抱歉,在创建你的帖子时发生了错误。请重试。"
edit: "抱歉,在编辑你的帖子时发生了错误。请重试。"
upload: "抱歉,在上传文件时发生了错误。请重试。"
upload_too_large: "抱歉,你上传的文件太大了(最大不能超过 {{max_size_kb}}kb请调整文件大小后重新上传。"
image_too_large: "抱歉,你上传的文件太大了(最大不能超过 {{max_size_kb}}kb请调整文件大小后重新上传。"
too_many_uploads: "抱歉, 你只能一次上传一张图片。"
upload_not_authorized: "抱歉, 你不能上传此类型文件(可上传的文件类型有: {{authorized_extensions}})。"
upload_not_allowed_for_new_user: "抱歉,新用户不能上传图片。"

View file

@ -660,7 +660,7 @@ zh_TW:
create: "抱歉,在創建你的帖子時發生了錯誤。請重試。"
edit: "抱歉,在編輯你的帖子時發生了錯誤。請重試。"
upload: "抱歉,在上傳文件時發生了錯誤。請重試。"
upload_too_large: "抱歉,你上傳的文件太大了(最大不能超過 {{max_size_kb}}kb請調整文件大小後重新上傳。"
image_too_large: "抱歉,你上傳的文件太大了(最大不能超過 {{max_size_kb}}kb請調整文件大小後重新上傳。"
too_many_uploads: "抱歉, 你只能一次上傳一張圖片。"
abandon: "你確定要丟棄你的帖子嗎?"

View file

@ -1100,7 +1100,7 @@ cs:
upload:
pasted_image_filename: ""
image:
images:
fetch_failure: "Bohužel, nastala chybí při získávání obrázku."
unknown_image_type: "Bohužel, soubor, který se snažíte nahrát, zřejmě není obrázek."
size_not_found: "Bohužel se nepodařilo zjistit velikost obrázku. Není soubor s obrázkem poškozený?"

View file

@ -1004,7 +1004,7 @@ de:
upload:
pasted_image_filename: ""
image:
images:
fetch_failure: "Entschuldige, beim Laden des Bildes ist ein Fehler aufgetreten."
unknown_image_type: "Entschuldige, aber die Datei die Du hochladen möchtest schein kein Bild zu sein."
size_not_found: "Entschuldige, aber wir konnten die Grösse des Bildes nicht feststellen. Vielleicht ist das Bild defekt?"

View file

@ -1090,7 +1090,10 @@ en:
upload:
unauthorized: "Sorry, the file you are trying to upload is not authorized (authorized extensions: %{authorized_extensions})."
pasted_image_filename: "Pasted image"
image:
attachments:
too_large: "Sorry, the file you are trying to upload is too big (maximum size is %{max_size_kb}%kb)."
images:
too_large: "Sorry, the image you are trying to upload is too big (maximum size is %{max_size_kb}%kb), please resize it and try again."
fetch_failure: "Sorry, there has been an error while fetching the image."
unknown_image_type: "Sorry, but the file you tried to upload doesn't appear to be an image."
size_not_found: "Sorry, but we couldn't determine the size of the image. Maybe your image is corrupted?"

View file

@ -962,7 +962,10 @@ fr:
upload:
pasted_image_filename: "Image collée"
image:
attachments:
too_large: "Désolé, le fichier que vous êtes en train d'uploader est trop grand (la taille maximum est %{max_size_kb}% ko)."
images:
too_large: "Désolé, l'image que vous êtes en train d'uploader est trop grande (la taille maximum est %{max_size_kb}% ko)."
fetch_failure: "Désolé, une erreur s'est produite lorsque nous avons essayé de récupérer l'image."
unknown_image_type: "Désolé, mais le fichier que vous essayez d'envoyer ne semble pas être une image."
size_not_found: "Désolé, mais nous n'avons pas réussit à déterminer la taille de l'image. Peut-être que l'image est corrompue ?"

View file

@ -917,7 +917,7 @@ it:
upload:
pasted_image_filename: ""
image:
images:
fetch_failure: "Spiacente, si è verificato un errore nel recupero dell'immagine."
unknown_image_type: "Spiacente, ma il file che hai provato a caricare non sembra un'immagine."
size_not_found: "Spiacente, ma non riusciamo a determinare la dimensione dell'immagine. Probabilmente l'immagine è corrotta?"

View file

@ -932,7 +932,7 @@ ko:
deleted: 'deleted'
upload:
image:
images:
fetch_failure: "Sorry, there has been an error while fetching the image."
unknown_image_type: "Sorry, but the file you tried to upload doesn't appear to be an image."
size_not_found: "Sorry, but we couldn't determine the size of the image. Maybe your image is corrupted?"

View file

@ -1075,7 +1075,7 @@ nl:
upload:
pasted_image_filename: "Geplakte afbeelding"
image:
images:
fetch_failure: "Er ging iets mis bij het opvragen van de afbeelding."
unknown_image_type: "Het bestand dat je wil uploaden is geen afbeelding."
size_not_found: "Het is niet gelukt de afmetingen van de afbeelding te bepalen. Misschien is het bestand corrupt?"

View file

@ -1273,7 +1273,7 @@ pseudo:
deleted: '[[ ďéłéťéď ]]'
upload:
pasted_image_filename: '[[ Рášťéď íɱáǧé ]]'
image:
images:
fetch_failure: '[[ Šóřřý, ťĥéřé ĥáš ƀééɳ áɳ éřřóř ŵĥíłé ƒéťčĥíɳǧ ťĥé íɱáǧé.
]]'
unknown_image_type: '[[ Šóřřý, ƀůť ťĥé ƒíłé ýóů ťříéď ťó ůƿłóáď ďóéšɳ''ť áƿƿéář

View file

@ -955,7 +955,7 @@ pt_BR:
upload:
unauthorized: "Desculpe-nos, o arquivo que você está tentando enviar não é autorizado (extensões autorizadas: %{authorized_extensions})."
pasted_image_filename: "Imagem colada"
image:
images:
fetch_failure: "Desculpe, houve um erro ao transferir a imagem."
unknown_image_type: "Desculpe, mas o arquivo que você tentou enviar não parece ser uma imagem."
size_not_found: "Desculpe, mas não conseguimos determinar o tamanho da imagem. É possível que seu arquivo de imagem esteja corrompido?"

View file

@ -1073,7 +1073,7 @@ ru:
upload:
unauthorized: 'К сожалению, вы не можете загрузить файл данного типа (список разрешенных типов файлов: %{authorized_extensions}).'
pasted_image_filename: Имя файла изображения
image:
images:
fetch_failure: Извините, во время извлечения изображения произошла ошибка.
unknown_image_type: Файл, который вы загружаете, не является изображением.
size_not_found: Извините, мы не можем определить размер изображения. Возможно, изображение повреждено?

View file

@ -934,7 +934,7 @@ zh_CN:
upload:
pasted_image_filename: ""
image:
images:
fetch_failure: "抱歉,获取图片時发生错误。"
unknown_image_type: "抱歉,你上传的文件似乎不是一张图片。"
size_not_found: "抱歉,我们无法获取图片大小,请检查你的图片是否已损坏。"

View file

@ -917,7 +917,7 @@ zh_TW:
upload:
pasted_image_filename: ""
image:
images:
fetch_failure: "抱歉,獲取圖片時發生錯誤。"
unknown_image_type: "抱歉,你上傳的文件似乎不是一張圖片。"
size_not_found: "抱歉,我們無法獲取圖片大小,請檢查你的圖片是否已損壞。"

View file

@ -41,13 +41,29 @@ describe UploadsController do
context 'when authorized' do
before { SiteSetting.stubs(:authorized_extensions).returns(".txt") }
before { SiteSetting.stubs(:authorized_extensions).returns(".png|.txt") }
it 'is successful' do
it 'is successful with an image' do
xhr :post, :create, file: logo
response.status.should eq 200
end
it 'is successful with an attachment' do
xhr :post, :create, file: text_file
response.status.should eq 200
end
context 'with a big file' do
before { SiteSetting.stubs(:max_attachment_size_kb).returns(1) }
it 'rejects the upload' do
xhr :post, :create, file: text_file
response.status.should eq 413
end
end
end
context 'when not authorized' do

View file

@ -27,6 +27,7 @@ describe Upload do
end
let(:image_sha1) { Digest::SHA1.file(image.tempfile).hexdigest }
let(:image_filesize) { File.size(image.tempfile) }
let(:attachment) do
ActionDispatch::Http::UploadedFile.new({
@ -35,6 +36,8 @@ describe Upload do
})
end
let(:attachment_filesize) { File.size(attachment.tempfile) }
context ".create_thumbnail!" do
it "does not create a thumbnail when disabled" do
@ -77,7 +80,7 @@ describe Upload do
it "does not create another upload if it already exists" do
Upload.expects(:where).with(sha1: image_sha1).returns([upload])
Upload.expects(:create!).never
Upload.create_for(user_id, image).should == upload
Upload.create_for(user_id, image, image_filesize).should == upload
end
it "computes width & height for images" do
@ -85,24 +88,24 @@ describe Upload do
FastImage.any_instance.expects(:size).returns([100, 200])
ImageSizer.expects(:resize)
ActionDispatch::Http::UploadedFile.any_instance.expects(:rewind)
Upload.create_for(user_id, image)
Upload.create_for(user_id, image, image_filesize)
end
it "does not create an upload when there is an error with FastImage" do
SiteSetting.expects(:authorized_image?).returns(true)
Upload.expects(:create!).never
expect { Upload.create_for(user_id, attachment) }.to raise_error(FastImage::UnknownImageType)
expect { Upload.create_for(user_id, attachment, attachment_filesize) }.to raise_error(FastImage::UnknownImageType)
end
it "does not compute width & height for non-image" do
SiteSetting.expects(:authorized_image?).returns(false)
FastImage.any_instance.expects(:size).never
Upload.create_for(user_id, image)
Upload.create_for(user_id, image, image_filesize)
end
it "saves proper information" do
Upload.expects(:store_file).returns(url)
upload = Upload.create_for(user_id, image)
upload = Upload.create_for(user_id, image, image_filesize)
upload.user_id.should == user_id
upload.original_filename.should == image.original_filename
upload.filesize.should == File.size(image.tempfile)

View file

@ -7,9 +7,9 @@ test("emailValid", function() {
ok(utils.emailValid('bob@EXAMPLE.com'), "allows upper case in the email domain");
});
var validUpload = utils.validateFilesForUpload;
var validUpload = utils.validateUploadedFiles;
test("validateFilesForUpload", function() {
test("validateUploadedFiles", function() {
ok(!validUpload(null), "no files are invalid");
ok(!validUpload(undefined), "undefined files are invalid");
ok(!validUpload([]), "empty array of files is invalid");
@ -55,7 +55,7 @@ test("prevents files that are too big from being uploaded", function() {
this.stub(bootbox, "alert");
ok(!validUpload([image]));
ok(bootbox.alert.calledWith(I18n.t('post.errors.upload_too_large', { max_size_kb: 5 })));
ok(bootbox.alert.calledWith(I18n.t('post.errors.image_too_large', { max_size_kb: 5 })));
});
var dummyBlob = function() {
@ -83,17 +83,6 @@ test("allows valid uploads to go through", function() {
ok(!bootbox.alert.calledOnce);
});
var isAuthorized = function (filename) {
return utils.isAuthorizedUpload({ name: filename });
};
test("isAuthorizedUpload", function() {
ok(isAuthorized("image.png"));
ok(isAuthorized("image.jpg"));
ok(!isAuthorized("image.txt"));
ok(!isAuthorized(""));
});
var getUploadMarkdown = function(filename) {
return utils.getUploadMarkdown({
original_filename: filename,

View file

@ -1,3 +1,3 @@
/*jshint maxlen:10000000 */
Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":"","authorized_extensions":".jpg|.jpeg|.png|.gif","relative_date_duration":14};
Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":"","authorized_extensions":".jpg|.jpeg|.png|.gif|.txt","relative_date_duration":14};
Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal);