google-authenticator-rails 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 00704838d9ed31eedcc4224c0116b6606b50ca57
4
- data.tar.gz: e0c8bf5800b17aa91190e090dd1f44e0f7872e69
2
+ SHA256:
3
+ metadata.gz: 440ad5551c31c754fd9870dfd810d9ea97969627f5a97e058c336cc8148b5e59
4
+ data.tar.gz: 1324392b3336a8ebe39c5c57c117412472d33b9985be59b6a11e72d62414955c
5
5
  SHA512:
6
- metadata.gz: e0e2a51adac592a8cd82be253b82007cbd8b39937ec8b161c1c6e5c39eebc26a0d87e252320540e350026d017301f517ef8565d183e17a723540864ca7874341
7
- data.tar.gz: 4f6d131a29bfbb93385637230a192c61682b5e7afb7912532eeae05fc9d6116760a0a5cf37296801aa66d3b3da602ec45ce8277644102e878364b621fd294a88
6
+ metadata.gz: 98c1cfa7de93eb922afc7c6d58db9fccb732be27e092846902db62993b75f4d55768c57f3352b56ffd28e3c2350faa17c8b458b61e02bf143b54458ceb856124
7
+ data.tar.gz: 724c84f98fbe300eb2488dcb2c24649592df811e65d1af5fc8c17aeec14c069102e5a3564592083cc131f2de193e95d82d8d44f4a904874c0e5faf59203573f0
data/Appraisals CHANGED
@@ -4,37 +4,18 @@ major = version_info.first.to_i
4
4
  minor = version_info[1].to_i
5
5
  hotfix = version_info.last.to_i
6
6
 
7
- appraise "rails3.0" do
8
- gem "activerecord", "~> 3.0.0"
7
+ appraise "rails-5.2" do
8
+ gem "activerecord", "~> 5.2.0"
9
9
  end
10
10
 
11
- appraise "rails3.1" do
12
- gem "activerecord", "~> 3.1.0"
11
+ appraise "rails-6.0" do
12
+ gem "activerecord", "~> 6.0.0"
13
13
  end
14
14
 
15
- appraise "rails3.2" do
16
- gem "activerecord", "~> 3.2.0"
15
+ appraise "rails-6.1" do
16
+ gem "activerecord", "~> 6.1.0"
17
17
  end
18
18
 
19
- appraise "rails4.0" do
20
- gem "activerecord", "~> 4.0.0"
21
- gem "protected_attributes"
22
- end
23
-
24
- appraise "rails4.1" do
25
- gem "activerecord", "~> 4.1.0"
26
- gem "protected_attributes"
27
- gem "json", "~> 1.8.3"
28
- end
29
-
30
- appraise "rails4.2" do
31
- gem "activerecord", "~> 4.2.0"
32
- end
33
-
34
- appraise "rails5.0" do
35
- gem "activerecord", "~> 5.0.0"
36
- end
37
-
38
- appraise "rails5.1" do
39
- gem "activerecord", "~> 5.1.0"
40
- end
19
+ appraise "rails-7.0" do
20
+ gem "activerecord", "~> 7.0.0"
21
+ end
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in google-authenticator.gemspec
4
- gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,156 +1,201 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- google-authenticator-rails (2.0.0)
4
+ google-authenticator-rails (3.0.0)
5
5
  actionpack
6
6
  activerecord
7
- google-qr
8
7
  rails
9
- rotp (= 3.3.0)
8
+ rotp (>= 5.0, < 7.0)
9
+ rqrcode
10
10
 
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- actioncable (5.2.0)
15
- actionpack (= 5.2.0)
14
+ actioncable (7.0.3)
15
+ actionpack (= 7.0.3)
16
+ activesupport (= 7.0.3)
16
17
  nio4r (~> 2.0)
17
18
  websocket-driver (>= 0.6.1)
18
- actionmailer (5.2.0)
19
- actionpack (= 5.2.0)
20
- actionview (= 5.2.0)
21
- activejob (= 5.2.0)
19
+ actionmailbox (7.0.3)
20
+ actionpack (= 7.0.3)
21
+ activejob (= 7.0.3)
22
+ activerecord (= 7.0.3)
23
+ activestorage (= 7.0.3)
24
+ activesupport (= 7.0.3)
25
+ mail (>= 2.7.1)
26
+ net-imap
27
+ net-pop
28
+ net-smtp
29
+ actionmailer (7.0.3)
30
+ actionpack (= 7.0.3)
31
+ actionview (= 7.0.3)
32
+ activejob (= 7.0.3)
33
+ activesupport (= 7.0.3)
22
34
  mail (~> 2.5, >= 2.5.4)
35
+ net-imap
36
+ net-pop
37
+ net-smtp
23
38
  rails-dom-testing (~> 2.0)
24
- actionpack (5.2.0)
25
- actionview (= 5.2.0)
26
- activesupport (= 5.2.0)
27
- rack (~> 2.0)
39
+ actionpack (7.0.3)
40
+ actionview (= 7.0.3)
41
+ activesupport (= 7.0.3)
42
+ rack (~> 2.0, >= 2.2.0)
28
43
  rack-test (>= 0.6.3)
29
44
  rails-dom-testing (~> 2.0)
30
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
31
- actionview (5.2.0)
32
- activesupport (= 5.2.0)
45
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
46
+ actiontext (7.0.3)
47
+ actionpack (= 7.0.3)
48
+ activerecord (= 7.0.3)
49
+ activestorage (= 7.0.3)
50
+ activesupport (= 7.0.3)
51
+ globalid (>= 0.6.0)
52
+ nokogiri (>= 1.8.5)
53
+ actionview (7.0.3)
54
+ activesupport (= 7.0.3)
33
55
  builder (~> 3.1)
34
56
  erubi (~> 1.4)
