devise 0.9.2 → 1.0.0

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.

Files changed (54) hide show
  1. data/CHANGELOG.rdoc +11 -0
  2. data/README.rdoc +3 -2
  3. data/TODO +0 -1
  4. data/app/controllers/confirmations_controller.rb +18 -7
  5. data/app/controllers/passwords_controller.rb +18 -7
  6. data/app/controllers/registrations_controller.rb +55 -0
  7. data/app/controllers/sessions_controller.rb +17 -5
  8. data/app/controllers/unlocks_controller.rb +18 -7
  9. data/app/models/devise_mailer.rb +3 -2
  10. data/app/views/registrations/edit.html.erb +25 -0
  11. data/app/views/registrations/new.html.erb +17 -0
  12. data/app/views/sessions/new.html.erb +10 -12
  13. data/app/views/shared/_devise_links.erb +5 -1
  14. data/generators/devise_install/templates/devise.rb +3 -1
  15. data/lib/devise.rb +15 -8
  16. data/lib/devise/controllers/helpers.rb +1 -1
  17. data/lib/devise/controllers/internal_helpers.rb +15 -6
  18. data/lib/devise/controllers/url_helpers.rb +7 -7
  19. data/lib/devise/locales/en.yml +6 -0
  20. data/lib/devise/mapping.rb +9 -15
  21. data/lib/devise/models.rb +9 -16
  22. data/lib/devise/models/authenticatable.rb +38 -8
  23. data/lib/devise/models/lockable.rb +42 -24
  24. data/lib/devise/models/registerable.rb +8 -0
  25. data/lib/devise/models/timeoutable.rb +1 -1
  26. data/lib/devise/orm/active_record.rb +3 -2
  27. data/lib/devise/orm/data_mapper.rb +3 -3
  28. data/lib/devise/orm/mongo_mapper.rb +3 -3
  29. data/lib/devise/rails/routes.rb +9 -6
  30. data/lib/devise/strategies/authenticatable.rb +11 -1
  31. data/lib/devise/strategies/base.rb +5 -13
  32. data/lib/devise/strategies/http_authenticatable.rb +49 -0
  33. data/lib/devise/strategies/rememberable.rb +1 -1
  34. data/lib/devise/strategies/token_authenticatable.rb +9 -10
  35. data/lib/devise/version.rb +1 -1
  36. data/test/devise_test.rb +1 -1
  37. data/test/integration/authenticatable_test.rb +59 -43
  38. data/test/integration/http_authenticatable_test.rb +44 -0
  39. data/test/integration/registerable_test.rb +130 -0
  40. data/test/integration/token_authenticatable_test.rb +4 -4
  41. data/test/mailers/confirmation_instructions_test.rb +9 -0
  42. data/test/mapping_test.rb +14 -10
  43. data/test/models/authenticatable_test.rb +31 -9
  44. data/test/models/lockable_test.rb +8 -8
  45. data/test/models_test.rb +1 -1
  46. data/test/rails_app/app/active_record/admin.rb +1 -1
  47. data/test/rails_app/app/active_record/user.rb +4 -2
  48. data/test/rails_app/config/routes.rb +3 -2
  49. data/test/routes_test.rb +35 -0
  50. data/test/support/integration_tests_helper.rb +5 -1
  51. data/test/support/tests_helper.rb +35 -1
  52. metadata +9 -4
  53. data/lib/devise/controllers/common.rb +0 -24
  54. data/test/support/model_tests_helper.rb +0 -36
