devise 3.1.2 → 3.2.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 (62) hide show
  1. data/CHANGELOG.md +111 -99
  2. data/Gemfile.lock +1 -1
  3. data/README.md +2 -2
  4. data/app/controllers/devise/confirmations_controller.rb +2 -9
  5. data/app/controllers/devise/passwords_controller.rb +1 -1
  6. data/app/controllers/devise/registrations_controller.rb +6 -6
  7. data/app/controllers/devise/sessions_controller.rb +3 -3
  8. data/app/controllers/devise/unlocks_controller.rb +1 -1
  9. data/app/controllers/devise_controller.rb +6 -2
  10. data/app/mailers/devise/mailer.rb +15 -13
  11. data/config/locales/en.yml +1 -2
  12. data/gemfiles/Gemfile.rails-3.2.x.lock +1 -1
  13. data/lib/devise.rb +23 -12
  14. data/lib/devise/controllers/helpers.rb +16 -84
  15. data/lib/devise/controllers/rememberable.rb +2 -12
  16. data/lib/devise/controllers/sign_in_out.rb +103 -0
  17. data/lib/devise/failure_app.rb +11 -2
  18. data/lib/devise/hooks/forgetable.rb +1 -1
  19. data/lib/devise/hooks/proxy.rb +21 -0
  20. data/lib/devise/hooks/rememberable.rb +1 -1
  21. data/lib/devise/hooks/timeoutable.rb +4 -1
  22. data/lib/devise/models.rb +0 -5
  23. data/lib/devise/models/authenticatable.rb +8 -9
  24. data/lib/devise/models/confirmable.rb +0 -4
  25. data/lib/devise/models/database_authenticatable.rb +17 -7
  26. data/lib/devise/models/lockable.rb +6 -4
  27. data/lib/devise/models/recoverable.rb +0 -8
  28. data/lib/devise/modules.rb +0 -1
  29. data/lib/devise/rails/routes.rb +29 -15
  30. data/lib/devise/strategies/database_authenticatable.rb +3 -6
  31. data/lib/devise/test_helpers.rb +1 -0
  32. data/lib/devise/version.rb +1 -1
  33. data/lib/generators/mongoid/devise_generator.rb +0 -3
  34. data/lib/generators/templates/devise.rb +6 -10
  35. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  36. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  37. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  38. data/test/controllers/internal_helpers_test.rb +2 -2
  39. data/test/controllers/sessions_controller_test.rb +1 -1
  40. data/test/devise_test.rb +12 -1
  41. data/test/failure_app_test.rb +11 -0
  42. data/test/integration/confirmable_test.rb +0 -12
  43. data/test/integration/http_authenticatable_test.rb +0 -10
  44. data/test/integration/recoverable_test.rb +2 -2
  45. data/test/integration/rememberable_test.rb +3 -3
  46. data/test/integration/timeoutable_test.rb +28 -0
  47. data/test/mapping_test.rb +2 -2
  48. data/test/models/confirmable_test.rb +0 -9
  49. data/test/models/database_authenticatable_test.rb +19 -1
  50. data/test/models/lockable_test.rb +16 -10
  51. data/test/models/recoverable_test.rb +0 -10
  52. data/test/rails_app/app/mongoid/user.rb +0 -3
  53. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -3
  54. data/test/rails_app/db/schema.rb +0 -1
  55. data/test/rails_app/lib/shared_user.rb +1 -1
  56. data/test/support/locale/en.yml +4 -0
  57. data/test/test_helpers_test.rb +22 -0
  58. metadata +4 -8
  59. data/lib/devise/models/token_authenticatable.rb +0 -92
  60. data/lib/devise/strategies/token_authenticatable.rb +0 -91
  61. data/test/integration/token_authenticatable_test.rb +0 -205
  62. data/test/models/token_authenticatable_test.rb +0 -55
@@ -44,7 +44,6 @@ ActiveRecord::Schema.define(:version => 20100401102949) do
44
44
  t.integer "failed_attempts", :default => 0
