devise-token_authenticatable 0.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +20 -0
  4. data/README.md +31 -0
  5. data/Rakefile +1 -0
  6. data/devise-token_authenticatable.gemspec +36 -0
  7. data/lib/devise-token_authenticatable.rb +1 -0
  8. data/lib/devise/token_authenticatable.rb +27 -0
  9. data/lib/devise/token_authenticatable/model.rb +90 -0
  10. data/lib/devise/token_authenticatable/strategy.rb +102 -0
  11. data/lib/devise/token_authenticatable/version.rb +5 -0
  12. data/spec/factories/admin.rb +24 -0
  13. data/spec/factories/user.rb +25 -0
  14. data/spec/models/devise/token_authenticatable/model_spec.rb +79 -0
  15. data/spec/requests/devise/token_authenticatable/strategy_spec.rb +340 -0
  16. data/spec/spec_helper.rb +42 -0
  17. data/spec/support/helpers.rb +33 -0
  18. data/spec/support/integration.rb +8 -0
  19. data/spec/support/rails_app.rb +19 -0
  20. data/spec/support/rails_app/Rakefile +6 -0
  21. data/spec/support/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  22. data/spec/support/rails_app/app/controllers/admins_controller.rb +11 -0
  23. data/spec/support/rails_app/app/controllers/application_controller.rb +9 -0
  24. data/spec/support/rails_app/app/controllers/home_controller.rb +25 -0
  25. data/spec/support/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  26. data/spec/support/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  27. data/spec/support/rails_app/app/controllers/users_controller.rb +31 -0
  28. data/spec/support/rails_app/app/mailers/users/mailer.rb +12 -0
  29. data/spec/support/rails_app/app/models/admin.rb +9 -0
  30. data/spec/support/rails_app/app/models/user.rb +25 -0
  31. data/spec/support/rails_app/app/views/users/index.html.erb +1 -0
  32. data/spec/support/rails_app/config.ru +4 -0
  33. data/spec/support/rails_app/config/database.yml +11 -0
  34. data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  35. data/spec/support/rails_app/config/initializers/devise.rb +173 -0
  36. data/spec/support/rails_app/config/initializers/inflections.rb +2 -0
  37. data/spec/support/rails_app/config/initializers/secret_token.rb +4 -0
  38. data/spec/support/rails_app/config/routes.rb +104 -0
  39. data/spec/support/rails_app/db/migrate/20100401102949_create_tables.rb +74 -0
  40. data/spec/support/rails_app/db/schema.rb +52 -0
  41. data/spec/support/rails_app/public/404.html +26 -0
  42. data/spec/support/rails_app/public/422.html +26 -0
  43. data/spec/support/rails_app/public/500.html +26 -0
  44. data/spec/support/rails_app/public/favicon.ico +0 -0
  45. data/spec/support/session_helper.rb +27 -0
  46. metadata +289 -0