35
57
  rails-dom-testing (~> 2.0)
36
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
37
- activejob (5.2.0)
38
- activesupport (= 5.2.0)
58
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
59
+ activejob (7.0.3)
60
+ activesupport (= 7.0.3)
39
61
  globalid (>= 0.3.6)
40
- activemodel (5.2.0)
41
- activesupport (= 5.2.0)
42
- activerecord (5.2.0)
43
- activemodel (= 5.2.0)
44
- activesupport (= 5.2.0)
45
- arel (>= 9.0)
46
- activestorage (5.2.0)
47
- actionpack (= 5.2.0)
48
- activerecord (= 5.2.0)
49
- marcel (~> 0.3.1)
50
- activesupport (5.2.0)
62
+ activemodel (7.0.3)
63
+ activesupport (= 7.0.3)
64
+ activerecord (7.0.3)
65
+ activemodel (= 7.0.3)
66
+ activesupport (= 7.0.3)
67
+ activestorage (7.0.3)
68
+ actionpack (= 7.0.3)
69
+ activejob (= 7.0.3)
70
+ activerecord (= 7.0.3)
71
+ activesupport (= 7.0.3)
72
+ marcel (~> 1.0)
73
+ mini_mime (>= 1.1.0)
74
+ activesupport (7.0.3)
51
75
  concurrent-ruby (~> 1.0, >= 1.0.2)
52
- i18n (>= 0.7, < 2)
53
- minitest (~> 5.1)
54
- tzinfo (~> 1.1)
55
- appraisal (0.5.2)
76
+ i18n (>= 1.6, < 2)
77
+ minitest (>= 5.1)
78
+ tzinfo (~> 2.0)
79
+ appraisal (2.4.1)
56
80
  bundler
57
81
  rake
58
- arel (9.0.0)
59
- builder (3.2.3)
60
- concurrent-ruby (1.0.5)
61
- crass (1.0.4)
62
- diff-lcs (1.1.3)
63
- docile (1.1.5)
64
- erubi (1.7.1)
65
- globalid (0.4.1)
66
- activesupport (>= 4.2.0)
67
- google-qr (0.2.2)
68
- i18n (1.0.1)
82
+ thor (>= 0.14.0)
83
+ builder (3.2.4)
84
+ chunky_png (1.4.0)
85
+ concurrent-ruby (1.1.10)
86
+ crass (1.0.6)
87
+ diff-lcs (1.5.0)
88
+ digest (3.1.0)
89
+ docile (1.4.0)
90
+ erubi (1.10.0)
91
+ globalid (1.0.0)
92
+ activesupport (>= 5.0)
93
+ i18n (1.10.0)
69
94
  concurrent-ruby (~> 1.0)
70
- json (2.1.0)
71
- loofah (2.2.2)
95
+ loofah (2.18.0)
72
96
  crass (~> 1.0.2)
73
97
  nokogiri (>= 1.5.9)
74
- mail (2.7.0)
98
+ mail (2.7.1)
75
99
  mini_mime (>= 0.1.1)
76
- marcel (0.3.2)
77
- mimemagic (~> 0.3.2)
78
- method_source (0.9.0)
79
- mimemagic (0.3.2)
80
- mini_mime (1.0.0)
81
- mini_portile2 (2.3.0)
82
- minitest (5.11.3)
83
- nio4r (2.3.1)
84
- nokogiri (1.8.3)
85
- mini_portile2 (~> 2.3.0)
86
- rack (2.0.5)
87
- rack-test (1.0.0)
100
+ marcel (1.0.2)
101
+ method_source (1.0.0)
102
+ mini_mime (1.1.2)
103
+ mini_portile2 (2.8.0)
104
+ minitest (5.15.0)
105
+ net-imap (0.2.3)
106
+ digest
107
+ net-protocol
108
+ strscan
109
+ net-pop (0.1.1)
110
+ digest
111
+ net-protocol
112
+ timeout
113
+ net-protocol (0.1.3)
114
+ timeout
115
+ net-smtp (0.3.1)
116
+ digest
117
+ net-protocol
118
+ timeout
119
+ nio4r (2.5.8)
120
+ nokogiri (1.13.6)
121
+ mini_portile2 (~> 2.8.0)
122
+ racc (~> 1.4)
123
+ racc (1.6.0)
124
+ rack (2.2.3.1)
125
+ rack-test (1.1.0)
88
126
  rack (>= 1.0, < 3)
89
- rails (5.2.0)
90
- actioncable (= 5.2.0)
91
- actionmailer (= 5.2.0)
92
- actionpack (= 5.2.0)
93
- actionview (= 5.2.0)
94
- activejob (= 5.2.0)
95
- activemodel (= 5.2.0)
96
- activerecord (= 5.2.0)
97
- activestorage (= 5.2.0)
98
- activesupport (= 5.2.0)
99
- bundler (>= 1.3.0)
100
- railties (= 5.2.0)
101
- sprockets-rails (>= 2.0.0)
127
+ rails (7.0.3)
128
+ actioncable (= 7.0.3)
129
+ actionmailbox (= 7.0.3)
130
+ actionmailer (= 7.0.3)
131
+ actionpack (= 7.0.3)
132
+ actiontext (= 7.0.3)
133
+ actionview (= 7.0.3)
134
+ activejob (= 7.0.3)
135
+ activemodel (= 7.0.3)
136
+ activerecord (= 7.0.3)
137
+ activestorage (= 7.0.3)
138
+ activesupport (= 7.0.3)
139
+ bundler (>= 1.15.0)
140
+ railties (= 7.0.3)
102
141
  rails-dom-testing (2.0.3)
103
142
  activesupport (>= 4.2.0)
104
143
  nokogiri (>= 1.6)