45
45
  t.string "unlock_token"
46
46
  t.datetime "locked_at"
47
- t.string "authentication_token"
48
47
  t.datetime "created_at"
49
48
  t.datetime "updated_at"
50
49
  end
@@ -3,7 +3,7 @@ module SharedUser
3
3
 
4
4
  included do
5
5
  devise :database_authenticatable, :confirmable, :lockable, :recoverable,
6
- :registerable, :rememberable, :timeoutable, :token_authenticatable,
6
+ :registerable, :rememberable, :timeoutable,
7
7
  :trackable, :validatable, :omniauthable
8
8
 
9
9
  attr_accessor :other_key
@@ -1,4 +1,8 @@
1
1
  en:
2
+ devise:
3
+ failure:
4
+ user:
5
+ does_not_exist: "User %{name} does not exist"
2
6
  errors:
3
7
  messages:
4
8
  taken: "has already been taken"
@@ -148,4 +148,26 @@ class TestHelpersTest < ActionController::TestCase
148
148
  get :index
149
149
  assert_match /User ##{second_user.id}/, @response.body
150
150
  end
151
+
152
+
153
+ test "passes given headers from the failure app to the response" do
154
+
155
+ begin
156
+ old_failure_app = Devise.warden_config[:failure_app]
157
+ class CustomTestFailureApp < Devise::FailureApp
158
+ def respond
159
+ self.status = 401
160
+ self.response.headers["CUSTOMHEADER"] = 1
161
+ end
162
+ end
163
+ Devise.warden_config[:failure_app] = CustomTestFailureApp
164
+ user = create_user
165
+ sign_in user
166
+ get :index
167
+ assert_equal 1, @response.headers["CUSTOMHEADER"]
168
+ ensure
169
+ Devise.warden_config[:failure_app] = old_failure_app
170
+ end
171
+ end
172
+
151
173
  end
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: 3.1.2
4
+ version: 3.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-11-13 00:00:00.000000000 Z
13
+ date: 2013-11-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: warden
@@ -143,6 +143,7 @@ files:
143
143
  - lib/devise/controllers/helpers.rb
144
144
  - lib/devise/controllers/rememberable.rb
145
145
  - lib/devise/controllers/scoped_views.rb
146
+ - lib/devise/controllers/sign_in_out.rb
146
147
  - lib/devise/controllers/url_helpers.rb
147
148
  - lib/devise/delegator.rb
148
149
  - lib/devise/failure_app.rb
@@ -150,6 +151,7 @@ files:
150
151
  - lib/devise/hooks/csrf_cleaner.rb
151
152
  - lib/devise/hooks/forgetable.rb
152
153
  - lib/devise/hooks/lockable.rb
154
+ - lib/devise/hooks/proxy.rb
153
155
  - lib/devise/hooks/rememberable.rb
154
156
  - lib/devise/hooks/timeoutable.rb
155
157
  - lib/devise/hooks/trackable.rb
@@ -165,7 +167,6 @@ files:
165
167
  - lib/devise/models/registerable.rb
166
168
  - lib/devise/models/rememberable.rb
167
169
  - lib/devise/models/timeoutable.rb
168
- - lib/devise/models/token_authenticatable.rb
169
170
  - lib/devise/models/trackable.rb
170
171
  - lib/devise/models/validatable.rb
171
172
  - lib/devise/modules.rb
@@ -183,7 +184,6 @@ files:
183
184
  - lib/devise/strategies/base.rb
184
185
  - lib/devise/strategies/database_authenticatable.rb
185
186
  - lib/devise/strategies/rememberable.rb
186
- - lib/devise/strategies/token_authenticatable.rb
187
187
  - lib/devise/test_helpers.rb
188
188
  - lib/devise/time_inflector.rb
189
189
  - lib/devise/token_generator.rb
