SignedCookieJar and PermanentCookieJar properly delegate everything to parent_jar #6745

Closed
wants to merge 3 commits into from
View
57 actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -293,13 +293,47 @@ def write_cookie?(cookie)
end
end
- class PermanentCookieJar < CookieJar #:nodoc:
+ class ProxyCookieJar #:nodoc:
def initialize(parent_jar, key_generator, options = {})
@parent_jar = parent_jar
@key_generator = key_generator
@options = options
end
+ def is_a?(klass)
+ super || @parent_jar.is_a?(klass)
+ end
+
+ def permanent
+ if is_a? PermanentCookieJar
+ self
+ else
+ @permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
+ end
+ end
+
+ def signed
+ if is_a? SignedCookieJar
+ self
+ else
+ @signed ||= SignedCookieJar.new(self, @key_generator, @options)
+ end
+ end
+
+ def encrypted
+ if is_a? EncryptedCookieJar
+ self
+ else
+ @encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
+ end
+ end
+
+ def method_missing(method, *arguments, &block)
+ @parent_jar.send(method, *arguments, &block)
+ end
+ end
+
+ class PermanentCookieJar < ProxyCookieJar #:nodoc:
def []=(key, options)
if options.is_a?(Hash)
options.symbolize_keys!
@@ -310,20 +344,15 @@ def []=(key, options)
options[:expires] = 20.years.from_now
@parent_jar[key] = options
end
-
- def method_missing(method, *arguments, &block)
- @parent_jar.send(method, *arguments, &block)
- end
end
- class SignedCookieJar < CookieJar #:nodoc:
+ class SignedCookieJar < ProxyCookieJar #:nodoc:
MAX_COOKIE_SIZE = 4096 # Cookies can typically store 4096 bytes.
def initialize(parent_jar, key_generator, options = {})
- @parent_jar = parent_jar
- @options = options
+ super
secret = key_generator.generate_key(@options[:signed_cookie_salt])
- @verifier = ActiveSupport::MessageVerifier.new(secret)
+ @verifier = ActiveSupport::MessageVerifier.new(secret)
end
def [](name)
@@ -345,10 +374,6 @@ def []=(key, options)
raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
@parent_jar[key] = options
end
-
- def method_missing(method, *arguments, &block)
- @parent_jar.send(method, *arguments, &block)
- end
end
class EncryptedCookieJar < SignedCookieJar #:nodoc:
@@ -358,8 +383,8 @@ def initialize(parent_jar, key_generator, options = {})
"Set config.secret_key_base in config/initializers/secret_token.rb"
end
- @parent_jar = parent_jar
- @options = options
+ super
+
secret = key_generator.generate_key(@options[:encrypted_cookie_salt])
sign_secret = key_generator.generate_key(@options[:encrypted_signed_cookie_salt])
@encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
@@ -370,7 +395,7 @@ def [](name)
@encryptor.decrypt_and_verify(encrypted_message)
end
rescue ActiveSupport::MessageVerifier::InvalidSignature,
- ActiveSupport::MessageVerifier::InvalidMessage
+ ActiveSupport::MessageEncryptor::InvalidMessage
nil
end
View
59 actionpack/test/dispatch/cookies_test.rb
@@ -94,6 +94,27 @@ def delete_and_set_cookie
head :ok
end
+ def delete_signed_cookie
+ cookies.signed.delete :user_name
+ head :ok
+ end
+
+ def delete_permanent_cookie
+ cookies.permanent.delete :user_name
+ head :ok
+ end
+
+ def clear_encrypted_cookie
+ cookies.encrypted.clear
+ head :ok
+ end
+
+ def delete_and_set_signed_permanent_encrypted_cookie
+ cookies.signed.permanent.encrypted.delete :user_name
+ cookies.signed.permanent.encrypted[:user_surname] = 'Smith'
+ head :ok
+ end
+
def set_cookie_with_domain
cookies[:user_name] = {:value => "rizwanreza", :domain => :all}
head :ok
@@ -327,6 +348,44 @@ def test_permanent_signed_cookie
assert_equal 100, @controller.send(:cookies).signed[:remember_me]
end
+ def test_delete_signed_cookie
+ @controller.send(:cookies).signed[:user_name] = 'Joe'
+ get :delete_signed_cookie
+ assert_nil @controller.send(:cookies).signed[:user_name]
+ assert_nil @controller.send(:cookies)[:user_name]
+ assert @controller.send(:cookies).deleted?(:user_name)
+ assert @controller.send(:cookies).signed.deleted?(:user_name)
+ end
+
+ def test_delete_permanent_cookie
+ @controller.send(:cookies).permanent[:user_name] = 'Joe'
+ get :delete_permanent_cookie
+ assert_nil @controller.send(:cookies).permanent[:user_name]
+ assert_nil @controller.send(:cookies)[:user_name]
+ assert @controller.send(:cookies).deleted?(:user_name)
+ assert @controller.send(:cookies).permanent.deleted?(:user_name)
+ end
+
+ def test_clear_encrypted_cookie
+ @controller.send(:cookies).permanent[:user_name] = 'Joe'
+ @controller.send(:cookies).permanent[:user_surname] = 'Smith'
+ get :clear_encrypted_cookie
+ assert_nil @controller.send(:cookies)[:user_name]
+ assert_nil @controller.send(:cookies)[:user_surname]
+ assert @controller.send(:cookies).deleted?(:user_name)
+ assert @controller.send(:cookies).encrypted.deleted?(:user_name)
+ end
+
+ def test_delete_and_set_signed_permanent_encrypted_cookie
+ @controller.send(:cookies).signed.permanent.encrypted[:user_name] = 'Joe'
+ get :delete_and_set_signed_permanent_encrypted_cookie
+ assert_nil @controller.send(:cookies)[:user_name]
+ assert_nil @controller.send(:cookies).signed.permanent.encrypted[:user_name]
+ assert_equal @controller.send(:cookies).signed.permanent.encrypted[:user_surname], 'Smith'
+ assert_not_equal @controller.send(:cookies)[:user_surname], 'Smith'
+ assert_not_equal @controller.send(:cookies).encrypted[:user_surname], 'Smith'
+ end
+
def test_delete_and_set_cookie
request.cookies[:user_name] = 'Joe'
get :delete_and_set_cookie