FEATURE: support for enabling all upload file types
BUGFIX: authorized extensions is now case insensitive
This commit is contained in:
parent
359d59242e
commit
4371374ba6
|
@ -7,9 +7,6 @@
|
|||
**/
|
||||
Discourse.Utilities = {
|
||||
|
||||
IMAGE_EXTENSIONS: [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tif", ".tiff"],
|
||||
IS_AN_IMAGE_REGEXP: /\.(png|jpg|jpeg|gif|bmp|tif|tiff)$/i,
|
||||
|
||||
translateSize: function(size) {
|
||||
switch (size) {
|
||||
case 'tiny': return 20;
|
||||
|
@ -180,9 +177,9 @@ Discourse.Utilities = {
|
|||
@returns true whenever the upload is valid
|
||||
**/
|
||||
validateUploadedFile: function(file, type) {
|
||||
|
||||
// check that the uploaded file is authorized
|
||||
if (!Discourse.Utilities.isAuthorizedUpload(file)) {
|
||||
if (!Discourse.Utilities.authorizesAllExtensions() &&
|
||||
!Discourse.Utilities.isAuthorizedUpload(file)) {
|
||||
var extensions = Discourse.Utilities.authorizedExtensions();
|
||||
bootbox.alert(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
|
||||
return false;
|
||||
|
@ -206,6 +203,16 @@ Discourse.Utilities = {
|
|||
return true;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
Determine whether all file extensions are authorized.
|
||||
|
||||
@method authorizesAllExtensions
|
||||
**/
|
||||
authorizesAllExtensions: function() {
|
||||
return Discourse.SiteSettings.authorized_extensions.indexOf("*") >= 0;
|
||||
},
|
||||
|
||||
/**
|
||||
Check the extension of the file against the list of authorized extensions
|
||||
|
||||
|
@ -213,9 +220,27 @@ Discourse.Utilities = {
|
|||
@param {File} file The file we want to upload
|
||||
**/
|
||||
isAuthorizedUpload: function(file) {
|
||||
var extensions = Discourse.SiteSettings.authorized_extensions;
|
||||
var regexp = new RegExp("(" + extensions + ")$", "i");
|
||||
return file && file.name ? file.name.match(regexp) : false;
|
||||
if (file && file.name) {
|
||||
var extensions = _.chain(Discourse.SiteSettings.authorized_extensions.split("|"))
|
||||
.reject(function(extension) { return extension.indexOf("*") >= 0; })
|
||||
.map(function(extension) { return (extension.indexOf(".") === 0 ? extension.substring(1) : extension).replace(".", "\\."); })
|
||||
.value();
|
||||
return new RegExp("\\.(" + extensions.join("|") + ")$", "i").test(file.name);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
List the authorized extension for display
|
||||
|
||||
@method authorizedExtensions
|
||||
**/
|
||||
authorizedExtensions: function() {
|
||||
return _.chain(Discourse.SiteSettings.authorized_extensions.split("|"))
|
||||
.reject(function(extension) { return extension.indexOf("*") >= 0; })
|
||||
.map(function(extension) { return extension.toLowerCase(); })
|
||||
.value()
|
||||
.join(", ");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -239,7 +264,7 @@ Discourse.Utilities = {
|
|||
@param {String} path The path
|
||||
**/
|
||||
isAnImage: function(path) {
|
||||
return Discourse.Utilities.IS_AN_IMAGE_REGEXP.test(path);
|
||||
return (/\.(png|jpg|jpeg|gif|bmp|tif|tiff)$/i).test(path);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -248,11 +273,8 @@ Discourse.Utilities = {
|
|||
@method allowsAttachments
|
||||
**/
|
||||
allowsAttachments: function() {
|
||||
return _.difference(Discourse.SiteSettings.authorized_extensions.split("|"), Discourse.Utilities.IMAGE_EXTENSIONS).length > 0;
|
||||
},
|
||||
|
||||
authorizedExtensions: function() {
|
||||
return Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
|
||||
return Discourse.Utilities.authorizesAllExtensions() ||
|
||||
(/(png|jpg|jpeg|gif|bmp|tif|tiff)/i).test(Discourse.SiteSettings.authorized_extensions);
|
||||
},
|
||||
|
||||
displayErrorForUpload: function(data) {
|
||||
|
|
|
@ -803,7 +803,7 @@ en:
|
|||
|
||||
max_image_size_kb: "The maximum size of images we allow users to upload in kB - configure the limit in nginx (client_max_body_size) / apache or proxy as well."
|
||||
max_attachment_size_kb: "The maximum size of files we allow users to upload in kB - configure the limit in nginx (client_max_body_size) / apache or proxy as well."
|
||||
authorized_extensions: "A pipe (|) separated list of file extensions allowed for upload"
|
||||
authorized_extensions: "A pipe (|) separated list of file extensions allowed for upload ('*' for enabling all file types)"
|
||||
max_similar_results: "How many similar topics to show a user while they are composing a new topic"
|
||||
|
||||
title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc."
|
||||
|
|
|
@ -284,7 +284,7 @@ files:
|
|||
default: 1024
|
||||
authorized_extensions:
|
||||
client: true
|
||||
default: '.jpg|.jpeg|.png|.gif'
|
||||
default: 'jpg|jpeg|png|gif'
|
||||
refresh: true
|
||||
list: true
|
||||
crawl_images:
|
||||
|
|
|
@ -31,7 +31,7 @@ class FileHelper
|
|||
end
|
||||
|
||||
def self.images_regexp
|
||||
@@images_regexp ||= /\.(#{images.to_a.join("|").gsub(".", "\.")})$/i
|
||||
@@images_regexp ||= /\.(#{images.to_a.join("|")})$/i
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -47,30 +47,39 @@ class Validators::UploadValidator < ActiveModel::Validator
|
|||
.tr(" ", "")
|
||||
.split("|")
|
||||
.each do |extension|
|
||||
authorized_uploads << (extension.start_with?(".") ? extension[1..-1] : extension)
|
||||
next if extension.include?("*")
|
||||
authorized_uploads << (extension.start_with?(".") ? extension[1..-1] : extension).downcase
|
||||
end
|
||||
|
||||
authorized_uploads
|
||||
end
|
||||
|
||||
def authorized_images
|
||||
@authorized_images ||= (authorized_uploads & FileHelper.images)
|
||||
authorized_uploads & FileHelper.images
|
||||
end
|
||||
|
||||
def authorized_attachments
|
||||
@authorized_attachments ||= (authorized_uploads - FileHelper.images)
|
||||
authorized_uploads - FileHelper.images
|
||||
end
|
||||
|
||||
def authorizes_all_extensions?
|
||||
SiteSetting.authorized_extensions.include?("*")
|
||||
end
|
||||
|
||||
def authorized_extensions(upload, extension, extensions)
|
||||
unless authorized = extensions.include?(extension)
|
||||
return true if authorizes_all_extensions?
|
||||
|
||||
unless authorized = extensions.include?(extension.downcase)
|
||||
message = I18n.t("upload.unauthorized", authorized_extensions: extensions.to_a.join(", "))
|
||||
upload.errors.add(:original_filename, message)
|
||||
end
|
||||
|
||||
authorized
|
||||
end
|
||||
|
||||
def maximum_file_size(upload, type)
|
||||
max_size_kb = SiteSetting.send("max_#{type}_size_kb").kilobytes
|
||||
|
||||
if upload.filesize > max_size_kb
|
||||
message = I18n.t("upload.#{type}s.too_large", max_size_kb: max_size_kb)
|
||||
upload.errors.add(:filesize, message)
|
||||
|
|
|
@ -28,7 +28,7 @@ describe UploadsController do
|
|||
|
||||
let(:text_file) do
|
||||
ActionDispatch::Http::UploadedFile.new({
|
||||
filename: 'LICENSE.txt',
|
||||
filename: 'LICENSE.TXT',
|
||||
tempfile: File.new("#{Rails.root}/LICENSE.txt")
|
||||
})
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ describe UploadsController do
|
|||
|
||||
context 'when authorized' do
|
||||
|
||||
before { SiteSetting.stubs(:authorized_extensions).returns(".png|.txt") }
|
||||
before { SiteSetting.stubs(:authorized_extensions).returns(".PNG|.txt") }
|
||||
|
||||
it 'is successful with an image' do
|
||||
xhr :post, :create, file: logo
|
||||
|
@ -75,6 +75,22 @@ describe UploadsController do
|
|||
|
||||
end
|
||||
|
||||
context 'when everything is authorized' do
|
||||
|
||||
before { SiteSetting.stubs(:authorized_extensions).returns("*") }
|
||||
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with some files' do
|
||||
|
|
Loading…
Reference in New Issue