@@ -233,7 +233,6 @@ files:
233
233
  - test/integration/registerable_test.rb
234
234
  - test/integration/rememberable_test.rb
235
235
  - test/integration/timeoutable_test.rb
236
- - test/integration/token_authenticatable_test.rb
237
236
  - test/integration/trackable_test.rb
238
237
  - test/mailers/confirmation_instructions_test.rb
239
238
  - test/mailers/reset_password_instructions_test.rb
@@ -249,7 +248,6 @@ files:
249
248
  - test/models/rememberable_test.rb
250
249
  - test/models/serializable_test.rb
251
250
  - test/models/timeoutable_test.rb
252
- - test/models/token_authenticatable_test.rb
253
251
  - test/models/trackable_test.rb
254
252
  - test/models/validatable_test.rb
255
253
  - test/models_test.rb
@@ -372,7 +370,6 @@ test_files:
372
370
  - test/integration/registerable_test.rb
373
371
  - test/integration/rememberable_test.rb
374
372
  - test/integration/timeoutable_test.rb
375
- - test/integration/token_authenticatable_test.rb
376
373
  - test/integration/trackable_test.rb
377
374
  - test/mailers/confirmation_instructions_test.rb
378
375
  - test/mailers/reset_password_instructions_test.rb
@@ -388,7 +385,6 @@ test_files:
388
385
  - test/models/rememberable_test.rb
389
386
  - test/models/serializable_test.rb
390
387
  - test/models/timeoutable_test.rb
391
- - test/models/token_authenticatable_test.rb
392
388
  - test/models/trackable_test.rb
393
389
  - test/models/validatable_test.rb
394
390
  - test/models_test.rb
