devise-otp 0.2.2 → 0.4.0

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 (64) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +36 -0
  3. data/CHANGELOG.md +17 -0
  4. data/Gemfile +1 -22
  5. data/README.md +42 -75
  6. data/app/assets/javascripts/devise-otp.js +1 -0
  7. data/app/assets/javascripts/qrcode.js +609 -0
  8. data/app/controllers/devise_otp/devise/otp_credentials_controller.rb +102 -0
  9. data/app/controllers/devise_otp/devise/otp_tokens_controller.rb +112 -0
  10. data/app/views/devise/otp_credentials/refresh.html.erb +19 -0
  11. data/app/views/devise/otp_credentials/show.html.erb +31 -0
  12. data/app/views/devise/otp_tokens/_token_secret.html.erb +23 -0
  13. data/app/views/devise/otp_tokens/_trusted_devices.html.erb +12 -0
  14. data/app/views/devise/otp_tokens/recovery.html.erb +21 -0
  15. data/app/views/devise/otp_tokens/recovery_codes.text.erb +3 -0
  16. data/app/views/devise/otp_tokens/show.html.erb +21 -0
  17. data/config/locales/en.yml +8 -8
  18. data/devise-otp.gemspec +15 -10
  19. data/docs/QR_CODES.md +48 -0
  20. data/lib/devise-otp/version.rb +2 -2
  21. data/lib/devise-otp.rb +12 -11
  22. data/lib/devise_otp_authenticatable/controllers/helpers.rb +22 -15
  23. data/lib/devise_otp_authenticatable/controllers/url_helpers.rb +6 -7
  24. data/lib/devise_otp_authenticatable/engine.rb +22 -13
  25. data/lib/devise_otp_authenticatable/hooks/sessions.rb +8 -7
  26. data/lib/devise_otp_authenticatable/hooks.rb +1 -1
  27. data/lib/devise_otp_authenticatable/models/otp_authenticatable.rb +14 -13
  28. data/lib/devise_otp_authenticatable/routes.rb +2 -5
  29. data/lib/generators/active_record/templates/migration.rb +1 -1
  30. data/lib/generators/devise_otp/install_generator.rb +8 -5
  31. data/lib/generators/devise_otp/views_generator.rb +2 -3
  32. data/test/dummy/app/assets/config/manifest.js +2 -0
  33. data/test/dummy/app/assets/javascripts/application.js +1 -0
  34. data/test/dummy/app/controllers/application_controller.rb +1 -1
  35. data/test/dummy/app/controllers/posts_controller.rb +2 -0
  36. data/test/dummy/app/models/user.rb +1 -1
  37. data/test/dummy/config/application.rb +2 -1
  38. data/test/dummy/config/database.yml +1 -1
  39. data/test/dummy/config/environments/development.rb +0 -7
  40. data/test/dummy/config/environments/production.rb +0 -4
  41. data/test/dummy/db/migrate/20130125101430_create_users.rb +1 -1
  42. data/test/dummy/db/migrate/20130131092406_add_devise_to_users.rb +1 -1
  43. data/test/dummy/db/migrate/20130131142320_create_posts.rb +1 -1
  44. data/test/dummy/db/migrate/20130131160351_devise_otp_add_to_users.rb +2 -2
  45. data/test/dummy/script/rails +0 -0
  46. data/test/integration/persistence_test.rb +81 -0
  47. data/test/integration/refresh_test.rb +2 -18
  48. data/test/integration/sign_in_test.rb +13 -3
  49. data/test/integration/token_test.rb +1 -4
  50. data/test/integration_tests_helper.rb +7 -3
  51. data/test/models/otp_authenticatable_test.rb +14 -9
  52. data/test/orm/active_record.rb +3 -1
  53. data/test/test_helper.rb +71 -2
  54. metadata +132 -25
  55. data/.travis.yml +0 -12
  56. data/app/controllers/devise_otp/credentials_controller.rb +0 -106
  57. data/app/controllers/devise_otp/tokens_controller.rb +0 -105
  58. data/app/views/devise_otp/credentials/refresh.html.erb +0 -20
  59. data/app/views/devise_otp/credentials/show.html.erb +0 -23
  60. data/app/views/devise_otp/tokens/_token_secret.html.erb +0 -17
  61. data/app/views/devise_otp/tokens/_trusted_devices.html.erb +0 -10
  62. data/app/views/devise_otp/tokens/recovery.html.erb +0 -21
  63. data/app/views/devise_otp/tokens/show.html.erb +0 -19
  64. data/lib/devise_otp_authenticatable/mapping.rb +0 -19
