devise-2fa 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.hound.yml +2 -0
  4. data/.ruby-style.yml +1248 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +25 -0
  7. data/LICENSE +21 -0
  8. data/README.md +130 -0
  9. data/Rakefile +41 -0
  10. data/app/controllers/devise/credentials_controller.rb +100 -0
  11. data/app/controllers/devise/tokens_controller.rb +99 -0
  12. data/app/views/devise/credentials/refresh.html.erb +20 -0
  13. data/app/views/devise/credentials/show.html.erb +23 -0
  14. data/app/views/devise/tokens/_token_secret.html.erb +19 -0
  15. data/app/views/devise/tokens/_trusted_devices.html.erb +10 -0
  16. data/app/views/devise/tokens/recovery.html.erb +21 -0
  17. data/app/views/devise/tokens/recovery_codes.text.erb +3 -0
  18. data/app/views/devise/tokens/show.html.erb +19 -0
  19. data/config/locales/en.yml +57 -0
  20. data/devise-2fa.gemspec +27 -0
  21. data/lib/devise-2fa.rb +74 -0
  22. data/lib/devise-2fa/version.rb +5 -0
  23. data/lib/devise_two_factorable/controllers/helpers.rb +136 -0
  24. data/lib/devise_two_factorable/controllers/url_helpers.rb +30 -0
  25. data/lib/devise_two_factorable/engine.rb +22 -0
  26. data/lib/devise_two_factorable/helpers.rb +136 -0
  27. data/lib/devise_two_factorable/hooks.rb +11 -0
  28. data/lib/devise_two_factorable/hooks/sessions.rb +49 -0
  29. data/lib/devise_two_factorable/mapping.rb +12 -0
  30. data/lib/devise_two_factorable/models/two_factorable.rb +131 -0
  31. data/lib/devise_two_factorable/routes.rb +26 -0
  32. data/lib/devise_two_factorable/two_factorable.rb +131 -0
  33. data/lib/generators/active_record/devise_two_factor_generator.rb +32 -0
  34. data/lib/generators/active_record/templates/migration.rb +27 -0
  35. data/lib/generators/devise_two_factor/devise_two_factor_generator.rb +16 -0
  36. data/lib/generators/devise_two_factor/install_generator.rb +52 -0
  37. data/lib/generators/devise_two_factor/views_generator.rb +19 -0
  38. data/lib/generators/mongoid/devise_two_factor_generator.rb +34 -0
  39. data/test/dummy/README.rdoc +261 -0
  40. data/test/dummy/Rakefile +7 -0
  41. data/test/dummy/app/assets/javascripts/application.js +13 -0
  42. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  43. data/test/dummy/app/controllers/application_controller.rb +4 -0
  44. data/test/dummy/app/controllers/posts_controller.rb +83 -0
  45. data/test/dummy/app/helpers/application_helper.rb +2 -0
  46. data/test/dummy/app/helpers/posts_helper.rb +2 -0
  47. data/test/dummy/app/mailers/.gitkeep +0 -0
  48. data/test/dummy/app/models/post.rb +2 -0
  49. data/test/dummy/app/models/user.rb +20 -0
  50. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  51. data/test/dummy/app/views/posts/_form.html.erb +25 -0
  52. data/test/dummy/app/views/posts/edit.html.erb +6 -0
  53. data/test/dummy/app/views/posts/index.html.erb +25 -0
  54. data/test/dummy/app/views/posts/new.html.erb +5 -0
  55. data/test/dummy/app/views/posts/show.html.erb +15 -0
  56. data/test/dummy/config.ru +4 -0
  57. data/test/dummy/config/application.rb +67 -0
  58. data/test/dummy/config/boot.rb +10 -0
  59. data/test/dummy/config/database.yml +25 -0
  60. data/test/dummy/config/environment.rb +5 -0
  61. data/test/dummy/config/environments/development.rb +37 -0
  62. data/test/dummy/config/environments/production.rb +73 -0
  63. data/test/dummy/config/environments/test.rb +36 -0
  64. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  65. data/test/dummy/config/initializers/devise.rb +251 -0
  66. data/test/dummy/config/initializers/inflections.rb +15 -0
  67. data/test/dummy/config/initializers/mime_types.rb +5 -0
  68. data/test/dummy/config/initializers/secret_token.rb +8 -0
  69. data/test/dummy/config/initializers/session_store.rb +8 -0
  70. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  71. data/test/dummy/config/locales/en.yml +5 -0
  72. data/test/dummy/config/routes.rb +6 -0
  73. data/test/dummy/db/migrate/20130125101430_create_users.rb +9 -0
  74. data/test/dummy/db/migrate/20130131092406_add_devise_to_users.rb +52 -0
  75. data/test/dummy/db/migrate/20130131142320_create_posts.rb +10 -0
  76. data/test/dummy/db/migrate/20130131160351_devise_otp_add_to_users.rb +28 -0
  77. data/test/dummy/lib/assets/.gitkeep +0 -0
  78. data/test/dummy/public/404.html +26 -0
  79. data/test/dummy/public/422.html +26 -0
  80. data/test/dummy/public/500.html +25 -0
  81. data/test/dummy/public/favicon.ico +0 -0
  82. data/test/dummy/script/rails +6 -0
  83. data/test/integration/persistence_test.rb +63 -0
  84. data/test/integration/refresh_test.rb +103 -0
  85. data/test/integration/sign_in_test.rb +85 -0
  86. data/test/integration/token_test.rb +30 -0
  87. data/test/integration_tests_helper.rb +64 -0
  88. data/test/model_tests_helper.rb +20 -0
  89. data/test/models/two_factorable_test.rb +120 -0
  90. data/test/orm/active_record.rb +4 -0
  91. data/test/orm/mongoid.rb +13 -0
  92. data/test/support/mongoid.yml +6 -0
  93. data/test/support/symmetric_encryption.yml +70 -0
  94. data/test/test_helper.rb +18 -0
  95. metadata +269 -0
