FIX: No error displayed when 2FA token is invalid on admin login page.

This commit is contained in:
Guo Xiang Tan 2018-02-22 09:45:57 +08:00
parent 412b298f55
commit 964624f3ab
3 changed files with 44 additions and 15 deletions

View File

@ -593,8 +593,27 @@ class UsersController < ApplicationController
email_token_user = EmailToken.confirmable(token)&.user email_token_user = EmailToken.confirmable(token)&.user
totp_enabled = email_token_user.totp_enabled? totp_enabled = email_token_user.totp_enabled?
second_factor_token = params[:second_factor_token]
confirm_email = false
if !totp_enabled || email_token_user.authenticate_totp(params[:second_factor_token]) confirm_email =
if totp_enabled
@second_factor_required = true
@message = I18n.t("login.second_factor_title")
if second_factor_token.present?
if email_token_user.authenticate_totp(second_factor_token)
true
else
@error = I18n.t("login.invalid_second_factor_code")
false
end
end
else
true
end
if confirm_email
@user = EmailToken.confirm(token) @user = EmailToken.confirm(token)
if @user && @user.admin? if @user && @user.admin?
@ -603,9 +622,6 @@ class UsersController < ApplicationController
else else
@message = I18n.t("admin_login.errors.unknown_email_address") @message = I18n.t("admin_login.errors.unknown_email_address")
end end
else
@second_factor_required = true
@message = I18n.t("login.second_factor_title")
end end
else else
@message = I18n.t("admin_login.errors.invalid_token") @message = I18n.t("admin_login.errors.invalid_token")

View File

@ -5,13 +5,13 @@
<body> <body>
<% if @message %> <% if @message %>
<%= @message %> <%= @message %>
<% if @second_factor_required %> <% if @error %><p><%= @error %></p><% end %>
<%=form_tag({}, method: :put) do %> <%=form_tag({}, method: :put) do %>
<%= label_tag(:second_factor_token, t('login.second_factor_description')) %> <%= label_tag(:second_factor_token, t('login.second_factor_description')) %>
<%= text_field_tag(:second_factor_token, nil, autofocus: true) %><br><br> <%= text_field_tag(:second_factor_token, nil, autofocus: true) %><br><br>
<%= submit_tag t('submit')%> <%= submit_tag t('submit')%>
<% end %> <% end %>
<% end %>
<% else %> <% else %>
<%=form_tag({}, method: :put) do %> <%=form_tag({}, method: :put) do %>
<%= label_tag(:email, t('admin_login.email_input')) %> <%= label_tag(:email, t('admin_login.email_input')) %>

View File

@ -554,22 +554,35 @@ describe UsersController do
describe 'when 2 factor authentication is enabled' do describe 'when 2 factor authentication is enabled' do
let(:second_factor) { Fabricate(:user_second_factor, user: admin) } let(:second_factor) { Fabricate(:user_second_factor, user: admin) }
let(:email_token) { Fabricate(:email_token, user: admin) }
render_views render_views
it 'does not log in when token required' do it 'does not log in when token required' do
second_factor second_factor
token = admin.email_tokens.create(email: admin.email).token get :admin_login, params: { token: email_token.token }
get :admin_login, params: { token: token }
expect(response).not_to redirect_to('/') expect(response).not_to redirect_to('/')
expect(session[:current_user_id]).not_to eq(admin.id) expect(session[:current_user_id]).not_to eq(admin.id)
expect(response.body).to include(I18n.t('login.second_factor_description')); expect(response.body).to include(I18n.t('login.second_factor_description'));
end end
it 'logs in when a valid 2-factor token is given' do describe 'invalid 2 factor token' do
token = admin.email_tokens.create(email: admin.email).token it 'should display the right error' do
second_factor
put :admin_login, params: { put :admin_login, params: {
token: token, token: email_token.token,
second_factor_token: '13213'
}
expect(response.status).to eq(200)
expect(response.body).to include(I18n.t('login.second_factor_description'));
expect(response.body).to include(I18n.t('login.invalid_second_factor_code'));
end
end
it 'logs in when a valid 2-factor token is given' do
put :admin_login, params: {
token: email_token.token,
second_factor_token: ROTP::TOTP.new(second_factor.data).now second_factor_token: ROTP::TOTP.new(second_factor.data).now
} }