@@ -3,17 +3,17 @@ require 'model_tests_helper'
3
3
 
4
4
  class OtpAuthenticatableTest < ActiveSupport::TestCase
5
5
 
6
- def setup
7
- new_user
6
+ def setup
7
+ new_user
8
8
  end
9
9
 
10
10
  test 'new users have a non-nil secret set' do
11
- assert_not_nil User.first.otp_auth_secret
12
- end
11
+ assert_not_nil User.first.otp_auth_secret
12
+ end
13
13
 
14
14
  test 'new users have OTP disabled by default' do
15
- assert !User.first.otp_enabled
16
- end
15
+ assert !User.first.otp_enabled
16
+ end
17
17
 
18
18
  test 'users should have an instance of TOTP/ROTP objects' do
19
19
  u = User.first
@@ -80,6 +80,12 @@ class OtpAuthenticatableTest < ActiveSupport::TestCase
80
80
  assert_equal false, u.otp_challenge_valid?
81
81
  end
82
82
 
83
+ test 'null otp challenge' do
84
+ u = User.first
85
+ u.update_attribute(:otp_enabled, true)
86
+ assert_equal false, u.validate_otp_token('')
87
+ assert_equal false, u.validate_otp_token(nil)
88
+ end
83
89
 
84
90
  test 'generated otp token should be valid for the user' do
85
91
  u = User.first
@@ -109,8 +115,7 @@ class OtpAuthenticatableTest < ActiveSupport::TestCase
109
115
  recovery = u.next_otp_recovery_tokens
110
116
 
111
117
  assert u.valid_otp_recovery_token? recovery.fetch(0)
112
- assert_equal false, u.valid_otp_recovery_token?(recovery.fetch(0))
118
+ assert_nil u.valid_otp_recovery_token?(recovery.fetch(0))
113
119
  assert u.valid_otp_recovery_token? recovery.fetch(2)
114
120
  end
115
-
116
- end
121
+ end
@@ -1,4 +1,6 @@
1
1
  ActiveRecord::Migration.verbose = false
2
2
  ActiveRecord::Base.logger = Logger.new(nil)
3
3
 
4
- ActiveRecord::Migrator.migrate(File.expand_path("../../dummy/db/migrate/", __FILE__))
4
+ migrations_path = File.expand_path("../../dummy/db/migrate/", __FILE__)
5
+
6
+ ActiveRecord::MigrationContext.new(migrations_path, ActiveRecord::SchemaMigration).migrate
data/test/test_helper.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  ENV["RAILS_ENV"] = "test"
2
2
  DEVISE_ORM = (ENV["DEVISE_ORM"] || :active_record).to_sym
3
3
 
4
- $:.unshift File.dirname(__FILE__)
5
4
  puts "\n==> Devise.orm = #{DEVISE_ORM.inspect}"
6
5
  require "dummy/config/environment"
7
6
  require "orm/#{DEVISE_ORM}"
8
7
  require 'rails/test_help'
9
8
  require 'capybara/rails'
9
+ require 'capybara/cuprite'
10
10
  require 'minitest/reporters'
11
11
 
12
12
  MiniTest::Reporters.use!
@@ -15,8 +15,77 @@ MiniTest::Reporters.use!
15
15
 
16
16
  #ActiveSupport::Deprecation.silenced = true
17
17
 