@@ -0,0 +1,130 @@
1
+ require 'test/test_helper'
2
+
3
+ class RegistrationTest < ActionController::IntegrationTest
4
+
5
+ test 'a guest admin should be able to sign in successfully' do
6
+ visit new_admin_session_path
7
+ click_link 'Sign up'
8
+
9
+ assert_template 'registrations/new'
10
+
11
+ fill_in 'email', :with => 'new_user@test.com'
12
+ fill_in 'password', :with => 'new_user123'
13
+ fill_in 'password confirmation', :with => 'new_user123'
14
+ click_button 'Sign up'
15
+
16
+ assert_contain 'You have signed up successfully.'
17
+ assert warden.authenticated?(:admin)
18
+
19
+ admin = Admin.last
20
+ assert_equal admin.email, 'new_user@test.com'
21
+ end
22
+
23
+ test 'a guest user should be able to sign up successfully and be blocked by confirmation' do
24
+ visit new_user_registration_path
25
+
26
+ fill_in 'email', :with => 'new_user@test.com'
27
+ fill_in 'password', :with => 'new_user123'
28
+ fill_in 'password confirmation', :with => 'new_user123'
29
+ click_button 'Sign up'
30
+
31
+ assert_equal true, @controller.send(:flash)[:"user_signed_up"]
32
+ assert_equal "You have signed up successfully.", @controller.send(:flash)[:notice]
33
+
34
+ # For some reason flash is not being set correctly, so instead of getting the
35
+ # "signed_up" message we get the unconfirmed one. Seems to be an issue with
36
+ # the internal redirect by the hook and the tests.
37
+ # follow_redirect!
38
+ # assert_contain 'You have signed up successfully.'
39
+ # assert_not_contain 'confirm your account'
40
+
41
+ assert_not warden.authenticated?(:user)
42
+
43
+ user = User.last
44
+ assert_equal user.email, 'new_user@test.com'
45
+ assert_not user.confirmed?
46
+ end
47
+
48
+ test 'a guest user cannot sign up with invalid information' do
49
+ visit new_user_registration_path
50
+
51
+ fill_in 'email', :with => 'invalid_email'
52
+ fill_in 'password', :with => 'new_user123'
53
+ fill_in 'password confirmation', :with => 'new_user321'
54
+ click_button 'Sign up'
55
+
56
+ assert_template 'registrations/new'
57
+ assert_have_selector '#errorExplanation'
58
+ assert_contain "Email is invalid"
59
+ assert_contain "Password doesn't match confirmation"
60
+ assert_nil User.first
61
+
62
+ assert_not warden.authenticated?(:user)
63
+ end
64
+
65
+ test 'a guest should not sign up with email/password that already exists' do
66
+ user = create_user
67
+ visit new_user_registration_path
68
+
69
+ fill_in 'email', :with => 'user@test.com'
70
+ fill_in 'password', :with => '123456'
71
+ fill_in 'password confirmation', :with => '123456'
72
+ click_button 'Sign up'
73
+
74
+ assert_template 'registrations/new'
75
+ assert_contain 'Email has already been taken'
76
+
77
+ assert_not warden.authenticated?(:user)
78
+ end
79
+
80
+ test 'a guest should not be able to change account' do
81
+ visit edit_user_registration_path
82
+ follow_redirect!
83
+ assert_template 'sessions/new'
84
+ end
85
+
86
+ test 'a signed in user should not be able to access sign up' do
87
+ sign_in_as_user
88
+ visit new_user_registration_path
89
+ assert_template 'home/index'
90
+ end
91
+
92
+ test 'a signed in user should be able to edit his account' do
93
+ sign_in_as_user
94
+ visit edit_user_registration_path
95
+
96
+ fill_in 'email', :with => 'user.new@email.com'
97
+ fill_in 'current password', :with => '123456'
98
+ click_button 'Update'
99
+
100
+ assert_template 'home/index'
101
+ assert_contain 'You updated your account successfully.'
102
+
103
+ assert_equal "user.new@email.com", User.first.email
104
+ end
105
+
106
+ test 'a signed in user should be able to edit his password' do
107
+ sign_in_as_user
108
+ visit edit_user_registration_path
109
+
110
+ fill_in 'password', :with => 'pas123'
111
+ fill_in 'password confirmation', :with => 'pas123'
112
+ fill_in 'current password', :with => '123456'
113
+ click_button 'Update'
114
+
115
+ assert_template 'home/index'
116
+ assert_contain 'You updated your account successfully.'
117
+
118
+ assert User.first.valid_password?('pas123')
119
+ end
120
+
121
+ test 'a signed in user should be able to cancel his account' do
122
+ sign_in_as_user
123
+ visit edit_user_registration_path
124
+
125
+ click_link "Cancel my account"
126
+ assert_contain "Bye! Your account was successfully cancelled. We hope to see you again soon."
127
+
128
+ assert User.all.empty?
129
+ end
130
+ end
@@ -2,7 +2,7 @@ require 'test/test_helper'
2
2
 
