devise-authy 1.10.0 → 2.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2944ca880949d1d99ba1116f87399c9be0043cc210d29c4d5c500b08b74a3ba
4
- data.tar.gz: 400fe93a97c18c62904d7f3b2795193bdfe724b4022c677bf20a507f12881cab
3
+ metadata.gz: e9332df09a8a1b3e1a71ff775f2cccc75c573123eccb8a6830454cdc3ef3834d
4
+ data.tar.gz: a0e4f00b59ece3eefe9fee9c04c51227216e13f241ac24afe94c4ec361416443
5
5
  SHA512:
6
- metadata.gz: 394a6c85daf4d32bd9a7f8be985cdb81dbc6aad4578b317bfbf2cd0514226bbef466fe0f3831b85034d7de6d99d7be2f4c461243705bb1936491e9454d595360
7
- data.tar.gz: a5defe4716260f048cf8080bd40fa47d4fb13da62ed42a75461b62c46c0b4b7eba25d6d8896064666e8252364d6da159b4375111019174591dc1f2b046f370ed
6
+ metadata.gz: 3d00cb1eb54d0169277b2e514431bb121f8c5e2dc6a565e07786a4866a29904b301a3730cdbff201f48d1ba5afb4c8b10249b75e9c8ab45da8a0022b9b1f64f9
7
+ data.tar.gz: 54596845d7b20034aa433497281d74135886f59828e9ae8026ae9fc43f0cfe2b4874cd90c4d69f8295ff76bc02ac7eaadb077fd53d1281354f7a3aa113dac65e
data/.gitignore CHANGED
@@ -31,14 +31,15 @@ build/
31
31
  Gemfile.lock
32
32
  .ruby-version
33
33
  .ruby-gemset