18
- #Capybara.default_driver = :selenium
18
+ # Use a module to not pollute the global namespace
19
+ module CapybaraHelper
20
+ def self.register_driver(driver_name, args = [])
21
+ opts = { headless: true, js_errors: true, window_size: [1920, 1200], browser_options: {} }
22
+ args.each do |arg|
23
+ opts[:browser_options][arg] = nil
24
+ end
25
+
26
+ Capybara.register_driver(driver_name) do |app|
27
+ Capybara::Cuprite::Driver.new(app, opts)
28
+ end
29
+ end
30
+ end
31
+
32
+ # Register our own custom drivers
33
+ CapybaraHelper.register_driver(:headless_chrome, %w[disable-gpu no-sandbox disable-dev-shm-usage])
34
+
35
+ # Configure Capybara JS driver
36
+ Capybara.current_driver = :headless_chrome
37
+ Capybara.javascript_driver = :headless_chrome
38
+
39
+ # Configure Capybara server
40
+ Capybara.run_server = true
41
+ Capybara.server = :puma, { Silent: true }
19
42
 
20
43
  class ActionDispatch::IntegrationTest
21
44
  include Capybara::DSL
45
+
46
+ # What capybara calls a "page" in its DSL is actually a Capybara::Session
47
+ # and doesn't know about the *command* method that allows us to play with
48
+ # the Chrome API.
49
+ # See: https://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session
50
+ #
51
+ # To enable downloads we need to do it on the browser's page object, so fetch it
52
+ # from this long method chain.
53
+ # See: https://github.com/rubycdp/ferrum/blob/master/lib/ferrum/page.rb
54
+ def enable_chrome_headless_downloads(session, directory)
55
+ page = session.driver.browser.page
56
+ page.command('Page.setDownloadBehavior', behavior: 'allow', downloadPath: directory)
57
+ end
58
+ end
59
+
60
+ # From https://collectiveidea.com/blog/archives/2012/01/27/testing-file-downloads-with-capybara-and-chromedriver
61
+ module DownloadHelper
62
+ extend self
63
+
64
+ TIMEOUT = 10
65
+
66
+ def downloads
67
+ Dir["/tmp/devise-otp/*"]
68
+ end
69
+
70
+ def wait_for_download(count: 1)
71
+ yield if block_given?
72
+
73
+ Timeout.timeout(TIMEOUT) do
74
+ sleep 0.2 until downloaded?(count)
75
+ end
76
+ end
77
+
78
+ def downloaded?(count)
79
+ !downloading? && downloads.size == count
80
+ end
81
+
82
+ def downloading?
83
+ downloads.grep(/\.crdownload$/).any?
84
+ end
85
+
86
+ def clear_downloads
87
+ FileUtils.rm_f(downloads)
88
+ end
22
89
  end
90
+
91
+ require "devise-otp"
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-otp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lele Forzani
8
- autorequire:
8
+ - Josef Strzibny
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-08-14 00:00:00.000000000 Z
12
+ date: 2022-04-05 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rails
@@ -16,40 +17,40 @@ dependencies:
16
17
  requirements:
17
18
  - - ">="
18
19
  - !ruby/object:Gem::Version
19
- version: 3.2.6
20
+ version: '7.0'
20
21
  - - "<"
21
22
  - !ruby/object:Gem::Version
22
- version: '5'
23
+ version: '7.1'
23
24
  type: :runtime
24
25
  prerelease: false
25
26
  version_requirements: !ruby/object:Gem::Requirement
26
27
  requirements:
27
28
  - - ">="
28
29
  - !ruby/object:Gem::Version
29
- version: 3.2.6
30
+ version: '7.0'
30
31
  - - "<"
31
32
  - !ruby/object:Gem::Version
32
- version: '5'
33
+ version: '7.1'
33
34
  - !ruby/object:Gem::Dependency
34
35
  name: devise
35
36
  requirement: !ruby/object:Gem::Requirement
36
37
  requirements:
37
38
  - - ">="
