devise 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of devise might be problematic. Click here for more details.
- data/CHANGELOG.rdoc +11 -1
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/TODO +0 -1
- data/generators/devise_install/templates/devise.rb +7 -0
- data/lib/devise.rb +17 -1
- data/lib/devise/controllers/filters.rb +44 -6
- data/lib/devise/controllers/helpers.rb +1 -12
- data/lib/devise/mapping.rb +12 -0
- data/lib/devise/models.rb +21 -19
- data/lib/devise/models/authenticatable.rb +21 -4
- data/lib/devise/models/rememberable.rb +1 -2
- data/lib/devise/models/validatable.rb +10 -6
- data/lib/devise/rails.rb +0 -3
- data/lib/devise/rails/warden_compat.rb +0 -4
- data/lib/devise/serializers/authenticatable.rb +9 -0
- data/lib/devise/serializers/base.rb +41 -0
- data/lib/devise/serializers/rememberable.rb +26 -0
- data/lib/devise/strategies/authenticatable.rb +5 -9
- data/lib/devise/strategies/base.rb +9 -10
- data/lib/devise/version.rb +1 -1
- data/test/controllers/filters_test.rb +41 -8
- data/test/devise_test.rb +12 -0
- data/test/integration/authenticatable_test.rb +7 -0
- data/test/integration/rememberable_test.rb +1 -1
- data/test/mapping_test.rb +18 -2
- data/test/models/authenticatable_test.rb +31 -0
- data/test/test_helper.rb +1 -0
- metadata +6 -6
- data/lib/devise/hooks/rememberable.rb +0 -29
- data/lib/devise/middlewares/rememberable.rb +0 -35
- data/lib/devise/warden.rb +0 -20
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
* enhancements
|
2
|
+
* [#28] Improved sign_in and sign_out helpers to accepts resources
|
3
|
+
* [#28] Added stored_location_for as a helper
|
4
|
+
|
5
|
+
== 0.5.1
|
6
|
+
|
7
|
+
* enhancements
|
8
|
+
* Added serializers based on Warden ones
|
9
|
+
* Allow authentication keys to be set
|
10
|
+
|
1
11
|
== 0.5.0
|
2
12
|
|
3
13
|
* bug fix
|
@@ -11,7 +21,7 @@
|
|
11
21
|
== 0.4.3
|
12
22
|
|
13
23
|
* bug fix
|
14
|
-
* [#29] Authentication
|
24
|
+
* [#29] Authentication just fails if user cannot be serialized from session, without raising errors;
|
15
25
|
* Default configuration values should not overwrite user values;
|
16
26
|
|
17
27
|
== 0.4.2
|
data/README.rdoc
CHANGED
@@ -46,7 +46,7 @@ And you're ready to go.
|
|
46
46
|
|
47
47
|
This is a walkthrough with all steps you need to setup a devise resource, including model, migration, route files, and optional configuration. You can also check out the *Generators* section below to help you start.
|
48
48
|
|
49
|
-
Devise must be
|
49
|
+
Devise must be set up within the model (or models) you want to use, and devise routes must be created inside your routes.rb file.
|
50
50
|
|
51
51
|
We're assuming here you want a User model. First of all you have to setup a migration with the following fields:
|
52
52
|
|
@@ -93,7 +93,7 @@ Note that validations aren't added by default, so you're able to customize it. I
|
|
93
93
|
|
94
94
|
== Model configuration
|
95
95
|
|
96
|
-
In addition to :except, you can provide :pepper, :stretches, :confirm_within and :remember_for as options to devise method.
|
96
|
+
In addition to :except, you can provide :pepper, :stretches, :encryptor, :authentication_keys, :confirm_within and :remember_for as options to devise method.
|
97
97
|
|
98
98
|
All those options are described in "config/initializers/devise.rb", which is generated when you invoke `ruby script/generate devise_install` in your application root.
|
99
99
|
|
data/Rakefile
CHANGED
@@ -36,7 +36,7 @@ begin
|
|
36
36
|
s.description = "Flexible authentication solution for Rails with Warden"
|
37
37
|
s.authors = ['José Valim', 'Carlos Antônio']
|
38
38
|
s.files = FileList["[A-Z]*", "{app,config,generators,lib}/**/*", "init.rb"]
|
39
|
-
s.add_dependency("warden", "~> 0.
|
39
|
+
s.add_dependency("warden", "~> 0.6.0")
|
40
40
|
end
|
41
41
|
|
42
42
|
Jeweler::GemcutterTasks.new
|
data/TODO
CHANGED
@@ -15,6 +15,13 @@ Devise.setup do |config|
|
|
15
15
|
# should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
16
16
|
# config.encryptor = :sha1
|
17
17
|
|
18
|
+
# Configure which keys are used when authenticating an user. By default is
|
19
|
+
# just :email. You can configure it to use [:username, :subdomain], so for
|
20
|
+
# authenticating an user, both parameters are required. Remember that those
|
21
|
+
# parameters are used only when authenticating and not when retrieving from
|
22
|
+
# session. If you need permissions, you should implement that in a before filter.
|
23
|
+
# config.authentication_keys = [ :email ]
|
24
|
+
|
18
25
|
# The time you want give to your user to confirm his account. During this time
|
19
26
|
# he will be able to access your application without confirming. Default is nil.
|
20
27
|
# config.confirm_within = 2.days
|
data/lib/devise.rb
CHANGED
@@ -9,6 +9,7 @@ module Devise
|
|
9
9
|
}.freeze
|
10
10
|
|
11
11
|
STRATEGIES = [:authenticatable].freeze
|
12
|
+
SERIALIZERS = [:authenticatable, :rememberable].freeze
|
12
13
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
13
14
|
|
14
15
|
# Maps the messages types that comes from warden to a flash type.
|
@@ -35,6 +36,10 @@ module Devise
|
|
35
36
|
mattr_accessor :stretches
|
36
37
|
@@stretches = 10
|
37
38
|
|
39
|
+
# Keys used when authenticating an user.
|
40
|
+
mattr_accessor :authentication_keys
|
41
|
+
@@authentication_keys = [ :email ]
|
42
|
+
|
38
43
|
# Time interval where the remember me token is valid.
|
39
44
|
mattr_accessor :remember_for
|
40
45
|
@@remember_for = 2.weeks
|
@@ -104,8 +109,10 @@ module Devise
|
|
104
109
|
# block.
|
105
110
|
def configure_warden_manager(manager) #:nodoc:
|
106
111
|
manager.default_strategies *Devise::STRATEGIES
|
112
|
+
manager.default_serializers *Devise::SERIALIZERS
|
107
113
|
manager.failure_app = Devise::Failure
|
108
114
|
manager.silence_missing_strategies!
|
115
|
+
manager.silence_missing_serializers!
|
109
116
|
|
110
117
|
# If the user provided a warden hook, call it now.
|
111
118
|
@warden_config.try :call, manager
|
@@ -118,5 +125,14 @@ module Devise
|
|
118
125
|
end
|
119
126
|
end
|
120
127
|
|
121
|
-
|
128
|
+
begin
|
129
|
+
require 'warden'
|
130
|
+
rescue
|
131
|
+
gem 'warden'
|
132
|
+
require 'warden'
|
133
|
+
end
|
134
|
+
|
135
|
+
require 'devise/strategies/base'
|
136
|
+
require 'devise/serializers/base'
|
137
|
+
|
122
138
|
require 'devise/rails'
|
@@ -49,17 +49,45 @@ module Devise
|
|
49
49
|
warden.authenticated?(scope)
|
50
50
|
end
|
51
51
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
|
52
|
+
# Sign in an user that already was authenticated. This helper is useful for logging
|
53
|
+
# users in after sign up.
|
54
|
+
#
|
55
|
+
# Examples:
|
56
|
+
#
|
57
|
+
# sign_in :user, @user # sign_in(scope, resource)
|
58
|
+
# sign_in @user # sign_in(resource)
|
59
|
+
#
|
60
|
+
def sign_in(resource_or_scope, resource=nil)
|
61
|
+
scope ||= find_devise_scope(resource_or_scope)
|
62
|
+
resource ||= resource_or_scope
|
55
63
|
warden.set_user(resource, :scope => scope)
|
56
64
|
end
|
57
65
|
|
58
|
-
# Sign out
|
59
|
-
|
66
|
+
# Sign out a given user or scope. This helper is useful for signing out an user
|
67
|
+
# after deleting accounts.
|
68
|
+
#
|
69
|
+
# Examples:
|
70
|
+
#
|
71
|
+
# sign_out :user # sign_out(scope)
|
72
|
+
# sign_out @user # sign_out(resource)
|
73
|
+
#
|
74
|
+
def sign_out(resource_or_scope)
|
75
|
+
scope = find_devise_scope(resource_or_scope)
|
60
76
|
warden.user(scope) # Without loading user here, before_logout hook is not called
|
61
77
|
warden.raw_session.inspect # Without this inspect here. The session does not clear.
|
62
|
-
warden.logout(scope
|
78
|
+
warden.logout(scope)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns and delete the url stored in the session for the given scope. Useful
|
82
|
+
# for giving redirect backs after sign up:
|
83
|
+
#
|
84
|
+
# Example:
|
85
|
+
#
|
86
|
+
# redirect_to stored_location_for(:user) || root_path
|
87
|
+
#
|
88
|
+
def stored_location_for(resource_or_scope)
|
89
|
+
scope = find_devise_scope(resource_or_scope)
|
90
|
+
session.delete(:"#{scope}.return_to")
|
63
91
|
end
|
64
92
|
|
65
93
|
# Define authentication filters and accessor helpers based on mappings.
|
@@ -106,6 +134,16 @@ module Devise
|
|
106
134
|
METHODS
|
107
135
|
end
|
108
136
|
|
137
|
+
protected
|
138
|
+
|
139
|
+
def find_devise_scope(resource_or_scope)
|
140
|
+
if resource_or_scope.is_a?(Symbol)
|
141
|
+
resource_or_scope
|
142
|
+
else
|
143
|
+
Devise::Mapping.find_by_class!(resource_or_scope.class).name
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
109
147
|
end
|
110
148
|
end
|
111
149
|
end
|
@@ -45,18 +45,7 @@ module Devise
|
|
45
45
|
# Redirects to stored uri before signing in or the default path and clear
|
46
46
|
# return to.
|
47
47
|
def redirect_back_or_to(default)
|
48
|
-
redirect_to(
|
49
|
-
clear_return_to
|
50
|
-
end
|
51
|
-
|
52
|
-
# Access to scoped stored uri
|
53
|
-
def return_to
|
54
|
-
session[:"#{resource_name}.return_to"]
|
55
|
-
end
|
56
|
-
|
57
|
-
# Clear scoped stored uri
|
58
|
-
def clear_return_to
|
59
|
-
session[:"#{resource_name}.return_to"] = nil
|
48
|
+
redirect_to(stored_location_for(resource_name) || default)
|
60
49
|
end
|
61
50
|
|
62
51
|
# Checks for the existence of the resource root path. If it exists,
|
data/lib/devise/mapping.rb
CHANGED
@@ -34,6 +34,18 @@ module Devise
|
|
34
34
|
nil
|
35
35
|
end
|
36
36
|
|
37
|
+
# Find a mapping by a given class. It takes into account single table inheritance as well.
|
38
|
+
def self.find_by_class(klass)
|
39
|
+
Devise.mappings.values.find { |m| return m if klass <= m.to }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Find by class but raising an error in case it can't be found.
|
43
|
+
def self.find_by_class!(klass)
|
44
|
+
mapping = find_by_class(klass)
|
45
|
+
raise "Could not find a valid mapping for #{klass}" unless mapping
|
46
|
+
mapping
|
47
|
+
end
|
48
|
+
|
37
49
|
# Default url options which can be used as prefix.
|
38
50
|
def self.default_url_options
|
39
51
|
{}
|
data/lib/devise/models.rb
CHANGED
@@ -16,28 +16,30 @@ module Devise
|
|
16
16
|
# To add the class methods you need to have a module ClassMethods defined
|
17
17
|
# inside the given class.
|
18
18
|
#
|
19
|
-
def self.config(mod,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def self.config(mod, *accessors) #:nodoc:
|
20
|
+
accessors.each do |accessor|
|
21
|
+
mod.class_eval <<-METHOD, __FILE__, __LINE__
|
22
|
+
def #{accessor}
|
23
|
+
self.class.#{accessor}
|
24
|
+
end
|
25
|
+
METHOD
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
mod.const_get(:ClassMethods).class_eval <<-METHOD, __FILE__, __LINE__
|
28
|
+
def #{accessor}
|
29
|
+
if defined?(@#{accessor})
|
30
|
+
@#{accessor}
|
31
|
+
elsif superclass.respond_to?(:#{accessor})
|
32
|
+
superclass.#{accessor}
|
33
|
+
else
|
34
|
+
Devise.#{accessor}
|
35
|
+
end
|
34
36
|
end
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def #{accessor}=(value)
|
39
|
+
@#{accessor} = value
|
40
|
+
end
|
41
|
+
METHOD
|
42
|
+
end
|
41
43
|
end
|
42
44
|
|
43
45
|
# Shortcut method for including all devise modules inside your model.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'devise/strategies/authenticatable'
|
2
|
+
require 'devise/serializers/authenticatable'
|
2
3
|
|
3
4
|
module Devise
|
4
5
|
module Models
|
@@ -18,6 +19,10 @@ module Devise
|
|
18
19
|
#
|
19
20
|
# stretches: defines how many times the password will be encrypted.
|
20
21
|
#
|
22
|
+
# encryptor: the encryptor going to be used. By default :sha1.
|
23
|
+
#
|
24
|
+
# authentication_keys: parameters used for authentication. By default [:email]
|
25
|
+
#
|
21
26
|
# Examples:
|
22
27
|
#
|
23
28
|
# User.authenticate('email@test.com', 'password123') # returns authenticated user or nil
|
@@ -64,7 +69,9 @@ module Devise
|
|
64
69
|
# authenticated user if it's valid or nil.
|
65
70
|
# Attributes are :email and :password
|
66
71
|
def authenticate(attributes={})
|
67
|
-
|
72
|
+
return unless authentication_keys.all? { |k| attributes[k].present? }
|
73
|
+
conditions = attributes.slice(*authentication_keys)
|
74
|
+
authenticatable = find(:first, :conditions => conditions)
|
68
75
|
authenticatable if authenticatable.try(:valid_password?, attributes[:password])
|
69
76
|
end
|
70
77
|
|
@@ -77,11 +84,21 @@ module Devise
|
|
77
84
|
end
|
78
85
|
perishable
|
79
86
|
end
|
87
|
+
|
88
|
+
# Hook to serialize user into session. Overwrite if you want.
|
89
|
+
def serialize_into_session(record)
|
90
|
+
[record.class, record.id]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Hook to serialize user from session. Overwrite if you want.
|
94
|
+
def serialize_from_session(keys)
|
95
|
+
klass, id = keys
|
96
|
+
raise "#{self} cannot serialize from #{klass} session since it's not its ancestors" unless klass <= self
|
97
|
+
klass.find_by_id(id)
|
98
|
+
end
|
80
99
|
end
|
81
100
|
|
82
|
-
Devise::Models.config(self, :pepper)
|
83
|
-
Devise::Models.config(self, :stretches)
|
84
|
-
Devise::Models.config(self, :encryptor)
|
101
|
+
Devise::Models.config(self, :pepper, :stretches, :encryptor, :authentication_keys)
|
85
102
|
end
|
86
103
|
end
|
87
104
|
end
|
@@ -12,14 +12,18 @@ module Devise
|
|
12
12
|
|
13
13
|
def self.included(base)
|
14
14
|
base.class_eval do
|
15
|
+
attribute = authentication_keys.first
|
15
16
|
|
16
|
-
validates_presence_of
|
17
|
-
validates_uniqueness_of
|
18
|
-
validates_format_of
|
17
|
+
validates_presence_of attribute
|
18
|
+
validates_uniqueness_of attribute, :allow_blank => true
|
19
|
+
validates_format_of attribute, :with => EMAIL_REGEX, :allow_blank => true,
|
20
|
+
:scope => authentication_keys[1..-1]
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
with_options :if => :password_required? do |v|
|
23
|
+
v.validates_presence_of :password
|
24
|
+
v.validates_confirmation_of :password
|
25
|
+
v.validates_length_of :password, :within => 6..20, :allow_blank => true
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
data/lib/devise/rails.rb
CHANGED
@@ -10,8 +10,5 @@ Rails.configuration.after_initialize do
|
|
10
10
|
Devise.configure_warden_manager(manager)
|
11
11
|
end
|
12
12
|
|
13
|
-
# If using a rememberable module, include the middleware that log users.
|
14
|
-
Rails.configuration.middleware.use Devise::Middlewares::Rememberable
|
15
|
-
|
16
13
|
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
|
17
14
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Devise
|
2
|
+
module Serializers
|
3
|
+
module Base
|
4
|
+
include Devise::Strategies::Base
|
5
|
+
attr_reader :scope
|
6
|
+
|
7
|
+
def serialize(record)
|
8
|
+
record.class.send(:"serialize_into_#{serialization_type}", record)
|
9
|
+
end
|
10
|
+
|
11
|
+
def deserialize(keys)
|
12
|
+
mapping.to.send(:"serialize_from_#{serialization_type}", keys)
|
13
|
+
end
|
14
|
+
|
15
|
+
def store(user, scope)
|
16
|
+
@scope = scope
|
17
|
+
return unless valid?
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch(scope)
|
22
|
+
@scope = scope
|
23
|
+
return unless valid?
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(scope, user=nil)
|
28
|
+
@scope = scope
|
29
|
+
return unless valid?
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def serialization_type
|
34
|
+
@serialization_type ||= begin
|
35
|
+
warden = self.class.ancestors.find{ |k| k < Warden::Serializers::Base && k != self.class }
|
36
|
+
warden.name.split("::").last.underscore
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Devise
|
2
|
+
module Serializers
|
3
|
+
class Rememberable < Warden::Serializers::Cookie
|
4
|
+
include Devise::Serializers::Base
|
5
|
+
|
6
|
+
def store(record, scope)
|
7
|
+
remember_me = params[scope].try(:fetch, :remember_me, nil)
|
8
|
+
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
9
|
+
record.remember_me!
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_options(record)
|
15
|
+
super.merge!(:expires => record.remember_expires_at)
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete(scope, record=nil)
|
19
|
+
record.forget_me! if record && record.respond_to?(:forget_me!)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Warden::Serializers.add(:rememberable, Devise::Serializers::Rememberable)
|
@@ -2,7 +2,8 @@ module Devise
|
|
2
2
|
module Strategies
|
3
3
|
# Default strategy for signing in a user, based on his email and password.
|
4
4
|
# Redirects to sign_in page if it's not authenticated
|
5
|
-
class Authenticatable <
|
5
|
+
class Authenticatable < Warden::Strategies::Base
|
6
|
+
include Devise::Strategies::Base
|
6
7
|
|
7
8
|
# Authenticate a user based on email and password params, returning to warden
|
8
9
|
# success and the authenticated user if everything is okay. Otherwise redirect
|
@@ -12,7 +13,7 @@ module Devise
|
|
12
13
|
# The first does not perform any action when calling authenticate, just
|
13
14
|
# when authenticate! is invoked. The second always perform the action.
|
14
15
|
def authenticate!
|
15
|
-
if valid_attributes? && resource = mapping.to.authenticate(
|
16
|
+
if valid_attributes? && resource = mapping.to.authenticate(params[scope])
|
16
17
|
success!(resource)
|
17
18
|
else
|
18
19
|
store_location
|
@@ -22,14 +23,9 @@ module Devise
|
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
#
|
26
|
-
def attributes
|
27
|
-
@attributes ||= params[scope]
|
28
|
-
end
|
29
|
-
|
30
|
-
# Check for the right keys.
|
26
|
+
# Check if params and password are given. Others are checked inside authenticate.
|
31
27
|
def valid_attributes?
|
32
|
-
|
28
|
+
params[scope] && params[scope][:password].present?
|
33
29
|
end
|
34
30
|
|
35
31
|
# Stores requested uri to redirect the user after signing in. We cannot use
|
@@ -1,23 +1,22 @@
|
|
1
1
|
module Devise
|
2
2
|
module Strategies
|
3
|
-
# Base strategy for Devise. Responsible for verifying correct scope and
|
4
|
-
|
5
|
-
class Base < Warden::Strategies::Base
|
6
|
-
|
3
|
+
# Base strategy for Devise. Responsible for verifying correct scope and mapping.
|
4
|
+
module Base
|
7
5
|
# Validate strategy. By default will raise an error if no scope or an
|
8
6
|
# invalid mapping is found.
|
9
7
|
def valid?
|
10
|
-
mapping.for.include?(
|
8
|
+
mapping.for.include?(klass_type)
|
11
9
|
end
|
12
10
|
|
13
11
|
# Checks if a valid scope was given for devise and find mapping based on
|
14
12
|
# this scope.
|
15
13
|
def mapping
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
Devise.mappings[scope]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Store this class type.
|
18
|
+
def klass_type
|
19
|
+
@klass_type ||= self.class.name.split("::").last.underscore.to_sym
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|
data/lib/devise/version.rb
CHANGED
@@ -14,11 +14,13 @@ class MockController < ApplicationController
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class ControllerAuthenticableTest < ActionController::TestCase
|
17
|
+
tests MockController
|
17
18
|
|
18
19
|
def setup
|
19
20
|
@controller = MockController.new
|
20
21
|
@mock_warden = OpenStruct.new
|
21
22
|
@controller.env = { 'warden' => @mock_warden }
|
23
|
+
@controller.session = {}
|
22
24
|
end
|
23
25
|
|
24
26
|
test 'setup warden' do
|
@@ -47,12 +49,6 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
|
47
49
|
@controller.current_user
|
48
50
|
end
|
49
51
|
|
50
|
-
test 'proxy logout to warden' do
|
51
|
-
@mock_warden.expects(:user).with(:user).returns(true)
|
52
|
-
@mock_warden.expects(:logout).with(:user).returns(true)
|
53
|
-
@controller.sign_out(:user)
|
54
|
-
end
|
55
|
-
|
56
52
|
test 'proxy user_authenticate! to authenticate with user scope' do
|
57
53
|
@mock_warden.expects(:authenticate!).with(:scope => :user)
|
58
54
|
@controller.authenticate_user!
|
@@ -83,11 +79,48 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
|
83
79
|
@controller.admin_session
|
84
80
|
end
|
85
81
|
|
86
|
-
test 'sign in
|
87
|
-
|
82
|
+
test 'sign in proxy to set_user on warden' do
|
83
|
+
user = User.new
|
84
|
+
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
|
88
85
|
@controller.sign_in(:user, user)
|
89
86
|
end
|
90
87
|
|
88
|
+
test 'sign in accepts a resource as argument' do
|
89
|
+
user = User.new
|
90
|
+
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
|
91
|
+
@controller.sign_in(user)
|
92
|
+
end
|
93
|
+
|
94
|
+
test 'sign out proxy to logout on warden' do
|
95
|
+
@mock_warden.expects(:user).with(:user).returns(true)
|
96
|
+
@mock_warden.expects(:logout).with(:user).returns(true)
|
97
|
+
@controller.sign_out(:user)
|
98
|
+
end
|
99
|
+
|
100
|
+
test 'sign out accepts a resource as argument' do
|
101
|
+
@mock_warden.expects(:user).with(:user).returns(true)
|
102
|
+
@mock_warden.expects(:logout).with(:user).returns(true)
|
103
|
+
@controller.sign_out(User.new)
|
104
|
+
end
|
105
|
+
|
106
|
+
test 'stored location for returns the location for a given scope' do
|
107
|
+
assert_nil @controller.stored_location_for(:user)
|
108
|
+
@controller.session[:"user.return_to"] = "/foo.bar"
|
109
|
+
assert_equal "/foo.bar", @controller.stored_location_for(:user)
|
110
|
+
end
|
111
|
+
|
112
|
+
test 'stored location for accepts a resource as argument' do
|
113
|
+
assert_nil @controller.stored_location_for(:user)
|
114
|
+
@controller.session[:"user.return_to"] = "/foo.bar"
|
115
|
+
assert_equal "/foo.bar", @controller.stored_location_for(User.new)
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'stored location cleans information after reading' do
|
119
|
+
@controller.session[:"user.return_to"] = "/foo.bar"
|
120
|
+
assert_equal "/foo.bar", @controller.stored_location_for(:user)
|
121
|
+
assert_nil @controller.session[:"user.return_to"]
|
122
|
+
end
|
123
|
+
|
91
124
|
test 'is not a devise controller' do
|
92
125
|
assert_not @controller.devise_controller?
|
93
126
|
end
|
data/test/devise_test.rb
CHANGED
@@ -15,6 +15,10 @@ class DeviseTest < ActiveSupport::TestCase
|
|
15
15
|
@silence_missing_strategies = true
|
16
16
|
end
|
17
17
|
|
18
|
+
def silence_missing_serializers!
|
19
|
+
@silence_missing_serializers = true
|
20
|
+
end
|
21
|
+
|
18
22
|
def default_strategies(*args)
|
19
23
|
if args.empty?
|
20
24
|
@default_strategies
|
@@ -22,6 +26,14 @@ class DeviseTest < ActiveSupport::TestCase
|
|
22
26
|
@default_strategies = args
|
23
27
|
end
|
24
28
|
end
|
29
|
+
|
30
|
+
def default_serializers(*args)
|
31
|
+
if args.empty?
|
32
|
+
@default_serializers
|
33
|
+
else
|
34
|
+
@default_serializers = args
|
35
|
+
end
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
39
|
test 'DeviseMailer.sender can be configured through Devise' do
|
@@ -76,6 +76,13 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|
76
76
|
assert_contain 'Welcome Admin'
|
77
77
|
end
|
78
78
|
|
79
|
+
test 'sign in as user should not authenticate if not using proper authentication keys' do
|
80
|
+
swap Devise, :authentication_keys => [:username] do
|
81
|
+
sign_in_as_user
|
82
|
+
assert_not warden.authenticated?(:user)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
79
86
|
test 'admin signing in with invalid email should return to sign in form with error message' do
|
80
87
|
sign_in_as_admin do
|
81
88
|
fill_in 'email', :with => 'wrongemail@test.com'
|
@@ -6,7 +6,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|
6
6
|
Devise.remember_for = 1
|
7
7
|
user = create_user
|
8
8
|
user.remember_me!
|
9
|
-
cookies['
|
9
|
+
cookies['warden.user.user.key'] = User.serialize_into_cookie(user) + add_to_token
|
10
10
|
user
|
11
11
|
end
|
12
12
|
|
data/test/mapping_test.rb
CHANGED
@@ -30,15 +30,31 @@ class MappingTest < ActiveSupport::TestCase
|
|
30
30
|
assert_not mapping.allows?(:passwords)
|
31
31
|
end
|
32
32
|
|
33
|
-
test '
|
33
|
+
test 'find mapping by path' do
|
34
34
|
assert_nil Devise::Mapping.find_by_path("/foo/bar")
|
35
35
|
assert_equal Devise.mappings[:user], Devise::Mapping.find_by_path("/users/session")
|
36
36
|
end
|
37
37
|
|
38
|
-
test '
|
38
|
+
test 'find mapping by customized path' do
|
39
39
|
assert_equal Devise.mappings[:admin], Devise::Mapping.find_by_path("/admin_area/session")
|
40
40
|
end
|
41
41
|
|
42
|
+
test 'find mapping by class' do
|
43
|
+
assert_nil Devise::Mapping.find_by_class(String)
|
44
|
+
assert_equal Devise.mappings[:user], Devise::Mapping.find_by_class(User)
|
45
|
+
end
|
46
|
+
|
47
|
+
test 'find mapping by class works with single table inheritance' do
|
48
|
+
klass = Class.new(User)
|
49
|
+
assert_equal Devise.mappings[:user], Devise::Mapping.find_by_class(klass)
|
50
|
+
end
|
51
|
+
|
52
|
+
test 'find mapping raises an error for invalid class' do
|
53
|
+
assert_raise RuntimeError do
|
54
|
+
Devise::Mapping.find_by_class!(String)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
42
58
|
test 'return default path names' do
|
43
59
|
mapping = Devise.mappings[:user]
|
44
60
|
assert_equal 'sign_in', mapping.path_names[:sign_in]
|
@@ -127,4 +127,35 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|
127
127
|
authenticated_user = User.authenticate(:email => user.email, :password => 'another_password')
|
128
128
|
assert_nil authenticated_user
|
129
129
|
end
|
130
|
+
|
131
|
+
test 'should use authentication keys to retrieve users' do
|
132
|
+
swap Devise, :authentication_keys => [:username] do
|
133
|
+
user = create_user(:username => "josevalim")
|
134
|
+
assert_nil User.authenticate(:email => user.email, :password => user.password)
|
135
|
+
assert_not_nil User.authenticate(:username => user.username, :password => user.password)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
test 'should serialize user into session' do
|
140
|
+
user = create_user
|
141
|
+
assert_equal [User, user.id], User.serialize_into_session(user)
|
142
|
+
end
|
143
|
+
|
144
|
+
test 'should serialize user from session' do
|
145
|
+
user = create_user
|
146
|
+
assert_equal user.id, User.serialize_from_session([User, user.id]).id
|
147
|
+
end
|
148
|
+
|
149
|
+
test 'should not serialize another klass from session' do
|
150
|
+
user = create_user
|
151
|
+
assert_raise RuntimeError, /ancestors/ do
|
152
|
+
User.serialize_from_session([Admin, user.id])
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
test 'should serialize another klass from session' do
|
157
|
+
user = create_user
|
158
|
+
klass = Class.new(User)
|
159
|
+
assert_equal user.id, User.serialize_from_session([klass, user.id]).id
|
160
|
+
end
|
130
161
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jos\xC3\xA9 Valim"
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-11-
|
13
|
+
date: 2009-11-15 00:00:00 -02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ~>
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.
|
24
|
+
version: 0.6.0
|
25
25
|
version:
|
26
26
|
description: Flexible authentication solution for Rails with Warden
|
27
27
|
email: contact@plataformatec.com.br
|
@@ -70,10 +70,8 @@ files:
|
|
70
70
|
- lib/devise/encryptors/sha512.rb
|
71
71
|
- lib/devise/failure.rb
|
72
72
|
- lib/devise/hooks/confirmable.rb
|
73
|
-
- lib/devise/hooks/rememberable.rb
|
74
73
|
- lib/devise/locales/en.yml
|
75
74
|
- lib/devise/mapping.rb
|
76
|
-
- lib/devise/middlewares/rememberable.rb
|
77
75
|
- lib/devise/models.rb
|
78
76
|
- lib/devise/models/authenticatable.rb
|
79
77
|
- lib/devise/models/confirmable.rb
|
@@ -86,10 +84,12 @@ files:
|
|
86
84
|
- lib/devise/rails/routes.rb
|
87
85
|
- lib/devise/rails/warden_compat.rb
|
88
86
|
- lib/devise/schema.rb
|
87
|
+
- lib/devise/serializers/authenticatable.rb
|
88
|
+
- lib/devise/serializers/base.rb
|
89
|
+
- lib/devise/serializers/rememberable.rb
|
89
90
|
- lib/devise/strategies/authenticatable.rb
|
90
91
|
- lib/devise/strategies/base.rb
|
91
92
|
- lib/devise/version.rb
|
92
|
-
- lib/devise/warden.rb
|
93
93
|
has_rdoc: true
|
94
94
|
homepage: http://github.com/plataformatec/devise
|
95
95
|
licenses: []
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# After authenticate hook to verify if the user in the given scope asked to be
|
2
|
-
# remembered while he does not sign out. Generates a new remember token for
|
3
|
-
# that specific user and adds a cookie with this user info to sign in this user
|
4
|
-
# automatically without asking for credentials. Refer to rememberable strategy
|
5
|
-
# for more info.
|
6
|
-
Warden::Manager.after_authentication do |record, warden, options|
|
7
|
-
scope = options[:scope]
|
8
|
-
remember_me = warden.params[scope].try(:fetch, :remember_me, nil)
|
9
|
-
|
10
|
-
if Devise::TRUE_VALUES.include?(remember_me) && record.respond_to?(:remember_me!)
|
11
|
-
record.remember_me!
|
12
|
-
|
13
|
-
warden.response.set_cookie "remember_#{scope}_token", {
|
14
|
-
:value => record.class.serialize_into_cookie(record),
|
15
|
-
:expires => record.remember_expires_at,
|
16
|
-
:path => "/"
|
17
|
-
}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Before logout hook to forget the user in the given scope, only if rememberable
|
22
|
-
# is activated for this scope. Also clear remember token to ensure the user
|
23
|
-
# won't be remembered again.
|
24
|
-
Warden::Manager.before_logout do |record, warden, scope|
|
25
|
-
if record.respond_to?(:forget_me!)
|
26
|
-
record.forget_me!
|
27
|
-
warden.response.delete_cookie "remember_#{scope}_token"
|
28
|
-
end
|
29
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Devise
|
2
|
-
module Middlewares
|
3
|
-
class Rememberable
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
auth = env['warden']
|
10
|
-
scopes = select_cookies(auth.request)
|
11
|
-
scopes.each do |scope, token|
|
12
|
-
mapping = Devise.mappings[scope]
|
13
|
-
next unless mapping && mapping.for.include?(:rememberable)
|
14
|
-
user = mapping.to.serialize_from_cookie(token)
|
15
|
-
auth.set_user(user, :scope => scope) if user
|
16
|
-
end
|
17
|
-
|
18
|
-
@app.call(env)
|
19
|
-
end
|
20
|
-
|
21
|
-
protected
|
22
|
-
|
23
|
-
def select_cookies(request)
|
24
|
-
scopes = {}
|
25
|
-
matching = /remember_(#{Devise.mappings.keys.join("|")})_token/
|
26
|
-
request.cookies.each do |key, value|
|
27
|
-
if key.to_s =~ matching
|
28
|
-
scopes[$1.to_sym] = value
|
29
|
-
end
|
30
|
-
end
|
31
|
-
scopes
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/devise/warden.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'warden'
|
3
|
-
rescue
|
4
|
-
gem 'warden'
|
5
|
-
require 'warden'
|
6
|
-
end
|
7
|
-
|
8
|
-
# Session Serialization in. This block determines how the user will be stored
|
9
|
-
# in the session. If you're using a complex object like an ActiveRecord model,
|
10
|
-
# it is not a good idea to store the complete object. An ID is sufficient.
|
11
|
-
Warden::Manager.serialize_into_session{ |user| [user.class, user.id] }
|
12
|
-
|
13
|
-
# Session Serialization out. This block gets the user out of the session.
|
14
|
-
# It should be the reverse of serializing the object into the session
|
15
|
-
Warden::Manager.serialize_from_session do |klass, id|
|
16
|
-
klass.find_by_id(id)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Setup devise strategies for Warden
|
20
|
-
require 'devise/strategies/base'
|