1
0
Fork 0
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:
José Valim 2009-11-15 00:13:43 -02:00
parent 1c8c0a4f00
commit 7ffd0900c1
14 changed files with 125 additions and 99 deletions

View file

@ -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'

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -1,6 +1,5 @@
require 'digest/sha1'
require 'devise/hooks/rememberable'
require 'devise/middlewares/rememberable'
require 'devise/serializers/rememberable'
module Devise
module Models

View file

@ -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

View 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)

View 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

View 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)

View file

@ -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

View file

@ -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

View file

@ -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'

View file

@ -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

View file

@ -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