3
3
  class TokenAuthenticationTest < ActionController::IntegrationTest
4
4
 
5
- test 'sign in user should authenticate with valid authentication token and proper authentication token key' do
5
+ test 'sign in should authenticate with valid authentication token and proper authentication token key' do
6
6
  swap Devise, :token_authentication_key => :secret_token do
7
7
  sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
8
8
 
@@ -13,7 +13,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
13
13
  end
14
14
  end
15
15
 
16
- test 'user signing in with valid authentication token - but improper authentication token key - return to sign in form with error message' do
16
+ test 'signing in with valid authentication token - but improper authentication token key - return to sign in form with error message' do
17
17
  swap Devise, :token_authentication_key => :donald_duck_token do
18
18
  sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
19
19
  assert_redirected_to new_user_session_path(:unauthenticated => true)
@@ -25,7 +25,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
25
25
  end
26
26
  end
27
27
 
28
- test 'user signing in with invalid authentication token should return to sign in form with error message' do
28
+ test 'signing in with invalid authentication token should return to sign in form with error message' do
29
29
  store_translations :en, :devise => {:sessions => {:invalid_token => 'LOL, that was not a single character correct.'}} do
30
30
  sign_in_as_new_user_with_token(:auth_token => '*** INVALID TOKEN ***')
31
31
  assert_redirected_to new_user_session_path(:invalid_token => true)
@@ -40,7 +40,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
40
40
 
41
41
  private
42
42
 
43
- def sign_in_as_new_user_with_token(options = {}, &block)
43
+ def sign_in_as_new_user_with_token(options = {})
44
44
  options[:auth_token_key] ||= Devise.token_authentication_key
45
45
  options[:auth_token] ||= VALID_AUTHENTICATION_TOKEN
46
46
 
@@ -63,6 +63,15 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
63
63
  end
64
64
  end
65
65
 
66
+ test 'renders a scoped if scoped_views is set in the mailer class' do
67
+ begin
68
+ DeviseMailer.scoped_views = true
69
+ assert_equal user.email, mail.body
70
+ ensure
71
+ DeviseMailer.send :remove_instance_variable, :@scoped_views
72
+ end
73
+ end
74
+
66
75
  test 'mailer sender accepts a proc' do
67
76
  swap Devise, :mailer_sender => lambda { "another@example.com" } do
68
77
  assert_equal ['another@example.com'], mail.from
@@ -63,18 +63,22 @@ class MappingTest < ActiveSupport::TestCase
63
63
 
64
64
  test 'return default path names' do
65
65
  mapping = Devise.mappings[:user]
66
- assert_equal 'sign_in', mapping.path_names[:sign_in]
67
- assert_equal 'sign_out', mapping.path_names[:sign_out]
68
- assert_equal 'password', mapping.path_names[:password]
66
+ assert_equal 'sign_in', mapping.path_names[:sign_in]
67
+ assert_equal 'sign_out', mapping.path_names[:sign_out]
68
+ assert_equal 'password', mapping.path_names[:password]
69
69
  assert_equal 'confirmation', mapping.path_names[:confirmation]
70
+ assert_equal 'sign_up', mapping.path_names[:sign_up]
71
+ assert_equal 'unlock', mapping.path_names[:unlock]
70
72
  end
71
73
 
72
74
  test 'allow custom path names to be given' do
73
75
  mapping = Devise.mappings[:manager]