@@ -0,0 +1,120 @@
1
+ require 'test_helper'
2
+ require 'model_tests_helper'
3
+
4
+ class TwoFactorableTest < ActiveSupport::TestCase
5
+ def setup
6
+ new_user
7
+ end
8
+
9
+ test 'new users have a non-nil secret set' do
10
+ assert_not_nil User.first.otp_auth_secret
11
+ end
12
+
13
+ test 'new users have OTP disabled by default' do
14
+ assert !User.first.otp_enabled
15
+ end
16
+
17
+ test 'users should have an instance of TOTP/ROTP objects' do
18
+ u = User.first
19
+ assert u.time_based_otp.is_a? ROTP::TOTP
20
+ assert u.recovery_otp.is_a? ROTP::HOTP
21
+ end
22
+
23
+ test 'users should have their otp_auth_secret/persistence_seed set on creation' do
24
+ assert User.first.otp_auth_secret
25
+ assert User.first.otp_persistence_seed
26
+ end
27
+
28
+ test 'reset_otp_credentials should generate new secrets and disable OTP' do
29
+ u = User.first
30
+ u.update_attribute(:otp_enabled, true)
31
+ assert u.otp_enabled
32
+ otp_auth_secret = u.otp_auth_secret
33
+ otp_persistence_seed = u.otp_persistence_seed
34
+
35
+ u.reset_otp_credentials!
36
+ assert !(otp_auth_secret == u.otp_auth_secret)
37
+ assert !(otp_persistence_seed == u.otp_persistence_seed)
38
+ assert !u.otp_enabled
39
+ end
40
+
41
+ test 'reset_otp_persistence should generate new persistence_seed but NOT change the otp_auth_secret' do
42
+ u = User.first
43
+ u.update_attribute(:otp_enabled, true)
44
+ assert u.otp_enabled
45
+ otp_auth_secret = u.otp_auth_secret
46
+ otp_persistence_seed = u.otp_persistence_seed
47
+
48
+ u.reset_otp_persistence!
49
+ assert (otp_auth_secret == u.otp_auth_secret)
50
+ assert !(otp_persistence_seed == u.otp_persistence_seed)
51
+ assert u.otp_enabled
52
+ end
53
+
54
+ test 'generating a challenge, should retrieve the user later' do
55
+ u = User.first
56
+ u.update_attribute(:otp_enabled, true)
57
+ challenge = u.generate_otp_challenge!
58
+
59
+ w = User.find_valid_otp_challenge(challenge)
60
+ assert w.is_a? User
61
+ assert_equal w, u
62
+ end
63
+
64
+ test 'expiring the challenge, should retrieve nothing' do
65
+ u = User.first
66
+ u.update_attribute(:otp_enabled, true)
67
+ challenge = u.generate_otp_challenge!(1.second)
68
+ sleep(2)
69
+
70
+ w = User.find_valid_otp_challenge(challenge)
71
+ assert_nil w
72
+ end
73
+
74
+ test 'expired challenges should not be valid' do
75
+ u = User.first
76
+ u.update_attribute(:otp_enabled, true)
77
+ challenge = u.generate_otp_challenge!(1.second)
78
+ sleep(2)
79
+ assert_equal false, u.otp_challenge_valid?
80
+ end
81
+
82
+ test 'null otp challenge' do
83
+ u = User.first
84
+ u.update_attribute(:otp_enabled, true)
85
+ assert_equal false, u.validate_otp_token('')
86
+ assert_equal false, u.validate_otp_token(nil)
87
+ end
88
+
89
+ test 'generated otp token should be valid for the user' do
90
+ u = User.first
91
+ u.update_attribute(:otp_enabled, true)
92
+
93
+ secret = u.otp_auth_secret
94
+ token = ROTP::TOTP.new(secret).now
95
+
96
+ assert_equal true, u.validate_otp_token(token)
97
+ end
98
+
99
+ test 'generated otp token, out of drift window, should be NOT valid for the user' do
100
+ u = User.first
101
+ u.update_attribute(:otp_enabled, true)
102
+
103
+ secret = u.otp_auth_secret
104
+
105
+ [3.minutes.from_now, 3.minutes.ago].each do |time|
106
+ token = ROTP::TOTP.new(secret).at(time)
107
+ assert_equal false, u.valid_otp_token?(token)
108
+ end
109
+ end
110
+
111
+ test 'recovery secrets should be valid, and valid only once' do
112
+ u = User.first
113
+ u.update_attribute(:otp_enabled, true)
114
+ recovery = u.next_otp_recovery_tokens
115
+
116
+ assert u.valid_otp_recovery_token? recovery.fetch(0)
117
+ assert_equal false, u.valid_otp_recovery_token?(recovery.fetch(0))
118
+ assert u.valid_otp_recovery_token? recovery.fetch(2)
119
+ end
120
+ end
@@ -0,0 +1,4 @@
1
+ ActiveRecord::Migration.verbose = false
2
+ ActiveRecord::Base.logger = Logger.new(nil)
3
+
4
+ ActiveRecord::Migrator.migrate(File.expand_path('../../dummy/db/migrate/', __FILE__))
@@ -0,0 +1,13 @@
1
+ require 'mongoid/version'
2
+
3
+ Mongoid.configure do |config|
4
+ config.load!('test/support/mongoid.yml')
5
+ config.use_utc = true
6
+ config.include_root_in_json = true
7
+ end
8
+
9
+ class ActiveSupport::TestCase
10
+ setup do
11
+ Mongoid.purge!
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ <%= Mongoid::VERSION.to_i > 4 ? 'clients' : 'sessions' %>:
3
+ default:
4
+ database: devise-2fa-test-suite
5
+ hosts:
6
+ - localhost:<%= ENV['MONGODB_PORT'] || '27017' %>
@@ -0,0 +1,70 @@
1
+ #
2
+ # Symmetric Encryption for Ruby
3
+ #
4
+ ---
5
+ # For the development and test environments the test symmetric encryption keys
6
+ # can be placed directly in the source code.
7
+ # And therefore no RSA private key is required
8
+ development: &development_defaults
9
+ key: 1234567890ABCDEF1234567890ABCDEF
10
+ iv: 1234567890ABCDEF
11
+ cipher_name: aes-128-cbc
12
+
13
+ test:
14
+ <<: *development_defaults
15
+
16
+ production:
17
+ # Since the key to encrypt and decrypt with must NOT be stored along with the
18
+ # source code, we only hold a RSA key that is used to unlock the file
19
+ # containing the actual symmetric encryption key
20
+ #
21
+ # Sample RSA Key, DO NOT use this RSA key, generate a new one using
22
+ # openssl genrsa 2048
23
+ private_rsa_key: |
24
+ -----BEGIN RSA PRIVATE KEY-----
25
+ MIIEpAIBAAKCAQEAxIL9H/jYUGpA38v6PowRSRJEo3aNVXULNM/QNRpx2DTf++KH
26
+ 6DcuFTFcNSSSxG9n4y7tKi755be8N0uwCCuOzvXqfWmXYjbLwK3Ib2vm0btpHyvA
27
+ qxgqeJOOCxKdW/cUFLWn0tACUcEjVCNfWEGaFyvkOUuR7Ub9KfhbW9cZO3BxZMUf
28
+ IPGlHl/gWyf484sXygd+S7cpDTRRzo9RjG74DwfE0MFGf9a1fTkxnSgeOJ6asTOy
29
+ fp9tEToUlbglKaYGpOGHYQ9TV5ZsyJ9jRUyb4SP5wK2eK6dHTxTcHvT03kD90Hv4
30
+ WeKIXv3WOjkwNEyMdpnJJfSDb5oquQvCNi7ZSQIDAQABAoIBAQCbzR7TUoBugU+e
31
+ ICLvpC2wOYOh9kRoFLwlyv3QnH7WZFWRZzFJszYeJ1xr5etXQtyjCnmOkGAg+WOI
32
+ k8GlOKOpAuA/PpB/leJFiYL4lBwU/PmDdTT0cdx6bMKZlNCeMW8CXGQKiFDOcMqJ
33
+ 0uGtH5YD+RChPIEeFsJxnC8SyZ9/t2ra7XnMGiCZvRXIUDSEIIsRx/mOymJ7bL+h
34
+ Lbp46IfXf6ZuIzwzoIk0JReV/r+wdmkAVDkrrMkCmVS4/X1wN/Tiik9/yvbsh/CL
35
+ ztC55eSIEjATkWxnXfPASZN6oUfQPEveGH3HzNjdncjH/Ho8FaNMIAfFpBhhLPi9
36
+ nG5sbH+BAoGBAOdoUyVoAA/QUa3/FkQaa7Ajjehe5MR5k6VtaGtcxrLiBjrNR7x+
37
+ nqlZlGvWDMiCz49dgj+G1Qk1bbYrZLRX/Hjeqy5dZOGLMfgf9eKUmS1rDwAzBMcj
38
+ M9jnnJEBx8HIlNzaR6wzp3GMd0rrccs660A8URvzkgo9qNbvMLq9vyUtAoGBANll
39
+ SY1Iv9uaIz8klTXU9YzYtsfUmgXzw7K8StPdbEbo8F1J3JPJB4D7QHF0ObIaSWuf
40
+ suZqLsvWlYGuJeyX2ntlBN82ORfvUdOrdrbDlmPyj4PfFVl0AK3U3Ai374DNrjKR
41
+ hF6YFm4TLDaJhUjeV5C43kbE1N2FAMS9LYtPJ44NAoGAFDGHZ/E+aCLerddfwwun
42
+ MBS6MnftcLPHTZ1RimTrNfsBXipBw1ItWEvn5s0kCm9X24PmdNK4TnhqHYaF4DL5
43
+ ZjbQK1idEA2Mi8GGPIKJJ2x7P6I0HYiV4qy7fe/w1ZlCXE90B7PuPbtrQY9wO7Ll
44
+ ipJ45X6I1PnyfOcckn8yafUCgYACtPAlgjJhWZn2v03cTbqA9nHQKyV/zXkyUIXd
45
+ /XPLrjrP7ouAi5A8WuSChR/yx8ECRgrEM65Be3qBEtoGCB4AS1G0NcigM6qhKBFi
46
+ VS0aMXr3+V8argcUIwJaWW/x+p2go48yXlJpLHPweeXe8mXEt4iM+QZte6p2yKQ4
47
+ h9PGQQKBgQCqSydmXBnXGIVTp2sH/2GnpxLYnDBpcJE0tM8bJ42HEQQgRThIChsn
48
+ PnGA91G9MVikYapgI0VYBHQOTsz8rTIUzsKwXG+TIaK+W84nxH5y6jUkjqwxZmAz
49
+ r1URaMAun2PfAB4g2N/kEZTExgeOGqXjFhvvjdzl97ux2cTyZhaTXg==
50
+ -----END RSA PRIVATE KEY-----
51
+
52
+ # List Symmetric Key files in the order of current / latest first
53
+ ciphers:
54
+ -
55
+ # Filename containing Symmetric Encryption Key encrypted using the
56
+ # RSA public key derived from the private key above
57
+ key_filename: /etc/rails/.rails.key
58
+ iv_filename: /etc/rails/.rails.iv
59
+
60
+ # Encryption cipher_name
61
+ # Recommended values:
62
+ # aes-256-cbc
63
+ # 256 AES CBC Algorithm. Very strong
64
+ # Ruby 1.8.7 MRI Approximately 100,000 encryptions or decryptions per second
65
+ # JRuby 1.6.7 with Ruby 1.8.7 Approximately 22,000 encryptions or decryptions per second
66
+ # aes-128-cbc
67
+ # 128 AES CBC Algorithm. Less strong.
68
+ # Ruby 1.8.7 MRI Approximately 100,000 encryptions or decryptions per second
69
+ # JRuby 1.6.7 with Ruby 1.8.7 Approximately 22,000 encryptions or decryptions per second
70
+ cipher_name: aes-256-cbc
@@ -0,0 +1,18 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+ DEVISE_ORM = (ENV['DEVISE_ORM'] || :active_record).to_sym
3
+
4
+ $LOAD_PATH.unshift File.dirname(__FILE__)
5
+ puts "\n==> Devise.orm = #{DEVISE_ORM.inspect}"
6
+ require 'dummy/config/environment'
7
+ require "orm/#{DEVISE_ORM}"
8
+ require 'rails/test_help'
9
+ require 'capybara/rails'
10
+ require 'minitest/reporters'
11
+
12
+ I18n.load_path << File.expand_path("../support/locale/en.yml", __FILE__) if DEVISE_ORM == :mongoid
13
+
14
+ MiniTest::Reporters.use!
15
+
16
+ class ActionDispatch::IntegrationTest
17
+ include Capybara::DSL
18
+ end
metadata ADDED
@@ -0,0 +1,269 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise-2fa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - William A. Todd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: devise
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.2.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.2.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rotp
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rqrcode
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.10.1
61
+ - !ruby/object:Gem::Dependency
62
+ name: symmetric-encryption
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.8'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.8'
75
+ - !ruby/object:Gem::Dependency
76
+ name: sqlite3
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: Time Based OTP/rfc6238 authentication for Devise
90
+ email:
91
+ - info@investinwaffles.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - ".gitignore"
97
+ - ".hound.yml"
98
+ - ".ruby-style.yml"
99
+ - ".travis.yml"
100
+ - Gemfile
101
+ - LICENSE
102
+ - README.md
103
+ - Rakefile
104
+ - app/controllers/devise/credentials_controller.rb
105
+ - app/controllers/devise/tokens_controller.rb
106
+ - app/views/devise/credentials/refresh.html.erb
107
+ - app/views/devise/credentials/show.html.erb
108
+ - app/views/devise/tokens/_token_secret.html.erb
109
+ - app/views/devise/tokens/_trusted_devices.html.erb
110
+ - app/views/devise/tokens/recovery.html.erb
111
+ - app/views/devise/tokens/recovery_codes.text.erb
112
+ - app/views/devise/tokens/show.html.erb
113
+ - config/locales/en.yml
114
+ - devise-2fa.gemspec
115
+ - lib/devise-2fa.rb
116
+ - lib/devise-2fa/version.rb
117
+ - lib/devise_two_factorable/controllers/helpers.rb
118
+ - lib/devise_two_factorable/controllers/url_helpers.rb
119
+ - lib/devise_two_factorable/engine.rb
120
+ - lib/devise_two_factorable/helpers.rb
121
+ - lib/devise_two_factorable/hooks.rb
122
+ - lib/devise_two_factorable/hooks/sessions.rb
123
+ - lib/devise_two_factorable/mapping.rb
124
+ - lib/devise_two_factorable/models/two_factorable.rb
125
+ - lib/devise_two_factorable/routes.rb
126
+ - lib/devise_two_factorable/two_factorable.rb
127
+ - lib/generators/active_record/devise_two_factor_generator.rb
128
+ - lib/generators/active_record/templates/migration.rb
129
+ - lib/generators/devise_two_factor/devise_two_factor_generator.rb
130
+ - lib/generators/devise_two_factor/install_generator.rb
131
+ - lib/generators/devise_two_factor/views_generator.rb
132
+ - lib/generators/mongoid/devise_two_factor_generator.rb
133
+ - test/dummy/README.rdoc
134
+ - test/dummy/Rakefile
135
+ - test/dummy/app/assets/javascripts/application.js
136
+ - test/dummy/app/assets/stylesheets/application.css
137
+ - test/dummy/app/controllers/application_controller.rb
138
+ - test/dummy/app/controllers/posts_controller.rb
139
+ - test/dummy/app/helpers/application_helper.rb
140
+ - test/dummy/app/helpers/posts_helper.rb
141
+ - test/dummy/app/mailers/.gitkeep
142
+ - test/dummy/app/models/post.rb
143
+ - test/dummy/app/models/user.rb
144
+ - test/dummy/app/views/layouts/application.html.erb
145
+ - test/dummy/app/views/posts/_form.html.erb
146
+ - test/dummy/app/views/posts/edit.html.erb
147
+ - test/dummy/app/views/posts/index.html.erb
148
+ - test/dummy/app/views/posts/new.html.erb
149
+ - test/dummy/app/views/posts/show.html.erb
150
+ - test/dummy/config.ru
151
+ - test/dummy/config/application.rb
152
+ - test/dummy/config/boot.rb
153
+ - test/dummy/config/database.yml
154
+ - test/dummy/config/environment.rb
155
+ - test/dummy/config/environments/development.rb
156
+ - test/dummy/config/environments/production.rb
157
+ - test/dummy/config/environments/test.rb
158
+ - test/dummy/config/initializers/backtrace_silencers.rb
159
+ - test/dummy/config/initializers/devise.rb
160
+ - test/dummy/config/initializers/inflections.rb
161
+ - test/dummy/config/initializers/mime_types.rb
162
+ - test/dummy/config/initializers/secret_token.rb
163
+ - test/dummy/config/initializers/session_store.rb
164
+ - test/dummy/config/initializers/wrap_parameters.rb
165
+ - test/dummy/config/locales/en.yml
166
+ - test/dummy/config/routes.rb
167
+ - test/dummy/db/migrate/20130125101430_create_users.rb
168
+ - test/dummy/db/migrate/20130131092406_add_devise_to_users.rb
169
+ - test/dummy/db/migrate/20130131142320_create_posts.rb
170
+ - test/dummy/db/migrate/20130131160351_devise_otp_add_to_users.rb
171
+ - test/dummy/lib/assets/.gitkeep
172
+ - test/dummy/public/404.html
173
+ - test/dummy/public/422.html
174
+ - test/dummy/public/500.html
175
+ - test/dummy/public/favicon.ico
176
+ - test/dummy/script/rails
177
+ - test/integration/persistence_test.rb
178
+ - test/integration/refresh_test.rb
179
+ - test/integration/sign_in_test.rb
180
+ - test/integration/token_test.rb
181
+ - test/integration_tests_helper.rb
182
+ - test/model_tests_helper.rb
183
+ - test/models/two_factorable_test.rb
184
+ - test/orm/active_record.rb
185
+ - test/orm/mongoid.rb
186
+ - test/support/mongoid.yml
187
+ - test/support/symmetric_encryption.yml
188
+ - test/test_helper.rb
189
+ homepage: http://www.github.com/williamatodd/devise-2fa
190
+ licenses:
191
+ - MIT
192
+ metadata: {}
193
+ post_install_message:
194
+ rdoc_options: []
195
+ require_paths:
196
+ - lib
197
+ required_ruby_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ required_rubygems_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ requirements: []
208
+ rubyforge_project:
209
+ rubygems_version: 2.6.1
210
+ signing_key:
211
+ specification_version: 4
212
+ summary: Includes ActiveRecord and Mongoid ORM support
213
+ test_files:
214
+ - test/dummy/README.rdoc
215
+ - test/dummy/Rakefile
216
+ - test/dummy/app/assets/javascripts/application.js
217
+ - test/dummy/app/assets/stylesheets/application.css
218
+ - test/dummy/app/controllers/application_controller.rb
219
+ - test/dummy/app/controllers/posts_controller.rb
220
+ - test/dummy/app/helpers/application_helper.rb
221
+ - test/dummy/app/helpers/posts_helper.rb
222
+ - test/dummy/app/mailers/.gitkeep
223
+ - test/dummy/app/models/post.rb
224
+ - test/dummy/app/models/user.rb
225
+ - test/dummy/app/views/layouts/application.html.erb
226
+ - test/dummy/app/views/posts/_form.html.erb
227
+ - test/dummy/app/views/posts/edit.html.erb
228
+ - test/dummy/app/views/posts/index.html.erb
229
+ - test/dummy/app/views/posts/new.html.erb
230
+ - test/dummy/app/views/posts/show.html.erb
231
+ - test/dummy/config.ru
232
+ - test/dummy/config/application.rb
233
+ - test/dummy/config/boot.rb
234
+ - test/dummy/config/database.yml
235
+ - test/dummy/config/environment.rb
236
+ - test/dummy/config/environments/development.rb
237
+ - test/dummy/config/environments/production.rb
238
+ - test/dummy/config/environments/test.rb
239
+ - test/dummy/config/initializers/backtrace_silencers.rb
240
+ - test/dummy/config/initializers/devise.rb
241
+ - test/dummy/config/initializers/inflections.rb
242
+ - test/dummy/config/initializers/mime_types.rb
243
+ - test/dummy/config/initializers/secret_token.rb
244
+ - test/dummy/config/initializers/session_store.rb
245
+ - test/dummy/config/initializers/wrap_parameters.rb
246
+ - test/dummy/config/locales/en.yml
247
+ - test/dummy/config/routes.rb
248
+ - test/dummy/db/migrate/20130125101430_create_users.rb
249
+ - test/dummy/db/migrate/20130131092406_add_devise_to_users.rb
250
+ - test/dummy/db/migrate/20130131142320_create_posts.rb
251
+ - test/dummy/db/migrate/20130131160351_devise_otp_add_to_users.rb
252
+ - test/dummy/lib/assets/.gitkeep
253
+ - test/dummy/public/404.html
254
+ - test/dummy/public/422.html
255
+ - test/dummy/public/500.html
256
+ - test/dummy/public/favicon.ico
257
+ - test/dummy/script/rails
258
+ - test/integration/persistence_test.rb
259
+ - test/integration/refresh_test.rb
260
+ - test/integration/sign_in_test.rb
261
+ - test/integration/token_test.rb
262
+ - test/integration_tests_helper.rb
263
+ - test/model_tests_helper.rb
264
+ - test/models/two_factorable_test.rb
265
+ - test/orm/active_record.rb
266
+ - test/orm/mongoid.rb
267
+ - test/support/mongoid.yml
268
+ - test/support/symmetric_encryption.yml
269
+ - test/test_helper.rb