devise 1.1.rc0 → 1.1.rc1
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 -4
- data/Gemfile +1 -1
- data/README.rdoc +27 -22
- data/TODO +0 -1
- data/app/helpers/devise_helper.rb +17 -0
- data/app/{models → mailers}/devise/mailer.rb +8 -1
- data/app/views/devise/confirmations/new.html.erb +2 -2
- data/app/views/devise/passwords/edit.html.erb +2 -2
- data/app/views/devise/passwords/new.html.erb +2 -2
- data/app/views/devise/registrations/edit.html.erb +2 -2
- data/app/views/devise/registrations/new.html.erb +3 -2
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/views/devise/shared/_links.erb +1 -1
- data/app/views/devise/unlocks/new.html.erb +2 -2
- data/config/locales/en.yml +1 -1
- data/lib/devise/controllers/internal_helpers.rb +1 -0
- data/lib/devise/controllers/scoped_views.rb +1 -1
- data/lib/devise/hooks/activatable.rb +1 -20
- data/lib/devise/hooks/forgetable.rb +10 -0
- data/lib/devise/hooks/rememberable.rb +4 -14
- data/lib/devise/mapping.rb +21 -9
- data/lib/devise/models.rb +21 -9
- data/lib/devise/models/authenticatable.rb +40 -4
- data/lib/devise/models/confirmable.rb +0 -4
- data/lib/devise/models/database_authenticatable.rb +6 -5
- data/lib/devise/models/lockable.rb +6 -10
- data/lib/devise/models/rememberable.rb +1 -0
- data/lib/devise/models/token_authenticatable.rb +14 -35
- data/lib/devise/modules.rb +0 -1
- data/lib/devise/rails.rb +2 -0
- data/lib/devise/rails/routes.rb +26 -27
- data/lib/devise/strategies/authenticatable.rb +0 -12
- data/lib/devise/strategies/base.rb +14 -0
- data/lib/devise/strategies/database_authenticatable.rb +1 -0
- data/lib/devise/strategies/rememberable.rb +3 -1
- data/lib/devise/strategies/token_authenticatable.rb +4 -1
- data/lib/devise/version.rb +1 -1
- data/lib/generators/devise/devise_generator.rb +1 -1
- data/lib/generators/devise/templates/migration.rb +2 -0
- data/lib/generators/devise_install/templates/README +6 -0
- data/lib/generators/devise_views/devise_views_generator.rb +2 -2
- data/test/integration/confirmable_test.rb +2 -2
- data/test/integration/database_authenticatable_test.rb +7 -7
- data/test/integration/lockable_test.rb +10 -2
- data/test/integration/recoverable_test.rb +3 -3
- data/test/integration/registerable_test.rb +1 -1
- data/test/integration/rememberable_test.rb +1 -1
- data/test/mapping_test.rb +11 -9
- data/test/models/lockable_test.rb +3 -0
- data/test/models/token_authenticatable_test.rb +4 -11
- data/test/models_test.rb +9 -2
- data/test/rails_app/app/active_record/admin.rb +1 -1
- data/test/rails_app/app/active_record/user.rb +1 -1
- data/test/rails_app/app/data_mapper/admin.rb +1 -2
- data/test/rails_app/app/data_mapper/user.rb +1 -1
- data/test/rails_app/app/mongoid/admin.rb +1 -1
- data/test/rails_app/app/mongoid/user.rb +1 -1
- data/test/rails_app/config/application.rb +0 -4
- data/test/rails_app/config/environments/test.rb +2 -0
- data/test/rails_app/config/initializers/secret_token.rb +2 -0
- data/test/rails_app/config/routes.rb +2 -2
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +1 -1
- metadata +7 -5
- data/lib/devise/models/activatable.rb +0 -16
@@ -14,18 +14,6 @@ module Devise
|
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
18
|
-
def validate(resource, &block)
|
19
|
-
result = resource && resource.valid_for_authentication?(&block)
|
20
|
-
|
21
|
-
case result
|
22
|
-
when Symbol, String
|
23
|
-
fail!(result)
|
24
|
-
else
|
25
|
-
result
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
17
|
# Check if this is strategy is valid for http authentication.
|
30
18
|
def valid_for_http_auth?
|
31
19
|
http_authenticatable? && request.authorization && with_authentication_hash(http_auth_hash)
|
@@ -11,9 +11,23 @@ module Devise
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
protected
|
15
|
+
|
14
16
|
def succeeded?
|
15
17
|
@result == :success
|
16
18
|
end
|
19
|
+
|
20
|
+
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
21
|
+
def validate(resource, &block)
|
22
|
+
result = resource && resource.valid_for_authentication?(&block)
|
23
|
+
|
24
|
+
case result
|
25
|
+
when Symbol, String
|
26
|
+
fail!(result)
|
27
|
+
else
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
17
31
|
end
|
18
32
|
end
|
19
33
|
end
|
@@ -16,7 +16,9 @@ module Devise
|
|
16
16
|
# the record in the database. If the attempt fails, we pass to another
|
17
17
|
# strategy handle the authentication.
|
18
18
|
def authenticate!
|
19
|
-
|
19
|
+
resource = mapping.to.serialize_from_cookie(*remember_cookie)
|
20
|
+
|
21
|
+
if validate(resource)
|
20
22
|
success!(resource)
|
21
23
|
else
|
22
24
|
cookies.delete(remember_key)
|
@@ -11,7 +11,10 @@ module Devise
|
|
11
11
|
# you can pass anything and it will simply be ignored.
|
12
12
|
class TokenAuthenticatable < Authenticatable
|
13
13
|
def authenticate!
|
14
|
-
|
14
|
+
resource = mapping.to.find_for_token_authentication(authentication_hash)
|
15
|
+
|
16
|
+
if validate(resource)
|
17
|
+
resource.after_token_authentication
|
15
18
|
success!(resource)
|
16
19
|
else
|
17
20
|
fail(:invalid_token)
|
data/lib/devise/version.rb
CHANGED
@@ -37,7 +37,7 @@ class DeviseGenerator < Rails::Generators::NamedBase
|
|
37
37
|
def inject_devise_config_into_model
|
38
38
|
inject_into_class model_path, class_name, <<-CONTENT
|
39
39
|
# Include default devise modules. Others available are:
|
40
|
-
# :token_authenticatable, :lockable
|
40
|
+
# :token_authenticatable, :lockable and :timeoutable
|
41
41
|
devise :database_authenticatable, :registerable, :confirmable,
|
42
42
|
:recoverable, :rememberable, :trackable, :validatable
|
43
43
|
|
@@ -6,7 +6,9 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
|
6
6
|
t.recoverable
|
7
7
|
t.rememberable
|
8
8
|
t.trackable
|
9
|
+
|
9
10
|
# t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
|
11
|
+
# t.token_authenticatable
|
10
12
|
|
11
13
|
t.timestamps
|
12
14
|
end
|
@@ -16,4 +16,10 @@ Some setup you must do manually if you haven't yet:
|
|
16
16
|
|
17
17
|
root :to => "home#index"
|
18
18
|
|
19
|
+
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
|
20
|
+
For example:
|
21
|
+
|
22
|
+
<p class="notice"><%= notice %></p>
|
23
|
+
<p class="alert"><%= alert %></p>
|
24
|
+
|
19
25
|
===============================================================================
|
@@ -18,7 +18,7 @@ class DeviseViewsGenerator < Rails::Generators::Base
|
|
18
18
|
verify_haml_version
|
19
19
|
create_and_copy_haml_views
|
20
20
|
else
|
21
|
-
directory "devise", "app/views
|
21
|
+
directory "devise", "app/views/#{scope || 'devise'}"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -56,7 +56,7 @@ class DeviseViewsGenerator < Rails::Generators::Base
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
directory haml_root, "app/views
|
59
|
+
directory haml_root, "app/views/#{scope || 'devise'}"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -26,7 +26,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|
26
26
|
|
27
27
|
assert_response :success
|
28
28
|
assert_template 'confirmations/new'
|
29
|
-
assert_have_selector '#
|
29
|
+
assert_have_selector '#error_explanation'
|
30
30
|
assert_contain /Confirmation token(.*)invalid/
|
31
31
|
end
|
32
32
|
|
@@ -49,7 +49,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|
49
49
|
visit_user_confirmation_with_token(user.confirmation_token)
|
50
50
|
|
51
51
|
assert_template 'confirmations/new'
|
52
|
-
assert_have_selector '#
|
52
|
+
assert_have_selector '#error_explanation'
|
53
53
|
assert_contain 'already confirmed'
|
54
54
|
end
|
55
55
|
|
@@ -284,15 +284,15 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|
284
284
|
end
|
285
285
|
|
286
286
|
# Access
|
287
|
-
test 'render 404 on roles without
|
288
|
-
|
289
|
-
|
290
|
-
|
287
|
+
test 'render 404 on roles without routes' do
|
288
|
+
assert_raise ActionController::RoutingError do
|
289
|
+
get '/admin_area/password/new'
|
290
|
+
end
|
291
291
|
end
|
292
292
|
|
293
293
|
test 'render 404 on roles without mapping' do
|
294
|
-
|
295
|
-
|
296
|
-
|
294
|
+
assert_raise AbstractController::ActionNotFound do
|
295
|
+
get '/sign_in'
|
296
|
+
end
|
297
297
|
end
|
298
298
|
end
|
@@ -37,8 +37,16 @@ class LockTest < ActionController::IntegrationTest
|
|
37
37
|
end
|
38
38
|
|
39
39
|
test 'unlocked pages should not be available if email strategy is disabled' do
|
40
|
-
visit
|
40
|
+
visit "/users/sign_in"
|
41
|
+
click_link "Didn't receive unlock instructions?"
|
42
|
+
|
41
43
|
swap Devise, :unlock_strategy => :time do
|
44
|
+
visit "/users/sign_in"
|
45
|
+
|
46
|
+
assert_raise Webrat::NotFoundError do
|
47
|
+
click_link "Didn't receive unlock instructions?"
|
48
|
+
end
|
49
|
+
|
42
50
|
assert_raise AbstractController::ActionNotFound do
|
43
51
|
visit new_user_unlock_path
|
44
52
|
end
|
@@ -50,7 +58,7 @@ class LockTest < ActionController::IntegrationTest
|
|
50
58
|
|
51
59
|
assert_response :success
|
52
60
|
assert_template 'unlocks/new'
|
53
|
-
assert_have_selector '#
|
61
|
+
assert_have_selector '#error_explanation'
|
54
62
|
assert_contain /Unlock token(.*)invalid/
|
55
63
|
end
|
56
64
|
|
@@ -77,7 +77,7 @@ class PasswordTest < ActionController::IntegrationTest
|
|
77
77
|
|
78
78
|
assert_response :success
|
79
79
|
assert_template 'passwords/edit'
|
80
|
-
assert_have_selector '#
|
80
|
+
assert_have_selector '#error_explanation'
|
81
81
|
assert_contain /Reset password token(.*)invalid/
|
82
82
|
assert_not user.reload.valid_password?('987654321')
|
83
83
|
end
|
@@ -91,7 +91,7 @@ class PasswordTest < ActionController::IntegrationTest
|
|
91
91
|
|
92
92
|
assert_response :success
|
93
93
|
assert_template 'passwords/edit'
|
94
|
-
assert_have_selector '#
|
94
|
+
assert_have_selector '#error_explanation'
|
95
95
|
assert_contain 'Password doesn\'t match confirmation'
|
96
96
|
assert_not user.reload.valid_password?('987654321')
|
97
97
|
end
|
@@ -113,7 +113,7 @@ class PasswordTest < ActionController::IntegrationTest
|
|
113
113
|
fill_in 'Password confirmation', :with => 'other_password'
|
114
114
|
end
|
115
115
|
assert_response :success
|
116
|
-
assert_have_selector '#
|
116
|
+
assert_have_selector '#error_explanation'
|
117
117
|
assert_not user.reload.valid_password?('987654321')
|
118
118
|
|
119
119
|
reset_password :reset_password_token => user.reload.reset_password_token, :visit => false
|
@@ -48,7 +48,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
|
48
48
|
click_button 'Sign up'
|
49
49
|
|
50
50
|
assert_template 'registrations/new'
|
51
|
-
assert_have_selector '#
|
51
|
+
assert_have_selector '#error_explanation'
|
52
52
|
assert_contain "Email is invalid"
|
53
53
|
assert_contain "Password doesn't match confirmation"
|
54
54
|
assert_nil User.first
|
@@ -12,7 +12,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def generate_signed_cookie(raw_cookie)
|
15
|
-
request = ActionDispatch::
|
15
|
+
request = ActionDispatch::TestRequest.new
|
16
16
|
request.cookie_jar.signed['raw_cookie'] = raw_cookie
|
17
17
|
request.cookie_jar['raw_cookie']
|
18
18
|
end
|
data/test/mapping_test.rb
CHANGED
@@ -6,15 +6,17 @@ class MappingTest < ActiveSupport::TestCase
|
|
6
6
|
mapping = Devise.mappings[:user]
|
7
7
|
assert_equal User, mapping.to
|
8
8
|
assert_equal User.devise_modules, mapping.modules
|
9
|
-
assert_equal :users, mapping.
|
9
|
+
assert_equal :users, mapping.plural
|
10
|
+
assert_equal :user, mapping.singular
|
11
|
+
assert_equal :users, mapping.path
|
10
12
|
end
|
11
13
|
|
12
|
-
test 'allows
|
13
|
-
assert_equal :admin_area, Devise.mappings[:admin].
|
14
|
+
test 'allows path to be given' do
|
15
|
+
assert_equal :admin_area, Devise.mappings[:admin].path
|
14
16
|
end
|
15
17
|
|
16
|
-
test 'allows custom
|
17
|
-
assert_equal :accounts, Devise.mappings[:manager].
|
18
|
+
test 'allows custom singular to be given' do
|
19
|
+
assert_equal :accounts, Devise.mappings[:manager].path
|
18
20
|
end
|
19
21
|
|
20
22
|
test 'allows a controller depending on the mapping' do
|
@@ -91,13 +93,13 @@ class MappingTest < ActiveSupport::TestCase
|
|
91
93
|
end
|
92
94
|
|
93
95
|
test 'retrieve as from the proper position' do
|
94
|
-
assert_equal 1, Devise.mappings[:user].
|
95
|
-
assert_equal 2, Devise.mappings[:manager].
|
96
|
+
assert_equal 1, Devise.mappings[:user].segment_position
|
97
|
+
assert_equal 2, Devise.mappings[:manager].segment_position
|
96
98
|
end
|
97
99
|
|
98
100
|
test 'path is returned with path prefix and as' do
|
99
|
-
assert_equal '/users', Devise.mappings[:user].
|
100
|
-
assert_equal '/:locale/accounts', Devise.mappings[:manager].
|
101
|
+
assert_equal '/users', Devise.mappings[:user].full_path
|
102
|
+
assert_equal '/:locale/accounts', Devise.mappings[:manager].full_path
|
101
103
|
end
|
102
104
|
|
103
105
|
test 'magic predicates' do
|
@@ -7,6 +7,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
7
7
|
|
8
8
|
test "should respect maximum attempts configuration" do
|
9
9
|
user = create_user
|
10
|
+
user.confirm!
|
10
11
|
swap Devise, :maximum_attempts => 2 do
|
11
12
|
3.times { user.valid_for_authentication?{ false } }
|
12
13
|
assert user.reload.access_locked?
|
@@ -15,6 +16,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
15
16
|
|
16
17
|
test "should clear failed_attempts on successfull validation" do
|
17
18
|
user = create_user
|
19
|
+
user.confirm!
|
18
20
|
user.valid_for_authentication?{ false }
|
19
21
|
assert_equal 1, user.reload.failed_attempts
|
20
22
|
user.valid_for_authentication?{ true }
|
@@ -23,6 +25,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
23
25
|
|
24
26
|
test "should not touch failed_attempts if lock_strategy is none" do
|
25
27
|
user = create_user
|
28
|
+
user.confirm!
|
26
29
|
swap Devise, :lock_strategy => :none, :maximum_attempts => 2 do
|
27
30
|
3.times { user.valid_for_authentication?{ false } }
|
28
31
|
assert !user.access_locked?
|
@@ -2,13 +2,6 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class TokenAuthenticatableTest < ActiveSupport::TestCase
|
4
4
|
|
5
|
-
test 'should generate friendly authentication token on create' do
|
6
|
-
User.expects(:authentication_token).returns(VALID_AUTHENTICATION_TOKEN)
|
7
|
-
user = create_user
|
8
|
-
assert_present user.authentication_token
|
9
|
-
assert_equal VALID_AUTHENTICATION_TOKEN, user.authentication_token
|
10
|
-
end
|
11
|
-
|
12
5
|
test 'should reset authentication token' do
|
13
6
|
user = new_user
|
14
7
|
user.reset_authentication_token
|
@@ -26,18 +19,18 @@ class TokenAuthenticatableTest < ActiveSupport::TestCase
|
|
26
19
|
end
|
27
20
|
|
28
21
|
test 'should authenticate a valid user with authentication token and return it' do
|
29
|
-
User.expects(:authentication_token).returns(VALID_AUTHENTICATION_TOKEN)
|
30
22
|
user = create_user
|
23
|
+
user.ensure_authentication_token!
|
31
24
|
user.confirm!
|
32
|
-
authenticated_user = User.
|
25
|
+
authenticated_user = User.find_for_token_authentication(:auth_token => user.authentication_token)
|
33
26
|
assert_equal authenticated_user, user
|
34
27
|
end
|
35
28
|
|
36
29
|
test 'should return nil when authenticating an invalid user by authentication token' do
|
37
|
-
User.expects(:authentication_token).returns(VALID_AUTHENTICATION_TOKEN)
|
38
30
|
user = create_user
|
31
|
+
user.ensure_authentication_token!
|
39
32
|
user.confirm!
|
40
|
-
authenticated_user = User.
|
33
|
+
authenticated_user = User.find_for_token_authentication(:auth_token => user.authentication_token.reverse)
|
41
34
|
assert_nil authenticated_user
|
42
35
|
end
|
43
36
|
|
data/test/models_test.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class Configurable < User
|
4
|
-
devise :
|
4
|
+
devise :database_authenticatable, :confirmable, :rememberable, :timeoutable, :lockable,
|
5
5
|
:stretches => 15, :pepper => 'abcdef', :confirm_within => 5.days,
|
6
6
|
:remember_for => 7.days, :timeout_in => 15.minutes, :unlock_in => 10.days
|
7
7
|
end
|
8
8
|
|
9
|
+
class Inheritable < Admin
|
10
|
+
end
|
11
|
+
|
9
12
|
class ActiveRecordTest < ActiveSupport::TestCase
|
10
13
|
def include_module?(klass, mod)
|
11
14
|
klass.devise_modules.include?(mod) &&
|
@@ -22,10 +25,14 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
25
|
-
test '
|
28
|
+
test 'can cherry pick modules' do
|
26
29
|
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable
|
27
30
|
end
|
28
31
|
|
32
|
+
test 'chosen modules are inheritable' do
|
33
|
+
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable
|
34
|
+
end
|
35
|
+
|
29
36
|
test 'order of module inclusion' do
|
30
37
|
correct_module_order = [:database_authenticatable, :recoverable, :registerable, :timeoutable]
|
31
38
|
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
-
devise :
|
2
|
+
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
3
3
|
:registerable, :rememberable, :timeoutable, :token_authenticatable,
|
4
4
|
:trackable, :validatable
|
5
5
|
|
@@ -4,10 +4,9 @@ class Admin
|
|
4
4
|
property :id, Serial
|
5
5
|
property :username, String
|
6
6
|
|
7
|
-
devise :
|
7
|
+
devise :database_authenticatable, :registerable, :timeoutable, :recoverable
|
8
8
|
|
9
9
|
def self.create!(*args)
|
10
10
|
create(*args)
|
11
11
|
end
|
12
|
-
|
13
12
|
end
|
@@ -4,7 +4,7 @@ class User
|
|
4
4
|
property :id, Serial
|
5
5
|
property :username, String
|
6
6
|
|
7
|
-
devise :
|
7
|
+
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
8
8
|
:registerable, :rememberable, :timeoutable, :token_authenticatable,
|
9
9
|
:trackable, :validatable
|
10
10
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Admin
|
2
2
|
include Mongoid::Document
|
3
3
|
|
4
|
-
devise :
|
4
|
+
devise :database_authenticatable, :timeoutable, :registerable, :recoverable
|
5
5
|
|
6
6
|
def self.last(options={})
|
7
7
|
options.delete(:order) if options[:order] == "id"
|
@@ -3,7 +3,7 @@ class User
|
|
3
3
|
|
4
4
|
field :created_at, :type => DateTime
|
5
5
|
|
6
|
-
devise :
|
6
|
+
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
7
7
|
:registerable, :rememberable, :timeoutable, :token_authenticatable,
|
8
8
|
:trackable, :validatable
|
9
9
|
|