74
- assert_equal 'login', mapping.path_names[:sign_in]
75
- assert_equal 'logout', mapping.path_names[:sign_out]
76
- assert_equal 'secret', mapping.path_names[:password]
76
+ assert_equal 'login', mapping.path_names[:sign_in]
77
+ assert_equal 'logout', mapping.path_names[:sign_out]
78
+ assert_equal 'secret', mapping.path_names[:password]
77
79
  assert_equal 'verification', mapping.path_names[:confirmation]
80
+ assert_equal 'register', mapping.path_names[:sign_up]
81
+ assert_equal 'unblock', mapping.path_names[:unlock]
78
82
  end
79
83
 
80
84
  test 'has an empty path as default path prefix' do
@@ -86,7 +90,7 @@ class MappingTest < ActiveSupport::TestCase
86
90
  mapping = Devise.mappings[:manager]
87
91
  assert_equal '/:locale/', mapping.path_prefix
88
92
  end
89
-
93
+
90
94
  test 'retrieve as from the proper position' do
91
95
  assert_equal 1, Devise.mappings[:user].as_position
92
96
  assert_equal 2, Devise.mappings[:manager].as_position
@@ -96,13 +100,13 @@ class MappingTest < ActiveSupport::TestCase
96
100
  assert_equal '/users', Devise.mappings[:user].raw_path
97
101
  assert_equal '/:locale/accounts', Devise.mappings[:manager].raw_path
98
102
  end
99
-
103
+
100
104
  test 'raw path ignores the relative_url_root' do
101
105
  swap ActionController::Base, :relative_url_root => "/abc" do
102
106
  assert_equal '/users', Devise.mappings[:user].raw_path
103
107
  end
104
108
  end
105
-
109
+
106
110
  test 'parsed path is returned' do
107
111
  begin
108
112
  Devise.default_url_options {{ :locale => I18n.locale }}
@@ -112,7 +116,7 @@ class MappingTest < ActiveSupport::TestCase
112
116
  Devise.default_url_options {{ }}
113
117
  end
114
118
  end
115
-
119
+
116
120
  test 'parsed path adds in the relative_url_root' do
117
121
  swap ActionController::Base, :relative_url_root => '/abc' do
118
122
  assert_equal '/abc/users', Devise.mappings[:user].parsed_path
@@ -119,7 +119,7 @@ class AuthenticatableTest < ActiveSupport::TestCase
119
119
 
120
120
  test 'should use authentication keys to retrieve users' do
121
121
  swap Devise, :authentication_keys => [:username] do
122
- user = create_user(:username => "josevalim")
122
+ user = create_user
123
123
  assert_nil User.authenticate(:email => user.email, :password => user.password)
124
124
  assert_not_nil User.authenticate(:username => user.username, :password => user.password)
125
125
  end
@@ -130,29 +130,51 @@ class AuthenticatableTest < ActiveSupport::TestCase
130
130
  assert_not_nil Admin.authenticate(:email => admin.email, :password => admin.password)
131
131
  end
132
132
 
133
- test 'should respond to old password' do
134
- assert new_user.respond_to?(:old_password)
133
+ test 'should respond to current password' do
134
+ assert new_user.respond_to?(:current_password)
135
135
  end
136
136
 
137
- test 'should update password with valid old password' do
137
+ test 'should update password with valid current password' do
138
138
  user = create_user
