README.md in file_validators-1.1.0 vs README.md in file_validators-1.2.0
- old
+ new
@@ -1,20 +1,25 @@
# File Validators
-[![Gem Version](http://img.shields.io/gem/v/file_validators.svg)](https://rubygems.org/gems/file_validators)
+[![Gem Version](https://badge.fury.io/rb/file_validators.svg)](http://badge.fury.io/rb/file_validators)
[![Build Status](https://travis-ci.org/musaffa/file_validators.svg)](https://travis-ci.org/musaffa/file_validators)
-[![Dependency Status](http://img.shields.io/gemnasium/musaffa/file_validators.svg)](https://gemnasium.com/musaffa/file_validators)
-[![Coverage Status](http://img.shields.io/coveralls/musaffa/file_validators.svg)](https://coveralls.io/r/musaffa/file_validators)
-[![Code Climate](http://img.shields.io/codeclimate/github/musaffa/file_validators.svg)](https://codeclimate.com/github/musaffa/file_validators)
+[![Dependency Status](https://gemnasium.com/musaffa/file_validators.svg)](https://gemnasium.com/musaffa/file_validators)
+[![Coverage Status](https://coveralls.io/repos/musaffa/file_validators/badge.png)](https://coveralls.io/r/musaffa/file_validators)
+[![Code Climate](https://codeclimate.com/github/musaffa/file_validators/badges/gpa.svg)](https://codeclimate.com/github/musaffa/file_validators)
+[![Inline docs](http://inch-ci.org/github/musaffa/file_validators.svg)](http://inch-ci.org/github/musaffa/file_validators)
-File Validators gem adds file size and content type validations to ActiveModel. Any module that uses ActiveModel, for example ActiveRecord, can use these file validators.
+File Validators gem adds file size and content type validations to ActiveModel.
+Any module that uses ActiveModel, for example ActiveRecord, can use these file validators.
## Support
* ActiveModel versions: 3 and 4.
* Rails versions: 3 and 4.
+It has been tested to work with Carrierwave, Paperclip, Dragonfly etc file uploading solutions.
+Validations works both before and after uploads.
+
## Installation
Add the following to your Gemfile:
```ruby
@@ -29,22 +34,24 @@
class Profile
include ActiveModel::Validations
attr_accessor :avatar
validates :avatar, file_size: { less_than_or_equal_to: 100.kilobytes },
- file_content_type: { allow: ['image/jpeg', 'image/png', 'image/gif'] }
+ file_content_type: { allow: ['image/jpeg', 'image/png'] }
end
```
ActiveRecord example:
```ruby
class Profile < ActiveRecord::Base
validates :avatar, file_size: { less_than_or_equal_to: 100.kilobytes },
- file_content_type: { allow: ['image/jpeg', 'image/png', 'image/gif'] }
+ file_content_type: { allow: ['image/jpeg', 'image/png'] }
end
```
+You can also use `:validates_file_size` and `:validates_file_content_type` idioms.
+
## API
### File Size Validator:
* `in`: A range of bytes or a proc that returns a range
@@ -71,15 +78,15 @@
With `:in` you will get `min` and `max` as replacements.
`count`, `min` and `max` each will have its value and unit together.
You can write error messages without using any replacement.
```ruby
validates :avatar, file_size: { less_than: 100.kilobytes,
- message: 'avatar file size should be less than %{count}' }
+ message: 'avatar should be less than %{count}' }
```
```ruby
validates :document, file_size: { in: 1.kilobyte..1.megabyte,
- message: 'document should be within %{min} and %{max}' }
+ message: 'must be within %{min} and %{max}' }
```
* `if`: A lambda or name of an instance method. Validation will only be run if this lambda or method returns true.
* `unless`: Same as `if` but validates if lambda or method returns false.
You can combine different options.
@@ -101,18 +108,18 @@
validates :avatar, file_size: { less_than: lambda { |record| record.size_in_bytes } }
```
### File Content Type Validator
-* `allow`: Allowed content types. Can be a single content type or an array. Each type can be a String or a Regexp. It also accepts proc. Allows all by default.
+* `allow`: Allowed content types. Can be a single content type or an array. Each type can be a String or a Regexp. It also accepts `proc`. Allows all by default.
```ruby
# string
validates :avatar, file_content_type: { allow: 'image/jpeg' }
```
```ruby
# array of strings
-validates :attachment, file_content_type: { allow: ['image/jpeg', 'image/png', 'text/plain'] }
+validates :attachment, file_content_type: { allow: ['image/jpeg', 'text/plain'] }
```
```ruby
# regexp
validates :avatar, file_content_type: { allow: /^image\/.*/ }
```
@@ -131,34 +138,48 @@
* `exclude`: Forbidden content types. Can be a single content type or an array. Each type can be a String or a Regexp. It also accepts `proc`. See `:allow` options examples.
* `message`: The message to display when the uploaded file has an invalid content type.
You will get `types` as a replacement. You can write error messages without using any replacement.
```ruby
validates :avatar, file_content_type: { allow: ['image/jpeg', 'image/gif'],
- message: 'should have content type %{types}' }
+ message: 'only %{types} are allowed' }
```
```ruby
validates :avatar, file_content_type: { allow: ['image/jpeg', 'image/gif'],
- message: 'Avatar only allows jpeg and gif image files' }
+ message: 'Avatar only allows jpeg and gif' }
```
* `if`: A lambda or name of an instance method. Validation will only be run is this lambda or method returns true.
* `unless`: Same as `if` but validates if lambda or method returns false.
You can combine `:allow` and `:exclude`:
```ruby
# this will allow all the image types except png and gif
validates :avatar, file_content_type: { allow: /^image\/.*/, exclude: ['image/png', 'image/gif'] }
```
+## Security
+
+This gem uses file command to get the content type based on the content of the file rather
+than the extension. This prevents fake content types inserted in the request header.
+
+It also prevents file media type spoofing. For example, user may upload a .html document as
+a part of the EXIF header of a valid JPEG file. Content type validator will identify its content type
+as `image/jpeg` and, without spoof detection, it may pass the validation and be saved as .html document
+thus exposing your application to a security vulnerability. Media type spoof detector wont let that happen. It will not allow a file having `image/jpeg` content type to be saved as `text/plain`. It checks only media type mismatch, for example `text` of `text/plain` and `image` of `image/jpeg`. So it will not prevent `image/jpeg` from saving as `image/png` as both have the same `image` media type.
+
+**note**: Media type spoof detection is integrated in the [content type validator](#file-content-type-validator). This means without content type validation spoof detection wont be enabled.
+
## i18n Translations
File Size Errors
* `file_size_is_in`: takes `min` and `max` as replacements
* `file_size_is_less_than`: takes `count` as replacement
* `file_size_is_less_than_or_equal_to`: takes `count` as replacement
* `file_size_is_greater_than`: takes `count` as replacement
* `file_size_is_greater_than_or_equal_to`: takes `count` as replacement
Content Type Errors
+* `spoofed_file_media_type`: generated when file media type from its extension doesn't match the media type of its
+content. learn more from [security](#Security).
* `allowed_file_content_types`: generated when you have specified allowed types but the content type
of the file doesn't match. takes `types` as replacement.
* `excluded_file_content_types`: generated when you have specified excluded types and the content type
of the file matches anyone of them. takes `types` as replacement.