Commit dfd256f2 authored by Stan Hu's avatar Stan Hu

Support configurable attachment size via Application Settings

Fix bug where error messages from Dropzone would not be displayed on the issues page

Closes #1258
parent 16a6ea2d
Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased)
- Fix bug where error messages from Dropzone would not be displayed on the issues page (Stan Hu)
- Fix broken side-by-side diff view on merge request page (Stan Hu)
- Set Application controller default URL options to ensure all url_for calls are consistent (Stan Hu)
- Allow HTML tags in Markdown input
- Fix code unfold not working on Compare commits page (Stan Hu)
- Fix dots in Wiki slugs causing errors (Stan Hu)
- Make maximum attachment size configurable via Application Settings (Stan Hu)
- Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
- Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- Disable reference creation for comments surrounded by code/preformatted blocks (Stan Hu)
......
......@@ -10,6 +10,7 @@ class @DropzoneInput
iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>"
btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>"
project_uploads_path = window.project_uploads_path or null
max_file_size = gon.max_file_size or 10
form_textarea = $(form).find("textarea.markdown-area")
form_textarea.wrap "<div class=\"div-dropzone\"></div>"
......@@ -76,7 +77,7 @@ class @DropzoneInput
dictDefaultMessage: ""
clickable: true
paramName: "file"
maxFilesize: 10
maxFilesize: max_file_size
uploadMultiple: false
headers:
"X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")
......@@ -108,9 +109,10 @@ class @DropzoneInput
return
error: (temp, errorMessage) ->
checkIfMsgExists = $(".error-alert").children().length
errorAlert = $(form).find('.error-alert')
checkIfMsgExists = errorAlert.children().length
if checkIfMsgExists is 0
$(".error-alert").append divAlert
errorAlert.append divAlert
$(".div-dropzone-alert").append btnAlert + errorMessage
return
......@@ -221,9 +223,10 @@ class @DropzoneInput
"display": "none"
showError = (message) ->
checkIfMsgExists = $(".error-alert").children().length
errorAlert = $(form).find('.error-alert')
checkIfMsgExists = errorAlert.children().length
if checkIfMsgExists is 0
$(".error-alert").append divAlert
errorAlert.append divAlert
$(".div-dropzone-alert").append btnAlert + message
closeAlertMessage = ->
......
......@@ -38,6 +38,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:twitter_sharing_enabled,
:sign_in_text,
:home_page_url,
:max_attachment_size,
restricted_visibility_levels: []
)
end
......
......@@ -203,6 +203,7 @@ class ApplicationController < ActionController::Base
gon.api_version = API::API.version
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
gon.max_file_size = current_application_settings.max_attachment_size;
if current_user
gon.current_user_id = current_user.id
......
......@@ -16,6 +16,7 @@
# default_branch_protection :integer default(2)
# twitter_sharing_enabled :boolean default(TRUE)
# restricted_visibility_levels :text
# max_attachment_size :integer default(10)
#
class ApplicationSetting < ActiveRecord::Base
......@@ -49,7 +50,8 @@ class ApplicationSetting < ActiveRecord::Base
twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'],
gravatar_enabled: Settings.gravatar['enabled'],
sign_in_text: Settings.extra['sign_in_text'],
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels']
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
max_attachment_size: Settings.gitlab['max_attachment_size']
)
end
......
......@@ -22,6 +22,7 @@ require 'file_size_validator'
class Note < ActiveRecord::Base
include Mentionable
include Gitlab::CurrentSettings
default_value_for :system, false
......@@ -36,7 +37,8 @@ class Note < ActiveRecord::Base
validates :note, :project, presence: true
validates :line_code, format: { with: /\A[a-z0-9]+_\d+_\d+\Z/ }, allow_blank: true
validates :attachment, file_size: { maximum: 10.megabytes.to_i }
# Attachments are deprecated and are handled by Markdown uploader
validates :attachment, file_size: { maximum: :max_attachment_size }
validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' }
validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' }
......@@ -321,6 +323,10 @@ class Note < ActiveRecord::Base
end
end
def max_attachment_size
current_application_settings.max_attachment_size.megabytes.to_i
end
def commit_author
@commit_author ||=
project.team.users.find_by(email: noteable.author_email) ||
......
......@@ -5,7 +5,7 @@ module Projects
end
def execute
return nil unless @file
return nil unless @file and @file.size <= max_attachment_size
uploader = FileUploader.new(@project)
uploader.store!(@file)
......@@ -18,5 +18,11 @@ module Projects
'is_image' => uploader.image?
}
end
private
def max_attachment_size
current_application_settings.max_attachment_size.megabytes.to_i
end
end
end
......@@ -60,5 +60,10 @@
.col-sm-10
= f.text_area :sign_in_text, class: 'form-control', rows: 4
.help-block Markdown enabled
.form-group
= f.label :max_attachment_size, 'Maximum attachment size (MB)', class: 'control-label col-sm-2'
.col-sm-10
= f.number_field :max_attachment_size, class: 'form-control'
.form-actions
= f.submit 'Save', class: 'btn btn-primary'
......@@ -12,7 +12,7 @@
.comment-hints.clearfix
.pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }}
.pull-right Attach files by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }.
.error-alert
.note-form-actions
.buttons
......
......@@ -119,6 +119,7 @@ Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username
Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil?
Settings.gitlab['default_projects_features'] ||= {}
Settings.gitlab['webhook_timeout'] ||= 10
Settings.gitlab['max_attachment_size'] ||= 10
Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil?
Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.gitlab.default_projects_features['merge_requests'].nil?
Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil?
......
class AddMaxAttachmentSizeToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :max_attachment_size, :integer, default: 10, null: false
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150324155957) do
ActiveRecord::Schema.define(version: 20150328132231) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -28,6 +28,7 @@ ActiveRecord::Schema.define(version: 20150324155957) do
t.integer "default_branch_protection", default: 2
t.boolean "twitter_sharing_enabled", default: true
t.text "restricted_visibility_levels"
t.integer "max_attachment_size", default: 10, null: false
end
create_table "broadcast_messages", force: true do |t|
......
......@@ -42,6 +42,7 @@ Feature: Project Issues
Given I visit issue page "Release 0.4"
And I leave a comment like "XML attached"
Then I should see comment "XML attached"
And I should see an error alert section within the comment form
@javascript
Scenario: I search issue
......
......@@ -204,6 +204,12 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
step 'I should see an error alert section within the comment form' do
within(".js-main-target-form") do
find(".error-alert")
end
end
step 'The code block should be unchanged' do
page.should have_content("```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```")
end
......
......@@ -25,8 +25,8 @@ class FileSizeValidator < ActiveModel::EachValidator
keys.each do |key|
value = options[key]
unless value.is_a?(Integer) && value >= 0
raise ArgumentError, ":#{key} must be a nonnegative Integer"
unless (value.is_a?(Integer) && value >= 0) || value.is_a?(Symbol)
raise ArgumentError, ":#{key} must be a nonnegative Integer or symbol"
end
end
end
......@@ -39,6 +39,14 @@ class FileSizeValidator < ActiveModel::EachValidator
CHECKS.each do |key, validity_check|
next unless check_value = options[key]
check_value =
case check_value
when Integer
check_value
when Symbol
record.send(check_value)
end
value ||= [] if key == :maximum
value_size = value.size
......
......@@ -20,7 +20,8 @@ module Gitlab
signin_enabled: Settings.gitlab['signin_enabled'],
gravatar_enabled: Settings.gravatar['enabled'],
sign_in_text: Settings.extra['sign_in_text'],
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels']
restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
max_attachment_size: Settings.gitlab['max_attachment_size']
)
end
end
......
require 'spec_helper'
describe 'Gitlab::FileSizeValidatorSpec' do
let(:validator) { FileSizeValidator.new(options) }
let(:attachment) { AttachmentUploader.new }
let(:note) { create(:note) }
describe 'options uses an integer' do
let(:options) { { maximum: 10, attributes: { attachment: attachment } } }
it 'attachment exceeds maximum limit' do
allow(attachment).to receive(:size) { 100 }
validator.validate_each(note, :attachment, attachment)
expect(note.errors).to have_key(:attachment)
end
it 'attachment under maximum limit' do
allow(attachment).to receive(:size) { 1 }
validator.validate_each(note, :attachment, attachment)
expect(note.errors).not_to have_key(:attachment)
end
end
describe 'options uses a symbol' do
let(:options) { { maximum: :test,
attributes: { attachment: attachment } } }
before do
allow(note).to receive(:test) { 10 }
end
it 'attachment exceeds maximum limit' do
allow(attachment).to receive(:size) { 100 }
validator.validate_each(note, :attachment, attachment)
expect(note.errors).to have_key(:attachment)
end
it 'attachment under maximum limit' do
allow(attachment).to receive(:size) { 1 }
validator.validate_each(note, :attachment, attachment)
expect(note.errors).not_to have_key(:attachment)
end
end
end
......@@ -67,6 +67,16 @@ describe Projects::UploadService do
it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") }
it { expect(@link_to_file['url']).to match('doc_sample.txt') }
end
context 'for too large a file' do
before do
txt = fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain')
allow(txt).to receive(:size) { 1000.megabytes.to_i }
@link_to_file = upload_file(@project.repository, txt)
end
it { expect(@link_to_file).to eq(nil) }
end
end
def upload_file(repository, file)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment