Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for blacklisting certain content_types

  • Loading branch information...
commit 686f3c8ef88df928db2477227cb1d0de7a718eaf 1 parent 7f8a1a0
@ddonahue99 ddonahue99 authored
View
37 lib/paperclip/validators/attachment_content_type_validator.rb
@@ -8,21 +8,41 @@ def initialize(options)
def validate_each(record, attribute, value)
attribute = "#{attribute}_content_type".to_sym
- value = record.send(:read_attribute_for_validation, attribute)
- allowed_types = [options[:content_type]].flatten
+ value = record.send :read_attribute_for_validation, attribute
return if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
- if allowed_types.none? { |type| type === value }
- record.errors.add(attribute, :invalid, options.merge(
- :types => allowed_types.join(', ')
- ))
+ validate_whitelist(record, attribute, value)
+ validate_blacklist(record, attribute, value)
+ end
+
+ def validate_whitelist(record, attribute, value)
+ if allowed_types.present? && allowed_types.none? { |type| type === value }
+ mark_invalid record, attribute, allowed_types
+ end
+ end
+
+ def validate_blacklist(record, attribute, value)
+ if forbidden_types.present? && forbidden_types.any? { |type| type === value }
+ mark_invalid record, attribute, forbidden_types
end
end
+ def mark_invalid(record, attribute, types)
+ record.errors.add attribute, :invalid, options.merge(:types => types.join(', '))
+ end
+
+ def allowed_types
+ [options[:content_type]].flatten.compact
+ end
+
+ def forbidden_types
+ [options[:not]].flatten.compact
+ end
+
def check_validity!
- unless options.has_key?(:content_type)
- raise ArgumentError, "You must pass in :content_type to the validator"
+ unless options.has_key?(:content_type) || options.has_key?(:not)
+ raise ArgumentError, "You must pass in either :content_type or :not to the validator"
end
end
end
@@ -36,6 +56,7 @@ module HelperMethods
# may not expect. For example, JPEG images are given image/pjpeg and
# PNGs are image/x-png, so keep that in mind when determining how you
# match. Allows all by default.
+ # * +not+: Forbidden content types.
# * +message+: The message to display when the uploaded file has an invalid
# content type.
# * +if+: A lambda or name of an instance method. Validation will only
View
210 test/validators/attachment_content_type_validator_test.rb
@@ -76,93 +76,189 @@ def build_validator(options)
end
end
- context "with an allowed type" do
- context "as a string" do
- setup do
- build_validator :content_type => "image/jpg"
- @dummy.stubs(:avatar_content_type => "image/jpg")
- @validator.validate(@dummy)
- end
+ context "whitelist format" do
+ context "with an allowed type" do
+ context "as a string" do
+ setup do
+ build_validator :content_type => "image/jpg"
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
- should "not set an error message" do
- assert @dummy.errors[:avatar_content_type].blank?
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
- end
- context "as an regexp" do
- setup do
- build_validator :content_type => /^image\/.*/
- @dummy.stubs(:avatar_content_type => "image/jpg")
- @validator.validate(@dummy)
+ context "as an regexp" do
+ setup do
+ build_validator :content_type => /^image\/.*/
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
- should "not set an error message" do
- assert @dummy.errors[:avatar_content_type].blank?
+ context "as a list" do
+ setup do
+ build_validator :content_type => ["image/png", "image/jpg", "image/jpeg"]
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
end
- context "as a list" do
- setup do
- build_validator :content_type => ["image/png", "image/jpg", "image/jpeg"]
- @dummy.stubs(:avatar_content_type => "image/jpg")
- @validator.validate(@dummy)
+ context "with a disallowed type" do
+ context "as a string" do
+ setup do
+ build_validator :content_type => "image/png"
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct default error message" do
+ assert @dummy.errors[:avatar_content_type].present?
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
+ end
end
- should "not set an error message" do
- assert @dummy.errors[:avatar_content_type].blank?
+ context "as a regexp" do
+ setup do
+ build_validator :content_type => /^text\/.*/
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct default error message" do
+ assert @dummy.errors[:avatar_content_type].present?
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
+ end
+ end
+
+ context "with :message option" do
+ context "without interpolation" do
+ setup do
+ build_validator :content_type => "image/png", :message => "should be a PNG image"
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct error message" do
+ assert_includes @dummy.errors[:avatar_content_type], "should be a PNG image"
+ end
+ end
+
+ context "with interpolation" do
+ setup do
+ build_validator :content_type => "image/png", :message => "should have content type %{types}"
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct error message" do
+ assert_includes @dummy.errors[:avatar_content_type], "should have content type image/png"
+ end
+ end
end
end
end
- context "with a disallowed type" do
- context "as a string" do
- setup do
- build_validator :content_type => "image/png"
- @dummy.stubs(:avatar_content_type => "image/jpg")
- @validator.validate(@dummy)
- end
+ context "blacklist format" do
+ context "with an allowed type" do
+ context "as a string" do
+ setup do
+ build_validator :not => "image/gif"
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
- should "set a correct default error message" do
- assert @dummy.errors[:avatar_content_type].present?
- assert_includes @dummy.errors[:avatar_content_type], "is invalid"
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
- end
- context "as a regexp" do
- setup do
- build_validator :content_type => /^text\/.*/
- @dummy.stubs(:avatar_content_type => "image/jpg")
- @validator.validate(@dummy)
+ context "as an regexp" do
+ setup do
+ build_validator :not => /^text\/.*/
+ @dummy.stubs(:avatar_content_type => "image/jpg")
+ @validator.validate(@dummy)
+ end
+
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
- should "set a correct default error message" do
- assert @dummy.errors[:avatar_content_type].present?
- assert_includes @dummy.errors[:avatar_content_type], "is invalid"
+ context "as a list" do
+ setup do
+ build_validator :not => ["image/png", "image/jpg", "image/jpeg"]
+ @dummy.stubs(:avatar_content_type => "image/gif")
+ @validator.validate(@dummy)
+ end
+
+ should "not set an error message" do
+ assert @dummy.errors[:avatar_content_type].blank?
+ end
end
end
- context "with :message option" do
- context "without interpolation" do
+ context "with a disallowed type" do
+ context "as a string" do
setup do
- build_validator :content_type => "image/png", :message => "should be a PNG image"
- @dummy.stubs(:avatar_content_type => "image/jpg")
+ build_validator :not => "image/png"
+ @dummy.stubs(:avatar_content_type => "image/png")
@validator.validate(@dummy)
end
- should "set a correct error message" do
- assert_includes @dummy.errors[:avatar_content_type], "should be a PNG image"
+ should "set a correct default error message" do
+ assert @dummy.errors[:avatar_content_type].present?
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
end
end
- context "with interpolation" do
+ context "as a regexp" do
setup do
- build_validator :content_type => "image/png", :message => "should have content type %{types}"
- @dummy.stubs(:avatar_content_type => "image/jpg")
+ build_validator :not => /^text\/.*/
+ @dummy.stubs(:avatar_content_type => "text/plain")
@validator.validate(@dummy)
end
- should "set a correct error message" do
- assert_includes @dummy.errors[:avatar_content_type], "should have content type image/png"
+ should "set a correct default error message" do
+ assert @dummy.errors[:avatar_content_type].present?
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
+ end
+ end
+
+ context "with :message option" do
+ context "without interpolation" do
+ setup do
+ build_validator :not => "image/png", :message => "should not be a PNG image"
+ @dummy.stubs(:avatar_content_type => "image/png")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct error message" do
+ assert_includes @dummy.errors[:avatar_content_type], "should not be a PNG image"
+ end
+ end
+
+ context "with interpolation" do
+ setup do
+ build_validator :not => "image/png", :message => "should not have content type %{types}"
+ @dummy.stubs(:avatar_content_type => "image/png")
+ @validator.validate(@dummy)
+ end
+
+ should "set a correct error message" do
+ assert_includes @dummy.errors[:avatar_content_type], "should not have content type image/png"
+ end
end
end
end
@@ -185,8 +281,12 @@ def build_validator(options)
end
end
- should "not raise arguemnt error if :content_type was given" do
+ should "not raise argument error if :content_type was given" do
build_validator :content_type => "image/jpg"
end
+
+ should "not raise argument error if :not was given" do
+ build_validator :not => "image/jpg"
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.