38
39
  - !ruby/object:Gem::Version
39
- version: 3.1.0
40
+ version: 4.8.0
40
41
  - - "<"
41
42
  - !ruby/object:Gem::Version
42
- version: 4.0.0
43
+ version: 4.9.0
43
44
  type: :runtime
44
45
  prerelease: false
45
46
  version_requirements: !ruby/object:Gem::Requirement
46
47
  requirements:
47
48
  - - ">="
48
49
  - !ruby/object:Gem::Version
49
- version: 3.1.0
50
+ version: 4.8.0
50
51
  - - "<"
51
52
  - !ruby/object:Gem::Version
52
- version: 4.0.0
53
+ version: 4.9.0
53
54
  - !ruby/object:Gem::Dependency
54
55
  name: rotp
55
56
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +65,104 @@ dependencies:
64
65
  - - ">="
65
66
  - !ruby/object:Gem::Version
66
67
  version: 2.0.0
68
+ - !ruby/object:Gem::Dependency
69
+ name: capybara
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: cuprite
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: minitest-reporters
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 0.5.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 0.5.0
110
+ - !ruby/object:Gem::Dependency
111
+ name: puma
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: rdoc
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: shoulda
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ - !ruby/object:Gem::Dependency
153
+ name: sprockets-rails
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
67
166
  - !ruby/object:Gem::Dependency
68
167
  name: sqlite3
69
168
  requirement: !ruby/object:Gem::Requirement
@@ -81,26 +180,32 @@ dependencies:
81
180
  description: Time Based OTP/rfc6238 compatible authentication for Devise
82
181
  email:
83
182
  - lele@windmill.it
183
+ - strzibny@strzibny.name
84
184
  executables: []
85
185
  extensions: []
86
186
  extra_rdoc_files: []
87
187
  files:
188
+ - ".github/workflows/ci.yml"
88
189
  - ".gitignore"
89
- - ".travis.yml"
190
+ - CHANGELOG.md
90
191
  - Gemfile
91
192
  - LICENSE.txt
92
193
  - README.md
93
194
  - Rakefile
94
- - app/controllers/devise_otp/credentials_controller.rb
95
- - app/controllers/devise_otp/tokens_controller.rb
96
- - app/views/devise_otp/credentials/refresh.html.erb
97
- - app/views/devise_otp/credentials/show.html.erb
98
- - app/views/devise_otp/tokens/_token_secret.html.erb
99
- - app/views/devise_otp/tokens/_trusted_devices.html.erb
100
- - app/views/devise_otp/tokens/recovery.html.erb
101
- - app/views/devise_otp/tokens/show.html.erb
195
+ - app/assets/javascripts/devise-otp.js
196
+ - app/assets/javascripts/qrcode.js
197
+ - app/controllers/devise_otp/devise/otp_credentials_controller.rb
198
+ - app/controllers/devise_otp/devise/otp_tokens_controller.rb
199
+ - app/views/devise/otp_credentials/refresh.html.erb
200
+ - app/views/devise/otp_credentials/show.html.erb
201
+ - app/views/devise/otp_tokens/_token_secret.html.erb
202
+ - app/views/devise/otp_tokens/_trusted_devices.html.erb
203
+ - app/views/devise/otp_tokens/recovery.html.erb
204
+ - app/views/devise/otp_tokens/recovery_codes.text.erb
205
+ - app/views/devise/otp_tokens/show.html.erb
102
206
  - config/locales/en.yml
103
207
  - devise-otp.gemspec
208
+ - docs/QR_CODES.md
104
209
  - lib/devise-otp.rb
105
210
  - lib/devise-otp/version.rb
106
211
  - lib/devise_otp_authenticatable/controllers/helpers.rb
@@ -108,7 +213,6 @@ files:
108
213
  - lib/devise_otp_authenticatable/engine.rb
109
214
  - lib/devise_otp_authenticatable/hooks.rb
110
215
  - lib/devise_otp_authenticatable/hooks/sessions.rb
111
- - lib/devise_otp_authenticatable/mapping.rb
112
216
  - lib/devise_otp_authenticatable/models/otp_authenticatable.rb
113
217
  - lib/devise_otp_authenticatable/routes.rb
114
218
  - lib/generators/active_record/devise_otp_generator.rb
@@ -118,6 +222,7 @@ files:
118
222
  - lib/generators/devise_otp/views_generator.rb
119
223
  - test/dummy/README.rdoc
120
224
  - test/dummy/Rakefile
225
+ - test/dummy/app/assets/config/manifest.js
121
226
  - test/dummy/app/assets/javascripts/application.js
122
227
  - test/dummy/app/assets/stylesheets/application.css
123
228
  - test/dummy/app/controllers/application_controller.rb
@@ -160,6 +265,7 @@ files:
160
265
  - test/dummy/public/500.html
161
266
  - test/dummy/public/favicon.ico
162
267
  - test/dummy/script/rails
268
+ - test/integration/persistence_test.rb
163
269
  - test/integration/refresh_test.rb
164
270
  - test/integration/sign_in_test.rb
165
271
  - test/integration/token_test.rb
@@ -171,7 +277,7 @@ files:
171
277
  homepage: http://git.windmill.it/wm/devise-otp
172
278
  licenses: []
173
279
  metadata: {}
174
- post_install_message:
280
+ post_install_message:
175
281
  rdoc_options: []
176
282
  require_paths:
177
283
  - lib
@@ -186,14 +292,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
292
  - !ruby/object:Gem::Version
187
293
  version: '0'
188
294
  requirements: []
189
- rubyforge_project:
190
- rubygems_version: 2.2.2
191
- signing_key:
295
+ rubygems_version: 3.2.32
296
+ signing_key:
192
297
  specification_version: 4
193
298
  summary: Time Based OTP/rfc6238 compatible authentication for Devise
194
299
  test_files:
195
300
  - test/dummy/README.rdoc
196
301
  - test/dummy/Rakefile
302
+ - test/dummy/app/assets/config/manifest.js
197
303
  - test/dummy/app/assets/javascripts/application.js
198
304
  - test/dummy/app/assets/stylesheets/application.css
199
305
  - test/dummy/app/controllers/application_controller.rb
@@ -236,6 +342,7 @@ test_files:
236
342
  - test/dummy/public/500.html
237
343
  - test/dummy/public/favicon.ico
238
344
  - test/dummy/script/rails
345
+ - test/integration/persistence_test.rb
239
346
  - test/integration/refresh_test.rb
240
347
  - test/integration/sign_in_test.rb
241
348
  - test/integration/token_test.rb
