houdini / two_factor_authentication Goto Github PK
View Code? Open in Web Editor NEWTwo factor authentication extension for Devise
License: MIT License
Two factor authentication extension for Devise
License: MIT License
Hi,
Is there a way, to skip the 2FA if a user, in example has a specific role or other stuff?
So, I dont want to force 2FA when logging in, when the user is "Admin".
Thanks in advance
Regards
I implemented an auto-unlock mechanism to avoid admin interventions.
It adds an options to set how long will the account be locked. The default being 0, meaning no auto unlock.
I based it on a fork that works with mongoid, which removed the specs.
Let me know if you'd be interested in including this here, so I'll write the according specs.
Hi, thanks for the awesome lib. This strikes me as a very noob question, but after diving into your code and checking many options I'm filing an issue as a last resource.
The problem I'm having is that some non-devise controllers are passing through the two-factor flow even though they shouldn't. Here's my setup:
head -1 app/controllers/api/base_controller.rb:
class Api::BaseController < ActionController::Base
head -1 app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
When a test is ran through RSpec it fails with the following stack trace:
ERROR -- : undefined method `authenticate?' for nil:NilClass (NoMethodError)
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/devise-3.4.1/lib/devise/controllers/sign_in_out.rb:10:in `block in signed_in?'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/devise-3.4.1/lib/devise/controllers/sign_in_out.rb:9:in `each'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/devise-3.4.1/lib/devise/controllers/sign_in_out.rb:9:in `any?'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/devise-3.4.1/lib/devise/controllers/sign_in_out.rb:9:in `signed_in?'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/two_factor_authentication-1.1.5/lib/two_factor_authentication/controllers/helpers.rb:15:in `block in handle_two_factor_authentication'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/two_factor_authentication-1.1.5/lib/two_factor_authentication/controllers/helpers.rb:14:in `each'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/two_factor_authentication-1.1.5/lib/two_factor_authentication/controllers/helpers.rb:14:in `any?'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/two_factor_authentication-1.1.5/lib/two_factor_authentication/controllers/helpers.rb:14:in `handle_two_factor_authentication'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:429:in `block in make_lambda'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:161:in `call'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:161:in `block in halting'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:501:in `call'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:501:in `block in call'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:501:in `each'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:501:in `call'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/callbacks.rb:86:in `run_callbacks'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/abstract_controller/callbacks.rb:19:in `process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/metal/rescue.rb:29:in `process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/notifications.rb:159:in `block in instrument'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.1.12/lib/active_support/notifications.rb:159:in `instrument'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.1.12/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/abstract_controller/base.rb:136:in `process'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionview-4.1.12/lib/action_view/rendering.rb:30:in `process'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/test_case.rb:595:in `process'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/test_case.rb:64:in `process'
.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/actionpack-4.1.12/lib/action_controller/test_case.rb:495:in `get'
dev/spec/controllers/api_controller_spec.rb:98:in `block (3 levels) in <top (required)>'
The test goes something like this:
require 'rails_helper'
require 'factory_girl_rails'
require 'securerandom'
RSpec.describe Api::LoginController, :type => :controller do
context "login" do
it "logs in" do
post :authenticate, {username: "...", password: "..."}
expect(response.status).to eq(200)
end
end
end
The reason is that the condition unless devise_controller?
in handle_two_factor_authentication
method is positive, so it enters the flow.
Am I doing something wrong?
How can I bypass the two-factor validation for non-devise controllers?
Thanks in advance.
There's no way to hide this message "Two factor authentication successful."
Hey! Does this work with the most recent version of Devise and rails?
Hi
Great plugin, thanks.
Just one comment, it might be worth including in your readme that you need a relevant wordlist on your computer.
Otherwise the code generation fails with no error, no emails etc.
Just had this issue going from dev to pro.
Finally, working through things in the console, I found
User.first.generate_two_factor_code
RuntimeError: Words file not found. Check if it is installed in (/usr/share/dict/words or /usr/dict/words)
Which was easily fixed installing the list via apt:
apt-get install wbritish (or whichever you require)
Is there any way you could backport this commit: fd7e18c to 1.x? 2.x seems to have been in progress for a while and it'd be nice to be Rails 5 compatible in the meantime.
I am trying to improve my user experience by only asking for the 2nd factor for specific controlls / actions. Could someone provide me an idea on how to get this done?
In the docs, there's a method:
def need_two_factor_authentication?(request)
request.ip != '127.0.0.1'
end
However, I can't seem to access the current user from here. How do I check for a boolean (two_factor_auth) on the user model to see if they have two-factor auth enabled? Do I just use .self? I inspected the request variable and it's massive, but maybe there's something in there?
Thanks for your time!
When a user sign up, his login straight and two factor authentication is not call. thou its working for session
Just wondering what would be the best way to hook this into activeadmin for an admin user?
I'm getting this error as if the code isn't being passed to the method:
Completed 500 Internal Server Error in 193ms (ActiveRecord: 5.9ms)
ArgumentError (wrong number of arguments (0 for 1)):
-> def send_two_factor_authentication_code(code)
app/models/user.rb:124:in `send_two_factor_authentication_code'
Any ideas what might cause this?
i am getting the following error when i added the config values in the devise
undefined method
delete_cookie_on_logout=' for Devise:Module (NoMethodError)`. Can you please help me on this?
If the two-factor authentication is turned on, the user can still navigate to the edit registration path and update the information.
When I add recoverable to my user model and try to have a user go through the Devise password recovery workflow, the after_authentication callback is never executed. It seems like this is how Devise decides to handle the login callbacks. But that means that when I recover a user password, the user does not get the code.
This is very similar to my situation, but in more generic terms:
https://groups.google.com/forum/#!topic/plataformatec-devise/30oxTAWHdSs
Any thoughts?
it is calling send_two_factor_authentication_code method and sending sms on each login, how can we ignore to send sms once it is verified on a computer?
Right now the gemspec does not lock encryptor down to 2.0.0 and the encryptor gem recently had a release to 3.0.0 because of a security issue. The fix in 3.0.0 seems to break this gem. Here is the text that the encryptor gem has up on their README:
A bug was discovered in Encryptor 2.0.0 wherein the IV was not being used when using an AES--GCM algorithm. Unfornately fixing this major security issue results in the inability to decrypt records encrypted using an AES--GCM algorithm from Encryptor v2.0.0. While the behavior change is minimal between v2.0.0 and v3.0.0, the change has a significant impact on users that used v2.0.0 and encrypted data using an AES--GCM algorithm, which is the default algorithm for v2.0.0. Consequently, we decided to increment the version with a major bump to help people avoid a confusing situation where some of their data will not decrypt. A new option is available in Encryptor 3.0.0 that allows decryption of data encrypted using an AES--GCM algorithm from Encryptor v2.0.0.
It appears this gem is affected by this issue, because even though it specifies 'aes-256-cbc' when getting an iv, it does not specify an algorithm when calling encrypt or decrypt.
Any ideas on the best way around this at this point?
It would appear that the changes added in 1.1.5 are a little more significant than a patch level change. Support for ruby 1.9.3 is dropped and the addition of the Encryptor gem will break functionality for any anyone who has a custom Encryptor lib, such as myself. What was the reasoning for not making this a 1.2 release? It seems like it might have been better suited for a 1.2 as existing functionality breaks with the changes 1.1.5, which should not be the case with patch level changes.
I integrated the Houdini two factor authentication with existing rails application.
First I doesn't have any custom sessions_controller then the two_factor_authentication is working fine.
But whereas I written custom create action in Sessions Controller then it doesn't authenticated by two_factor_authentication.
Here is the custom code for create action of Sessions Controller.
if status_response.nil?
render :file => 'public/api_not_found.html', :status => :not_found, :layout => false
else
if status_response['code'].to_i == 1
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
flash[:alert] = 'Invalid Email ID or password.'
yield if block_given?
respond_to_on_destroy
else
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
end
Model code of user.rb:
devise :two_factor_authenticatable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, password_length: 8..30
has_one_time_password
def send_two_factor_authentication_code
puts ">>>>>>>>>>>>>>> otp_secret_key: #{otp_secret_key}, otp_code: #{otp_code}"
end
I know if we are customizing the create action of Sessions Controller then we should call the two_factor_authentication. I tried to invoke this in controller but it throws an error.
So my question how should i integrate the two_factor_authentication with custom create action of Session Controller?
Hi there,
I noticed today that the command:
bundle exec rails g two_factor_authentication MODEL
Does not seem to end the migtation in the .rb extension meaning that I had to add this manually before rake db:migrate would run the migration.
This is on Rails 4.1.5 and Devise 3.3.0
Not a huge issue I wouldn't suspect but you can replicate this in a new rails project by running the following commands:
rails new twofa
cd twofa
# Add 'devise' and 'two_factor_authentication' to Gemfile
bundle install
rails generate devise:install
rails generate devise User
rails g two_factor_authentication User
=>
โ twofa bundle exec rails g two_factor_authentication User
insert app/models/user.rb
invoke active_record
create db/migrate/20140922160755_two_factor_authentication_add_to_users
I'd like to suggest a more consistent naming convention to replace the new totp_timestamp
column in preparation for v2.0. A better name would be something like last_otp_at
. This would better match Rails naming conventions, it would better coincide with direct_otp_sent_at
, and this would match rotp's recommendation.
I'm happy to provide a pull-request for this, but I'd like to get some sense that it's likely to be accepted first and/or if it interests others that use this library.
I have followed all the instructions and I am getting this error.
After I hit sign in I get
No route matches [PATCH] "/admin_users/sign_in"
Just to mention that there are two good practices that are missing in this library. Worth considering their implementation to improve security.
First one is required by RFC 6238 - authentication code once accepted must not be accepted twice (i.e. again). This requires additional field in DB.
Second one is a best practice, also recommended by RFC 6238 - encrypt security key in DB. The encryption key must not be stored in DB. One-way hash functions like scrypt cannot be used for TOTP, but simple encryption would suffice.
(Also note there is by mistake used term "authorisation" in README.)
I followed the read me of this gem. Installed gem, generated it and made sure :two_factor_authenticatable is added in my user model. Not sure why I am getting the devise wrong number of arguments error only when :two_factor_authenticatable is added to user model. Could you please guide me on this.
I'm having an issue with 3 config options in my app. The following 3 config options cause "undefined method..." errors:
config.direct_otp_valid_for
config.direct_otp_length
config.second_factor_resource_id
Commenting out those three lines in my devise.rb initializer file allows the app to start, but I'm not sure if this breaks anything. Will look into it further.
Here's the full error message I get when starting the server:
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Exiting
/Users/dude/Work/myapp/config/initializers/devise.rb:338:in `block in <top (required)>': undefined method `second_factor_resource_id=' for Devise:Module (NoMethodError)
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/devise-4.2.0/lib/devise.rb:292:in `setup'
from /Users/dude/Work/myapp/config/initializers/devise.rb:3:in `<top (required)>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `block in load'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/engine.rb:648:in `block in load_config_initializer'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/activesupport-5.0.0.1/lib/active_support/notifications.rb:166:in `instrument'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/engine.rb:647:in `load_config_initializer'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/engine.rb:612:in `block (2 levels) in <class:Engine>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/engine.rb:611:in `each'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/engine.rb:611:in `block in <class:Engine>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:30:in `instance_exec'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:30:in `run'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:55:in `block in run_initializers'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:420:in `block (2 levels) in each_strongly_connected_component_from'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:419:in `block in each_strongly_connected_component_from'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:44:in `each'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:44:in `tsort_each_child'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:413:in `call'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:413:in `each_strongly_connected_component_from'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `call'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
from /Users/dude/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/initializable.rb:54:in `run_initializers'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/application.rb:352:in `initialize!'
from /Users/dude/Work/myapp/config/environment.rb:5:in `<top (required)>'
from /Users/dude/Work/myapp/config.ru:3:in `require_relative'
from /Users/dude/Work/myapp/config.ru:3:in `block in <main>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/builder.rb:55:in `instance_eval'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/builder.rb:55:in `initialize'
from /Users/dude/Work/myapp/config.ru:in `new'
from /Users/dude/Work/myapp/config.ru:in `<main>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/builder.rb:49:in `eval'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/builder.rb:49:in `new_from_string'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/builder.rb:40:in `parse_file'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/server.rb:318:in `build_app_and_options_from_config'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/server.rb:218:in `app'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/server.rb:59:in `app'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/rack-2.0.1/lib/rack/server.rb:353:in `wrapped_app'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/server.rb:124:in `log_to_stdout'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/server.rb:77:in `start'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:90:in `block in server'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:85:in `tap'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:85:in `server'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/railties-5.0.0.1/lib/rails/commands.rb:18:in `<top (required)>'
from /Users/dude/Work/myapp/bin/rails:9:in `require'
from /Users/dude/Work/myapp/bin/rails:9:in `<top (required)>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/client/rails.rb:28:in `load'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/client/rails.rb:28:in `call'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/client/command.rb:7:in `call'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/client.rb:30:in `run'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/bin/spring:49:in `<top (required)>'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/binstub.rb:11:in `load'
from /Users/dude/.rvm/gems/ruby-2.2.2/gems/spring-1.7.2/lib/spring/binstub.rb:11:in `<top (required)>'
from /Users/dude/Work/myapp/bin/spring:13:in `require'
from /Users/dude/Work/myapp/bin/spring:13:in `<top (required)>'
from bin/rails:3:in `load'
from bin/rails:3:in `<main>'
Any ideas? Or advice?
Thanks for your time!
Was unable to find recovery code functionality (like Github). Was seeing if that would fit under the scope of the gem and be ok to add?
If so I'm able to work on/propose an implementation.
I'm having difficulty with Google Auth for some users. SMS codes work fine, but integrating the gem with Google Auth, not so much. I've attempted it with the bar code and manual entry, but neither work. Has anyone else had this issue. I've also tried syncing the time. Still no go.
When add
config.delete_cookie_on_logout = true
it's appear exception:
Uncaught exception: undefined method 'delete_cookie_on_logout=' for Devise:Module
Thank you.
has this been pushed as a gem?
I used this post as a guide for implementing this gem into an existing app that uses Devise and I'm getting the error from the title when I update a user to enable two factor auth, specifically on the user.provisioning_uri line of the following helper:
def google_authenticator_qrcode(user)
data = user.provisioning_uri
data = Rack::Utils.escape(data)
url = "https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl=#{data}"
return image_tag(url, :alt => 'Google Authenticator QRCode')
end
Which is called from /users/registrations/confirm_two_factor_authentication.html.erb:
<%= google_authenticator_qrcode(resource) %>
Which the user is redirected to via my overridden after_update_path_for(resource)
.
Do I need to do anything specific to set the encrypted_otp_secret_x
columns for the existing users?
TIA
Looks like the changes introduced here, to allow scoped views, was not released with the gem update.
Hello. Is a way to apply two_factor_authentication configurations specific to resource type?
I'm trying to give different values to remember_otp_session_for_seconds
for admin
resource and user
.
Maybe there should be an option in the accounts view where users can enable two factor IF they want to.
Basically I would function something like the authy gem. https://github.com/authy/authy-devise There are some views create
, verify
, disable
and 2fa
. Basically if the user wants to enable 2fa to their account, they go to the create
view. There they can ask for a SMS or (google auth) QR code. Then they press a button: Send SMS or GA
, which takes them to the next page, verify
. There, they can input the SMS code or the GA code. That enables 2fa to the account. The next time the person logs in, they are forwarded to the 2fa
view, where they are able to put a GA code or ask for a SMS. Then finally, if they go to disable
, they can ask for a SMS or put in a GA code to disable 2fa for the account.
The names of views should be changeable.
This would be a REALLY great addition to the plugin!
Our app happily gives the data away without second factor if you just ask it for JSON.
Hi
Im running my app in production, and getting this error:
NoMethodError (undefined method `scan' for nil:NilClass):
app/models/user.rb:39:in `send_two_factor_authentication_code'
My method in the user model is:
def send_two_factor_authentication_code
# use Model#otp_code and send via SMS, etc.
#puts ">>>>>>>>>>>>>>>>>>>>>>>> otp_secret_key: #{otp_secret_key}, otp_code: #{otp_code}"
UserMailer.one_time_password(self).deliver
end
def one_time_password(user)
@user = user
mail :to => user.email, :subject => "Engangskodeord"
end
This only occurs on my production server, not on my Macbook in production or anywhere else.
Hello,
These configurations, should they go to rails application.rb
environment.rb
or devise.rb
config.max_login_attempts = 3 # Maximum second factor attempts count
config.allowed_otp_drift_seconds = 30 # Allowed time drift
config.otp_length = 6 # OTP code length
config.remember_otp_session_for_seconds = 30.days # Time before browser has to enter OTP code again
Hi
Is it possible to override the views that this gem provides?
I want to change the text to another language, since the site it is used at is not in english.
Regards
Logs
rails g two_factor_authentication User --trace
insert app/models/user.rb
error mongoid [not found]
Hello and thank you for this gem!
If a user makes too many login attempts, goes back to the login page and logs in again, send_two_factor_authentication_code
is still called, so the user gets a code although he can't enter it.
This can be easily avoided in send_two_factor_authentication_code
but I think it shouldn't be called at all.
I created a test case and offer a solution here.
I sadly can't make a PR as I already forked a fork of this repository (...), and that means I can't fork the root repository.
Steps to reproduce:
Expected Result: OTP should no longer be valid since a new one was generated. There should only ever be one valid OTP at any given time
Actual Result: The old OTP is considered valid and the user is able to fully authenticate
In the Upgrading from version 1.X to 2.X section of the README file, I don't understand this sentence:
The otp_secret_key is not only required for users who use Google Authentictor, so unless it has been shared with the user it should be set to nil.
I'm happy to help reword it, but I need to understand better what the condition is for setting the property to nil.
Thank you.
What should I define? Can't find in the readme. The error message is not useful at all.
Hi,
I need to allow my users to update a setting even without entering 2fa code ....
i need to allow my users to view or perform certain actions without providing 2fa code ... Could you please provide a possible solution ?
Hi
I am already using attr_encrypted gem. I want to use two_factor_authentication gem.
But I get the following error whenever user is saved:
ArgumentError - wrong number of arguments (2 for 1):
attr_encrypted (1.3.4) lib/attr_encrypted.rb:143:in `block (2 levels) in attr_encrypted'
Is two_factor_authentication gem supposed to work well with 'attr_encrypted', '~> 1.3.4' gem?
Thanks for this gem! In our app, we need to be able to perform certain actions after sign in, but before the OTP is sent to the User. But because the Warden::Manager.after_authentication
block is hardcoded in the gem, we can't customize it.
I propose moving that block into a separate initializer that can be placed in the app's config/initializers
directory via the generator. That way, it can easily be customized if desired.
Would you be open to a pull request that does this? Or do you have thoughts about other ways to solve this?
Hi,
I'm receiving this error message when I try to test entering a wrong code, any thoughts?
NoMethodError in Devise::TwoFactorAuthenticationController#update
undefined method `find_message' for #Devise::TwoFactorAuthenticationController:0x007f8f0e051eb0
Or is it possible to generate the controller or views and modify them like Devise does?
Thanks,
I'm using Twilio to send the OTP code to the user's phone. So I wrote my own send_two_factor_authentication_code method, but it doesn't get called. This is what I have in my user.rb file:
def send_two_factor_authentication_code(code)
# put your own credentials here
account_sid = ENV['TWILIO_SID']
auth_token = ENV['TWILIO_TOKEN']
number = "+1" + current_user.profile.phone
# set up a client to talk to the Twilio REST API
@client = Twilio::REST::Client.new account_sid, auth_token
@client.messages.create(
from: '+1xxx3607217',
to: number,
body: code
)
logger.info "Code sent."
end
Everything else seems to be working. I get to the page where you're asked to enter the code, but this one method simply is not called, so, no code is sent. I have Twilio working in other parts of my app, so I know that's not the problem.
Hi,
first thanks for making this great gem :)
After resetting cookies.signed[TwoFactorAuthentication::REMEMBER_TFA_COOKIE_NAME]
the Devise::TwoFactorAuthenticationController#update
produces the exception uninitialized constant Devise::VERSION
in line 33 if Devise::VERSION.to_f >= 4.2
. I'm using Rails 5 and Devise 4.2.0.
Trace:
/bundle/bundler/gems/two_factor_authentication-40fb11b069ddcontrollers/devise/two_factor_authentication_controller.rb:33:in `after_two_factor_success_for'
/bundle/bundler/gems/two_factor_authentication-40fb11b069ddcontrollers/devise/two_factor_authentication_controller.rb:14:in `update'
actionpack (5.0.0) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.0) lib/abstract_controller/base.rb:188:in `process_action'
actionpack (5.0.0) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
...
PR with fix: #115
I need to to authenticate a user is two-step authenticated or not.
As in simple devise we had a method like
authenticate_user!
I need to set this in before_action filter.
Can we have similar method for two-factor-authentication?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.