34
+ gemfiles/*.lock
34
35
 
35
36
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
37
  .rvmrc
37
38
 
38
- spec/rails-app/tmp
39
- spec/rails-app/db
40
- spec/rails-app/log
41
- *.sqlite3DS_Store
39
+ **/*.sqlite
40
+ **/*.log
42
41
 
43
42
  initializers/authy.rb
44
43
  .byebug_history
44
+
45
+ .rspec_status
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --require ./spec/spec_helper
@@ -1,12 +1,17 @@
1
1
  language: ruby
2
- before_install: cd spec/rails-app && bundle install
3
2
  script: bundle exec rspec
4
3
  rvm:
4
+ - 2.7
5
+ - 2.6
5
6
  - 2.5
6
7
  - 2.4
7
- - 2.3
8
- - 2.2
9
8
  - ruby-head
9
+ gemfile:
10
+ - gemfiles/rails_5_2.gemfile
11
+ - gemfiles/rails_6.gemfile
10
12
  matrix:
11
13
  allow_failures:
12
14
  - rvm: ruby-head
15
+ exclude:
16
+ - rvm: 2.4
17
+ gemfile: gemfiles/rails_6.gemfile
@@ -0,0 +1,21 @@
1
+ appraise "rails-5-2" do
2
+ gem "rails", "~> 5.2.0"
3
+ gem "sqlite3", "~> 1.3.13"
4
+
5
+ group :development, :test do
6
+ gem 'factory_girl_rails', :require => false
7
+ gem 'rspec-rails', "~>4.0.0.beta3", :require => false
8
+ gem 'database_cleaner', :require => false
9
+ end
10
+ end
11
+
12
+ appraise "rails-6" do
13
+ gem "rails", "~> 6.0.0"
14
+ gem "sqlite3", "~> 1.4"
15
+
16
+ group :development, :test do
17
+ gem 'factory_girl_rails', :require => false
18
+ gem 'rspec-rails', "~>4.0.0.beta3", :require => false
19
+ gem 'database_cleaner', :require => false
20
+ end
21
+ end if RUBY_VERSION.to_f >= 2.5
@@ -9,49 +9,127 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
9
9
 
10
10
  ...
11
11
 
12
+ ## [2.2.0] - 2020-06-04
13
+
14
+ ### Fixed
15
+
16
+ - Don't delete user in Authy if another user has the same authy_id (#144)
17
+
18
+ ## [2.1.0] - 2020-05-05
19
+
20
+ ### Added
21
+
22
+ - Support for generic authenticator tokens (#141)
23
+
24
+ ### Fixed
25
+
26
+ - Can remember device when enabling 2FA for the first time (#139)
27
+
28
+ ## [2.0.0] - 2020-04-28
29
+
30
+ Releasing this as version 2 because there is a significant change in dependencies. Minimum version of Rails is now 5 and of Devise is now 4. Otherwise the gem should work as before.
31
+
32
+ ### Added
33
+
34
+ - HTTP Only flag to remember_device cookie (#116 thanks @agronv)
35
+ - Remembers device when user logs in with One Touch (#128 thanks @cplopez4)
36
+ - Autocomplete attributes for HTML form (#130)
37
+
38
+ ### Changed
39
+
40
+ - Mocked API calls in test suite (#123)
41
+ - Full test suite refactor (#124)
42
+ - Increased required version for Devise and Rails (#125)
43
+ - Stopped calling `signed_in?` before it is needed (#126)
44
+
45
+ ### Fixes
46
+
47
+ - Remembers user correctly when logging in with One Touch (#129)
48
+
49
+ ## [1.11.1] - 2019-02-02
50
+
51
+ ### Fixed
52
+
53
+ - Using the version before loading it broke everything. :facepalm:
54
+
55
+ ## [1.11.0] - 2019-02-01
56
+
57
+ ### Fixed
58
+
59
+ - Corrects for label in verify_authy view (#103 thanks @mstruebing)
60
+ - Corrects heading in verify_authy view (#104 thanks @mstruebing)
61
+
62
+ ### Changed
63
+
64
+ - Allows you to define paths for request_sms and request_phone_call (#108 thanks @dedene)
65
+
66
+ ### Added
67
+
68
+ - Now sets a distinct user agent through the Authy gem (#110)
69
+
12
70
  ## [1.10.0] - 2018-09-26
13
71
 
14
72
  ### Changed
73
+
15
74
  - Moves OneTouch approval request copy to locale file.
16
75
 
17
76
  ### Removed
77
+
18
78
  - Demo app now lives in its own repo
19
79
 
20
80
  ## [1.9.0] - 2018-09-04
21
81
 
22
82
  ### Fixed
83
+
23
84
  - Generated migration now includes version number for Rails 5
24
85
 
25
86
  ### Changed
87
+
26
88
  - Removes Jeweler in favour of administering the gemspec by hand
27
89
  - Removes demo app files from gem package
28
90
 
29
91
  ## [1.8.3] - 2018-07-05
92
+
30
93
  ### Fixed
94
+
31
95
  - Fixes Ruby interpolation in HAML for onetouch (thanks @muan)
32
96
  - Records Authy authentication after install verification (thanks @nukturnal)
33
97
  - Forgets remember device cookie when disabling Authy (thanks @senekis)
34
98
 
35
99
  ### Changed
100
+
36
101
  - Updated testing Rubies in CI
37
102
 
38
103
  ## Older releases
39
104
 
40
- __*The following releases happened before the changelog was started. Some history will be added for clarity.*__
105
+ **_The following releases happened before the changelog was started. Some history will be added for clarity._**
41
106
 
42
107
  ## [1.8.2] - 2017-12-22
108
+
43
109
  ## [1.8.1] - 2016-12-06
110
+
44
111
  ## [1.8.0] - 2016-10-25
112
+
45
113
  ## [1.7.0] - 2015-12-22
114
+
46
115
  ## [1.6.0] - 2015-01-07
116
+
47
117
  ## [1.5.3] - 2014-06-11
118
+
48
119
  ## [1.5.2] - 2014-06-11
120
+
49
121
  ## [1.5.1] - 2014-04-24
122
+
50
123
  ## [1.5.0] - 2014-01-07
124
+
51
125
  ## [1.4.0] - 2013-12-17
126
+
52
127
  ## [1.3.0] - 2013-11-16
128
+
53
129
  ## [1.2.2] - 2013-09-04
130
+
54
131
  ## [1.2.1] - 2013-04-22
132
+
55
133
  ## [1.2.0] - 2013-04-22 [YANKED]
56
- ## [1.0.0] - 2013-04-10
57
134
 
135
+ ## [1.0.0] - 2013-04-10
data/Gemfile CHANGED
@@ -2,28 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- group :test do
6
- gem 'rails', '~> 4.2.7'
7
- gem 'sqlite3'
8
-
9
- # Use SCSS for stylesheets
10
- gem 'sass-rails', '~> 5.0'
11
-
12
- # Use Uglifier as compressor for JavaScript assets
13
- gem 'uglifier', '>= 1.3.0'
14
-
15
- # Use CoffeeScript for .coffee assets and views
16
- gem 'coffee-rails', '~> 4.1.0'
17
-
18
- # Use jquery as the JavaScript library
19
- gem 'jquery-rails'
20
-
21
- gem 'launchy'
22
- gem 'rspec-rails'
23
- gem 'database_cleaner'
24
- gem 'capybara'
25
- gem 'test-unit'
26
- end
27
-
28
5
  # bundle exec rake doc:rails generates the API under doc/api.
29
6
  gem 'sdoc', '~> 0.4.0', group: :doc
data/README.md CHANGED
@@ -1,10 +1,28 @@
1
1
  # Authy Devise [![Build Status](https://travis-ci.org/twilio/authy-devise.svg?branch=master)](https://travis-ci.org/twilio/authy-devise)
2
2
 
3
- This is a [Devise](https://github.com/plataformatec/devise) extension to add Two-Factor Authentication with Authy to your rails application.
3
+ This is a [Devise](https://github.com/plataformatec/devise) extension to add [Two-Factor Authentication with Authy](https://www.twilio.com/docs/authy) to your Rails application.
4
+
5
+ * [Pre-requisites](#pre-requisites)
6
+ * [Demo](#demo)
7
+ * [Getting started](#getting-started)
8
+ * [Configuring Models](#configuring-models)
9
+ * [With the generator](#with-the-generator)
10
+ * [Manually](#manually)
11
+ * [Final steps](#final-steps)
12
+ * [Custom Views](#custom-views)
13
+ * [Request a phone call](#request-a-phone-call)
14
+ * [Custom Redirect Paths (eg. using modules)](#custom-redirect-paths-eg-using-modules)
15
+ * [I18n](#i18n)
16
+ * [Session variables](#session-variables)
17
+ * [OneTouch support](#onetouch-support)
18
+ * [Generic authenticator token support](#generic-authenticator-token-support)
19
+ * [Rails 5 CSRF protection](#rails-5-csrf-protection)
20
+ * [Running Tests](#running-tests)
21
+ * [Copyright](#copyright)
4
22
 
5
23
  ## Pre-requisites
6
24
 
7
- To use the Authy API you will need a Twilio Account, [sign up for a free account here](https://www.twilio.com/try-twilio).
25
+ To use the Authy API you will need a Twilio Account, [sign up for a free Twilio account here](https://www.twilio.com/try-twilio).
8
26
 
9
27
  Create an [Authy Application in the Twilio console](https://www.twilio.com/console/authy/applications) and take note of the API key.
10
28
 
@@ -38,17 +56,55 @@ Add `Devise Authy` to your App:
38
56
 
39
57
  ### Configuring Models
40
58
 
41
- Configure your Devise user model:
59
+ You can add devise_authy to your user model in two ways.
42
60
 
43
- rails g devise_authy [MODEL_NAME]
61
+ #### With the generator
44
62
 
45
- or add the following line to your `User` model
63
+ This is the easiest way and is recommended. Run the following command:
64
+
65
+ ```bash
66
+ rails g devise_authy [MODEL_NAME]
67
+ ```
68
+
69
+ #### Manually
70
+
71
+ Add `:authy_authenticatable` to the `devise` options in your Devise user model:
46
72
 
47
73
  ```ruby
48
74
  devise :authy_authenticatable, :database_authenticatable
49
75
  ```
50
76
 
51
- Update the default routes to point to something like:
77
+ Also add a new migration. For example, if you are adding to the `User` model, use this migration:
78
+
79
+ ```ruby
80
+ class DeviseAuthyAddToUsers < ActiveRecord::Migration[6.0]
81
+ def self.up
82
+ change_table :users do |t|
83
+ t.string :authy_id
84
+ t.datetime :last_sign_in_with_authy
85
+ t.boolean :authy_enabled, :default => false
86
+ end
87
+
88
+ add_index :users, :authy_id
89
+ end
90
+
91
+ def self.down
92
+ change_table :users do |t|
93
+ t.remove :authy_id, :last_sign_in_with_authy, :authy_enabled
94
+ end
95
+ end
96
+ end
97
+ ```
98
+
99
+ #### Final steps
100
+
101
+ For either method above, run the migrations:
102
+
103
+ ```bash
104
+ rake db:migrate
105
+ ```
106
+
107
+ **[Optional]** Update the default routes to point to something like:
52
108
 
53
109
  ```ruby
54
110
  devise_for :users, :path_names => {
@@ -59,10 +115,6 @@ devise_for :users, :path_names => {
59
115
  }
60
116
  ```
61
117
 
62
- Then run the migrations:
63
-
64
- rake db:migrate
65
-
66
118
  Now whenever a user wants to enable two-factor authentication they can go to:
67
119
 
68
120
  http://your-app/users/enable-two-factor
@@ -71,7 +123,6 @@ And when the user logs in they will be redirected to:
71
123
 
72
124
  http://your-app/users/verify-token
73
125
 
74
-
75
126
  ## Custom Views
76
127
 
77
128
  If you want to customise your views, you can modify the files that are located at:
@@ -118,7 +169,6 @@ And tell the router to use this controller
118
169
  devise_for :users, controllers: {devise_authy: 'my_custom_module/devise_authy'}
119
170
  ```
120
171
 
121
-
122
172
  ## I18n
123
173
 
124
174
  The install generator also copies a `Devise Authy` i18n file which you can find at:
@@ -145,10 +195,36 @@ To enable [Authy push authentication](https://www.twilio.com/authy/features/push
145
195
  config.authy_enable_onetouch = true
146
196
  ```
147
197
 
198
+ ## Generic authenticator token support
199
+
200
+ Authy supports other authenticator apps by providing a QR code that your users can scan.
201
+
202
+ > **To use this feature, you need to enable it in your [Twilio Console](https://www.twilio.com/console/authy/applications)**
203
+
204
+ Once you have enabled generic authenticator tokens, you can enable this in devise-authy by modifying the Devise config file `config/initializers/devise.rb` and adding the configuration:
205
+
206
+ ```
207
+ config.authy_enable_qr_code = true
208
+ ```
209
+
210
+ This will display a QR code on the verification screen (you still need to take a user's phone number and country code). If you have implemented your own views, the QR code URL is available on the verification page as `@authy_qr_code`.
211
+
212
+ ## Rails 5 CSRF protection
213
+
214
+ In Rails 5 `protect_from_forgery` is no longer prepended to the `before_action` chain. If you call `authenticate_user` before `protect_from_forgery` your request will result in a "Can't verify CSRF token authenticity" error.
215
+
216
+ To remedy this, add `prepend: true` to your `protect_from_forgery` call, like in this example from the [Authy Devise demo app](https://github.com/twilio/authy-devise-demo):
217
+
218
+ ```ruby
219
+ class ApplicationController < ActionController::Base
220
+ protect_from_forgery with: :exception, prepend: true
221
+ end
222
+ ```
148
223
 
149
224
  ## Running Tests
150
225
 
151
226
  To prepare the tests run the following commands:
227
+
152
228
  ```bash
153
229
  $ cd spec/rails-app
154
230
  $ bundle install
@@ -156,17 +232,11 @@ $ RAILS_ENV=test bundle exec rake db:migrate
156
232
  ```
157
233
 
158
234
  Now on the project root run the following commands:
235
+
159
236
  ```bash
160
237
  $ bundle exec rspec spec/
161
238
  ```
162
239
 
163
- ## Backporting to Rails 3
164
-
165
- While we are not currently supporting Rails 3, there's an active fork that maintains the backwards compatibility.
166
-
167
- https://github.com/gcosta/authy-devise
168
-
169
240
  ## Copyright
170
241
 
171
- Copyright (c) 2012-2020 Authy Inc. See LICENSE.txt for
172
- further details.
242
+ Copyright (c) 2012-2020 Authy Inc. See LICENSE.txt for further details.
@@ -5,17 +5,25 @@ class Devise::DeviseAuthyController < DeviseController
5
5
  prepend_before_action :find_resource_and_require_password_checked, :only => [
6
6
  :GET_verify_authy, :POST_verify_authy, :GET_authy_onetouch_status
7
7
  ]
8
+
9
+ prepend_before_action :check_resource_has_authy_id, :only => [
10
+ :GET_verify_authy_installation, :POST_verify_authy_installation
11
+ ]
12
+
13
+ prepend_before_action :check_resource_not_authy_enabled, :only => [
14
+ :GET_verify_authy_installation, :POST_verify_authy_installation
15
+ ]
16
+
8
17
  prepend_before_action :authenticate_scope!, :only => [
9
- :GET_enable_authy, :POST_enable_authy,
10
- :GET_verify_authy_installation, :POST_verify_authy_installation,
11
- :POST_disable_authy
18
+ :GET_enable_authy, :POST_enable_authy, :GET_verify_authy_installation,
19
+ :POST_verify_authy_installation, :POST_disable_authy
12
20
  ]
21
+
13
22
  include Devise::Controllers::Helpers
14
23
 
15
24
  def GET_verify_authy
16
- @authy_id = @resource.authy_id
17
25
  if resource_class.authy_enable_onetouch
18
- approval_request = send_one_touch_request['approval_request']
26
+ approval_request = send_one_touch_request(@resource.authy_id)['approval_request']
19
27
  @onetouch_uuid = approval_request['uuid'] if approval_request.present?
20
28
  end
21
29
  render :verify_authy
@@ -30,10 +38,8 @@ class Devise::DeviseAuthyController < DeviseController
30
38
  })
31
39
 
32
40
  if token.ok?
33
- remember_device if params[:remember_device].to_i == 1
34
- if session.delete("#{resource_name}_remember_me") == true && @resource.respond_to?(:remember_me=)
35
- @resource.remember_me = true
36
- end
41
+ remember_device(@resource.id) if params[:remember_device].to_i == 1
42
+ remember_user
37
43
  record_authy_authentication
38
44
  respond_with resource, :location => after_sign_in_path_for(@resource)
39
45
  else
@@ -61,13 +67,11 @@ class Devise::DeviseAuthyController < DeviseController
61
67
  if @authy_user.ok?
62
68
  resource.authy_id = @authy_user.id
63
69
  if resource.save
64
- set_flash_message(:notice, :enabled)
70
+ redirect_to [resource_name, :verify_authy_installation] and return
65
71
  else
66
72
  set_flash_message(:error, :not_enabled)
67
73
  redirect_to after_authy_enabled_path_for(resource) and return
68
74
  end
69
-
70
- redirect_to [resource_name, :verify_authy_installation]
71
75
  else
72
76
  set_flash_message(:error, :not_enabled)
73
77
  render :enable_authy
@@ -76,22 +80,39 @@ class Devise::DeviseAuthyController < DeviseController
76
80
 
77
81
  # Disable 2FA
78
82
  def POST_disable_authy
79
- response = Authy::API.delete_user(:id => resource.authy_id)
80
-
81
- if response.ok?
82
- resource.update_attribute(:authy_enabled, false)
83
- resource.update_attribute(:authy_id, nil)
83
+ authy_id = resource.authy_id
84
+ resource.assign_attributes(:authy_enabled => false, :authy_id => nil)
85
+ resource.save(:validate => false)
86
+
87
+ other_resource = resource.class.find_by(:authy_id => authy_id)
88
+ if other_resource
89
+ # If another resource has the same authy_id, do not delete the user from
90
+ # the API.
84
91
  forget_device
85
-
86
92
  set_flash_message(:notice, :disabled)
87
93
  else
88
- set_flash_message(:error, :not_disabled)
94
+ response = Authy::API.delete_user(:id => authy_id)
95
+ if response.ok?
96
+ forget_device
97
+ set_flash_message(:notice, :disabled)
98
+ else
99
+ # If deleting the user from the API fails, set everything back to what
100
+ # it was before.
101
+ # I'm not sure this is a good idea, but it was existing behaviour.
102
+ # Could be changed in a major version bump.
103
+ resource.assign_attributes(:authy_enabled => true, :authy_id => authy_id)
104
+ resource.save(:validate => false)
105
+ set_flash_message(:error, :not_disabled)
106
+ end
89
107
  end
90
-
91
108
  redirect_to after_authy_disabled_path_for(resource)
92
109
  end
93
110
 
94
111
  def GET_verify_authy_installation
112
+ if resource_class.authy_enable_qr_code
113
+ response = Authy::API.request_qr_code(id: resource.authy_id)
114
+ @authy_qr_code = response.qr_code
115
+ end
95
116
  render :verify_authy_installation
96
117
  end
97
118
 
@@ -105,6 +126,7 @@ class Devise::DeviseAuthyController < DeviseController
105
126
  self.resource.authy_enabled = token.ok?
106
127
 
107
128
  if token.ok? && self.resource.save
129
+ remember_device(@resource.id) if params[:remember_device].to_i == 1
108
130
  record_authy_authentication
109
131
  set_flash_message(:notice, :enabled)
110
132
  redirect_to after_authy_verified_path_for(resource)
@@ -114,17 +136,20 @@ class Devise::DeviseAuthyController < DeviseController
114
136
  end
115
137
 
116
138
  def GET_authy_onetouch_status
117
- status = Authy::API.get_request("onetouch/json/approval_requests/#{params[:onetouch_uuid]}")['approval_request']['status']
139
+ response = Authy::OneTouch.approval_request_status(:uuid => params[:onetouch_uuid])
140
+ status = response.dig('approval_request', 'status')
118
141
  case status
119
142
  when 'pending'
120
143
  head 202
121
144
  when 'approved'
145
+ remember_device(@resource.id) if params[:remember_device].to_i == 1
146
+ remember_user
122
147
  record_authy_authentication
123
148
  render json: { redirect: after_sign_in_path_for(@resource) }
124
149
  when 'denied'
125
150
  head :unauthorized
126
151
  else
127
- head :error
152
+ head :internal_server_error
128
153
  end
129
154
  end
130
155
 
@@ -172,6 +197,16 @@ class Devise::DeviseAuthyController < DeviseController
172
197
  end
173
198
  end
174
199
 
200
+ def check_resource_has_authy_id
201
+ redirect_to [resource_name, :enable_authy] if !resource.authy_id
202
+ end
203
+
204
+ def check_resource_not_authy_enabled
205
+ if resource.authy_id && resource.authy_enabled
206
+ redirect_to after_authy_verified_path_for(resource)
207
+ end
208
+ end
209
+
175
210
  protected
176
211
 
177
212
  def after_authy_enabled_path_for(resource)
@@ -202,4 +237,10 @@ class Devise::DeviseAuthyController < DeviseController
202
237
  def after_account_is_locked
203
238
  sign_out_and_redirect @resource
204
239
  end
240
+
241
+ def remember_user
242
+ if session.delete("#{resource_name}_remember_me") == true && @resource.respond_to?(:remember_me=)
243
+ @resource.remember_me = true
244
+ end
245
+ end
205
246
  end