diff --git a/lib/clearance/configuration.rb b/lib/clearance/configuration.rb index cb5bc17a9..af0401b70 100644 --- a/lib/clearance/configuration.rb +++ b/lib/clearance/configuration.rb @@ -96,6 +96,12 @@ class Configuration # @return [Boolean|:migrate] attr_reader :signed_cookie + # Controls whether cookies are encrypted. + # Defaults to `nil` for backwards compatibility. + # When not nil overrides signed_cookie settings and if true uses Rails' encrypted cookies + # @return [Boolean|:migrate] + attr_reader :encrypted_cookie + # The array of sign in guards to run when signing a user in. # Defaults to an empty array. Sign in guards respond to `call` and are # initialized with a session and the current stack. Each guard can decide @@ -144,6 +150,7 @@ def initialize @routes = true @secure_cookie = false @signed_cookie = false + @encrypted_cookie = nil @sign_in_guards = [] @user_parameter = nil @sign_in_on_password_reset = true @@ -159,6 +166,16 @@ def signed_cookie=(value) end end + def encrypted_cookie=(value) + if [true, false, :migrate].include? value + @encrypted_cookie = value + else + raise "Clearance's enrcypted_cookie configuration value is invalid. " \ + "Valid values are true, false, or :migrate. " \ + "Set this option via Clearance.configure in an initializer" + end + end + # The class representing the configured user model. # In the default configuration, this is the `User` class. # @return [Class] diff --git a/lib/clearance/session.rb b/lib/clearance/session.rb index 85142df88..5a23411b1 100644 --- a/lib/clearance/session.rb +++ b/lib/clearance/session.rb @@ -108,24 +108,44 @@ def cookies # @api private def set_remember_token(token) - case Clearance.configuration.signed_cookie - when true, :migrate - cookies.signed[remember_token_cookie] = cookie_options(token) - when false - cookies[remember_token_cookie] = cookie_options(token) + if !Clearance.configuration.encrypted_cookie.nil? + case Clearance.configuration.encrypted_cookie + when true, :migrate + cookies.encrypted[remember_token_cookie] = cookie_options(token) + when false + cookies[remember_token_cookie] = cookie_options(token) + end + else + case Clearance.configuration.signed_cookie + when true, :migrate + cookies.signed[remember_token_cookie] = cookie_options(token) + when false + cookies[remember_token_cookie] = cookie_options(token) + end end remember_token end # @api private def remember_token - case Clearance.configuration.signed_cookie - when true - cookies.signed[remember_token_cookie] - when :migrate - cookies.signed[remember_token_cookie] || cookies[remember_token_cookie] - when false - cookies[remember_token_cookie] + if !Clearance.configuration.encrypted_cookie.nil? + case Clearance.configuration.encrypted_cookie + when true + cookies.encrypted[remember_token_cookie] + when :migrate + cookies.encrypted[remember_token_cookie] || cookies[remember_token_cookie] + when false + cookies[remember_token_cookie] + end + else + case Clearance.configuration.signed_cookie + when true + cookies.signed[remember_token_cookie] + when :migrate + cookies.signed[remember_token_cookie] || cookies[remember_token_cookie] + when false + cookies[remember_token_cookie] + end end end diff --git a/spec/support/request_with_remember_token.rb b/spec/support/request_with_remember_token.rb index ba3d6b0f8..4f84ddbf0 100644 --- a/spec/support/request_with_remember_token.rb +++ b/spec/support/request_with_remember_token.rb @@ -1,7 +1,9 @@ module RememberTokenHelpers def request_with_remember_token(remember_token) cookies = ActionDispatch::Request.new({}).cookie_jar - if Clearance.configuration.signed_cookie + if Clearance.configuration.encrypted_cookie + cookies.encrypted[Clearance.configuration.cookie_name] = remember_token + elsif Clearance.configuration.signed_cookie cookies.signed[Clearance.configuration.cookie_name] = remember_token else cookies[Clearance.configuration.cookie_name] = remember_token