mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 21:33:43 +08:00
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 = {
|
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) {
|
translateSize: function(size) {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 'tiny': return 20;
|
case 'tiny': return 20;
|
||||||
|
@ -180,9 +177,9 @@ Discourse.Utilities = {
|
||||||
@returns true whenever the upload is valid
|
@returns true whenever the upload is valid
|
||||||
**/
|
**/
|
||||||
validateUploadedFile: function(file, type) {
|
validateUploadedFile: function(file, type) {
|
||||||
|
|
||||||
// check that the uploaded file is authorized
|
// 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();
|
var extensions = Discourse.Utilities.authorizedExtensions();
|
||||||
bootbox.alert(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
|
bootbox.alert(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
|
||||||
return false;
|
return false;
|
||||||
|
@ -206,6 +203,16 @@ Discourse.Utilities = {
|
||||||
return true;
|
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
|
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
|
@param {File} file The file we want to upload
|
||||||
**/
|
**/
|
||||||
isAuthorizedUpload: function(file) {
|
isAuthorizedUpload: function(file) {
|
||||||
var extensions = Discourse.SiteSettings.authorized_extensions;
|
if (file && file.name) {
|
||||||
var regexp = new RegExp("(" + extensions + ")$", "i");
|
var extensions = _.chain(Discourse.SiteSettings.authorized_extensions.split("|"))
|
||||||
return file && file.name ? file.name.match(regexp) : false;
|
.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
|
@param {String} path The path
|
||||||
**/
|
**/
|
||||||
isAnImage: function(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
|
@method allowsAttachments
|
||||||
**/
|
**/
|
||||||
allowsAttachments: function() {
|
allowsAttachments: function() {
|
||||||
return _.difference(Discourse.SiteSettings.authorized_extensions.split("|"), Discourse.Utilities.IMAGE_EXTENSIONS).length > 0;
|
return Discourse.Utilities.authorizesAllExtensions() ||
|
||||||
},
|
(/(png|jpg|jpeg|gif|bmp|tif|tiff)/i).test(Discourse.SiteSettings.authorized_extensions);
|
||||||
|
|
||||||
authorizedExtensions: function() {
|
|
||||||
return Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
displayErrorForUpload: function(data) {
|
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_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."
|
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"
|
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."
|
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
|
default: 1024
|
||||||
authorized_extensions:
|
authorized_extensions:
|
||||||
client: true
|
client: true
|
||||||
default: '.jpg|.jpeg|.png|.gif'
|
default: 'jpg|jpeg|png|gif'
|
||||||
refresh: true
|
refresh: true
|
||||||
list: true
|
list: true
|
||||||
crawl_images:
|
crawl_images:
|
||||||
|
|
|
@ -31,7 +31,7 @@ class FileHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.images_regexp
|
def self.images_regexp
|
||||||
@@images_regexp ||= /\.(#{images.to_a.join("|").gsub(".", "\.")})$/i
|
@@images_regexp ||= /\.(#{images.to_a.join("|")})$/i
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,30 +47,39 @@ class Validators::UploadValidator < ActiveModel::Validator
|
||||||
.tr(" ", "")
|
.tr(" ", "")
|
||||||
.split("|")
|
.split("|")
|
||||||
.each do |extension|
|
.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
|
end
|
||||||
|
|
||||||
authorized_uploads
|
authorized_uploads
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorized_images
|
def authorized_images
|
||||||
@authorized_images ||= (authorized_uploads & FileHelper.images)
|
authorized_uploads & FileHelper.images
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorized_attachments
|
def authorized_attachments
|
||||||
@authorized_attachments ||= (authorized_uploads - FileHelper.images)
|
authorized_uploads - FileHelper.images
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorizes_all_extensions?
|
||||||
|
SiteSetting.authorized_extensions.include?("*")
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorized_extensions(upload, extension, extensions)
|
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(", "))
|
message = I18n.t("upload.unauthorized", authorized_extensions: extensions.to_a.join(", "))
|
||||||
upload.errors.add(:original_filename, message)
|
upload.errors.add(:original_filename, message)
|
||||||
end
|
end
|
||||||
|
|
||||||
authorized
|
authorized
|
||||||
end
|
end
|
||||||
|
|
||||||
def maximum_file_size(upload, type)
|
def maximum_file_size(upload, type)
|
||||||
max_size_kb = SiteSetting.send("max_#{type}_size_kb").kilobytes
|
max_size_kb = SiteSetting.send("max_#{type}_size_kb").kilobytes
|
||||||
|
|
||||||
if upload.filesize > max_size_kb
|
if upload.filesize > max_size_kb
|
||||||
message = I18n.t("upload.#{type}s.too_large", max_size_kb: max_size_kb)
|
message = I18n.t("upload.#{type}s.too_large", max_size_kb: max_size_kb)
|
||||||
upload.errors.add(:filesize, message)
|
upload.errors.add(:filesize, message)
|
||||||
|
|
|
@ -28,7 +28,7 @@ describe UploadsController do
|
||||||
|
|
||||||
let(:text_file) do
|
let(:text_file) do
|
||||||
ActionDispatch::Http::UploadedFile.new({
|
ActionDispatch::Http::UploadedFile.new({
|
||||||
filename: 'LICENSE.txt',
|
filename: 'LICENSE.TXT',
|
||||||
tempfile: File.new("#{Rails.root}/LICENSE.txt")
|
tempfile: File.new("#{Rails.root}/LICENSE.txt")
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ describe UploadsController do
|
||||||
|
|
||||||
context 'when authorized' 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
|
it 'is successful with an image' do
|
||||||
xhr :post, :create, file: logo
|
xhr :post, :create, file: logo
|
||||||
|
@ -75,6 +75,22 @@ describe UploadsController do
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'with some files' do
|
context 'with some files' do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user