105
- rails-html-sanitizer (1.0.4)
106
- loofah (~> 2.2, >= 2.2.2)
107
- railties (5.2.0)
108
- actionpack (= 5.2.0)
109
- activesupport (= 5.2.0)
144
+ rails-html-sanitizer (1.4.3)
145
+ loofah (~> 2.3)
146
+ railties (7.0.3)
147
+ actionpack (= 7.0.3)
148
+ activesupport (= 7.0.3)
110
149
  method_source
111
- rake (>= 0.8.7)
112
- thor (>= 0.18.1, < 2.0)
113
- rake (11.3.0)
114
- rotp (3.3.0)
115
- rspec (2.8.0)
116
- rspec-core (~> 2.8.0)
117
- rspec-expectations (~> 2.8.0)
118
- rspec-mocks (~> 2.8.0)
119
- rspec-core (2.8.0)
120
- rspec-expectations (2.8.0)
121
- diff-lcs (~> 1.1.2)
122
- rspec-mocks (2.8.0)
123
- simplecov (0.15.1)
124
- docile (~> 1.1.0)
125
- json (>= 1.8, < 3)
126
- simplecov-html (~> 0.10.0)
127
- simplecov-html (0.10.2)
128
- sprockets (3.7.2)
150
+ rake (>= 12.2)
151
+ thor (~> 1.0)
152
+ zeitwerk (~> 2.5)
153
+ rake (13.0.6)
154
+ rotp (6.2.0)
155
+ rqrcode (2.1.1)
156
+ chunky_png (~> 1.0)
157
+ rqrcode_core (~> 1.0)
158
+ rqrcode_core (1.2.0)
159
+ rspec (3.4.0)
160
+ rspec-core (~> 3.4.0)
161
+ rspec-expectations (~> 3.4.0)
162
+ rspec-mocks (~> 3.4.0)
163
+ rspec-core (3.4.4)
164
+ rspec-support (~> 3.4.0)
165
+ rspec-expectations (3.4.0)
166
+ diff-lcs (>= 1.2.0, < 2.0)
167
+ rspec-support (~> 3.4.0)
168
+ rspec-mocks (3.4.1)
169
+ diff-lcs (>= 1.2.0, < 2.0)
170
+ rspec-support (~> 3.4.0)
171
+ rspec-support (3.4.1)
172
+ simplecov (0.21.2)
173
+ docile (~> 1.1)
174
+ simplecov-html (~> 0.11)
175
+ simplecov_json_formatter (~> 0.1)
176
+ simplecov-html (0.12.3)
177
+ simplecov_json_formatter (0.1.4)
178
+ sqlite3 (1.4.2)
179
+ strscan (3.0.3)
180
+ thor (1.2.1)
181
+ timeout (0.3.0)
182
+ tzinfo (2.0.4)
129
183
  concurrent-ruby (~> 1.0)
130
- rack (> 1, < 3)
131
- sprockets-rails (3.2.1)
132
- actionpack (>= 4.0)
133
- activesupport (>= 4.0)
134
- sprockets (>= 3.0.0)
135
- sqlite3 (1.3.13)
136
- thor (0.20.0)
137
- thread_safe (0.3.6)
138
- tzinfo (1.2.5)
139
- thread_safe (~> 0.1)
140
- websocket-driver (0.7.0)
184
+ websocket-driver (0.7.5)
141
185
  websocket-extensions (>= 0.1.0)
142
- websocket-extensions (0.1.3)
186
+ websocket-extensions (0.1.5)
187
+ zeitwerk (2.5.4)
143
188
 
144
189
  PLATFORMS
145
190
  ruby
146
191
 
147
192
  DEPENDENCIES
148
- appraisal (~> 0.5.1)
193
+ appraisal (~> 2.4.1)
149
194
  google-authenticator-rails!
150
- rake (~> 11.0)
151
- rspec (~> 2.8.0)
195
+ rake (~> 13.0)
196
+ rspec (~> 3.4.0)
152
197
  simplecov
153
- sqlite3
198
+ sqlite3 (~> 1.4.0)
154
199
 
155
200
  BUNDLED WITH
