2014-04-15 04:55:57 +08:00
|
|
|
require_dependency "file_helper"
|
|
|
|
|
|
|
|
module Validators; end
|
|
|
|
|
|
|
|
class Validators::UploadValidator < ActiveModel::Validator
|
|
|
|
|
|
|
|
def validate(upload)
|
2016-08-03 23:55:54 +08:00
|
|
|
# check the attachment blacklist
|
2016-06-28 04:26:05 +08:00
|
|
|
if upload.is_attachment_for_group_message && SiteSetting.allow_all_attachments_for_group_messages
|
2016-08-03 23:55:54 +08:00
|
|
|
return upload.original_filename =~ SiteSetting.attachment_filename_blacklist_regex
|
2016-06-28 04:26:05 +08:00
|
|
|
end
|
2016-03-01 05:39:24 +08:00
|
|
|
|
2014-07-15 09:15:17 +08:00
|
|
|
extension = File.extname(upload.original_filename)[1..-1] || ""
|
2014-04-15 04:55:57 +08:00
|
|
|
|
|
|
|
if is_authorized?(upload, extension)
|
|
|
|
if FileHelper.is_image?(upload.original_filename)
|
|
|
|
authorized_image_extension(upload, extension)
|
|
|
|
maximum_image_file_size(upload)
|
|
|
|
else
|
|
|
|
authorized_attachment_extension(upload, extension)
|
|
|
|
maximum_attachment_file_size(upload)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def is_authorized?(upload, extension)
|
2017-05-10 05:20:28 +08:00
|
|
|
authorized_extensions(upload, extension, authorized_uploads(upload))
|
2014-04-15 04:55:57 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def authorized_image_extension(upload, extension)
|
2017-05-10 05:20:28 +08:00
|
|
|
authorized_extensions(upload, extension, authorized_images(upload))
|
2014-04-15 04:55:57 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def maximum_image_file_size(upload)
|
|
|
|
maximum_file_size(upload, "image")
|
|
|
|
end
|
|
|
|
|
|
|
|
def authorized_attachment_extension(upload, extension)
|
2017-05-10 05:20:28 +08:00
|
|
|
authorized_extensions(upload, extension, authorized_attachments(upload))
|
2014-04-15 04:55:57 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def maximum_attachment_file_size(upload)
|
|
|
|
maximum_file_size(upload, "attachment")
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
def authorized_uploads(upload)
|
2014-04-15 04:55:57 +08:00
|
|
|
authorized_uploads = Set.new
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
extensions = upload.for_theme ? SiteSetting.theme_authorized_extensions : SiteSetting.authorized_extensions
|
|
|
|
|
|
|
|
extensions
|
2016-10-21 01:53:41 +08:00
|
|
|
.gsub(/[\s\.]+/, "")
|
|
|
|
.downcase
|
2014-04-15 04:55:57 +08:00
|
|
|
.split("|")
|
2016-10-21 01:53:41 +08:00
|
|
|
.each { |extension| authorized_uploads << extension unless extension.include?("*") }
|
2014-04-15 04:55:57 +08:00
|
|
|
|
|
|
|
authorized_uploads
|
|
|
|
end
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
def authorized_images(upload)
|
|
|
|
authorized_uploads(upload) & FileHelper.images
|
2014-04-15 04:55:57 +08:00
|
|
|
end
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
def authorized_attachments(upload)
|
|
|
|
authorized_uploads(upload) - FileHelper.images
|
2014-04-30 01:12:35 +08:00
|
|
|
end
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
def authorizes_all_extensions?(upload)
|
|
|
|
extensions = upload.for_theme ? SiteSetting.theme_authorized_extensions : SiteSetting.authorized_extensions
|
|
|
|
extensions.include?("*")
|
2014-04-15 04:55:57 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def authorized_extensions(upload, extension, extensions)
|
2017-05-10 05:20:28 +08:00
|
|
|
return true if authorizes_all_extensions?(upload)
|
2014-04-30 01:12:35 +08:00
|
|
|
|
|
|
|
unless authorized = extensions.include?(extension.downcase)
|
2014-04-15 04:55:57 +08:00
|
|
|
message = I18n.t("upload.unauthorized", authorized_extensions: extensions.to_a.join(", "))
|
|
|
|
upload.errors.add(:original_filename, message)
|
|
|
|
end
|
2014-04-30 01:12:35 +08:00
|
|
|
|
2014-04-15 04:55:57 +08:00
|
|
|
authorized
|
|
|
|
end
|
|
|
|
|
|
|
|
def maximum_file_size(upload, type)
|
2015-05-04 01:26:54 +08:00
|
|
|
max_size_kb = SiteSetting.send("max_#{type}_size_kb")
|
|
|
|
max_size_bytes = max_size_kb.kilobytes
|
2014-04-30 01:12:35 +08:00
|
|
|
|
2015-05-04 01:26:54 +08:00
|
|
|
if upload.filesize > max_size_bytes
|
2014-04-15 04:55:57 +08:00
|
|
|
message = I18n.t("upload.#{type}s.too_large", max_size_kb: max_size_kb)
|
|
|
|
upload.errors.add(:filesize, message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|