Skip to content

Commit

Permalink
Merge pull request #12995 from rails/application-verifier
Browse files Browse the repository at this point in the history
Add Application#message_verifier method to return a message verifier
  • Loading branch information
rafaelfranca committed Dec 5, 2013
2 parents c9223dc + f56e51d commit 4f330b0
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 6 deletions.
12 changes: 12 additions & 0 deletions guides/source/4_1_release_notes.md
Expand Up @@ -124,6 +124,17 @@ See
[active_record/enum.rb](https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/enum.rb#L2-L42)
for a detailed write up.

### Application message verifier.

Create a message verifier that can be used to generate and verify signed
messages in the application.

```ruby
message = Rails.application.message_verifier('salt').generate('my sensible data')
Rails.application.message_verifier('salt').verify(message)
# => 'my sensible data'
```

Documentation
-------------

Expand Down Expand Up @@ -164,6 +175,7 @@ for detailed changes.

* Exposed `MiddlewareStack#unshift` to environment configuration. ([Pull Request](https://github.com/rails/rails/pull/12479))

* Add `Application#message_verifier` method to return a message verifier. ([Pull Request](https://github.com/rails/rails/pull/12995))

Action Mailer
-------------
Expand Down
17 changes: 17 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,20 @@
* Add `Application#message_verifier` method to return a message verifier.

This verifier can be used to generate and verify signed messages in the application.

message = Rails.application.message_verifier('salt').generate('my sensible data')
Rails.application.message_verifier('salt').verify(message)
# => 'my sensible data'

It is recommended not to use the same verifier for different things, so you can get different
verifiers passing the name argument.

message = Rails.application.message_verifier('cookies').generate('my sensible cookie data')

See the `ActiveSupport::MessageVerifier` documentation for more information.

*Rafael Mendonça França*

* The [Spring application
preloader](https://github.com/jonleighton/spring) is now installed
by default for new applications. It uses the development group of
Expand Down
39 changes: 33 additions & 6 deletions railties/lib/rails/application.rb
@@ -1,6 +1,7 @@
require 'fileutils'
require 'active_support/core_ext/object/blank'
require 'active_support/key_generator'
require 'active_support/message_verifier'
require 'rails/engine'

module Rails
Expand Down Expand Up @@ -107,12 +108,13 @@ def inherited(base)

def initialize(initial_variable_values = {}, &block)
super()
@initialized = false
@reloaders = []
@routes_reloader = nil
@app_env_config = nil
@ordered_railties = nil
@railties = nil
@initialized = false
@reloaders = []
@routes_reloader = nil
@app_env_config = nil
@ordered_railties = nil
@railties = nil
@message_verifiers = {}

add_lib_to_load_path!
ActiveSupport.run_load_hooks(:before_configuration, self)
Expand Down Expand Up @@ -158,6 +160,31 @@ def key_generator
end
end

# Returns a message verifier object.
#
# This verifier can be used to generate and verify signed messages in the application.
#
# It is recommended not to use the same verifier for different things, so you can get different
# verifiers passing the +verifier_name+ argument.
#
# ==== Parameters
#
# * +salt+ - the salt that will be used to generate the secret key of the verifier.
#
# ==== Examples
#
# message = Rails.application.message_verifier('salt').generate('my sensible data')
# Rails.application.message_verifier('salt').verify(message)
# # => 'my sensible data'
#
# See the +ActiveSupport::MessageVerifier+ documentation for more information.
def message_verifier(salt)
@message_verifiers[salt] ||= begin
secret = key_generator.generate_key(salt)
ActiveSupport::MessageVerifier.new(secret)
end
end

# Stores some of the Rails initial environment parameters which
# will be used by middlewares and engines to configure themselves.
def env_config
Expand Down
35 changes: 35 additions & 0 deletions railties/test/application/configuration_test.rb
Expand Up @@ -268,6 +268,41 @@ def index
assert_equal 'some_value', verifier.verify(last_response.body)
end

test "application verifier can be used in the entire application" do
make_basic_app do |app|
app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
app.config.session_store :disabled
end

message = app.message_verifier('salt').generate("some_value")

assert_equal 'some_value', Rails.application.message_verifier('salt').verify(message)

secret = app.key_generator.generate_key('salt')
verifier = ActiveSupport::MessageVerifier.new(secret)
assert_equal 'some_value', verifier.verify(message)
end

test "application verifier can build different verifiers" do
make_basic_app do |app|
app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
app.config.session_store :disabled
end

default_verifier = app.message_verifier('salt')
text_verifier = app.message_verifier('text')

message = text_verifier.generate('some_value')

assert_equal 'some_value', text_verifier.verify(message)
assert_raises ActiveSupport::MessageVerifier::InvalidSignature do
default_verifier.verify(message)
end

assert_equal default_verifier.object_id, app.message_verifier('salt').object_id
assert_not_equal default_verifier.object_id, text_verifier.object_id
end

test "protect from forgery is the default in a new app" do
make_basic_app

Expand Down

0 comments on commit 4f330b0

Please sign in to comment.