devise-token_authenticatable 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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