139
- assert user.update_with_password(:old_password => '123456',
139
+ assert user.update_with_password(:current_password => '123456',
140
140
  :password => 'pass321', :password_confirmation => 'pass321')
141
141
  assert user.reload.valid_password?('pass321')
142
142
  end
143
143
 
144
- test 'should add an error to old password when it is invalid' do
144
+ test 'should add an error to current password when it is invalid' do
145
145
  user = create_user
146
- assert_not user.update_with_password(:old_password => 'other',
146
+ assert_not user.update_with_password(:current_password => 'other',
147
147
  :password => 'pass321', :password_confirmation => 'pass321')
148
148
  assert user.reload.valid_password?('123456')
149
- assert_match /invalid/, user.errors[:old_password]
149
+ assert_match /invalid/, user.errors[:current_password]
150
+ end
151
+
152
+ test 'should add an error to current password when it is blank' do
153
+ user = create_user
154
+ assert_not user.update_with_password(:password => 'pass321',
155
+ :password_confirmation => 'pass321')
156
+ assert user.reload.valid_password?('123456')
157
+ assert_match /blank/, user.errors[:current_password]
158
+ end
159
+
160
+ test 'should ignore password and its confirmation if they are blank' do
161
+ user = create_user
162
+ assert user.update_with_password(:current_password => '123456', :email => "new@email.com")
163
+ assert_equal "new@email.com", user.email
150
164
  end
151
165
 
152
166
  test 'should not update password with invalid confirmation' do
153
167
  user = create_user
154
- assert_not user.update_with_password(:old_password => '123456',
168
+ assert_not user.update_with_password(:current_password => '123456',
155
169
  :password => 'pass321', :password_confirmation => 'other')
156
170
  assert user.reload.valid_password?('123456')
157
171
  end
172
+
173
+ test 'should clean up password fields on failure' do
174
+ user = create_user
175
+ assert_not user.update_with_password(:current_password => '123456',
176
+ :password => 'pass321', :password_confirmation => 'other')
177
+ assert user.password.blank?
178
+ assert user.password_confirmation.blank?
179
+ end
158
180
  end
@@ -1,25 +1,25 @@
1
1
  require 'test/test_helper'
2
2
 
3
3
  class LockableTest < ActiveSupport::TestCase
4
-
4
+
5
5
  def setup
6
6
  setup_mailer
7
7
  end
8
-
8
+
9
9
  test "should increment failed attempts on unsuccessful authentication" do
10
10
  user = create_user
11
11
  assert_equal 0, user.failed_attempts
12
12
  authenticated_user = User.authenticate(:email => user.email, :password => "anotherpassword")
13
13
  assert_equal 1, user.reload.failed_attempts
14
14
  end
15
-
15
+
16
16
  test "should lock account base on maximum_attempts" do
17
17
  user = create_user
18
18
  attempts = Devise.maximum_attempts + 1
19
19
  attempts.times { authenticated_user = User.authenticate(:email => user.email, :password => "anotherpassword") }
20
20
  assert user.reload.locked?
21
21
  end
22
-
22
+
23
23
  test "should respect maximum attempts configuration" do
24
24
  user = create_user
25
25
  swap Devise, :maximum_attempts => 2 do
@@ -27,7 +27,7 @@ class LockableTest < ActiveSupport::TestCase
27
27
  assert user.reload.locked?
28
28
  end
29
29
  end
30
-
30
+
31
31
  test "should clear failed_attempts on successfull sign in" do
32
32
  user = create_user
33
33
  User.authenticate(:email => user.email, :password => "anotherpassword")
@@ -61,8 +61,8 @@ class LockableTest < ActiveSupport::TestCase
61
61
  assert_nil user.reload.unlock_token
62
62
  assert 0, user.reload.failed_attempts
63
63
  end
64
-
65
- test 'should not unlcok an unlocked user' do
64
+
65
+ test 'should not unlock an unlocked user' do
66
66
  user = create_user
67
67
  assert_not user.unlock!
68
68
  assert_match /not locked/, user.errors[:email]
@@ -199,4 +199,4 @@ class LockableTest < ActiveSupport::TestCase
199
199
  assert_equal 'not locked', user.errors[:email]
200
200
  end
201
201
 
202
- end
202
+ end
@@ -23,7 +23,7 @@ class ActiveRecordTest < ActiveSupport::TestCase
23
23
  end
24
24
 
25
25
  test 'add modules cherry pick' do
26
- assert_include_modules Admin, :authenticatable, :timeoutable
26
+ assert_include_modules Admin, :authenticatable, :registerable, :timeoutable
27
27
  end
28
28
 
29
29
  test 'set a default value for stretches' do
@@ -1,5 +1,5 @@
1
1
  class Admin < ActiveRecord::Base
2
- devise :authenticatable, :timeoutable
2
+ devise :authenticatable, :registerable, :timeoutable
3
3
 
4
4
  def self.find_for_authentication(conditions)
5
5
  last(:conditions => conditions)
@@ -1,5 +1,7 @@
1
1
  class User < ActiveRecord::Base
2
- devise :authenticatable, :confirmable, :recoverable, :rememberable, :trackable,
3
- :validatable, :timeoutable, :lockable, :token_authenticatable
2
+ devise :authenticatable, :confirmable, :lockable, :recoverable,
3
+ :registerable, :rememberable, :timeoutable, :token_authenticatable,
4
+ :trackable, :validatable
5
+
4
6
  attr_accessible :username, :email, :password, :password_confirmation
5
7
  end
@@ -3,8 +3,9 @@ ActionController::Routing::Routes.draw do |map|
3
3
  map.devise_for :admin, :as => 'admin_area'
4
4
  map.devise_for :accounts, :scope => 'manager', :path_prefix => ':locale',
5
5
  :class_name => "User", :requirements => { :extra => 'value' }, :path_names => {
6
- :sign_in => 'login', :sign_out => 'logout', :password => 'secret',
7
- :confirmation => 'verification', :unlock => 'unblock'
6
+ :sign_in => 'login', :sign_out => 'logout',
7
+ :password => 'secret', :confirmation => 'verification',
8
+ :unlock => 'unblock', :sign_up => 'register'
8
9
  }
9
10
 
10
11
  map.resources :users, :only => [:index], :member => { :expire => :get }
@@ -42,6 +42,38 @@ class MapRoutingTest < ActionController::TestCase
42
42
  assert_recognizes({:controller => 'passwords', :action => 'update'}, {:path => 'users/password', :method => :put})
43
43
  end
44
44
 
45
+ test 'map new user unlock' do
46
+ assert_recognizes({:controller => 'unlocks', :action => 'new'}, 'users/unlock/new')
47
+ end
48
+
49
+ test 'map create user unlock' do
50
+ assert_recognizes({:controller => 'unlocks', :action => 'create'}, {:path => 'users/unlock', :method => :post})
51
+ end
52
+
53
+ test 'map show user unlock' do
54
+ assert_recognizes({:controller => 'unlocks', :action => 'show'}, {:path => 'users/unlock', :method => :get})
55
+ end
56
+
57
+ test 'map new user registration' do
58
+ assert_recognizes({:controller => 'registrations', :action => 'new'}, 'users/sign_up')
59
+ end
60
+
61
+ test 'map create user registration' do
62
+ assert_recognizes({:controller => 'registrations', :action => 'create'}, {:path => 'users', :method => :post})
63
+ end
64
+
65
+ test 'map edit user registration' do
66
+ assert_recognizes({:controller => 'registrations', :action => 'edit'}, {:path => 'users/edit', :method => :get})
67
+ end
68
+
69
+ test 'map update user registration' do
70
+ assert_recognizes({:controller => 'registrations', :action => 'update'}, {:path => 'users', :method => :put})
71
+ end
72
+
73
+ test 'map destroy user registration' do
74
+ assert_recognizes({:controller => 'registrations', :action => 'destroy'}, {:path => 'users', :method => :delete})
75
+ end
76
+
45
77
  test 'map admin session with :as option' do
46
78
  assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => 'admin_area/sign_in', :method => :get})
47
79
  end
@@ -72,4 +104,7 @@ class MapRoutingTest < ActionController::TestCase
72
104
  assert_recognizes({:controller => 'unlocks', :action => 'new', :locale => 'en', :extra => 'value'}, '/en/accounts/unblock/new')
73
105
  end
74
106
 
107
+ test 'map account with custom path name for registration' do
108
+ assert_recognizes({:controller => 'registrations', :action => 'new', :locale => 'en', :extra => 'value'}, '/en/accounts/register')
109
+ end
75
110
  end