devise-two-factor 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of devise-two-factor might be problematic. Click here for more details.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +49 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +153 -0
- data/Rakefile +26 -0
- data/certs/tinfoil-cacert.pem +41 -0
- data/certs/tinfoilsecurity-gems-cert.pem +33 -0
- data/devise-two-factor.gemspec +39 -0
- data/lib/devise-two-factor.rb +33 -0
- data/lib/devise_two_factor/models.rb +2 -0
- data/lib/devise_two_factor/models/two_factor_authenticatable.rb +62 -0
- data/lib/devise_two_factor/models/two_factor_backupable.rb +66 -0
- data/lib/devise_two_factor/spec_helpers.rb +2 -0
- data/lib/devise_two_factor/spec_helpers/two_factor_authenticatable_shared_examples.rb +76 -0
- data/lib/devise_two_factor/spec_helpers/two_factor_backupable_shared_examples.rb +89 -0
- data/lib/devise_two_factor/strategies.rb +2 -0
- data/lib/devise_two_factor/strategies/two_factor_authenticatable.rb +26 -0
- data/lib/devise_two_factor/strategies/two_factor_backupable.rb +25 -0
- data/lib/devise_two_factor/version.rb +3 -0
- data/lib/generators/devise_two_factor/devise_two_factor_generator.rb +79 -0
- data/spec/devise/models/two_factor_authenticatable_spec.rb +16 -0
- data/spec/devise/models/two_factor_backupable_spec.rb +19 -0
- data/spec/spec_helper.rb +32 -0
- metadata +302 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 938b85d49e3435d3b68b2c9f2b1e6c9af8ca9757
|
4
|
+
data.tar.gz: 0fbb5330958d58752c38291640b9dfad48ce7ee6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 731403794ad7ae6ef5b1830c168696b7acd82236af741f82b9623e44696f2b29492b16a089735fdc44b384c28818366894c292f306798250813a067aad5b6cae
|
7
|
+
data.tar.gz: 858170aa39d456777fa6fe7e1c80503a67a7d48e4c4b715d1668fcd7f132c20deea4c04a2f1700cc6f97050e247ddf21234145339a3206bc82d9d70a37001c12
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/.gitignore
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Gemfile.lock
|
2
|
+
*.gem
|
3
|
+
|
4
|
+
# rcov generated
|
5
|
+
coverage
|
6
|
+
coverage.data
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
19
|
+
#
|
20
|
+
# * Create a file at ~/.gitignore
|
21
|
+
# * Include files you want ignored
|
22
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
23
|
+
#
|
24
|
+
# After doing this, these files will be ignored in all your git projects,
|
25
|
+
# saving you from having to 'pollute' every project you touch with them
|
26
|
+
#
|
27
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
28
|
+
#
|
29
|
+
# For MacOS:
|
30
|
+
#
|
31
|
+
#.DS_Store
|
32
|
+
|
33
|
+
# For TextMate
|
34
|
+
#*.tmproj
|
35
|
+
#tmtags
|
36
|
+
|
37
|
+
# For emacs:
|
38
|
+
#*~
|
39
|
+
#\#*
|
40
|
+
#.\#*
|
41
|
+
|
42
|
+
# For vim:
|
43
|
+
#*.swp
|
44
|
+
|
45
|
+
# For redcar:
|
46
|
+
#.redcar
|
47
|
+
|
48
|
+
# For rubinius:
|
49
|
+
#*.rbc
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
We love pull requests. Here's a quick guide:
|
2
|
+
|
3
|
+
1. Fork the repo.
|
4
|
+
|
5
|
+
2. Run the tests. We only take pull requests with passing tests, and it's great
|
6
|
+
to know that you have a clean slate: `bundle && rake`
|
7
|
+
|
8
|
+
3. Add a test for your change. Only refactoring and documentation changes
|
9
|
+
require no new tests. If you are adding functionality or fixing a bug, we need
|
10
|
+
a test!
|
11
|
+
|
12
|
+
4. Make the test pass.
|
13
|
+
|
14
|
+
5. Push to your fork and submit a pull request.
|
15
|
+
|
16
|
+
|
17
|
+
At this point you're waiting on us. We like to at least comment on, if not
|
18
|
+
accept, pull requests within three business days (and, typically, one business
|
19
|
+
day). We may suggest some changes or improvements or alternatives.
|
20
|
+
|
21
|
+
Some things that will increase the chance that your pull request is accepted,
|
22
|
+
taken straight from the Ruby on Rails guide:
|
23
|
+
|
24
|
+
* Use Rails idioms and helpers
|
25
|
+
* Include tests that fail without your code, and pass with it
|
26
|
+
* Update the documentation, the surrounding one, examples elsewhere, guides,
|
27
|
+
whatever is affected by your contribution
|
28
|
+
|
29
|
+
Syntax:
|
30
|
+
|
31
|
+
* Two spaces, no tabs.
|
32
|
+
* No trailing whitespace. Blank lines should not have any space.
|
33
|
+
* Prefer &&/|| over and/or.
|
34
|
+
* MyClass.my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
35
|
+
* a = b and not a=b.
|
36
|
+
* Follow the conventions you see used in the source already.
|
37
|
+
|
38
|
+
And in case we didn't emphasize it enough: we love tests!
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Tinfoil Security, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
# Devise-Two-Factor Authentication
|
2
|
+
By [Tinfoil Security](http://tinfoilsecurity.com/)
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/tinfoil/devise-two-factor.svg?branch=master)](https://travis-ci.org/tinfoil/devise-two-factor)
|
5
|
+
|
6
|
+
Devise-two-factor is a minimalist extension to Devise which offers support for two-factor authentication. It:
|
7
|
+
|
8
|
+
* Allows you to incorporate two-factor authentication into your existing models
|
9
|
+
* Is opinionated about security, so you don't have to be
|
10
|
+
* Integrates easily with two-factor applications like Google Authenticator and Authy
|
11
|
+
* Is extensible, and includes two-factor backup codes as an example of how plugins can be structured
|
12
|
+
|
13
|
+
## Example App
|
14
|
+
An example Rails 4 application is provided in demo/
|
15
|
+
|
16
|
+
It showcases a minimal example of devise-two-factor in action, and can act as a reference for integrating the gem into your own application.
|
17
|
+
|
18
|
+
|
19
|
+
## Getting Started
|
20
|
+
Devise-two-factor doesn't require much to get started, but there are a few prerequisites before you can start using it in your application.
|
21
|
+
|
22
|
+
First, you'll need a Rails application setup with Devise. Visit the Devise [homepage](https://github.com/plataformatec/devise) for instructions.
|
23
|
+
|
24
|
+
Next, since devise-two-factor encrypts its secrets before storing them in the database, you'll need to generate an encryption key, and store it in an environment variable of your choice.
|
25
|
+
|
26
|
+
Finally, you can automate all of the required setup by simply running:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
rails generate devise_two_factor MODEL ENVIRONMENT_VARIABLE
|
30
|
+
```
|
31
|
+
|
32
|
+
Where MODEL is the name of the model you wish to add two-factor functionality to, and ENVIRONMENT_VARIABLE is the name of the variable you're storing your encryption key in.
|
33
|
+
|
34
|
+
This generator will add a few columns to the specified model:
|
35
|
+
|
36
|
+
* encrypted_otp_secret
|
37
|
+
* encrypted_otp_secret_iv
|
38
|
+
* encrypted_otp_secret_salt
|
39
|
+
* otp_required_for_login
|
40
|
+
|
41
|
+
It also adds the :two_factor_authenticatable directive to your model, and sets up your encryption key. If present, it will remove :database_authenticatable from the model, as the two strategies are incompatible. Lastly, the generator will add a Warden config block to your Devise initializer, which enables the strategies required for two-factor authenticatation.
|
42
|
+
|
43
|
+
If you're running Rails 3, or do not have strong parameters enabled, the generator will also setup the required mass-assignment security options in your model.
|
44
|
+
|
45
|
+
**After running the generator, verify that :database_authenticatable is not being loaded by your model. The generator will try to remove it, but if you have a non-standard Devise setup, this step may fail. Loading both :database_authenticatable and :two_factor_authenticatable in a model will allow users to bypass two-factor authenticatable due to the way Warden handles cascading strategies.**
|
46
|
+
|
47
|
+
## Designing Your Workflow
|
48
|
+
Devise-two-factor only worries about the backend, leaving the details of the integration up to you. This means that you're responsible for building the UI that drives the gem. While there is an example Rails application included in the gem, it is importable to remember that this gem is intentionally very open-ended, and you should build a user experience which fits your individual application.
|
49
|
+
|
50
|
+
There are two key workflows you'll have to think about:
|
51
|
+
|
52
|
+
1. Logging in with two-factor authentication
|
53
|
+
2. Enabling two-factor authentication for a given user
|
54
|
+
|
55
|
+
We chose to keep things as simple as possible, and our implemention can be found by registering at [Tinfoil Security](https://tinfoilsecurity.com/), and enabling two-factor authentication from the [security settings page](https://www.tinfoilsecurity.com/account/security).
|
56
|
+
|
57
|
+
|
58
|
+
### Logging In
|
59
|
+
Logging in with two-factor authentication works extremely similarly to regular database authentication in Devise. The TwoFactorAuthenticatable strategy accepts three parameters:
|
60
|
+
|
61
|
+
1. email
|
62
|
+
2. password
|
63
|
+
3. otp_attempt (Their one-time password for this session)
|
64
|
+
|
65
|
+
These parameters can be submitted to the standard Devise login route, and the strategy will handle the authentication of the user for you.
|
66
|
+
|
67
|
+
### Enabling Two-Factor Authentication
|
68
|
+
Enabling two-factor authentication for a user is easy. For example, if my user model were named User, I could do the following:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
current_user.otp_required_for_login = true
|
72
|
+
current_user.otp_secret = User.generate_otp_secret
|
73
|
+
current_user.save!
|
74
|
+
```
|
75
|
+
|
76
|
+
Before you can do this however, you need to decide how you're going to transmit two-factor tokens to a user. Common strategies include sending an SMS, or using a mobile application such as Google Authenticator.
|
77
|
+
|
78
|
+
At Tinfoil Security, we opted to use the excellent [rqrcode-rails3](https://github.com/samvincent/rqrcode-rails3) gem to generate a QR-code representing the user's secret key, which can then be scanned by any mobile two-factor authentication client.
|
79
|
+
|
80
|
+
However you decide to handle enrollment, there are a few important considerations to be made:
|
81
|
+
|
82
|
+
* Whether you'll force the use of two-factor authentication, and if so, how you'll migrate existing users to system, and what your onboarding experience will look like
|
83
|
+
* If you authenticate using SMS, you'll want to verify the user's ownership of the phone, in much the same way you're probably verifying their email address
|
84
|
+
* How you'll handle device revocation in the event that a user loses access to their device, or that device is rendered temporarily unavailable (This gem includes TwoFactorBackupable as an example extension meant to solve this problem)
|
85
|
+
|
86
|
+
It sounds like a lot of work, but most of these problems have been very elegantly solved by other people. We recommend taking a look at the excellent workflows used by Heroku and Google for inspiration.
|
87
|
+
|
88
|
+
## Backup Codes
|
89
|
+
Devise-two-factor is designed with extensibility in mind. One such extension, TwoFactorBackupable, is included and serves as a good example of how to extend this gem. This plugin allows you to add the ability to generate single-use backup codes for a user, which they may use to bypass two-factor authentication, in the event that they lose access to their device.
|
90
|
+
|
91
|
+
To install it, you need to add the :two_factor_backupable directive to your model.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
devise :two_factor_backupable
|
95
|
+
```
|
96
|
+
|
97
|
+
You'll also be required to enable the :two_factor_backupable strategy, by adding the following line to your Warden config in your Devise initializer, substituting :user for the name of your Devise scope.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
manager.default_strategies(:scope => :user).unshift :two_factor_backupable
|
101
|
+
```
|
102
|
+
|
103
|
+
The final installation step is dependent on your version of Rails. If you're not running Rails 4, skip to the next section. Otherwise, create the following migration:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class AddDeviseTwoFactorBackupableToUsers < ActiveRecord::Migration
|
107
|
+
def change
|
108
|
+
add_column :users, :otp_backup_codes, :string, array: true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
You can then generate backup codes for a user:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
codes = current_user.generate_otp_backup_codes!
|
117
|
+
current_user.save!
|
118
|
+
# Display codes to the user somehow!
|
119
|
+
```
|
120
|
+
|
121
|
+
The backup codes are stored in the database as bcrypt hashes, so be sure to display them to the user at this point. If all went well, the user should be able to login using each of the generated codes in place of their two-factor token. Each code is single-use, and generating a new set of backup codes for that user will invalidate all of the old ones.
|
122
|
+
|
123
|
+
You can customize the length of each code, and the number of codes generated by passing the options into `:two_factor_backupable` in the Devise directive:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
devise :two_factor_backupable, otp_backup_code_length: 32,
|
127
|
+
otp_number_of_backup_codes: 10
|
128
|
+
```
|
129
|
+
|
130
|
+
### Help! I'm not using Rails 4.0!
|
131
|
+
Don't worry! TwoFactorBackupable stores the backup codes as an array of strings in the database. In Rails 4.0 this is supported natively, but in earlier versions you can use a gem to emulate this behaviour: we recommend [activerecord-postgres-array](https://github.com/tlconnor/activerecord-postgres-array).
|
132
|
+
|
133
|
+
You'll then simply have to create a migration to add an array named `otp_backup_codes` to your model. If you use the above gem, this migration might look like:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
class AddTwoFactorBackupCodesToUsers < ActiveRecord::Migration
|
137
|
+
def change
|
138
|
+
add_column :users, :otp_backup_codes, :string_array
|
139
|
+
end
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
Now just continue with the setup in the previous section, skipping the generator step.
|
144
|
+
|
145
|
+
## Testing
|
146
|
+
Devise-two-factor includes shared-examples for both TwoFactorAuthenticatable and TwoFactorBackupable. Adding the following two lines to the specs for your two-factor enabled models will allow you to test your models for two-factor functionality:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
require 'devise_two_factor/spec_helpers
|
150
|
+
|
151
|
+
it_behaves_like "two_factor_authenticatable"
|
152
|
+
it_behaves_like "two_factor_backupable"
|
153
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'rspec/core'
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
17
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Code coverage detail"
|
21
|
+
task :simplecov do
|
22
|
+
ENV['COVERAGE'] = "true"
|
23
|
+
Rake::Task['spec'].execute
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :spec
|
@@ -0,0 +1,41 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIHSjCCBTKgAwIBAgIJAK2u0LojMCNgMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
3
|
+
VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEfMB0GA1UE
|
4
|
+
ChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEfMB0GA1UEAxMWVGluZm9pbCBTZWN1
|
5
|
+
cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYbc3VwcG9ydEB0aW5mb2lsc2VjdXJp
|
6
|
+
dHkuY29tMB4XDTExMTIyNzA1MDc0N1oXDTIxMTIyNDA1MDc0N1owgZwxCzAJBgNV
|
7
|
+
BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
|
8
|
+
ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR8wHQYDVQQDExZUaW5mb2lsIFNlY3Vy
|
9
|
+
aXR5LCBJbmMuMSowKAYJKoZIhvcNAQkBFhtzdXBwb3J0QHRpbmZvaWxzZWN1cml0
|
10
|
+
eS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqbHvsSj0H0FB1
|
11
|
+
0gLYoDK1BKugkSB2DZeZZHP6B1UdWRahJXJP9oT1lhfQxx8iX4cgEi7JU3NqA6NR
|
12
|
+
cIRFQ50eH/qlmgs7909gaf8pDaeC0vR3wd0GeRg6qr1eDEnkzIyr/D1AMiX6H1eP
|
13
|
+
Y7J3SfrdaL3gft2iPRKGkgqsXR7oBNLA3n/ShiNgPXqRDl1CCj6aMY0cn5ROFScz
|
14
|
+
vT2FUB4DEwPD2l18m1p99OnXqsOLL2J65qA2+cI8FtgFmlwIi5oSf+URvIdNx+cH
|
15
|
+
lInlAtVHCvAKYLY0dlQ7czMQBcRpYjp2rwPt9f2ksq9b/voMTBABYHFV+IVn8svv
|
16
|
+
GZ5e1+icjtr/R7dCGmCdEdFLXVxafmZhukymG9USv9DKuv1qh7r4q8KaPIE8n7nQ
|
17
|
+
m97jENFfsgnwv+nUmIJ3tzuW5ZxO7A0tIIYdwzt0UjrO3ya4R5bTFXr4bnzZ/g/s
|
18
|
+
CLknWqg1BCRlPd6LnpVGPT0gNDV1pEO25wE3A3Yy0Ujxudcgay/CgUhnlU11qOAc
|
19
|
+
xmar2fhNZsviUhndd/220Ad5QMV2XzcAiopJIeu0juIVGRQM7x2h19Hsp0m6sOEF
|
20
|
+
jfhvbdUa4nvmIFeYFY+hr/YkTmG9ZjyBa8YaZXhwjhSmKCQ374J7mn5e0Cryuvi5
|
21
|
+
tYhwJn8rdwYZF/h2qqfEu8vaLoD09QIDAQABo4IBizCCAYcwHQYDVR0OBBYEFMmT
|
22
|
+
/x412UH+5OHqgleeTjLOv6iHMIHRBgNVHSMEgckwgcaAFMmT/x412UH+5OHqglee
|
23
|
+
TjLOv6iHoYGipIGfMIGcMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNV
|
24
|
+
BAcTCVBhbG8gQWx0bzEfMB0GA1UEChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEf
|
25
|
+
MB0GA1UEAxMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYb
|
26
|
+
c3VwcG9ydEB0aW5mb2lsc2VjdXJpdHkuY29tggkAra7QuiMwI2AwDwYDVR0TAQH/
|
27
|
+
BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQYwCQYDVR0SBAIwADArBglghkgBhvhC
|
28
|
+
AQ0EHhYcVGlueUNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAmBgNVHREEHzAdgRtz
|
29
|
+
dXBwb3J0QHRpbmZvaWxzZWN1cml0eS5jb20wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
|
30
|
+
SIb3DQEBBQUAA4ICAQAD7nsmdg1vStFTi8/P2rgSFxlXxZT0aaVVB1bFBe/m5phb
|
31
|
+
MjvKQ7VAuiFZxEp3oBNdXTi4FzT1QjhRKdlYMgKZQnU+XDLLIYuoi+atxr5qGD4B
|
32
|
+
m58eCGO6ZEutVs3Z7s63UOm5rG0zJ+IEWh8VHMvxgSwiX88QyJuhOtqeiKhIeSGZ
|
33
|
+
2/qGGMWgsScnPg3J/ZVOIKUn/4ljEDlC64Gh5Zz5PZUbGSXPMhdYbSD3EknDvEGA
|
34
|
+
omYW4jlPMeK3GJgwAZu9yWC8hHGFpiMca/6W0W622cg7MX+CByOd+24dvWFnOHur
|
35
|
+
NHBqI+kZo/7Sjdm8x7TWEOz9Rfh5RPMeVNRTj4iq0B6GzfaecT3Yn8y7HTRRiWns
|
36
|
+
IYpP+iHCFYnZhDZsFi4ccKqxKtj6BGmhLf00FuNpgkvrsU3cXrhidkCaYGYj1SME
|
37
|
+
1CMfy0PPKVDpDKeFb6y0NvLf4d57vi99dZAvSJEO18rrNEHN2VUfCKRPA/mBSMLY
|
38
|
+
RxKWAby1YVT/8iC9JWix9yvgsEUtTLyOFxLGtgj3PRiQSvbNe/jK4G9WAIFe6R9E
|
39
|
+
9+HUO2owcmyFXyU3rC/z/lBfDP+2pIRFdUVRGlYCMeUqR08PXpfva5+NQz21fC69
|
40
|
+
FPRMZvXh70ntnFaWAq+j6NCss+AauC8ckECiQsTgbzJvJd6C3mJXYHkNCQODhg==
|
41
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,33 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIFyjCCA7KgAwIBAgIJAK2u0LojMCNtMA0GCSqGSIb3DQEBDQUAMIGcMQswCQYD
|
3
|
+
VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEfMB0GA1UE
|
4
|
+
ChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEfMB0GA1UEAxMWVGluZm9pbCBTZWN1
|
5
|
+
cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYbc3VwcG9ydEB0aW5mb2lsc2VjdXJp
|
6
|
+
dHkuY29tMB4XDTE0MDUyMDIxMTAwMFoXDTE2MDUyMDIxMTAwMFowgZwxCzAJBgNV
|
7
|
+
BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
|
8
|
+
ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR0wGwYDVQQDExR0aW5mb2lsc2VjdXJp
|
9
|
+
dHktZ2VtczEsMCoGCSqGSIb3DQEJARYdZW5naW5lZXJzQHRpbmZvaWxzZWN1cml0
|
10
|
+
eS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDNJYNH8D+8lACL
|
11
|
+
t3KzjEIPs3XVBCPaMm2eD/Xk9OOTuDV/NqgMK0icD9MRxMUtS3SCrC9QcPocXT76
|
12
|
+
f2LQ3yVJuK+rBUasymEES47PIx2czC4n4Hga0xPPuBpioO26oaRFsobyzh9RPOIb
|
13
|
+
nYfpjyqtdrbm+YyM3sPR4XzFirv9xomT4E9T4RCLgOQHTcLKL9K9m+EN7PeVdVUX
|
14
|
+
V0Pa7cVs2vJUKedsd7vnr6Lzbn8ToPk/7J/4W931PbaeI5yg9ZuaRa9K2IaY1TkP
|
15
|
+
I67NW4qKitBVepRlXw6Sb7TYcUncWEQ/eC5CpnOmqUrG5tfGD8cc5aGZOkitW/VX
|
16
|
+
ZgVj81xgCv1hk4HjErrqq4FBNAaCSNyBfwR0TUYqg1lN1nbNjOKwfb6YRn06R2ov
|
17
|
+
cFJG0tmGhsQULCr6fW8u2TfSM+U9WFSIJx2griureY7EZPwg/MgsUiWUWMFemz3G
|
18
|
+
VYXWJR3dN2pW9Uqr3rkjKZbA0bstGWahJO9HuFdDakQxoaTPYPtTQDC+kskkO6lK
|
19
|
+
G1KLIoZ1iLZzB1Ks1vEeyE7lp1imWgpUq+q23PFkt1gIBi/4tGvzsLZye25QU2Y+
|
20
|
+
XLzldCNm+DyRFXZ+Q+bK33IveUeUWEOv4T1qTXHAOypyzmgodVRG/PrlsSMOBfE5
|
21
|
+
15kG1mDMGjRcCpEtlskgxUbf7qM7hQIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqG
|
22
|
+
SIb3DQEBDQUAA4ICAQCLXzGJOr0isGHscTvm73ReEAOv4g0IOSXjfHfHAOWKhzdM
|
23
|
+
g+D8nrzhy8wnARqAt2Ob4I+R9scEIfI5MPp/C5HHqWed4m0W0Uygx3V3qyixavkc
|
24
|
+
nVUJMZ4TPS6W48IHdGGVD45hopx7ycFy+iPm7QUFk4sg044dO53mkScTetm2AvIE
|
25
|
+
xDTotsFNpn/hrAnzXlH4MQQ7LKXAedPmFi8Jv5nJwv9BnEGJQJhvzQtdx7le4S8J
|
26
|
+
a78vwAq429N2gVnfSdeU9v9QqdHOF1215lC6qaDI4bk8hVE4RyMxSBZmWKhnPLAm
|
27
|
+
jFXGc6Wj2yF7HQ2YtEGAAEyjH+tAwF35STv+J3eweUFhyGZPH8Sf+b+UKZc9UF1D
|
28
|
+
J/VmzQd9D9RaB+pOclDYR3Uiji5EBq1La2FPg48hA0uCd4KJ9dBGwNrxvjDNSBW0
|
29
|
+
FiM1vjR6AVxIAhOwICeWG6QTvH5Jrnq/UDBnnK/KALCbFw3YbbhOyy+295jta7xf
|
30
|
+
r32d4cJAvbDF1C6t2JRjNwi0ANgPw0cytl+8yvCyXpXMZpT0YpDk76XICo97SOHI
|
31
|
+
5C31v4YyRBnNCp0pN66nxYX2avEiQ8riTBP5mlkPPOhsIoYQHHe2Uj75aVpu0LZ3
|
32
|
+
cdFzuO4GC1dV0Wv+dsDm+MyF7DT5E9pUPXpnMJuPvPrFpCb+wrFlszW9hGjXbQ==
|
33
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,39 @@
|
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
2
|
+
require 'devise_two_factor/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'devise-two-factor'
|
6
|
+
s.version = DeviseTwoFactor::VERSION.dup
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.licenses = ['MIT']
|
9
|
+
s.summary = 'Barebones two-factor authentication with Devise'
|
10
|
+
s.email = 'engineers@tinfoilsecurity.com'
|
11
|
+
s.homepage = 'https://github.com/tinfoil/devise-two-factor'
|
12
|
+
s.description = 'Barebones two-factor authentication with Devise'
|
13
|
+
s.authors = ['Shane Wilton']
|
14
|
+
|
15
|
+
s.cert_chain = [
|
16
|
+
'certs/tinfoil-cacert.pem',
|
17
|
+
'certs/tinfoilsecurity-gems-cert.pem'
|
18
|
+
]
|
19
|
+
s.signing_key = File.expand_path("~/.ssh/tinfoilsecurity-gems-key.pem") if $0 =~ /gem\z/
|
20
|
+
|
21
|
+
s.rubyforge_project = 'devise-two-factor'
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n").delete_if { |x| x.match('demo/*') }
|
24
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
25
|
+
s.require_paths = ['lib']
|
26
|
+
|
27
|
+
s.add_runtime_dependency 'rails' # For generators
|
28
|
+
s.add_runtime_dependency 'activesupport'
|
29
|
+
s.add_runtime_dependency 'activemodel'
|
30
|
+
s.add_runtime_dependency 'attr_encrypted'
|
31
|
+
s.add_runtime_dependency 'devise'
|
32
|
+
s.add_runtime_dependency 'rotp'
|
33
|
+
|
34
|
+
s.add_development_dependency 'bundler', '> 1.0'
|
35
|
+
s.add_development_dependency 'rspec', '~> 2.8'
|
36
|
+
s.add_development_dependency 'simplecov'
|
37
|
+
s.add_development_dependency 'faker'
|
38
|
+
s.add_development_dependency 'timecop'
|
39
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'devise'
|
2
|
+
require 'devise_two_factor/models'
|
3
|
+
require 'devise_two_factor/strategies'
|
4
|
+
|
5
|
+
module Devise
|
6
|
+
# The length of generated OTP secrets
|
7
|
+
mattr_accessor :otp_secret_length
|
8
|
+
@@otp_secret_length = 128
|
9
|
+
|
10
|
+
# The number of seconds before and after the current
|
11
|
+
# time for which codes will be accepted
|
12
|
+
mattr_accessor :otp_allowed_drift
|
13
|
+
@@otp_allowed_drift = 30
|
14
|
+
|
15
|
+
# The key used to encrypt OTP secrets in the database
|
16
|
+
mattr_accessor :otp_secret_encryption_key
|
17
|
+
@@otp_secret_encryption_key = nil
|
18
|
+
|
19
|
+
# The length of all generated OTP backup codes
|
20
|
+
mattr_accessor :otp_backup_code_length
|
21
|
+
@@otp_backup_code_length = 16
|
22
|
+
|
23
|
+
# The number of backup codes generated by a call to
|
24
|
+
# generate_otp_backup_codes!
|
25
|
+
mattr_accessor :otp_number_of_backup_codes
|
26
|
+
@@otp_number_of_backup_codes = 5
|
27
|
+
end
|
28
|
+
|
29
|
+
Devise.add_module(:two_factor_authenticatable, :route => :session, :strategy => true,
|
30
|
+
:controller => :sessions, :model => true)
|
31
|
+
|
32
|
+
Devise.add_module(:two_factor_backupable, :route => :session, :strategy => true,
|
33
|
+
:controller => :sessions, :model => true)
|