data/.travis.yml DELETED
@@ -1,12 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.2
6
- - rbx-19mode
7
- - rbx-20mode
8
- script: rake test
9
- env:
10
- - DEVISE_ORM=active_record
11
- matrix:
12
- allow_failures:
@@ -1,106 +0,0 @@
1
- class DeviseOtp::CredentialsController < DeviseController
2
- helper_method :new_session_path
3
-
4
- prepend_before_filter :authenticate_scope!, :only => [:get_refresh, :set_refresh]
5
- prepend_before_filter :require_no_authentication, :only => [ :show, :update ]
6
-
7
- #
8
- # show a request for the OTP token
9
- #
10
- def show
11
- @challenge = params[:challenge]
12
- @recovery = (params[:recovery] == 'true') && recovery_enabled?
13
-
14
- if @challenge.nil?
15
- redirect_to :root
16
-
17
- else
18
- self.resource = resource_class.find_valid_otp_challenge(@challenge)
19
- if resource.nil?
20
- redirect_to :root
21
- elsif @recovery
22
- @recovery_count = resource.otp_recovery_counter
23
- render :show
24
- else
25
- render :show
26
- end
27
- end
28
- end
29
-
30
- #
31
- # signs the resource in, if the OTP token is valid and the user has a valid challenge
32
- #
33
- def update
34
-
35
- resource = resource_class.find_valid_otp_challenge(params[resource_name][:challenge])
36
- recovery = (params[resource_name][:recovery] == 'true') && recovery_enabled?
37
- token = params[resource_name][:token]
38
-
39
- if token.blank?
40
- otp_set_flash_message(:alert, :token_blank)
41
- redirect_to otp_credential_path_for(resource_name, :challenge => params[resource_name][:challenge],
42
- :recovery => recovery)
43
- elsif resource.nil?
44
- otp_set_flash_message(:alert, :otp_session_invalid)
45
- redirect_to new_session_path(resource_name)
46
- else
47
- if resource.otp_challenge_valid? && resource.validate_otp_token(params[resource_name][:token], recovery)
48
- set_flash_message(:success, :signed_in) if is_navigational_format?
49
- sign_in(resource_name, resource)
50
-
51
- otp_refresh_credentials_for(resource)
52
- respond_with resource, :location => after_sign_in_path_for(resource)
53
- else
54
- otp_set_flash_message :alert, :token_invalid
55
- redirect_to new_session_path(resource_name)
56
- end
57
- end
58
- end
59
-
60
-
61
- #
62
- # displays the request for a credentials refresh
63
- #
64
- def get_refresh
65
- ensure_resource!
66
- render :refresh
67
- end
68
-
69
- #
70
- # lets the user through is the refresh is valid
71
- #
72
- def set_refresh
73
-
74
- ensure_resource!
75
- # I am sure there's a much better way
76
- if resource.valid_password?(params[resource_name][:refresh_password])
77
- if resource.otp_enabled?
78
- if resource.validate_otp_token(params[resource_name][:token])
79
- done_valid_refresh
80
- else
81
- failed_refresh
82
- end
83
- else
84
- done_valid_refresh
85
- end
86
- else
87
- failed_refresh
88
- end
89
- end
90
-
91
-
92
- private
93
-
94
- def done_valid_refresh
95
- otp_refresh_credentials_for(resource)
96
- otp_set_flash_message :success, :valid_refresh if is_navigational_format?
97
-
98
- respond_with resource, :location => otp_fetch_refresh_return_url
99
- end
100
-
101
- def failed_refresh
102
- otp_set_flash_message :alert, :invalid_refresh
103
- render :refresh
104
- end
105
-
106
- end
@@ -1,105 +0,0 @@
1
- class DeviseOtp::TokensController < DeviseController
2
- include Devise::Controllers::Helpers
3
-
4
- prepend_before_filter :ensure_credentials_refresh
5
- prepend_before_filter :authenticate_scope!
6
-
7
- protect_from_forgery :except => [:clear_persistence, :delete_persistence]
8
-
9
- #
10
- # Displays the status of OTP authentication
11
- #
12
- def show
13
- if resource.nil?
14
- redirect_to stored_location_for(scope) || :root
15
- else
16
- render :show
17
- end
18
- end
19
-
20
- #
21
- # Updates the status of OTP authentication
22
- #
23
- def update
24
-
25
- enabled = (params[resource_name][:otp_enabled] == '1')
26
- if (enabled ? resource.enable_otp! : resource.disable_otp!)
27
-
28
- otp_set_flash_message :success, :successfully_updated
29
- end
30
- render :show
31
- end
32
-
33
- #
34
- # Resets OTP authentication, generates new credentials, sets it to off
35
- #
36
- def destroy
37
-
38
- if resource.reset_otp_credentials!
39
- otp_set_flash_message :success, :successfully_reset_creds
40
- end
41
- render :show
42
- end
43
-
44
-
45
- #
46
- # makes the current browser persistent
47
- #
48
- def get_persistence
49
-
50
-
51
- if otp_set_trusted_device_for(resource)
52
- otp_set_flash_message :success, :successfully_set_persistence
53
- end
54
- redirect_to :action => :show
55
- end
56
-
57
-
58
- #
59
- # clears persistence for the current browser
60
- #
61
- def clear_persistence
62
- if otp_clear_trusted_device_for(resource)
63
- otp_set_flash_message :success, :successfully_cleared_persistence
64
- end
65
-
66
- redirect_to :action => :show
67
- end
68
-
69
-
70
- #
71
- # rehash the persistence secret, thus, making all the persistence cookies invalid
72
- #
73
- def delete_persistence
74
- if otp_reset_persistence_for(resource)
75
- otp_set_flash_message :notice, :successfully_reset_persistence
76
- end
77
-
78
- redirect_to :action => :show
79
- end
80
-
81
- #
82
- #
83
- #
84
- def recovery
85
- render :recovery
86
- end
87
-
88
-
89
- private
90
-
91
- def ensure_credentials_refresh
92
-
93
- ensure_resource!
94
- if needs_credentials_refresh?(resource)
95
- otp_set_flash_message :notice, :need_to_refresh_credentials
96
- redirect_to refresh_otp_credential_path_for(resource)
97
- end
98
- end
99
-
100
- def scope
101
- resource_name.to_sym
102
- end
103
-
104
-
105
- end
@@ -1,20 +0,0 @@
1
- <h2><%= I18n.t('title', {:scope => 'devise.otp.credentials_refresh'}) %></h2>
2
- <p><%= I18n.t('explain', {:scope => 'devise.otp.credentials_refresh'}) %></p>
3
-
4
- <%= form_for(resource, :as => resource_name, :url => [:refresh, resource_name, :otp_credential], :html => { :method => :put }) do |f| %>
5
-
6
- <%= devise_error_messages! %>
7
-
8
- <div><%= f.label :email %><br />
9
- <%= f.text_field :email, :disabled => :true%></div>
10
-
11
- <div><%= f.label :password %><br />
12
- <%= f.password_field :refresh_password, :autocomplete => :off, :autofocus => true %></div>
13
-
14
- <%- if resource.otp_enabled? %>
15
- <div><%= f.label :token, I18n.t(:token, {:scope => 'devise.otp.credentials_refresh'}) %></p><br />
16
- <%= f.password_field :token, :autocomplete => :off%></div>
17
- <% end %>
18
-
19
- <div><%= f.submit I18n.t(:go_on, {:scope => 'devise.otp.credentials_refresh'}) %></div>
20
- <% end %>
@@ -1,23 +0,0 @@
1
- <h2><%= I18n.t('title', {:scope => 'devise.otp.submit_token'}) %></h2>
2
- <p><%= I18n.t('explain', {:scope => 'devise.otp.submit_token'}) %></p>
3
-
4
- <%= form_for(resource, :as => resource_name, :url => [resource_name, :otp_credential], :html => { :method => :put }) do |f| %>
5
-
6
- <%= f.hidden_field :challenge, {:value => @challenge} %>
7
- <%= f.hidden_field :recovery, {:value => @recovery} %>
8
-
9
- <%- if @recovery %>
10
- <p><%= f.label :token, I18n.t('recovery_prompt', {:scope => 'devise.otp.submit_token'}) %><br />
11
- <%= f.text_field :otp_recovery_counter, :autocomplete => :off, :disabled => true, :size => 4 %>
12
- <% else %>
13
- <p><%= f.label :token, I18n.t('prompt', {:scope => 'devise.otp.submit_token'}) %><br />
14
- <% end %>
15
-
16
- <%= f.text_field :token, :autocomplete => :off, :autofocus => true, :size => 6, :value => '' %>
17
- </p>
18
-
19
- <p><%= f.submit I18n.t('submit', {:scope => 'devise.otp.submit_token'}) %></p>
20
- <%- if !@recovery && recovery_enabled? %>
21
- <p><%= link_to I18n.t('recovery_link', {:scope => 'devise.otp.submit_token'}), otp_credential_path_for(resource_name, :challenge => @challenge, :recovery => true) %></p>
22
- <% end %>
23
- <% end %>