mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Rely on Warden new serializers.
This commit is contained in:
parent
1c8c0a4f00
commit
7ffd0900c1
14 changed files with 125 additions and 99 deletions
|
@ -9,6 +9,7 @@ module Devise
|
|||
}.freeze
|
||||
|
||||
STRATEGIES = [:authenticatable].freeze
|
||||
SERIALIZERS = [:authenticatable, :rememberable].freeze
|
||||
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
||||
|
||||
# Maps the messages types that comes from warden to a flash type.
|
||||
|
@ -104,8 +105,10 @@ module Devise
|
|||
# block.
|
||||
def configure_warden_manager(manager) #:nodoc:
|
||||
manager.default_strategies *Devise::STRATEGIES
|
||||
manager.default_serializers *Devise::SERIALIZERS
|
||||
manager.failure_app = Devise::Failure
|
||||
manager.silence_missing_strategies!
|
||||
manager.silence_missing_serializers!
|
||||
|
||||
# If the user provided a warden hook, call it now.
|
||||
@warden_config.try :call, manager
|
||||
|
@ -118,5 +121,14 @@ module Devise
|
|||
end
|
||||
end
|
||||
|
||||
require 'devise/warden'
|
||||
begin
|
||||
require 'warden'
|
||||
rescue
|
||||
gem 'warden'
|
||||
require 'warden'
|
||||
end
|
||||
|
||||
require 'devise/strategies/base'
|
||||
require 'devise/serializers/base'
|
||||
|
||||
require 'devise/rails'
|
|
@ -1,29 +0,0 @@
|
|||
# After authenticate hook to verify if the user in the given scope asked to be
|
||||
# remembered while he does not sign out. Generates a new remember token for
|
||||
# that specific user and adds a cookie with this user info to sign in this user
|
||||
# automatically without asking for credentials. Refer to rememberable strategy
|
||||
# for more info.
|
||||
Warden::Manager.after_authentication do |record, warden, options|
|
||||
scope = options[:scope]
|
||||
remember_me = warden.params[scope].try(:fetch, :remember_me, nil)
|
||||
|
||||
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
||||
record.remember_me!
|
||||
|
||||
warden.response.set_cookie "remember_#{scope}_token", {
|
||||
:value => record.class.serialize_into_cookie(record),
|
||||
:expires => record.remember_expires_at,
|
||||
:path => "/"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Before logout hook to forget the user in the given scope, only if rememberable
|
||||
# is activated for this scope. Also clear remember token to ensure the user
|
||||
# won't be remembered again.
|
||||
Warden::Manager.before_logout do |record, warden, scope|
|
||||
if record.respond_to?(:forget_me!)
|
||||
record.forget_me!
|
||||
warden.response.delete_cookie "remember_#{scope}_token"
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
module Devise
|
||||
module Middlewares
|
||||
class Rememberable
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
auth = env['warden']
|
||||
scopes = select_cookies(auth.request)
|
||||
scopes.each do |scope, token|
|
||||
mapping = Devise.mappings[scope]
|
||||
next unless mapping && mapping.for.include?(:rememberable)
|
||||
user = mapping.to.serialize_from_cookie(token)
|
||||
auth.set_user(user, :scope => scope) if user
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def select_cookies(request)
|
||||
scopes = {}
|
||||
matching = /remember_(#{Devise.mappings.keys.join("|")})_token/
|
||||
request.cookies.each do |key, value|
|
||||
if key.to_s =~ matching
|
||||
scopes[$1.to_sym] = value
|
||||
end
|
||||
end
|
||||
scopes
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require 'devise/strategies/authenticatable'
|
||||
require 'devise/serializers/authenticatable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
|
@ -77,6 +78,17 @@ module Devise
|
|||
end
|
||||
perishable
|
||||
end
|
||||
|
||||
# Hook to serialize user into session. Overwrite if you want.
|
||||
def serialize_into_session(record)
|
||||
[record.class, record.id]
|
||||
end
|
||||
|
||||
# Hook to serialize user from session. Overwrite if you want.
|
||||
def serialize_from_session(keys)
|
||||
klass, id = keys
|
||||
klass.find_by_id(id)
|
||||
end
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :pepper)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
require 'digest/sha1'
|
||||
require 'devise/hooks/rememberable'
|
||||
require 'devise/middlewares/rememberable'
|
||||
require 'devise/serializers/rememberable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
|
|
|
@ -10,8 +10,5 @@ Rails.configuration.after_initialize do
|
|||
Devise.configure_warden_manager(manager)
|
||||
end
|
||||
|
||||
# If using a rememberable module, include the middleware that log users.
|
||||
Rails.configuration.middleware.use Devise::Middlewares::Rememberable
|
||||
|
||||
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
|
||||
end
|
||||
|
|
9
lib/devise/serializers/authenticatable.rb
Normal file
9
lib/devise/serializers/authenticatable.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
module Devise
|
||||
module Serializers
|
||||
class Authenticatable < Warden::Serializers::Session
|
||||
include Devise::Serializers::Base
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Warden::Serializers.add(:authenticatable, Devise::Serializers::Authenticatable)
|
41
lib/devise/serializers/base.rb
Normal file
41
lib/devise/serializers/base.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
module Devise
|
||||
module Serializers
|
||||
module Base
|
||||
include Devise::Strategies::Base
|
||||
attr_reader :scope
|
||||
|
||||
def serialize(record)
|
||||
record.class.send(:"serialize_into_#{serialization_type}", record)
|
||||
end
|
||||
|
||||
def deserialize(keys)
|
||||
mapping.to.send(:"serialize_from_#{serialization_type}", keys)
|
||||
end
|
||||
|
||||
def store(user, scope)
|
||||
@scope = scope
|
||||
return unless valid?
|
||||
super
|
||||
end
|
||||
|
||||
def fetch(scope)
|
||||
@scope = scope
|
||||
return unless valid?
|
||||
super
|
||||
end
|
||||
|
||||
def delete(scope, user=nil)
|
||||
@scope = scope
|
||||
return unless valid?
|
||||
super
|
||||
end
|
||||
|
||||
def serialization_type
|
||||
@serialization_type ||= begin
|
||||
warden = self.class.ancestors.find{ |k| k < Warden::Serializers::Base && k != self.class }
|
||||
warden.name.split("::").last.underscore
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
26
lib/devise/serializers/rememberable.rb
Normal file
26
lib/devise/serializers/rememberable.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module Devise
|
||||
module Serializers
|
||||
class Rememberable < Warden::Serializers::Cookie
|
||||
include Devise::Serializers::Base
|
||||
|
||||
def store(record, scope)
|
||||
remember_me = params[scope].try(:fetch, :remember_me, nil)
|
||||
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
||||
record.remember_me!
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def default_options(record)
|
||||
super.merge!(:expires => record.remember_expires_at)
|
||||
end
|
||||
|
||||
def delete(scope, record=nil)
|
||||
record.forget_me! if record && record.respond_to?(:forget_me!)
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Warden::Serializers.add(:rememberable, Devise::Serializers::Rememberable)
|
|
@ -2,7 +2,8 @@ module Devise
|
|||
module Strategies
|
||||
# Default strategy for signing in a user, based on his email and password.
|
||||
# Redirects to sign_in page if it's not authenticated
|
||||
class Authenticatable < Devise::Strategies::Base
|
||||
class Authenticatable < Warden::Strategies::Base
|
||||
include Devise::Strategies::Base
|
||||
|
||||
# Authenticate a user based on email and password params, returning to warden
|
||||
# success and the authenticated user if everything is okay. Otherwise redirect
|
||||
|
|
|
@ -2,22 +2,23 @@ module Devise
|
|||
module Strategies
|
||||
# Base strategy for Devise. Responsible for verifying correct scope and
|
||||
# mapping.
|
||||
class Base < Warden::Strategies::Base
|
||||
module Base
|
||||
|
||||
# Validate strategy. By default will raise an error if no scope or an
|
||||
# invalid mapping is found.
|
||||
def valid?
|
||||
mapping.for.include?(self.class.name.split("::").last.underscore.to_sym)
|
||||
mapping.for.include?(klass_type)
|
||||
end
|
||||
|
||||
# Checks if a valid scope was given for devise and find mapping based on
|
||||
# this scope.
|
||||
def mapping
|
||||
@mapping ||= begin
|
||||
raise "You need to give a scope for Devise authentication" unless scope
|
||||
raise "You need to give a valid Devise mapping" unless mapping = Devise.mappings[scope]
|
||||
mapping
|
||||
end
|
||||
@mapping ||= Devise.mappings[scope]
|
||||
end
|
||||
|
||||
# Store this class type.
|
||||
def klass_type
|
||||
@klass_type ||= self.class.name.split("::").last.underscore.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
begin
|
||||
require 'warden'
|
||||
rescue
|
||||
gem 'warden'
|
||||
require 'warden'
|
||||
end
|
||||
|
||||
# Session Serialization in. This block determines how the user will be stored
|
||||
# in the session. If you're using a complex object like an ActiveRecord model,
|
||||
# it is not a good idea to store the complete object. An ID is sufficient.
|
||||
Warden::Manager.serialize_into_session{ |user| [user.class, user.id] }
|
||||
|
||||
# Session Serialization out. This block gets the user out of the session.
|
||||
# It should be the reverse of serializing the object into the session
|
||||
Warden::Manager.serialize_from_session do |klass, id|
|
||||
klass.find_by_id(id)
|
||||
end
|
||||
|
||||
# Setup devise strategies for Warden
|
||||
require 'devise/strategies/base'
|
|
@ -15,6 +15,10 @@ class DeviseTest < ActiveSupport::TestCase
|
|||
@silence_missing_strategies = true
|
||||
end
|
||||
|
||||
def silence_missing_serializers!
|
||||
@silence_missing_serializers = true
|
||||
end
|
||||
|
||||
def default_strategies(*args)
|
||||
if args.empty?
|
||||
@default_strategies
|
||||
|
@ -22,6 +26,14 @@ class DeviseTest < ActiveSupport::TestCase
|
|||
@default_strategies = args
|
||||
end
|
||||
end
|
||||
|
||||
def default_serializers(*args)
|
||||
if args.empty?
|
||||
@default_serializers
|
||||
else
|
||||
@default_serializers = args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'DeviseMailer.sender can be configured through Devise' do
|
||||
|
|
|
@ -6,7 +6,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
Devise.remember_for = 1
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
cookies['remember_user_token'] = User.serialize_into_cookie(user) + add_to_token
|
||||
cookies['warden.user.user.key'] = User.serialize_into_cookie(user) + add_to_token
|
||||
user
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue