From de9e1c3bad18e4ca00cfdced75e5cc4c42905761 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 31 Mar 2015 04:19:01 +0300 Subject: [PATCH] Turn 2-factor authentication into 2 steps process. Disabled 2fa UI for ldap users since it is not supported --- app/controllers/application_controller.rb | 2 +- app/controllers/sessions_controller.rb | 24 ++++++++++++++ app/views/devise/sessions/_new_base.html.haml | 4 +-- .../devise/sessions/two_factor.html.haml | 16 ++++++++++ app/views/profiles/accounts/show.html.haml | 31 ++++++++++--------- 5 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 app/views/devise/sessions/two_factor.html.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index eee10d6c22a..247f5cc32d3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -252,7 +252,7 @@ class ApplicationController < ActionController::Base end def configure_permitted_parameters - devise_parameter_sanitizer.sanitize(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me) } + devise_parameter_sanitizer.sanitize(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me, :otp_attempt) } end def hexdigest(string) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 3f11d7afe6f..68cd02b2d79 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,4 +1,6 @@ class SessionsController < Devise::SessionsController + prepend_before_filter :two_factor_enabled?, only: :create + def new redirect_path = if request.referer.present? && (params['redirect_to_referer'] == 'yes') @@ -34,4 +36,26 @@ class SessionsController < Devise::SessionsController end end end + + private + + def two_factor_enabled? + user_params = params[:user] + @user = User.by_login(user_params[:login]) + + if user_params[:otp_attempt].present? + unless @user.valid_otp?(user_params[:otp_attempt]) + @error = 'Invalid two-factor code' + render :two_factor and return + end + else + if @user && @user.valid_password?(params[:user][:password]) + self.resource = @user + + if resource.otp_required_for_login + render :two_factor and return + end + end + end + end end diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 4ecb74fb56e..dcb989e8d81 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,7 +1,7 @@ = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" - = f.password_field :password, class: "form-control middle", placeholder: "Password" - = f.text_field :otp_attempt, class: 'form-control bottom', placeholder: 'Two-factor authentication token' + = f.password_field :password, class: "form-control bottom", placeholder: "Password" + = f.hidden_field :otp_attempt, value: '' - if devise_mapping.rememberable? .remember-me.checkbox %label{for: "user_remember_me"} diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml new file mode 100644 index 00000000000..3a19e926b6d --- /dev/null +++ b/app/views/devise/sessions/two_factor.html.haml @@ -0,0 +1,16 @@ +%div + .login-box + .login-heading + %h3 Two-Factor Authentication + .login-body + = form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f| + - if @error + .alert.alert-danger + = @error + .hide + = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" + = f.password_field :password, class: "form-control bottom", placeholder: "Password" + = f.text_field :otp_attempt, class: 'form-control', + placeholder: 'Two-factor authentication token', required: true, autofocus: true + .prepend-top-20 + = f.submit "Verify code", class: "btn btn-save" diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 19b0c5bcb41..dcce29a81f4 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -26,21 +26,22 @@ %span You don`t have one yet. Click generate to fix it. = f.submit 'Generate', class: "btn success btn-build-token" - %fieldset - %legend Two-Factor Authentication - %p - Keep your account secure by enabling two-factor authentication. - %br - Each time you log in, you’ll be required to provide your password plus a randomly generated access code. - %div - - if current_user.otp_required_for_login - %strong.text-success - %i.fa.fa-check - 2-Factor Authentication enabled - .pull-right - = link_to "Disable 2-Factor Authentication", profile_two_factor_auth_path, method: :delete, class: 'btn btn-close btn-sm' - - else - = link_to "Enable 2-Factor Authentication", new_profile_two_factor_auth_path, class: 'btn btn-success' + - unless current_user.ldap_user? + %fieldset + %legend Two-Factor Authentication + %p + Keep your account secure by enabling two-factor authentication. + %br + Each time you log in, you’ll be required to provide your password plus a randomly generated access code. + %div + - if current_user.otp_required_for_login + %strong.text-success + %i.fa.fa-check + 2-Factor Authentication enabled + .pull-right + = link_to "Disable 2-Factor Authentication", profile_two_factor_auth_path, method: :delete, class: 'btn btn-close btn-sm' + - else + = link_to "Enable 2-Factor Authentication", new_profile_two_factor_auth_path, class: 'btn btn-success' - if show_profile_social_tab? %fieldset