@@ -1,92 +0,0 @@
1
- require 'devise/strategies/token_authenticatable'
2
-
3
- module Devise
4
- module Models
5
- # The TokenAuthenticatable module is responsible for generating an authentication token and
6
- # validating the authenticity of the same while signing in.
7
- #
8
- # This module only provides a few helpers to help you manage the token, but it is up to you
9
- # to choose how to use it. For example, if you want to have a new token every time the user
10
- # saves his account, you can do the following:
11
- #
12
- # before_save :reset_authentication_token
13
- #
14
- # On the other hand, if you want to generate token unless one exists, you should use instead:
15
- #
16
- # before_save :ensure_authentication_token
17
- #
18
- # If you want to delete the token after it is used, you can do so in the
19
- # after_token_authentication callback.
20
- #
21
- # == APIs
22
- #
23
- # If you are using token authentication with APIs and using trackable. Every
24
- # request will be considered as a new sign in (since there is no session in
25
- # APIs). You can disable this by creating a before filter as follow:
26
- #
27
- # before_filter :skip_trackable
28
- #
29
- # def skip_trackable
30
- # request.env['devise.skip_trackable'] = true
31
- # end
32
- #
33
- # == Options
34
- #
35
- # TokenAuthenticatable adds the following options to devise_for:
36
- #
37
- # * +token_authentication_key+: Defines name of the authentication token params key. E.g. /users/sign_in?some_key=...
38
- #
39
- module TokenAuthenticatable
40
- extend ActiveSupport::Concern
41
-
42
- def self.required_fields(klass)
43
- [:authentication_token]
44
- end
45
-
46
- # Generate new authentication token (a.k.a. "single access token").
47
- def reset_authentication_token
48
- self.authentication_token = self.class.authentication_token
49
- end
50
-
51
- # Generate new authentication token and save the record.
52
- def reset_authentication_token!
53
- reset_authentication_token
54
- save(:validate => false)
55
- end
56
-
57
- # Generate authentication token unless already exists.
58
- def ensure_authentication_token
59
- reset_authentication_token if authentication_token.blank?
60
- end
61
-
62
- # Generate authentication token unless already exists and save the record.
63
- def ensure_authentication_token!
64
- reset_authentication_token! if authentication_token.blank?
65
- end
66
-
67
- # Hook called after token authentication.
68
- def after_token_authentication
69
- end
70
-
71
- def expire_auth_token_on_timeout
72
- self.class.expire_auth_token_on_timeout
73
- end
74
-
75
- module ClassMethods
76
- def find_for_token_authentication(conditions)
77
- find_for_authentication(:authentication_token => conditions[token_authentication_key])
78
- end
79
-
80
- # Generate a token checking if one does not already exist in the database.
81
- def authentication_token
82
- loop do
83
- token = Devise.friendly_token
84
- break token unless to_adapter.find_first({ :authentication_token => token })
85
- end
86
- end
87
-
88
- Devise::Models.config(self, :token_authentication_key, :expire_auth_token_on_timeout)
89
- end
90
- end
91
- end
92
- end
@@ -1,91 +0,0 @@
1
- require 'devise/strategies/base'
2
-
3
- module Devise
4
- module Strategies
5
- # Strategy for signing in a user, based on a authenticatable token. This works for both params
6
- # and http. For the former, all you need to do is to pass the params in the URL:
7
- #
8
- # http://myapp.example.com/?user_token=SECRET
9
- #
10
- # For headers, you can use basic authentication passing the token as username and
11
- # blank password. Since some clients may require a password, you can pass "X" as
12
- # password and it will simply be ignored.
13
- #
14
- # You may also pass the token using the Token authentication mechanism provided
15
- # by Rails: http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
16
- # The token options are stored in request.env['devise.token_options']
17
- class TokenAuthenticatable < Authenticatable
18
- def store?
19
- super && !mapping.to.skip_session_storage.include?(:token_auth)
20
- end
21
-
22
- def valid?
23
- super || valid_for_token_auth?
24
- end
25
-
26
- def authenticate!
27
- resource = mapping.to.find_for_token_authentication(authentication_hash)
28
- return fail(:invalid_token) unless resource
29
-
30
- if validate(resource)
31
- resource.after_token_authentication
32
- success!(resource)
33
- end
34
- end
35
-
36
- private
37
-
38
- # Token Authenticatable can be authenticated with params in any controller and any verb.
39
- def valid_params_request?
40
- true
41
- end
42
-
43
- # Do not use remember_me behavior with token.
44
- def remember_me?
45
- false
46
- end
47
-
48
- # Check if the model accepts this strategy as token authenticatable.
49
- def token_authenticatable?
50
- mapping.to.http_authenticatable?(:token_options)
51
- end
52
-
53
- # Check if this is strategy is valid for token authentication by:
54
- #
55
- # * Validating if the model allows http token authentication;
56
- # * If the http auth token exists;
57
- # * If all authentication keys are present;
58
- #
59
- def valid_for_token_auth?
60
- token_authenticatable? && auth_token.present? && with_authentication_hash(:token_auth, token_auth_hash)
61
- end
62
-
63
- # Extract the auth token from the request
64
- def auth_token
65
- @auth_token ||= ActionController::HttpAuthentication::Token.token_and_options(request)
66
- end
67
-
68
- # Extract a hash with attributes:values from the auth_token
69
- def token_auth_hash
70
- request.env['devise.token_options'] = auth_token.last
71
- { authentication_keys.first => auth_token.first }
72
- end
73
-
74
- # Try both scoped and non scoped keys
75
- def params_auth_hash
76
- if params[scope].kind_of?(Hash) && params[scope].has_key?(authentication_keys.first)
77
- params[scope]
78
- else
79
- params
80
- end
81
- end
82
-
83
- # Overwrite authentication keys to use token_authentication_key.
84
- def authentication_keys
85
- @authentication_keys ||= [mapping.to.token_authentication_key]
86
- end
87
- end
88
- end
89
- end
90
-
91
- Warden::Strategies.add(:token_authenticatable, Devise::Strategies::TokenAuthenticatable)
@@ -1,205 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TokenAuthenticationTest < ActionDispatch::IntegrationTest
4
-
5
- test 'authenticate with valid authentication token key and value through params' do
6
- swap Devise, :token_authentication_key => :secret_token do
7
- sign_in_as_new_user_with_token
8
-
9
- assert_response :success
10
- assert_current_url "/users?secret_token=#{VALID_AUTHENTICATION_TOKEN}"
11
- assert_contain 'Welcome'
12
- assert warden.authenticated?(:user)
13
- end
14
- end
15
-
16
- test 'authenticate with valid authentication token key and value through params, when params with the same key as scope exist' do
17
- swap Devise, :token_authentication_key => :secret_token do
18
- user = create_user_with_authentication_token
19
- post exhibit_user_path(user), Devise.token_authentication_key => user.authentication_token, :user => { :some => "data" }
20
-
21
- assert_response :success
22
- assert_contain 'User is authenticated'
23
- assert warden.authenticated?(:user)
24
- end
25
- end
26
-
27
- test 'authenticate with valid authentication token key but does not store if stateless' do
28
- swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth] do
29
- sign_in_as_new_user_with_token
30
- assert warden.authenticated?(:user)
31
-
32
- get users_path
33
- assert_redirected_to new_user_session_path
34
- assert_not warden.authenticated?(:user)
35
- end
36
- end
37
-
38
- test 'authenticate with valid authentication token key and value through http' do
39
- swap Devise, :token_authentication_key => :secret_token do
40
- sign_in_as_new_user_with_token(:http_auth => true)
41
-
42
- assert_response :success
43
- assert_match '<email>user@test.com</email>', response.body
44
- assert warden.authenticated?(:user)
45
- end
46
- end
47
-
48
- test 'does authenticate with valid authentication token key and value through params if not configured' do
49
- swap Devise, :token_authentication_key => :secret_token, :params_authenticatable => [:database] do
50
- sign_in_as_new_user_with_token
51
-
52
- assert_contain 'You need to sign in or sign up before continuing'
53
- assert_contain 'Sign in'
54
- assert_not warden.authenticated?(:user)
55
- end
56
- end
57
-
58
- test 'does authenticate with valid authentication token key and value through http if not configured' do
59
- swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => [:database] do
60
- sign_in_as_new_user_with_token(:http_auth => true)
61
-
62
- assert_response 401
63
- assert_contain 'Invalid email or password.'
64
- assert_not warden.authenticated?(:user)
65
- end
66
- end
67
-
68
- test 'does not authenticate with improper authentication token key' do
69
- swap Devise, :token_authentication_key => :donald_duck_token do
70
- sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
71
- assert_equal new_user_session_path, @request.path
72
-
73
- assert_contain 'You need to sign in or sign up before continuing'
74
- assert_contain 'Sign in'
75
- assert_not warden.authenticated?(:user)
76
- end
77
- end
78
-
79
- test 'does not authenticate with improper authentication token value' do
80
- store_translations :en, :devise => {:failure => {:invalid_token => 'LOL, that was not a single character correct.'}} do
81
- sign_in_as_new_user_with_token(:auth_token => '*** INVALID TOKEN ***')
82
- assert_equal new_user_session_path, @request.path
83
-
84
- assert_contain 'LOL, that was not a single character correct.'
85
- assert_contain 'Sign in'
86
- assert_not warden.authenticated?(:user)
87
- end
88
- end
89
-
90
- test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
91
- swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth], :timeout_in => (0.1).second do
92
- user = sign_in_as_new_user_with_token
93
- assert warden.authenticated?(:user)
94
-
95
- # Expiring does not work because we are setting the session value when accessing it
96
- sleep 0.3
97
-
98
- get_users_path_as_existing_user(user)
99
- assert warden.authenticated?(:user)
100
- end
101
- end
102
-
103
- test 'should reset token and not authenticate when expire_auth_token_on_timeout is set to true, timeoutable is enabled and we have a timed out session' do
104
- swap Devise, :token_authentication_key => :secret_token, :expire_auth_token_on_timeout => true, :timeout_in => (-1).minute do
105
- user = sign_in_as_new_user_with_token
106
- assert warden.authenticated?(:user)
107
- token = user.authentication_token
108
-
109
- get_users_path_as_existing_user(user)
110
- assert_not warden.authenticated?(:user)
111
- user.reload
112
- assert_not_equal token, user.authentication_token
113
- end
114
- end
115
-
116
- test 'should not be subject to injection' do
117
- swap Devise, :token_authentication_key => :secret_token do
118
- user1 = create_user_with_authentication_token()
119
-
120
- # Clean up user cache
121
- @user = nil
122
-
123
- user2 = create_user_with_authentication_token(:email => "another@test.com")
124
- user2.update_attribute(:authentication_token, "ANOTHERTOKEN")
125
-
126
- assert_not_equal user1, user2
127
- visit users_path(Devise.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
128
- assert_nil warden.user(:user)
129
- end
130
- end
131
-
132
- test 'authenticate with valid authentication token key and value through http header' do
133
- swap Devise, :token_authentication_key => :secret_token do
134
- sign_in_as_new_user_with_token(:token_auth => true)
135
-
136
- assert_response :success
137
- assert_match '<email>user@test.com</email>', response.body
138
- assert_equal request.env['devise.token_options'], {}
139
- assert warden.authenticated?(:user)
140
- end
141
- end
142
-
143
- test 'authenticate with valid authentication token key and value through http header, with options' do
144
- swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => [:token_options] do
145
- signature = "**TESTSIGNATURE**"
146
- sign_in_as_new_user_with_token(:token_auth => true, :token_options => {:signature => signature, :nonce => 'def'})
147
-
148
- assert_response :success
149
- assert_match '<email>user@test.com</email>', response.body
150
- assert_equal request.env['devise.token_options'][:signature], signature
151
- assert_equal request.env['devise.token_options'][:nonce], 'def'
152
- assert warden.authenticated?(:user)
153
- end
154
- end
155
-
156
- test 'authenticate with valid authentication token key and value through http header without allowing token authorization setting is denied' do
157
- swap Devise, :token_authentication_key => :secret_token, :http_authenticatable => false do
158
- sign_in_as_new_user_with_token(:token_auth => true)
159
-
160
- assert_response :unauthorized
161
- assert_nil warden.user(:user)
162
- end
163
- end
164
-
165
- test 'does not authenticate with improper authentication token value in header' do
166
- sign_in_as_new_user_with_token(:token_auth => true, :auth_token => '*** INVALID TOKEN ***')
167
-
168
- assert_response :unauthorized
169
- assert_nil warden.user(:user)
170
- end
171
-
172
- private
173
-
174
- def sign_in_as_new_user_with_token(options = {})
175
- user = options.delete(:user) || create_user_with_authentication_token(options)
176
-
177
- options[:auth_token_key] ||= Devise.token_authentication_key
178
- options[:auth_token] ||= user.authentication_token
179
-
180
- if options[:http_auth]
181
- header = "Basic #{Base64.encode64("#{VALID_AUTHENTICATION_TOKEN}:X")}"
182
- get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => header
183
- elsif options[:token_auth]
184
- token_options = options[:token_options] || {}
185
- header = ActionController::HttpAuthentication::Token.encode_credentials(options[:auth_token], token_options)
186
- get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => header
187
- else
188
- visit users_path(options[:auth_token_key].to_sym => options[:auth_token])
189
- end
190
-
191
- user
192
- end
193
-
194
- def create_user_with_authentication_token(options={})
195
- user = create_user(options)
196
- user.authentication_token = VALID_AUTHENTICATION_TOKEN
197
- user.save
198
- user
199
- end
200
-
201
- def get_users_path_as_existing_user(user)
202
- sign_in_as_new_user_with_token(:user => user)
203
- end
204
-
205
- end