devise-2fa 0.2.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +66 -41
- data/.gitignore +3 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +11 -0
- data/bin/rspec +2 -9
- data/bin/setup +3 -1
- data/devise_2fa.gemspec +6 -5
- data/lib/devise-2fa/version.rb +1 -1
- data/lib/devise_two_factorable/models/two_factorable.rb +9 -4
- data/spec/dummy/app/models/application_record.rb +6 -2
- data/spec/dummy/app/models/user.rb +37 -5
- data/spec/dummy/app/views/layouts/application.html.erb +0 -3
- data/spec/dummy/bin/setup +1 -16
- data/spec/dummy/config/application.rb +9 -2
- data/spec/dummy/config/database.yml +0 -10
- data/spec/dummy/config/environments/development.rb +0 -14
- data/spec/dummy/config/environments/test.rb +1 -14
- data/spec/dummy/config/initializers/devise.rb +5 -1
- data/spec/dummy/config/mongoid.yml +164 -0
- data/spec/dummy/config/routes.rb +6 -1
- data/spec/dummy/db/migrate/{20190312222952_devise_two_factor_add_to_users.rb → 20190625052821_devise_two_factor_add_to_users.rb} +1 -1
- data/spec/models/user_spec.rb +47 -2
- data/spec/spec_helper.rb +7 -3
- data/spec/system/token_spec.rb +1 -1
- metadata +34 -25
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +0 -3
- data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a34165f30cdc2d197acd726713f2ca7a6ed4ac2d4410aea31c10d4c12958e45d
|
4
|
+
data.tar.gz: ce5559076cac73dedcb0454982e8cd0f6dcd6d79ef2113b8e2426cc626e2cf27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65d4138506168bbf1403791cb00573270781c30c54e9a7bf49b43c8145247188ac19fd7410558f86cc95c46986ecd5d78920725919210d0c24a2a2dbb36556b3
|
7
|
+
data.tar.gz: 8f2cc4f9f4f8215cc6b3e3cd0caf8e917608ac95ce3bbcfc6d371678fbaef8399f9cdccdc31cbe379319a244979278201c1607abc642c7c944a8f6275e6ed028
|
data/.circleci/config.yml
CHANGED
@@ -1,45 +1,70 @@
|
|
1
1
|
version: 2
|
2
|
+
|
3
|
+
build_config: &build_config
|
4
|
+
working_directory: ~/repo
|
5
|
+
steps:
|
6
|
+
- checkout
|
7
|
+
|
8
|
+
- restore_cache:
|
9
|
+
keys:
|
10
|
+
- v1-dependencies-{{ checksum "devise_2fa.gemspec" }}-{{ checksum "Appraisals" }}
|
11
|
+
- v1-dependencies-{{ checksum "devise_2fa.gemspec" }}
|
12
|
+
- v1-dependencies
|
13
|
+
|
14
|
+
- run: bin/setup
|
15
|
+
|
16
|
+
- save_cache:
|
17
|
+
paths:
|
18
|
+
- ./vendor/bundle
|
19
|
+
key: v1-dependencies-{{ checksum "devise_2fa.gemspec" }}-{{ checksum "Appraisals" }}
|
20
|
+
|
21
|
+
- run:
|
22
|
+
name: Setup Symmetric Encryption Config
|
23
|
+
command: |
|
24
|
+
cd spec/dummy/
|
25
|
+
symmetric-encryption -g
|
26
|
+
|
27
|
+
- run:
|
28
|
+
name: Run Tests
|
29
|
+
command: |
|
30
|
+
mkdir /tmp/test-results
|
31
|
+
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
|
32
|
+
circleci tests split --split-by=timings)"
|
33
|
+
|
34
|
+
bundle exec appraisal rspec \
|
35
|
+
--format progress \
|
36
|
+
--format RspecJunitFormatter \
|
37
|
+
--out /tmp/test-results/rspec.xml \
|
38
|
+
--format progress \
|
39
|
+
$TEST_FILES
|
40
|
+
|
41
|
+
- store_test_results:
|
42
|
+
path: /tmp/test-results
|
43
|
+
- store_artifacts:
|
44
|
+
path: /tmp/test-results
|
45
|
+
destination: test-results
|
46
|
+
|
2
47
|
jobs:
|
48
|
+
ruby-2.4:
|
49
|
+
<<: *build_config
|
50
|
+
docker:
|
51
|
+
- image: circleci/ruby:2.4-node-browsers
|
52
|
+
- image: circleci/mongo
|
53
|
+
ruby-2.5:
|
54
|
+
<<: *build_config
|
55
|
+
docker:
|
56
|
+
- image: circleci/ruby:2.5-node-browsers
|
57
|
+
- image: circleci/mongo
|
3
58
|
build:
|
59
|
+
<<: *build_config
|
4
60
|
docker:
|
5
|
-
- image: circleci/ruby:2.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- run:
|
17
|
-
name: install dependencies
|
18
|
-
command: |
|
19
|
-
bundle install --jobs=4 --retry=3 --path vendor/bundle
|
20
|
-
|
21
|
-
- save_cache:
|
22
|
-
paths:
|
23
|
-
- ./vendor/bundle
|
24
|
-
key: v1-dependencies-{{ checksum "devise_2fa.gemspec" }}
|
25
|
-
|
26
|
-
- run: cd spec/dummy && bin/setup
|
27
|
-
|
28
|
-
- run:
|
29
|
-
name: run tests
|
30
|
-
command: |
|
31
|
-
mkdir /tmp/test-results
|
32
|
-
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
|
33
|
-
circleci tests split --split-by=timings)"
|
34
|
-
|
35
|
-
bundle exec rspec \
|
36
|
-
--format progress \
|
37
|
-
--out /tmp/test-results/rspec.xml \
|
38
|
-
--format progress \
|
39
|
-
$TEST_FILES
|
40
|
-
|
41
|
-
- store_test_results:
|
42
|
-
path: /tmp/test-results
|
43
|
-
- store_artifacts:
|
44
|
-
path: /tmp/test-results
|
45
|
-
destination: test-results
|
61
|
+
- image: circleci/ruby:2.6-node-browsers
|
62
|
+
- image: circleci/mongo
|
63
|
+
|
64
|
+
workflows:
|
65
|
+
version: 2
|
66
|
+
build:
|
67
|
+
jobs:
|
68
|
+
- ruby-2.4
|
69
|
+
- ruby-2.5
|
70
|
+
- build
|
data/.gitignore
CHANGED
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.4.0] - 2019-08-22
|
10
|
+
### Added
|
11
|
+
- Appraisal suite.
|
12
|
+
- Mongoid specs.
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- Refactors #validate_otp_token_with_drift from #15.
|
16
|
+
- Upgraded rotp dependency to ```~> 5.1```.
|
17
|
+
|
18
|
+
## [0.3.0] - REVOKED
|
19
|
+
|
9
20
|
## [0.2.1] - 2019-05-28
|
10
21
|
### Changed
|
11
22
|
- Relaxed Rails dependency to ```~> 6.1```.
|
data/bin/rspec
CHANGED
@@ -1,10 +1,3 @@
|
|
1
|
-
#!/
|
2
|
-
# frozen_string_literal: true
|
1
|
+
#!/bin/bash
|
3
2
|
|
4
|
-
|
5
|
-
load File.expand_path('../spring', __FILE__)
|
6
|
-
rescue LoadError => e
|
7
|
-
raise unless e.message.include?('spring')
|
8
|
-
end
|
9
|
-
require 'bundler/setup'
|
10
|
-
load Gem.bin_path('rspec-core', 'rspec')
|
3
|
+
bundle exec appraisal rspec
|
data/bin/setup
CHANGED
data/devise_2fa.gemspec
CHANGED
@@ -21,14 +21,15 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency "rails", ">= 4.1", "< 6.1"
|
22
22
|
|
23
23
|
gem.add_runtime_dependency 'devise', '~> 4.0'
|
24
|
-
gem.add_runtime_dependency 'rotp', '~>
|
24
|
+
gem.add_runtime_dependency 'rotp', '~> 5.1'
|
25
25
|
gem.add_runtime_dependency 'rqrcode', '~> 0.10.1'
|
26
26
|
gem.add_runtime_dependency 'symmetric-encryption', '~> 4.3.0'
|
27
27
|
|
28
|
-
gem.add_development_dependency '
|
29
|
-
gem.add_development_dependency 'selenium-webdriver'
|
30
|
-
gem.add_development_dependency 'rspec-rails'
|
28
|
+
gem.add_development_dependency 'appraisal'
|
31
29
|
gem.add_development_dependency 'capybara'
|
32
|
-
gem.add_development_dependency 'rspec'
|
33
30
|
gem.add_development_dependency 'pry'
|
31
|
+
gem.add_development_dependency 'rspec'
|
32
|
+
gem.add_development_dependency 'rspec-rails'
|
33
|
+
gem.add_development_dependency 'rspec_junit_formatter'
|
34
|
+
gem.add_development_dependency 'selenium-webdriver'
|
34
35
|
end
|
data/lib/devise-2fa/version.rb
CHANGED
@@ -117,10 +117,15 @@ module Devise::Models
|
|
117
117
|
private
|
118
118
|
|
119
119
|
def validate_otp_token_with_drift(token)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
time_based_otp.verify(
|
121
|
+
token,
|
122
|
+
drift_behind: drift.minutes.seconds,
|
123
|
+
at: Time.now + drift.minutes.seconds / 2
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
def drift
|
128
|
+
self.class.otp_drift_window
|
124
129
|
end
|
125
130
|
|
126
131
|
def generate_otp_persistence_seed
|
@@ -1,6 +1,38 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'symmetric_encryption'
|
4
|
+
|
5
|
+
if defined?(ActiveRecord)
|
6
|
+
class User < ApplicationRecord
|
7
|
+
devise :two_factorable, :database_authenticatable, :registerable,
|
8
|
+
:recoverable, :rememberable, :validatable
|
9
|
+
end
|
10
|
+
else
|
11
|
+
require 'mongoid'
|
12
|
+
class User
|
13
|
+
include Mongoid::Document
|
14
|
+
field :encrypted_otp_auth_secret, type: String, encrypted: true
|
15
|
+
field :encrypted_otp_recovery_secret, type: String, encrypted: true
|
16
|
+
field :otp_enabled, type: Boolean, default: false
|
17
|
+
field :otp_mandatory, type: Boolean, default: false
|
18
|
+
field :otp_enabled_on, type: DateTime
|
19
|
+
field :otp_failed_attempts, type: Integer, default: 0
|
20
|
+
field :otp_recovery_counter, type: Integer, default: 0
|
21
|
+
field :otp_persistence_seed, type: String
|
22
|
+
field :otp_session_challenge, type: String
|
23
|
+
field :otp_challenge_expires, type: DateTime
|
24
|
+
|
25
|
+
index({ otp_session_challenge: 1 }, background: true)
|
26
|
+
index({ otp_challenge_expires: 1 }, background: true)
|
27
|
+
|
28
|
+
devise :two_factorable, :database_authenticatable, :registerable,
|
29
|
+
:recoverable, :rememberable, :validatable
|
30
|
+
field :email, type: String, default: ''
|
31
|
+
field :encrypted_password, type: String, default: ''
|
32
|
+
field :reset_password_token, type: String
|
33
|
+
field :reset_password_sent_at, type: Time
|
34
|
+
field :remember_created_at, type: Time
|
35
|
+
field :name, type: String
|
36
|
+
field :phone, type: String
|
37
|
+
end
|
6
38
|
end
|
data/spec/dummy/bin/setup
CHANGED
@@ -5,21 +5,6 @@ include FileUtils
|
|
5
5
|
# path to your application root.
|
6
6
|
APP_ROOT = File.expand_path('..', __dir__)
|
7
7
|
|
8
|
-
def system!(*args)
|
9
|
-
system(*args) || abort("\n== Command #{args} failed ==")
|
10
|
-
end
|
11
|
-
|
12
8
|
chdir APP_ROOT do
|
13
|
-
|
14
|
-
system! 'gem install bundler --conservative'
|
15
|
-
system('bundle check') || system!('bundle install')
|
16
|
-
|
17
|
-
puts "\n== Preparing database =="
|
18
|
-
system! 'bin/rails db:setup'
|
19
|
-
|
20
|
-
puts "\n== Removing old logs and tempfiles =="
|
21
|
-
system! 'bin/rails log:clear tmp:clear'
|
22
|
-
|
23
|
-
puts "\n== Restarting application server =="
|
24
|
-
system! 'bin/rails restart'
|
9
|
+
system 'bin/rails db:setup 2> /dev/null'
|
25
10
|
end
|
@@ -1,6 +1,14 @@
|
|
1
1
|
require_relative 'boot'
|
2
2
|
|
3
|
-
require 'rails
|
3
|
+
require 'rails'
|
4
|
+
require 'active_model/railtie'
|
5
|
+
unless ENV['BUNDLE_GEMFILE'].include?('mongodb')
|
6
|
+
require 'active_record/railtie'
|
7
|
+
end
|
8
|
+
require 'action_controller/railtie'
|
9
|
+
require 'action_view/railtie'
|
10
|
+
require 'sprockets/railtie'
|
11
|
+
require 'rails/test_unit/railtie'
|
4
12
|
|
5
13
|
Bundler.require(*Rails.groups)
|
6
14
|
require 'devise-2fa'
|
@@ -11,4 +19,3 @@ module Dummy
|
|
11
19
|
config.load_defaults 5.0
|
12
20
|
end
|
13
21
|
end
|
14
|
-
|
@@ -1,9 +1,3 @@
|
|
1
|
-
# SQLite version 3.x
|
2
|
-
# gem install sqlite3
|
3
|
-
#
|
4
|
-
# Ensure the SQLite 3 gem is defined in your Gemfile
|
5
|
-
# gem 'sqlite3'
|
6
|
-
#
|
7
1
|
default: &default
|
8
2
|
adapter: sqlite3
|
9
3
|
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
@@ -19,7 +13,3 @@ development:
|
|
19
13
|
test:
|
20
14
|
<<: *default
|
21
15
|
database: db/test.sqlite3
|
22
|
-
|
23
|
-
production:
|
24
|
-
<<: *default
|
25
|
-
database: db/production.sqlite3
|
@@ -27,23 +27,9 @@ Rails.application.configure do
|
|
27
27
|
config.cache_store = :null_store
|
28
28
|
end
|
29
29
|
|
30
|
-
# Store uploaded files on the local file system (see config/storage.yml for options)
|
31
|
-
config.active_storage.service = :local
|
32
|
-
|
33
|
-
# Don't care if the mailer can't send.
|
34
|
-
config.action_mailer.raise_delivery_errors = false
|
35
|
-
|
36
|
-
config.action_mailer.perform_caching = false
|
37
|
-
|
38
30
|
# Print deprecation notices to the Rails logger.
|
39
31
|
config.active_support.deprecation = :log
|
40
32
|
|
41
|
-
# Raise an error on page load if there are pending migrations.
|
42
|
-
config.active_record.migration_error = :page_load
|
43
|
-
|
44
|
-
# Highlight code that triggered database queries in logs.
|
45
|
-
config.active_record.verbose_query_logs = true
|
46
|
-
|
47
33
|
# Debug mode disables concatenation and preprocessing of assets.
|
48
34
|
# This option may cause significant delays in view rendering with a large
|
49
35
|
# number of complex assets.
|
@@ -10,7 +10,7 @@ Rails.application.configure do
|
|
10
10
|
# Do not eager load code on boot. This avoids loading your whole application
|
11
11
|
# just for the purpose of running a single test. If you are using a tool that
|
12
12
|
# preloads Rails for running tests, you may have to set it to true.
|
13
|
-
config.eager_load =
|
13
|
+
config.eager_load = true
|
14
14
|
|
15
15
|
# Configure public file server for tests with Cache-Control for performance
|
16
16
|
config.public_file_server.enabled = true
|
@@ -28,19 +28,6 @@ Rails.application.configure do
|
|
28
28
|
# Disable request forgery protection in test environment
|
29
29
|
config.action_controller.allow_forgery_protection = false
|
30
30
|
|
31
|
-
# Store uploaded files on the local file system in a temporary directory
|
32
|
-
config.active_storage.service = :test
|
33
|
-
|
34
|
-
config.action_mailer.perform_caching = false
|
35
|
-
|
36
|
-
# Tell Action Mailer not to deliver emails to the real world
|
37
|
-
# The :test delivery method accumulates sent emails in the
|
38
|
-
# ActionMailer::Base.deliveries array.
|
39
|
-
config.action_mailer.delivery_method = :test
|
40
|
-
|
41
31
|
# Print deprecation notices to the stderr
|
42
32
|
config.active_support.deprecation = :stderr
|
43
|
-
|
44
|
-
# Raises error for missing translations
|
45
|
-
# config.action_view.raise_on_missing_translations = true
|
46
33
|
end
|
@@ -30,7 +30,11 @@ Devise.setup do |config|
|
|
30
30
|
# Load and configure the ORM. Supports :active_record (default) and
|
31
31
|
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
32
32
|
# available as additional gems.
|
33
|
-
|
33
|
+
if defined?(ActiveRecord)
|
34
|
+
require 'devise/orm/active_record'
|
35
|
+
else
|
36
|
+
require 'devise/orm/mongoid'
|
37
|
+
end
|
34
38
|
|
35
39
|
# ==> Configuration for any authentication mechanism
|
36
40
|
# Configure which keys are used when authenticating a user. The default is
|
@@ -0,0 +1,164 @@
|
|
1
|
+
development:
|
2
|
+
# Configure available database clients. (required)
|
3
|
+
clients:
|
4
|
+
# Defines the default client. (required)
|
5
|
+
default:
|
6
|
+
# Defines the name of the default database that Mongoid can connect to.
|
7
|
+
# (required).
|
8
|
+
database: dummy_development
|
9
|
+
# Provides the hosts the default client can connect to. Must be an array
|
10
|
+
# of host:port pairs. (required)
|
11
|
+
hosts:
|
12
|
+
- localhost:27017
|
13
|
+
options:
|
14
|
+
# Note that all options listed below are Ruby driver client options (the mongo gem).
|
15
|
+
# Please refer to the driver documentation of the version of the mongo gem you are using
|
16
|
+
# for the most up-to-date list of options.
|
17
|
+
#
|
18
|
+
# Change the default write concern. (default = { w: 1 })
|
19
|
+
# write:
|
20
|
+
# w: 1
|
21
|
+
|
22
|
+
# Change the default read preference. Valid options for mode are: :secondary,
|
23
|
+
# :secondary_preferred, :primary, :primary_preferred, :nearest
|
24
|
+
# (default: primary)
|
25
|
+
# read:
|
26
|
+
# mode: :secondary_preferred
|
27
|
+
# tag_sets:
|
28
|
+
# - use: web
|
29
|
+
|
30
|
+
# The name of the user for authentication.
|
31
|
+
# user: 'user'
|
32
|
+
|
33
|
+
# The password of the user for authentication.
|
34
|
+
# password: 'password'
|
35
|
+
|
36
|
+
# The user's database roles.
|
37
|
+
# roles:
|
38
|
+
# - 'dbOwner'
|
39
|
+
|
40
|
+
# Change the default authentication mechanism. Valid options are: :scram,
|
41
|
+
# :mongodb_cr, :mongodb_x509, and :plain. Note that all authentication
|
42
|
+
# mechanisms require username and password, with the exception of :mongodb_x509.
|
43
|
+
# Default on mongoDB 3.0 is :scram, default on 2.4 and 2.6 is :plain.
|
44
|
+
# auth_mech: :scram
|
45
|
+
|
46
|
+
# The database or source to authenticate the user against.
|
47
|
+
# (default: the database specified above or admin)
|
48
|
+
# auth_source: admin
|
49
|
+
|
50
|
+
# Force a the driver cluster to behave in a certain manner instead of auto-
|
51
|
+
# discovering. Can be one of: :direct, :replica_set, :sharded. Set to :direct
|
52
|
+
# when connecting to hidden members of a replica set.
|
53
|
+
# connect: :direct
|
54
|
+
|
55
|
+
# Changes the default time in seconds the server monitors refresh their status
|
56
|
+
# via ismaster commands. (default: 10)
|
57
|
+
# heartbeat_frequency: 10
|
58
|
+
|
59
|
+
# The time in seconds for selecting servers for a near read preference. (default: 0.015)
|
60
|
+
# local_threshold: 0.015
|
61
|
+
|
62
|
+
# The timeout in seconds for selecting a server for an operation. (default: 30)
|
63
|
+
# server_selection_timeout: 30
|
64
|
+
|
65
|
+
# The maximum number of connections in the connection pool. (default: 5)
|
66
|
+
# max_pool_size: 5
|
67
|
+
|
68
|
+
# The minimum number of connections in the connection pool. (default: 1)
|
69
|
+
# min_pool_size: 1
|
70
|
+
|
71
|
+
# The time to wait, in seconds, in the connection pool for a connection
|
72
|
+
# to be checked in before timing out. (default: 5)
|
73
|
+
# wait_queue_timeout: 5
|
74
|
+
|
75
|
+
# The time to wait to establish a connection before timing out, in seconds.
|
76
|
+
# (default: 5)
|
77
|
+
# connect_timeout: 5
|
78
|
+
|
79
|
+
# The timeout to wait to execute operations on a socket before raising an error.
|
80
|
+
# (default: 5)
|
81
|
+
# socket_timeout: 5
|
82
|
+
|
83
|
+
# The name of the replica set to connect to. Servers provided as seeds that do
|
84
|
+
# not belong to this replica set will be ignored.
|
85
|
+
# replica_set: name
|
86
|
+
|
87
|
+
# Whether to connect to the servers via ssl. (default: false)
|
88
|
+
# ssl: true
|
89
|
+
|
90
|
+
# The certificate file used to identify the connection against MongoDB.
|
91
|
+
# ssl_cert: /path/to/my.cert
|
92
|
+
|
93
|
+
# The private keyfile used to identify the connection against MongoDB.
|
94
|
+
# Note that even if the key is stored in the same file as the certificate,
|
95
|
+
# both need to be explicitly specified.
|
96
|
+
# ssl_key: /path/to/my.key
|
97
|
+
|
98
|
+
# A passphrase for the private key.
|
99
|
+
# ssl_key_pass_phrase: password
|
100
|
+
|
101
|
+
# Whether or not to do peer certification validation. (default: true)
|
102
|
+
# ssl_verify: true
|
103
|
+
|
104
|
+
# The file containing a set of concatenated certification authority certifications
|
105
|
+
# used to validate certs passed from the other end of the connection.
|
106
|
+
# ssl_ca_cert: /path/to/ca.cert
|
107
|
+
|
108
|
+
|
109
|
+
# Configure Mongoid specific options. (optional)
|
110
|
+
options:
|
111
|
+
# Includes the root model name in json serialization. (default: false)
|
112
|
+
# include_root_in_json: false
|
113
|
+
|
114
|
+
# Include the _type field in serialization. (default: false)
|
115
|
+
# include_type_for_serialization: false
|
116
|
+
|
117
|
+
# Preload all models in development, needed when models use
|
118
|
+
# inheritance. (default: false)
|
119
|
+
# preload_models: false
|
120
|
+
|
121
|
+
# Raise an error when performing a #find and the document is not found.
|
122
|
+
# (default: true)
|
123
|
+
# raise_not_found_error: true
|
124
|
+
|
125
|
+
# Raise an error when defining a scope with the same name as an
|
126
|
+
# existing method. (default: false)
|
127
|
+
# scope_overwrite_exception: false
|
128
|
+
|
129
|
+
# Raise an error when defining a field with the same name as an
|
130
|
+
# existing method. (default: false)
|
131
|
+
# duplicate_fields_exception: false
|
132
|
+
|
133
|
+
# Use Active Support's time zone in conversions. (default: true)
|
134
|
+
# use_activesupport_time_zone: true
|
135
|
+
|
136
|
+
# Ensure all times are UTC in the app side. (default: false)
|
137
|
+
# use_utc: false
|
138
|
+
|
139
|
+
# Set the Mongoid and Ruby driver log levels when not in a Rails
|
140
|
+
# environment. The Mongoid logger will be set to the Rails logger
|
141
|
+
# otherwise.(default: :info)
|
142
|
+
# log_level: :info
|
143
|
+
|
144
|
+
# Control whether `belongs_to` association is required. By default
|
145
|
+
# `belongs_to` will trigger a validation error if the association
|
146
|
+
# is not present. (default: true)
|
147
|
+
# belongs_to_required_by_default: true
|
148
|
+
|
149
|
+
# Application name that is printed to the mongodb logs upon establishing a
|
150
|
+
# connection in server versions >= 3.4. Note that the name cannot exceed 128 bytes.
|
151
|
+
# app_name: MyApplicationName
|
152
|
+
|
153
|
+
# Use background indexes by default if `background` option not specified. (default: false)
|
154
|
+
# background_indexing: false
|
155
|
+
test:
|
156
|
+
clients:
|
157
|
+
default:
|
158
|
+
database: dummy_test
|
159
|
+
hosts:
|
160
|
+
- localhost:27017
|
161
|
+
options:
|
162
|
+
read:
|
163
|
+
mode: :primary
|
164
|
+
max_pool_size: 1
|
data/spec/dummy/config/routes.rb
CHANGED
data/spec/models/user_spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe User, type: :model do
|
6
|
-
subject
|
6
|
+
subject(:user) { User.create(email: 'mb@geemail.com', password: 'iwantabigmac1') }
|
7
7
|
it 'is valid' do
|
8
8
|
expect(user).to be_valid
|
9
9
|
end
|
@@ -23,11 +23,56 @@ RSpec.describe User, type: :model do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#password' do
|
26
|
-
subject(:user) { User.new(email: 'mb@geemail.com')}
|
26
|
+
subject(:user) { User.new(email: 'mb@geemail.com') }
|
27
27
|
|
28
28
|
it 'is required' do
|
29
29
|
expect(user).to be_invalid
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
describe '#validate_otp_token' do
|
35
|
+
context 'when otp_drift_window is 3 minutes (default)' do
|
36
|
+
let(:user_rotp) { ROTP::TOTP.new(user.otp_auth_secret) }
|
37
|
+
let(:control_time) { Time.now }
|
38
|
+
let(:token_time) { control_time }
|
39
|
+
|
40
|
+
before do
|
41
|
+
Devise.otp_drift_window = 3
|
42
|
+
allow(Time).to receive(:now).and_return(control_time)
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when token's time is 2 minutes before current time" do
|
46
|
+
let(:token_time) { control_time - 2.minutes }
|
47
|
+
|
48
|
+
it do
|
49
|
+
expect(user.validate_otp_token(user_rotp.at(token_time))).to be_falsey
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when token's time is 1 minute before current time" do
|
54
|
+
let(:token_time) { control_time - 1.minute }
|
55
|
+
|
56
|
+
it do
|
57
|
+
expect(user.validate_otp_token(user_rotp.at(token_time))).to be_truthy
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when token's time is 1 minute after current time" do
|
62
|
+
let(:token_time) { control_time + 1.minute }
|
63
|
+
|
64
|
+
it do
|
65
|
+
expect(user.validate_otp_token(user_rotp.at(token_time))).to be_truthy
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when token's time is 2 minutes after current time" do
|
70
|
+
let(:token_time) { control_time + 2.minute }
|
71
|
+
|
72
|
+
it do
|
73
|
+
expect(user.validate_otp_token(user_rotp.at(token_time))).to be_falsey
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
33
78
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
ENV[
|
3
|
+
ENV['RAILS_ENV'] ||= 'test'
|
4
4
|
|
5
|
-
require
|
6
|
-
require "dummy/config/application"
|
5
|
+
require 'dummy/config/application'
|
7
6
|
require 'bundler/setup'
|
8
7
|
require 'rspec/rails'
|
9
8
|
|
@@ -24,6 +23,11 @@ RSpec.configure do |config|
|
|
24
23
|
config.before(:each, type: :system) do
|
25
24
|
driven_by :rack_test
|
26
25
|
end
|
26
|
+
if defined? Mongoid
|
27
|
+
config.before :each do
|
28
|
+
Mongoid.purge!
|
29
|
+
end
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
|
data/spec/system/token_spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe 'Tokens' do
|
6
|
-
subject
|
6
|
+
subject(:user) { User.create(email: 'mb@geemail.com', password: 'iwantabigmac1') }
|
7
7
|
|
8
8
|
it 'can be disabled by a user after successfully enabling' do
|
9
9
|
enable_otp_and_sign_in user
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise-2fa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William A. Todd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '5.1'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '5.1'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rqrcode
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,21 +87,21 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: 4.3.0
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
90
|
+
name: appraisal
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - ">="
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
95
|
+
version: '0'
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: '0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
104
|
+
name: capybara
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - ">="
|
@@ -115,7 +115,7 @@ dependencies:
|
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
118
|
+
name: pry
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
121
|
- - ">="
|
@@ -129,7 +129,7 @@ dependencies:
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
132
|
+
name: rspec
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
135
|
- - ">="
|
@@ -143,7 +143,7 @@ dependencies:
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
|
-
name: rspec
|
146
|
+
name: rspec-rails
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
149
|
- - ">="
|
@@ -157,7 +157,21 @@ dependencies:
|
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '0'
|
159
159
|
- !ruby/object:Gem::Dependency
|
160
|
-
name:
|
160
|
+
name: rspec_junit_formatter
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: selenium-webdriver
|
161
175
|
requirement: !ruby/object:Gem::Requirement
|
162
176
|
requirements:
|
163
177
|
- - ">="
|
@@ -181,6 +195,7 @@ files:
|
|
181
195
|
- ".gitignore"
|
182
196
|
- ".hound.yml"
|
183
197
|
- ".ruby-style.yml"
|
198
|
+
- Appraisals
|
184
199
|
- CHANGELOG.md
|
185
200
|
- Gemfile
|
186
201
|
- LICENSE
|
@@ -217,10 +232,6 @@ files:
|
|
217
232
|
- lib/generators/devise_two_factor/views_generator.rb
|
218
233
|
- lib/generators/mongoid/devise_two_factor_generator.rb
|
219
234
|
- spec/dummy/Rakefile
|
220
|
-
- spec/dummy/app/assets/images/.keep
|
221
|
-
- spec/dummy/app/assets/javascripts/application.js
|
222
|
-
- spec/dummy/app/assets/javascripts/channels/.keep
|
223
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
224
235
|
- spec/dummy/app/controllers/application_controller.rb
|
225
236
|
- spec/dummy/app/controllers/concerns/.keep
|
226
237
|
- spec/dummy/app/helpers/application_helper.rb
|
@@ -253,12 +264,13 @@ files:
|
|
253
264
|
- spec/dummy/config/locales/devise.en.yml
|
254
265
|
- spec/dummy/config/locales/devise.two_factor.en.yml
|
255
266
|
- spec/dummy/config/locales/en.yml
|
267
|
+
- spec/dummy/config/mongoid.yml
|
256
268
|
- spec/dummy/config/puma.rb
|
257
269
|
- spec/dummy/config/routes.rb
|
258
270
|
- spec/dummy/config/spring.rb
|
259
271
|
- spec/dummy/config/storage.yml
|
260
272
|
- spec/dummy/db/migrate/20190311184605_devise_create_users.rb
|
261
|
-
- spec/dummy/db/migrate/
|
273
|
+
- spec/dummy/db/migrate/20190625052821_devise_two_factor_add_to_users.rb
|
262
274
|
- spec/dummy/db/schema.rb
|
263
275
|
- spec/dummy/lib/assets/.keep
|
264
276
|
- spec/dummy/package.json
|
@@ -294,16 +306,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
294
306
|
- !ruby/object:Gem::Version
|
295
307
|
version: '0'
|
296
308
|
requirements: []
|
297
|
-
rubygems_version: 3.0.
|
309
|
+
rubygems_version: 3.0.4
|
298
310
|
signing_key:
|
299
311
|
specification_version: 4
|
300
312
|
summary: Includes ActiveRecord and Mongoid ORM support
|
301
313
|
test_files:
|
302
314
|
- spec/dummy/Rakefile
|
303
|
-
- spec/dummy/app/assets/images/.keep
|
304
|
-
- spec/dummy/app/assets/javascripts/application.js
|
305
|
-
- spec/dummy/app/assets/javascripts/channels/.keep
|
306
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
307
315
|
- spec/dummy/app/controllers/application_controller.rb
|
308
316
|
- spec/dummy/app/controllers/concerns/.keep
|
309
317
|
- spec/dummy/app/helpers/application_helper.rb
|
@@ -336,12 +344,13 @@ test_files:
|
|
336
344
|
- spec/dummy/config/locales/devise.en.yml
|
337
345
|
- spec/dummy/config/locales/devise.two_factor.en.yml
|
338
346
|
- spec/dummy/config/locales/en.yml
|
347
|
+
- spec/dummy/config/mongoid.yml
|
339
348
|
- spec/dummy/config/puma.rb
|
340
349
|
- spec/dummy/config/routes.rb
|
341
350
|
- spec/dummy/config/spring.rb
|
342
351
|
- spec/dummy/config/storage.yml
|
343
352
|
- spec/dummy/db/migrate/20190311184605_devise_create_users.rb
|
344
|
-
- spec/dummy/db/migrate/
|
353
|
+
- spec/dummy/db/migrate/20190625052821_devise_two_factor_add_to_users.rb
|
345
354
|
- spec/dummy/db/schema.rb
|
346
355
|
- spec/dummy/lib/assets/.keep
|
347
356
|
- spec/dummy/package.json
|
File without changes
|
File without changes
|
@@ -1,15 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
-
* listed below.
|
4
|
-
*
|
5
|
-
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
-
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
-
*
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
-
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
-
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
-
* It is generally better to create a new file per style scope.
|
12
|
-
*
|
13
|
-
*= require_tree .
|
14
|
-
*= require_self
|
15
|
-
*/
|