@@ -0,0 +1,340 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Strategies::TokenAuthenticatable do
4
+
5
+ context "with valid authentication token key and value" do
6
+
7
+ context "through params" do
8
+
9
+ it "should be a success" do
10
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
11
+ sign_in_as_new_user_with_token
12
+
13
+ response.should be_success
14
+ end
15
+ end
16
+
17
+ it "should set the auth_token parameter" do
18
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
19
+ user = sign_in_as_new_user_with_token
20
+
21
+ expect(@request.fullpath).to eq("/users?secret_token=#{user.authentication_token}")
22
+ end
23
+ end
24
+
25
+ it "should authenticate user" do
26
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
27
+ sign_in_as_new_user_with_token
28
+
29
+ expect(warden).to be_authenticated(:user)
30
+ end
31
+ end
32
+
33
+ context "when params with the same key as scope exist" do
34
+ let(:user) { create(:user, :with_authentication_token) }
35
+
36
+ it 'should be a success' do
37
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
38
+ post exhibit_user_path(user), Devise::TokenAuthenticatable.token_authentication_key => user.authentication_token, user: { some: "data" }
39
+
40
+ response.should be_success
41
+ end
42
+ end
43
+
44
+ it 'should return proper data' do
45
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
46
+ post exhibit_user_path(user), Devise::TokenAuthenticatable.token_authentication_key => user.authentication_token, user: { some: "data" }
47
+
48
+ response.body.should eq('User is authenticated')
49
+ end
50
+ end
51
+
52
+ it 'should authenticate user' do
53
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
54
+ post exhibit_user_path(user), Devise::TokenAuthenticatable.token_authentication_key => user.authentication_token, user: { some: "data" }
55
+
56
+ expect(warden).to be_authenticated(:user)
57
+ end
58
+ end
59
+ end
60
+
61
+ context "when request is stateless" do
62
+
63
+ it 'should not store the session' do
64
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
65
+ swap Devise, :skip_session_storage => [:token_auth] do
66
+ sign_in_as_new_user_with_token
67
+ expect(warden).to be_authenticated(:user)
68
+
69
+ # Try to access a resource that requires authentication
70
+ get users_path
71
+ response.should redirect_to(new_user_session_path)
72
+ expect(warden).to_not be_authenticated(:user)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ context "when request is stateless and timeoutable" do
79
+
80
+ it 'should authenticate user' do
81
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
82
+ swap Devise, :skip_session_storage => [:token_auth], timeout_in: (0.1).second do
83
+ user = sign_in_as_new_user_with_token
84
+ expect(warden).to be_authenticated(:user)
85
+
86
+ # Expiring does not work because we are setting the session value when accessing the resource
87
+ Timecop.travel(Time.now + (0.3).second)
88
+
89
+ sign_in_as_new_user_with_token(user: user)
90
+ expect(warden).to be_authenticated(:user)
91
+
92
+ Timecop.return
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ context "when expire_auth_token_on_timeout is set to true, timeoutable is enabled and we have a timed out session" do
99
+
100
+ it 'should reset authentication token and not authenticate' do
101
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
102
+ swap Devise, expire_auth_token_on_timeout: true, timeout_in: (-1).minute do
103
+ user = sign_in_as_new_user_with_token
104
+ expect(warden).to be_authenticated(:user)
105
+ token = user.authentication_token
106
+
107
+ sign_in_as_new_user_with_token(user: user)
108
+ expect(warden).to_not be_authenticated(:user)
109
+ user.reload
110
+ expect(token).to_not eq(user.authentication_token)
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ context "when not configured" do
117
+
118
+ it "should redirect to sign in page" do
119
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
120
+ swap Devise, :params_authenticatable => [:database] do
121
+ sign_in_as_new_user_with_token
122
+
123
+ response.should redirect_to new_user_session_path
124
+ end
125
+ end
126
+ end
127
+
128
+ it "should not authenticate user" do
129
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
130
+ swap Devise, :params_authenticatable => [:database] do
131
+ sign_in_as_new_user_with_token
132
+
133
+ expect(warden).to_not be_authenticated(:user)
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ context "through http" do
141
+
142
+ it "should be a success" do
143
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
144
+ swap Devise, http_authenticatable: true do
145
+ sign_in_as_new_user_with_token(http_auth: true)
146
+
147
+ response.should be_success
148
+ end
149
+ end
150
+ end
151
+
152
+ it "should authenticate user" do
153
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
154
+ swap Devise, http_authenticatable: true do
155
+ sign_in_as_new_user_with_token(http_auth: true)
156
+
157
+ expect(warden).to be_authenticated(:user)
158
+ end
159
+ end
160
+ end
161
+
162
+ context "when not configured" do
163
+
164
+ it "should be an unauthorized" do
165
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
166
+ swap Devise, :http_authenticatable => [:database] do
167
+ sign_in_as_new_user_with_token(http_auth: true)
168
+
169
+ response.status.should eq(401)
170
+ end
171
+ end
172
+ end
173
+
174
+ it "should not authenticate user" do
175
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
176
+ swap Devise, :http_authenticatable => [:database] do
177
+ sign_in_as_new_user_with_token(http_auth: true)
178
+
179
+ expect(warden).to_not be_authenticated(:user)
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ context "through http header" do
187
+
188
+ it "should redirect to root path" do
189
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
190
+ swap Devise, http_authenticatable: true do
191
+ sign_in_as_new_user_with_token(token_auth: true)
192
+
193
+ response.should be_success
194
+ end
195
+ end
196
+ end
197
+
198
+ it "should authenticate user" do
199
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
200
+ swap Devise, http_authenticatable: true do
201
+ sign_in_as_new_user_with_token(token_auth: true)
202
+
203
+ expect(request.env['devise.token_options']).to eq({})
204
+ expect(warden).to be_authenticated(:user)
205
+ end
206
+ end
207
+ end
208
+
209
+ context "with options" do
210
+ let(:signature) { "**TESTSIGNATURE**" }
211
+
212
+ it "should redirect to root path" do
213
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
214
+ swap Devise, :http_authenticatable => [:token_options] do
215
+ sign_in_as_new_user_with_token(token_auth: true, token_options: { signature: signature, nonce: 'def' })
216
+
217
+ response.should be_success
218
+ end
219
+ end
220
+ end
221
+
222
+ it "should set the signature option" do
223
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
224
+ swap Devise, :http_authenticatable => [:token_options] do
225
+ sign_in_as_new_user_with_token(token_auth: true, token_options: { signature: signature, nonce: 'def' })
226
+
227
+ expect(request.env['devise.token_options'][:signature]).to eq(signature)
228
+ end
229
+ end
230
+ end
231
+
232
+ it "should set the nonce option" do
233
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
234
+ swap Devise, :http_authenticatable => [:token_options] do
235
+ sign_in_as_new_user_with_token(token_auth: true, token_options: { signature: signature, nonce: 'def' })
236
+
237
+ expect(request.env['devise.token_options'][:nonce]).to eq('def')
238
+ end
239
+ end
240
+ end
241
+
242
+ it "should authenticate user" do
243
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
244
+ swap Devise, :http_authenticatable => [:token_options] do
245
+ sign_in_as_new_user_with_token(token_auth: true, token_options: { signature: signature, nonce: 'def' })
246
+
247
+ expect(warden).to be_authenticated(:user)
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ context "with denied token authorization" do
254
+
255
+ it "should be an unauthorized" do
256
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
257
+ swap Devise, http_authenticatable: false do
258
+ sign_in_as_new_user_with_token(token_auth: true)
259
+
260
+ response.status.should eq(401)
261
+ end
262
+ end
263
+ end
264
+
265
+ it "should not authenticate user" do
266
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
267
+ swap Devise, http_authenticatable: false do
268
+ sign_in_as_new_user_with_token(token_auth: true)
269
+
270
+ expect(warden).to_not be_authenticated(:user)
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ context "with improper authentication token key" do
279
+
280
+ it "should redirect to the sign in page" do
281
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :donald_duck_token do
282
+ sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
283
+
284
+ response.should redirect_to(new_user_session_path)
285
+ end
286
+ end
287
+
288
+ it "should not authenticate user" do
289
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :donald_duck_token do
290
+ sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
291
+
292
+ expect(warden).to_not be_authenticated(:user)
293
+ end
294
+ end
295
+
296
+ it "should not be subject to injection" do
297
+ swap Devise::TokenAuthenticatable, :token_authentication_key => :secret_token do
298
+ user1 = create(:user, :with_authentication_token)
299
+
300
+ # Clean up user cache
301
+ @user = nil
302
+
303
+ user2 = create(:user, :with_authentication_token)
304
+
305
+ expect(user1).to_not eq(user2)
306
+ get users_path(Devise::TokenAuthenticatable.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
307
+ expect(warden).to_not be_authenticated(:user)
308
+ end
309
+ end
310
+ end
311
+
312
+ context "with improper authentication token value" do
313
+
314
+ context "through params" do
315
+
316
+ before { sign_in_as_new_user_with_token(auth_token: '*** INVALID TOKEN ***') }
317
+
318
+ it "should redirect to the sign in page" do
319
+ response.should redirect_to(new_user_session_path)
320
+ end
321
+
322
+ it "should not authenticate user" do
323
+ expect(warden).to_not be_authenticated(:user)
324
+ end
325
+ end
326
+
327
+ context "through http header" do
328
+
329
+ before { sign_in_as_new_user_with_token(token_auth: true, auth_token: '*** INVALID TOKEN ***') }
330
+
331
+ it "should be an unauthorized" do
332
+ response.status.should eq(401)
333
+ end
334
+
335
+ it "does not authenticate with improper authentication token value in header" do
336
+ expect(warden).to_not be_authenticated(:user)
337
+ end
338
+ end
339
+ end
340
+ end
@@ -0,0 +1,42 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ # Required modules
4
+ require 'devise'
5
+ require 'devise/token_authenticatable'
6
+ require 'rails/all'
7
+ require 'rspec/rails'
8
+ require 'timecop'
9
+ require 'pry'
10
+
11
+ # Required spec helper files
12
+ require 'support/rails_app'
13
+ require 'support/helpers'
14
+ require 'support/integration'
15
+ require 'support/session_helper'
16
+
17
+ # factory_girl_rails has to be required after the test rails app
18
+ # as it sets the right application root path
19
+ require 'factory_girl_rails'
20
+
21
+ # RSpec configuration
22
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
23
+ RSpec.configure do |config|
24
+ config.treat_symbols_as_metadata_keys_with_true_values = true
25
+ config.use_transactional_fixtures = true
26
+ config.run_all_when_everything_filtered = true
27
+
28
+ config.filter_run :focus
29
+
30
+ # Run specs in random order to surface order dependencies. If you find an
31
+ # order dependency and want to debug it, you can fix the order by providing
32
+ # the seed, which is printed after each run.
33
+ # --seed 1234
34
+ #config.order = 'random'
35
+
36
+ config.include FactoryGirl::Syntax::Methods
37
+
38
+ config.before(:suite) do
39
+ # Do initial migration
40
+ ActiveRecord::Migrator.migrate(File.expand_path("support/rails_app/db/migrate/", File.dirname(__FILE__)))
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ # Helpers used for devise testing.
2
+ #
3
+
4
+ # Execute the block setting the given values in
5
+ # +new_values+ and restoring the old values
6
+ # after the block was executed.
7
+ #
8
+ def swap(object, new_values)
9
+ old_values = {}
10
+
11
+ new_values.each do |key, value|
12
+ old_values[key] = object.send key
13
+ object.send(:"#{key}=", value)
14
+ end
15
+
16
+ clear_cached_variables(new_values)
17
+
18
+ yield
19
+ ensure
20
+ clear_cached_variables(new_values)
21
+
22
+ old_values.each do |key, value|
23
+ object.send(:"#{key}=", value)
24
+ end
25
+ end
26
+
27
+ def clear_cached_variables(options)
28
+ if options.key?(:case_insensitive_keys) || options.key?(:strip_whitespace_keys)
29
+ Devise.mappings.each do |_, mapping|
30
+ mapping.to.instance_variable_set(:@devise_parameter_filter, nil)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ # Helpers used in integration testing.
2
+ #
3
+
4
+ # Shortcut to the warden instance.
5
+ #
6
+ def warden
7
+ request.env['warden']
8
+ end
@@ -0,0 +1,19 @@
1
+ # Initializes the rails application used for
2
+ # testing.
3
+
4
+ # Do not output schema loading
5
+ ActiveRecord::Migration.verbose = false
6
+
7
+ module Devise
8
+ module TokenAuthenticatable
9
+ class RailsApp < Rails::Application
10
+ config.root = File.dirname(__FILE__) + "/rails_app"
11
+ config.active_support.deprecation = :log
12
+ config.action_mailer.default_url_options = { :host => "localhost:3000" }
13
+ config.action_mailer.delivery_method = :test
14
+ config.eager_load = false
15
+ end
16
+ end
17
+ end
18
+
19
+ Devise::TokenAuthenticatable::RailsApp.initialize!
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks