##// END OF EJS Templates
Option to specify allowed extensions for a file custom field (#6719)....
Jean-Philippe Lang -
r15539:f94711ea8c99
parent child
Show More
@@ -354,22 +354,37 class Attachment < ActiveRecord::Base
354 354 end
355 355 end
356 356
357 # Returns true if the extension is allowed, otherwise false
357 # Returns true if the extension is allowed regarding allowed/denied
358 # extensions defined in application settings, otherwise false
358 359 def self.valid_extension?(extension)
359 extension = extension.downcase.sub(/\A\.+/, '')
360
361 360 denied, allowed = [:attachment_extensions_denied, :attachment_extensions_allowed].map do |setting|
362 Setting.send(setting).to_s.split(",").map {|s| s.strip.downcase.sub(/\A\.+/, '')}.reject(&:blank?)
361 Setting.send(setting)
363 362 end
364 if denied.present? && denied.include?(extension)
363 if denied.present? && extension_in?(extension, denied)
365 364 return false
366 365 end
367 unless allowed.blank? || allowed.include?(extension)
366 if allowed.present? && !extension_in?(extension, allowed)
368 367 return false
369 368 end
370 369 true
371 370 end
372 371
372 # Returns true if extension belongs to extensions list.
373 def self.extension_in?(extension, extensions)
374 extension = extension.downcase.sub(/\A\.+/, '')
375
376 unless extensions.is_a?(Array)
377 extensions = extensions.to_s.split(",").map(&:strip)
378 end
379 extensions = extensions.map {|s| s.downcase.sub(/\A\.+/, '')}.reject(&:blank?)
380 extensions.include?(extension)
381 end
382
383 # Returns true if attachment's extension belongs to extensions list.
384 def extension_in?(extensions)
385 self.class.extension_in?(File.extname(filename), extensions)
386 end
387
373 388 private
374 389
375 390 # Physically deletes the file from the file system
@@ -87,7 +87,8 class CustomField < ActiveRecord::Base
87 87 'text_formatting',
88 88 'edit_tag_style',
89 89 'user_role',
90 'version_status'
90 'version_status',
91 'extensions_allowed'
91 92
92 93 def format
93 94 @format ||= Redmine::FieldFormat.find(field_format)
@@ -0,0 +1,4
1 <p>
2 <%= f.text_field :extensions_allowed, :size => 50, :label => :setting_attachment_extensions_allowed %>
3 <em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: txt, png</em>
4 </p>
@@ -861,6 +861,7 module Redmine
861 861 self.form_partial = 'custom_fields/formats/attachment'
862 862 self.is_filter_supported = false
863 863 self.change_no_details = true
864 field_attributes :extensions_allowed
864 865
865 866 def set_custom_field_value(custom_field, custom_field_value, value)
866 867 attachment_present = false
@@ -917,8 +918,18 module Redmine
917 918 def validate_custom_value(custom_value)
918 919 errors = []
919 920
920 if custom_value.instance_variable_get("@attachment_present") && custom_value.value.blank?
921 errors << ::I18n.t('activerecord.errors.messages.invalid')
921 if custom_value.value.blank?
922 if custom_value.instance_variable_get("@attachment_present")
923 errors << ::I18n.t('activerecord.errors.messages.invalid')
924 end
925 else
926 if custom_value.value.present?
927 attachment = Attachment.where(:id => custom_value.value.to_s).first
928 extensions = custom_value.custom_field.extensions_allowed
929 if attachment && extensions.present? && !attachment.extension_in?(extensions)
930 errors << "#{::I18n.t('activerecord.errors.messages.invalid')} (#{l(:setting_attachment_extensions_allowed)}: #{extensions})"
931 end
932 end
922 933 end
923 934
924 935 errors.uniq
@@ -153,4 +153,42 class AttachmentFieldFormatTest < Redmine::IntegrationTest
153 153 assert_equal attachment.id.to_s, custom_value.value
154 154 assert_equal custom_value, attachment.reload.container
155 155 end
156
157 def test_create_with_valid_extension
158 @field.extensions_allowed = "txt, log"
159 @field.save!
160
161 attachment = new_record(Attachment) do
162 assert_difference 'Issue.count' do
163 post '/projects/ecookbook/issues', {
164 :issue => {
165 :subject => "Blank",
166 :custom_field_values => {
167 @field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
168 }
169 }
170 }
171 assert_response 302
172 end
173 end
174 end
175
176 def test_create_with_invalid_extension_should_fail
177 @field.extensions_allowed = "png, jpeg"
178 @field.save!
179
180 attachment = new_record(Attachment) do
181 assert_no_difference 'Issue.count' do
182 post '/projects/ecookbook/issues', {
183 :issue => {
184 :subject => "Blank",
185 :custom_field_values => {
186 @field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
187 }
188 }
189 }
190 assert_response :success
191 end
192 end
193 end
156 194 end
General Comments 0
You need to be logged in to leave comments. Login now