156
- 1.16.1
201
+ 2.3.15
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # GoogleAuthenticatorRails
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/google-authenticator-rails.png)](http://badge.fury.io/rb/google-authenticator-rails)
4
- [![Build Status](https://secure.travis-ci.org/jaredonline/google-authenticator.png)](http://travis-ci.org/jaredonline/google-authenticator)
5
4
  [![Code Climate](https://codeclimate.com/github/jaredonline/google-authenticator.png)](https://codeclimate.com/github/jaredonline/google-authenticator)
6
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/41e825da75bd7630262f/test_coverage)](https://codeclimate.com/github/jaredonline/google-authenticator/test_coverage)
6
+ [![CircleCI](https://circleci.com/gh/jaredonline/google-authenticator/tree/master.svg?style=svg)](https://circleci.com/gh/jaredonline/google-authenticator/tree/master)
7
7
 
8
8
  Rails (ActiveRecord) integration with the Google Authenticator apps for [Android](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2) and the [iPhone](https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8). Uses the Authlogic style for cookie management.
9
9
 
@@ -52,7 +52,7 @@ Example:
52
52
 
53
53
  ```ruby
54
54
  class User
55
- acts_as_google_authenticated :column => :user_name
55
+ acts_as_google_authenticated :column_name => :user_name
56
56
  end
57
57
 
58
58
  @user = User.new(:user_name => "ted")
@@ -200,7 +200,7 @@ class UserMfaSession < GoogleAuthenticatorRails::Session::Base
200
200
  end
201
201
 
202
202
  # app/controllers/mfa_session_controller.rb
203
- def class MfaSessionController < ApplicationController
203
+ class MfaSessionController < ApplicationController
204
204
  def create
205
205
  UserMfaSession.create(user)
206
206
  end
@@ -367,7 +367,7 @@ to change all encrypted google secret fields to use the new key.
367
367
  If the app is not running under Rails version 4.1 or above, encryption will be disabled, and a warning issued if ```:encrypt_secrets```
368
368
  is enabled on a model.
369
369
 
370
- If encryption is enabled for a model, the Google secret column of its table must be able to hold at least 138 characters, rather than just 16.
370
+ If encryption is enabled for a model, the Google secret column of its table must be able to hold at least 162 characters, rather than just 32.
371
371
 
372
372
  ## Contributing
373
373
 
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/google-authenticator-rails/version', __FILE__)
3
+
4
+ version_info = RUBY_VERSION.split(".")
5
+
6
+ major = version_info.first.to_i
7
+ minor = version_info[1].to_i
8
+ hotfix = version_info.last.to_i
9
+
10
+ Gem::Specification.new do |gem|
11
+ gem.authors = ["Jared McFarland"]
12
+ gem.email = ["jared.online@gmail.com"]
13
+ gem.description = %q{Add the ability to use the Google Authenticator with ActiveRecord.}
14
+ gem.summary = %q{Add the ability to use the Google Authenticator with ActiveRecord.}
15
+ gem.homepage = "http://github.com/jaredonline/google-authenticator"
16
+
17
+ gem.files = Dir['lib/**/*.{rb,rake}'] + Dir['bin/*']
18
+ gem.files += Dir['[A-Z]*'] + Dir['spec/**/*.rb']
19
+ gem.files.reject! { |fn| fn.include? "CVS" }
20
+
21
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.name = "google-authenticator-rails"
24
+ gem.require_paths = ["lib"]
25
+ gem.version = GoogleAuthenticatorRails::VERSION
26
+
27
+ gem.add_dependency "rotp", ">= 5.0", "< 7.0"
28
+ gem.add_dependency "rails"
29
+ gem.add_dependency "activerecord"
30
+ gem.add_dependency "rqrcode"
31
+ gem.add_dependency "actionpack"
32
+
33
+ gem.add_development_dependency "rake", "~> 13.0"
34
+ gem.add_development_dependency "rspec", "~> 3.4.0"
35
+ gem.add_development_dependency "appraisal", "~> 2.4.1"
36
+ gem.add_development_dependency "simplecov"
37
+ gem.add_development_dependency "sqlite3", "~> 1.4.0"
38
+ end
@@ -34,6 +34,6 @@ module GoogleAuthenticatorRails
34
34
  end
35
35
  end
36
36
 
37
- if defined?(ActionController::Base)
37
+ ActiveSupport.on_load(:action_controller) do
38
38
  ActionController::Base.send(:include, GoogleAuthenticatorRails::ActionController::Integration)
39
39
  end
@@ -1,9 +1,9 @@
1
1
  module GoogleAuthenticatorRails # :nodoc:
2
2
  mattr_accessor :secret_encryptor
3
-
3
+
4
4
  module ActiveRecord # :nodoc:
5
5
  module Helpers
6
-
6
+
7
7
  # Returns and memoizes the plain text google secret for this instance, irrespective of the
8
8
  # name of the google secret storage column and whether secret encryption is enabled for this model.
9
9
  #
@@ -16,7 +16,7 @@ module GoogleAuthenticatorRails # :nodoc:
16
16
  @google_secret_value = secret_in_db.present? && self.class.google_secrets_encrypted ? google_secret_encryptor.decrypt_and_verify(secret_in_db) : secret_in_db
17
17
  end
18
18
  end
19
-
19
+
20
20
  def set_google_secret
21
21
  change_google_secret_to!(GoogleAuthenticatorRails::generate_secret)
22
22
  end
@@ -32,7 +32,12 @@ module GoogleAuthenticatorRails # :nodoc:
32
32
  end
33
33
 
34
34
  def google_qr_uri(size = nil)
35
- GoogleQR.new(:data => ROTP::TOTP.new(google_secret_value, :issuer => google_issuer).provisioning_uri(google_label), :size => size || self.class.google_qr_size).to_s
35
+ data = ROTP::TOTP.new(google_secret_value, :issuer => google_issuer).provisioning_uri(google_label)
36
+ "https://chart.googleapis.com/chart?cht=qr&chl=#{CGI.escape(data)}&chs=#{size || self.class.google_qr_size}"
37
+ end
38
+
39
+ def google_qr_to_base64(size = 200)
40
+ "data:image/png;base64,#{Base64.strict_encode64(RQRCode::QRCode.new(ROTP::TOTP.new(google_secret_value, :issuer => google_issuer).provisioning_uri(google_label).to_s).as_png(size: size).to_s)}"
36
41
  end
37
42
 
38
43
  def google_label
@@ -50,7 +55,7 @@ module GoogleAuthenticatorRails # :nodoc:
50
55
  def google_token_value
51
56
  self.__send__(self.class.google_lookup_token)
52
57
  end
53
-
58
+
54
59
  def encrypt_google_secret!
55
60
  change_google_secret_to!(google_secret_column_value)
56
61
  end
@@ -59,7 +64,7 @@ module GoogleAuthenticatorRails # :nodoc:
59
64
  def default_google_label_method
60
65
  self.__send__(self.class.google_label_column)
61
66
  end
62
-
67
+
63
68
  def google_secret_column_value
64
69
  self.__send__(self.class.google_secret_column)
65
70
  end
@@ -75,13 +80,16 @@ module GoogleAuthenticatorRails # :nodoc:
75
80
  issuer = self.class.google_issuer
76
81
  issuer.is_a?(Proc) ? issuer.call(self) : issuer
77
82
  end
78
-
83
+
79
84
  def google_secret_encryptor
80
85
  GoogleAuthenticatorRails.secret_encryptor ||= GoogleAuthenticatorRails::ActiveRecord::Helpers.get_google_secret_encryptor
81
86
  end
82
-
87
+
83
88
  def self.get_google_secret_encryptor
84
- ActiveSupport::MessageEncryptor.new(Rails.application.key_generator.generate_key('Google-secret encryption key', 32))
89
+ encryption_key = Rails.application.key_generator.generate_key('Google-secret encryption key', 32)
90
+ encryptor = ActiveSupport::MessageEncryptor.new(encryption_key)
91
+ encryptor.rotate(encryption_key, cipher: 'aes-256-cbc') # Legacy support for Rails 5.2
92
+ encryptor
85
93
  end
86
94
  end
87
95
  end
@@ -1,3 +1,3 @@
1
1
  module GoogleAuthenticatorRails
2
- VERSION = "2.0.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -4,7 +4,7 @@ require 'active_support'
4
4
  require 'active_record'
5
5
  require 'openssl'
6
6
  require 'rotp'
7
- require 'google-qr'
7
+ require 'rqrcode'
8
8
 
9
9
  # Stuff the gem is
10
10
  #
@@ -26,13 +26,13 @@ module GoogleAuthenticatorRails
26
26
  def self.encryption_supported?
27
27
  defined?(Rails) && (Rails::VERSION::MAJOR > 4 || Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR > 0)
28
28
  end
29
-
29
+
30
30
  class Railtie < Rails::Railtie
31
31
  rake_tasks do
32
32
  load 'tasks/google_authenticator.rake'
33
33
  end
34
- end if encryption_supported? && !Rails.env.test? # Without this last condition tasks under test are run twice
35
-
34
+ end if encryption_supported? && !Rails.env.test? # Without this last condition tasks under test are run twice
35
+
36
36
  # Drift is set to 6 because ROTP drift is not inclusive. This allows a drift of 5 seconds.
37
37
  DRIFT = 6
38
38
 
@@ -44,7 +44,7 @@ module GoogleAuthenticatorRails
44
44
 
45
45
  # Additional configuration passed to a Session::Persistence cookie.
46
46
  @@cookie_options = { :httponly => true }
47
-
47
+
48
48
  def self.generate_password(secret, iteration)
49
49
  ROTP::HOTP.new(secret).at(iteration)
50
50
  end
@@ -54,11 +54,11 @@ module GoogleAuthenticatorRails
54
54
  end
55
55
 
56
56
  def self.valid?(code, secret, drift = DRIFT)
57
- ROTP::TOTP.new(secret).verify_with_drift(code, drift)
57
+ !!ROTP::TOTP.new(secret).verify(code, drift_ahead: drift, drift_behind: drift)
58
58
  end
59
59
 
60
60
  def self.generate_secret
61
- ROTP::Base32.random_base32
61
+ ROTP::Base32.random
62
62
  end
63
63
 
64
64
  def self.time_until_expiration
@@ -7,9 +7,9 @@ namespace :google_authenticator do
7
7
  # Adapted from https://stackoverflow.com/a/8248849/7478194
8
8
  Dir[Rails.root.join('app/models/*.rb').to_s].map { |filename| File.basename(filename, '.rb').camelize }
9
9
  end
10
-
10
+
11
11
  ActiveRecord::Base.transaction do
12
- match_op = " = #{already_encrypted ? 138 : 16}"
12
+ match_op = already_encrypted ? " in (138,162)" : "in (16,32)"
13
13
  model_names.each do |model_name|
14
14
  klass = model_name.constantize
15
15
  next unless klass.ancestors.include?(ActiveRecord::Base) && klass.try(:google_secrets_encrypted)
@@ -23,7 +23,7 @@ namespace :google_authenticator do
23
23
  end
24
24
  end
25
25
  end
26
-
26
+
27
27
  desc 'Encrypt all secret columns (add the :encrypt_secrets options *before* running)'
28
28
  task :encrypt_secrets, [:optional_model_list] => :environment do |_t, args|
29
29
  do_encrypt(args, false, 'Encrypt') { |record| record.encrypt_google_secret! }
@@ -46,10 +46,10 @@ namespace :google_authenticator do
46
46
  end
47
47
  end
48
48
  end
49
-
49
+
50
50
  desc 'Decrypt all secret columns (remove the :encrypt_secrets options *after* running)'
51
51
  task :decrypt_secrets, [:optional_model_list] => :environment do |_t, args|
52
52
  do_encrypt(args, true, 'Decrypt') { |record| record.send(:change_google_secret_to!, record.google_secret_value, false) }
53
- end
53
+ end
54
54
 
55
55
  end
@@ -1,29 +1,33 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GoogleAuthenticatorRails do
4
+ def get_secret
5
+ 'LMFMFDV3UGN7LBO4FEMVQVJOK7F7FLLE'
6
+ end
7
+
4
8
  describe '#generate_password' do
5
- subject { GoogleAuthenticatorRails::generate_password("test", counter) }
9
+ subject { GoogleAuthenticatorRails::generate_password(get_secret, counter) }
6
10
 
7
11
  context 'counter = 1' do
8
12
  let(:counter) { 1 }
9
- it { should == "868864" }
13
+ it { should == "664045" }
10
14
  end
11
15
 
12
16
  context 'counter = 2' do
13
17
  let(:counter) { 2 }
14
- it { should == "304404" }
18
+ it { should == "548382" }
15
19
  end
16
20
  end
17
21
 
18
22
  context 'time-based passwords' do
19
- let(:secret) { '5qlcip7azyjuwm36' }
23
+ let(:secret) { get_secret }
20
24
  let(:original_time) { Time.parse("2012-08-07 11:11:00 AM +0700") }
21
25
  let!(:time) { original_time }
22
- let(:code) { "495502" }
26
+ let(:code) { "954578" }
23
27
 
24
28
  before do
25
- Time.stub!(:now).and_return(time)
26
- ROTP::Base32.stub!(:random_base32).and_return(secret)
29
+ allow(Time).to receive(:now).and_return(time)
30
+ allow(ROTP::Base32).to receive(:random).and_return(secret)
27
31
  end
28
32
 
29
33
  specify { GoogleAuthenticatorRails::time_based_password(secret).should == code }
@@ -43,44 +47,44 @@ describe GoogleAuthenticatorRails do
43
47
  @user = user
44
48
  user.google_secret = secret
45
49
  end
46
-
50
+
47
51
  context "custom drift" do
48
52
  # 30 seconds drift
49
53
  let(:user) { UserFactory.create DriftUser }
50
54
  subject { user.google_authentic?(code) }
51
-
55
+
52
56
  context '6 seconds of drift' do
53
57
  let(:time) { original_time + 36.seconds }
54
58
  it { should be true }
55
59
  end
56
-
60
+
57
61
  context '30 seconds of drift' do
58
62
  let(:time) { original_time + 61.seconds }
59
63
  it { should be false }
60
64
  end
61
65
  end
62
-
66
+
63
67
  context 'code validation' do
64
68
  subject { user.google_authentic?(code) }
65
-
69
+
66
70
  it { should be true }
67
-
71
+
68
72
  context 'within 5 seconds of drift' do
69
73
  let(:time) { original_time + 34.seconds }
70
74
  it { should be true }
71
75
  end
72
-
76
+
73
77
  context '6 seconds of drift' do
74
78
  let(:time) { original_time + 36.seconds }
75
79
  it { should be false }
76
80
  end
77
81
  end
78
-
82
+
79
83
  it 'creates a secret' do
80
84
  user.set_google_secret
81
85
  user.google_secret.should == secret
82
86
  end
83
-
87
+
84
88
  shared_examples 'handles nil secrets' do
85
89
  it 'clears a secret' do
86
90
  @user.clear_google_secret!
@@ -95,102 +99,102 @@ describe GoogleAuthenticatorRails do
95
99
  @user = UserFactory.create EncryptedUser
96
100
  @user.set_google_secret
97
101
  end
98
-
102
+
99
103
  it 'encrypts_the_secret' do
100
- @user.google_secret.length.should == (GoogleAuthenticatorRails.encryption_supported? ? 138 : 16)
104
+ @user.google_secret.length.should == (GoogleAuthenticatorRails.encryption_supported? ? 162 : 32)
101
105
  end
102
-
106
+
103
107
  it 'decrypts_the_secret' do
104
108
  @user.google_secret_value.should == secret
105
- end
106
-
109
+ end
110
+
107
111
  it 'validates code' do
108
- @user.google_authentic?(code).should be_true
112
+ @user.google_authentic?(code).should be_truthy
109
113
  end
110
114
 
111
115
  it_behaves_like 'handles nil secrets'
112
116
  end
113
-
117
+
114
118
  context 'custom secret column' do
115
119
  before do
116
120
  @user = UserFactory.create CustomUser
117
121
  @user.set_google_secret
118
122
  end
119
-
123
+
120
124
  it 'validates code' do
121
- @user.google_authentic?(code).should be_true
125
+ @user.google_authentic?(code).should be_truthy
122
126
  end
123
-
127
+
124
128
  it 'generates a url for a qr code' do
125
- @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=200x200"
129
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=200x200"
126
130
  end
127
131
  end
128
-
132
+
129
133
  context 'encrypted column with custom secret column' do
130
134
  before do
131
135
  @user = UserFactory.create EncryptedCustomUser
132
136
  @user.set_google_secret
133
137
  end
134
-
138
+
135
139
  it 'encrypts the secret' do
136
- @user.mfa_secret.length.should == (GoogleAuthenticatorRails.encryption_supported? ? 138 : 16)
140
+ @user.mfa_secret.length.should == (GoogleAuthenticatorRails.encryption_supported? ? 162 : 32)
137
141
  end
138
-
142
+
139
143
  it 'decrypts the secret' do
140
144
  @user.google_secret_value.should == secret
141
- end
142
-
145
+ end
146
+
143
147
  it 'validates code' do
144
- @user.google_authentic?(code).should be_true
148
+ @user.google_authentic?(code).should be_truthy
145
149
  end
146
150
  end
147
-
151
+
148
152
  if GoogleAuthenticatorRails.encryption_supported?
149
153
  context 'encryption Rake tasks' do
150
154
  before(:all) { Rails.application.load_tasks }
151
-
155
+
152
156
  def set_and_run_task(type)
153
157
  User.delete_all
154
- EncryptedCustomUser.delete_all
158
+ EncryptedCustomUser.delete_all
155
159
  @user = UserFactory.create User
156
160
  @user.set_google_secret
157
161
  @encrypted_user = UserFactory.create EncryptedCustomUser
158
162
  @encrypted_user.set_google_secret
159
163
  @non_encrypted_user = UserFactory.create EncryptedCustomUser
160
- @non_encrypted_user.update_attribute(:mfa_secret, secret)
164
+ @non_encrypted_user.update_attribute(:mfa_secret, get_secret)
161
165
  Rake.application.invoke_task("google_authenticator:#{type}_secrets[User,EncryptedCustomUser]")
162
- end
163
-
166
+ end
167
+
164
168
  def encryption_ok?(user, secret_should_be_encrypted)
165
169
  secret_value = user.reload.send(:google_secret_column_value)
166
- (secret_value.blank? || secret_value.length.should == (secret_should_be_encrypted ? 138 : 16)) &&
170
+ (secret_value.blank? || secret_value.length.should == (secret_should_be_encrypted ? 162 : 32)) &&
167
171
  (user.class.google_secrets_encrypted ^ secret_should_be_encrypted || user.google_secret_value == secret)
168
172
  end
169
-
173
+
170
174
  shared_examples 'task tests' do |type|
171
175
  it 'handles non-encrypted secrets' do
172
176
  encryption_ok?(@non_encrypted_user, type == 'encrypt')
173
177
  end
174
-
178
+
175
179
  it 'handles encrypted secrets' do
176
180
  encryption_ok?(@encrypted_user, type != 'decrypt')
177
181
  end
178
-
182
+
179
183
  it "doesn't #{type} non-encrypted models" do
180
184
  encryption_ok?(@user, false)
181
185
  end
182
186
  end
183
-
187
+
184
188
  context 'encrypt_secrets task' do
185
189
  before(:all) { set_and_run_task('encrypt') }
186
190
  it_behaves_like 'task tests', 'encrypt'
187
191
  end
188
-
192
+
189
193
  context 'decrypt_secrets task' do
190
194
  before(:all) { set_and_run_task('decrypt') }
191
195
  it_behaves_like 'task tests', 'decrypt'
192
196
  end
193
-
197
+
194
198
  context 'reencrypt_secrets task' do
195
199
  before(:all) do
196
200
  def reset_encryption(secret_key_base)
@@ -198,79 +202,84 @@ describe GoogleAuthenticatorRails do
198
202
  Rails.application.instance_eval { @caching_key_generator = nil }
199
203
  GoogleAuthenticatorRails.secret_encryptor = nil
200
204
  end
201
-
205
+
202
206
  current_secret_key_base = Rails.application.secrets[:secret_key_base]
203
207
  reset_encryption(Rails.application.secrets.old_secret_key_base)
204
208
  set_and_run_task('reencrypt')
205
209
  reset_encryption(current_secret_key_base)
206
210
  end
207
-
211
+
208
212
  it_behaves_like 'task tests', 'reencrypt'
209
213
  end
210
214
  end
211
215
  end
212
-
216
+
213
217
  context 'google label' do
214
218
  let(:user) { UserFactory.create NilMethodUser }
215
219
  subject { lambda { user.google_label } }
216
220
  it { should raise_error(NoMethodError) }
217
221
  end
218
-
222
+
219
223
  context "drift value" do
220
224
  it { DriftUser.google_drift.should == 31 }
221
-
225
+
222
226
  context "default value" do
223
227
  it { User.google_drift.should == 6 }
224
228
  end
225
229
  end
226
-
230
+
227
231
  context 'qr codes' do
228
232
  let(:user) { UserFactory.create User }
229
233
  before { user.set_google_secret }
230
234
  subject { user.google_qr_uri }
231
-
232
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=200x200" }
233
-
235
+
236
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=200x200" }
237
+
234
238
  context 'custom column name' do
235
239
  let(:user) { UserFactory.create ColumnNameUser }
236
240
  it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest_user%3Fsecret%3D#{secret}&chs=200x200" }
237
241
  end
238
-
242
+
239
243
  context 'custom proc' do
240
244
  let(:user) { UserFactory.create ProcLabelUser }
241
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest_user%40futureadvisor-admin%3Fsecret%3D#{secret}&chs=200x200" }
245
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest_user%2540futureadvisor-admin%3Fsecret%3D#{secret}&chs=200x200" }
242
246
  end
243
-
247
+
244
248
  context 'custom issuer' do
245
249
  let(:user) { UserFactory.create ProcIssuerUser }
246
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2FFA%2520Admin%3Atest%40example.com%3Fsecret%3D#{secret}%26issuer%3DFA%2BAdmin&chs=200x200" }
250
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2FFA%2520Admin%3Atest%2540example.com%3Fsecret%3D#{secret}%26issuer%3DFA%2520Admin&chs=200x200" }
247
251
  end
248
-
252
+
249
253
  context 'method defined by symbol' do
250
254
  let(:user) { UserFactory.create SymbolUser }
251
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=200x200" }
255
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=200x200" }
252
256
  end
253
-
257
+
254
258
  context 'method defined by string' do
255
259
  let(:user) { UserFactory.create StringUser }
256
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=200x200" }
260
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=200x200" }
257
261
  end
258
-
262
+
259
263
  context 'custom qr size' do
260
264
  let(:user) { UserFactory.create QrCodeUser }
261
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=300x300" }
265
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=300x300" }
262
266
  end
263
-
267
+
264
268
  context 'qr size passed to method' do
265
269
  subject { user.google_qr_uri('400x400') }
266
- let(:user) { UserFactory.create StringUser }
267
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=400x400" }
270
+ let(:user) { UserFactory.create StringUser }
271
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=400x400" }
268
272
  end
269
-
273
+
270
274
  context 'qr size passed to method and size set on model' do
271
275
  let(:user) { UserFactory.create QrCodeUser }
272
276
  subject { user.google_qr_uri('400x400') }
273
- it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40example.com%3Fsecret%3D#{secret}&chs=400x400" }
277
+ it { should eq "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%2540example.com%3Fsecret%3D#{secret}&chs=400x400" }
278
+ end
279
+
280
+ context 'generates base64 image' do
281
+ let(:user) { UserFactory.create QrCodeUser }
282
+ it { user.google_qr_to_base64.include?('data:image/png;base64').should be_truthy }
274
283
  end
275
284
  end
276
285
  end
@@ -20,7 +20,9 @@ describe GoogleAuthenticatorRails::Session::Base do
20
20
  after { clear_cookie unless user.nil? }
21
21
 
22
22
  it { should be_a UserMfaSession }
23
- its(:record) { should eq user }
23
+ it "can fetch the record" do
24
+ expect(subject.record).to eq(user)
25
+ end
24
26
 
25
27
  context 'custom lookup token' do
26
28
  let(:user) { SaltUser.create(:password => "password", :email => "email@example.com") }
@@ -28,7 +30,9 @@ describe GoogleAuthenticatorRails::Session::Base do
28
30
  subject { SaltUserMfaSession.find }
29
31
 
30
32
  it { should be_a SaltUserMfaSession }
31
- its(:record) { should eq user }
33
+ it "can fetch the record" do
34
+ expect(subject.record).to eq(user)
35
+ end
32
36
  end
33
37
 
34
38
  context 'after destroy' do
@@ -46,7 +50,9 @@ describe GoogleAuthenticatorRails::Session::Base do
46
50
  subject { UserMfaSession.create(user) }
47
51
 
48
52
  it { should be_a UserMfaSession }
49
- its(:record) { should eq user }
53
+ it "can fetch the record" do
54
+ expect(subject.record).to eq(user)
55
+ end
50
56
 
51
57
  context 'nil user' do
52
58
  let(:user) { nil }
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-authenticator-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared McFarland
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-02 00:00:00.000000000 Z
11
+ date: 2022-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rotp
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: 3.3.0
22
+ version: '7.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - '='
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: 3.3.0
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rails
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +59,7 @@ dependencies:
53
59
  - !ruby/object:Gem::Version
54
60
  version: '0'
55
61
  - !ruby/object:Gem::Dependency
56
- name: google-qr
62
+ name: rqrcode
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - ">="
@@ -86,42 +92,42 @@ dependencies:
86
92
  requirements:
87
93
  - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: '11.0'
95
+ version: '13.0'
90
96
  type: :development
91
97
  prerelease: false
92
98
  version_requirements: !ruby/object:Gem::Requirement
93
99
  requirements:
94
100
  - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: '11.0'
102
+ version: '13.0'
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: rspec
99
105
  requirement: !ruby/object:Gem::Requirement
100
106
  requirements:
101
107
  - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: 2.8.0
109
+ version: 3.4.0
104
110
  type: :development
105
111
  prerelease: false
106
112
  version_requirements: !ruby/object:Gem::Requirement
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: 2.8.0
116
+ version: 3.4.0
111
117
  - !ruby/object:Gem::Dependency
112
118
  name: appraisal
113
119
  requirement: !ruby/object:Gem::Requirement
114
120
  requirements:
115
121
  - - "~>"
116
122
  - !ruby/object:Gem::Version
117
- version: 0.5.1
123
+ version: 2.4.1
118
124
  type: :development
119
125
  prerelease: false
120
126
  version_requirements: !ruby/object:Gem::Requirement
121
127
  requirements:
122
128
  - - "~>"
123
129
  - !ruby/object:Gem::Version
124
- version: 0.5.1
130
+ version: 2.4.1
125
131
  - !ruby/object:Gem::Dependency
126
132
  name: simplecov
127
133
  requirement: !ruby/object:Gem::Requirement
@@ -140,16 +146,16 @@ dependencies:
140
146
  name: sqlite3
141
147
  requirement: !ruby/object:Gem::Requirement
142
148
  requirements:
143
- - - ">="
149
+ - - "~>"
144
150
  - !ruby/object:Gem::Version
145
- version: '0'
151
+ version: 1.4.0
146
152
  type: :development
147
153
  prerelease: false
148
154
  version_requirements: !ruby/object:Gem::Requirement
149
155
  requirements:
150
- - - ">="
156
+ - - "~>"
151
157
  - !ruby/object:Gem::Version
152
- version: '0'
158
+ version: 1.4.0
153
159
  description: Add the ability to use the Google Authenticator with ActiveRecord.
154
160
  email:
155
161
  - jared.online@gmail.com
@@ -160,12 +166,12 @@ files:
160
166
  - Appraisals
161
167
  - CODE_OF_CONDUCT.md
162
168
  - CONTRIBUTING.md
163
- - Dockerfile
164
169
  - Gemfile
165
170
  - Gemfile.lock
166
171
  - LICENSE
167
172
  - README.md
168
173
  - Rakefile
174
+ - google-authenticator.gemspec
169
175
  - lib/google-authenticator-rails.rb
170
176
  - lib/google-authenticator-rails/action_controller.rb
171
177
  - lib/google-authenticator-rails/action_controller/rails_adapter.rb
@@ -187,7 +193,7 @@ files:
187
193
  homepage: http://github.com/jaredonline/google-authenticator
188
194
  licenses: []
189
195
  metadata: {}
190
- post_install_message:
196
+ post_install_message:
191
197
  rdoc_options: []
192
198
  require_paths:
193
199
  - lib
@@ -202,9 +208,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
208
  - !ruby/object:Gem::Version
203
209
  version: '0'
204
210
  requirements: []
205
- rubyforge_project:
206
- rubygems_version: 2.5.1
207
- signing_key:
211
+ rubygems_version: 3.3.15
212
+ signing_key:
208
213
  specification_version: 4
209
214
  summary: Add the ability to use the Google Authenticator with ActiveRecord.
210
215
  test_files:
data/Dockerfile DELETED
@@ -1,17 +0,0 @@
1
- FROM ruby:2.3.1
2
-
3
- RUN mkdir -p /var/app
4
-
5
- COPY Gemfile /var/app/Gemfile
6
- COPY Gemfile.lock /var/app/Gemfile.lock
7
- COPY google-authenticator.gemspec /var/app/google-authenticator.gemspec
8
- COPY lib/google-authenticator-rails/version.rb /var/app/lib/google-authenticator-rails/version.rb
9
- COPY Rakefile /var/app/Rakefile
10
- COPY gemfiles/*.gemfile /var/app/
11
- WORKDIR /var/app
12
-
13
- RUN gem install bundler --version=1.15.4 --no-ri --no-rdoc
14
-
15
- RUN bundle install
16
- RUN bundle exec rake appraisal:install
17
-