aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2013-12-04 17:17:51 -0800
committerRafael Mendonça França <rafaelmfranca@gmail.com>2013-12-04 17:17:51 -0800
commit4f330b042833452d590122ce524d4e06e5039216 (patch)
tree779da00d5586b082b59ff82c2c271cdc98fcdf22
parentc9223dc366f17b61d0cffeff14a7e670ece9d0d4 (diff)
parentf56e51d4e43f257b85cff3e9479564890f1317f8 (diff)
downloadrails-4f330b042833452d590122ce524d4e06e5039216.tar.gz
rails-4f330b042833452d590122ce524d4e06e5039216.tar.bz2
rails-4f330b042833452d590122ce524d4e06e5039216.zip
Merge pull request #12995 from rails/application-verifier
Add Application#message_verifier method to return a message verifier
-rw-r--r--guides/source/4_1_release_notes.md12
-rw-r--r--railties/CHANGELOG.md17
-rw-r--r--railties/lib/rails/application.rb39
-rw-r--r--railties/test/application/configuration_test.rb35
4 files changed, 97 insertions, 6 deletions
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index 6cdb28ad50..b3cd560de0 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -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
-------------
@@ -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
-------------
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 0eda858cca..166080c5b0 100644
--- a/railties/CHANGELOG.md
+++ b/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
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index d1e88cfafd..e45bfaf6fc 100644
--- a/railties/lib/rails/application.rb
+++ b/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
@@ -107,12 +108,13 @@ module Rails
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)
@@ -158,6 +160,31 @@ module Rails
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
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 03a735b1c1..722c940d8e 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -268,6 +268,41 @@ module ApplicationTests
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