2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-06 10:50:21 +08:00
discourse/spec/controllers/second_factor_controller_spec.rb
Jeff Wong f4f8a293e7 FEATURE: Implement 2factor login TOTP
implemented review items.

Blocking previous codes - valid 2-factor auth tokens can only be authenticated once/30 seconds.
I played with updating the “last used” any time the token was attempted but that seemed to be overkill, and frustrating as to why a token would fail.
Translatable texts.
Move second factor logic to a helper class.
Move second factor specific controller endpoints to its own controller.
Move serialization logic for 2-factor details in admin user views.
Add a login ember component for de-duplication
Fix up code formatting
Change verbiage of google authenticator

add controller tests:
second factor controller tests
change email tests
change password tests
admin login tests

add qunit tests - password reset, preferences

fix: check for 2factor on change email controller
fix: email controller - only show second factor errors on attempt
fix: check against 'true' to enable second factor.

Add modal for explaining what 2fa with links to Google Authenticator/FreeOTP

add two factor to email signin link

rate limit if second factor token present

add rate limiter test for second factor attempts
2018-02-21 09:04:07 +08:00

69 lines
2.1 KiB
Ruby

require 'rails_helper'
RSpec.describe SecondFactorController, type: :controller do
# featheredtoast-todo also write qunit tests.
describe '.create' do
let(:user) { Fabricate(:user) }
describe 'create 2fa request' do
it 'fails on incorrect password' do
post :create, params: {
login: user.username, password: 'wrongpassword'
}, format: :json
expect(JSON.parse(response.body)['error']).to eq(I18n.t("login.incorrect_username_email_or_password"))
end
it 'succeeds on correct password' do
post :create, params: {
login: user.username, password: 'myawesomepassword'
}, format: :json
expect(JSON.parse(response.body).keys).to contain_exactly('key', 'qr')
end
end
end
describe '.update' do
let(:user) { Fabricate(:user) }
context 'when user has totp setup' do
second_factor_data = "rcyryaqage3jexfj"
before do
user.user_second_factor = UserSecondFactor.create(user_id: user.id, method: "totp", data: second_factor_data)
end
it 'errors on incorrect code' do
post :update, params: {
username: user.username,
token: '000000',
enable: 'true'
}, format: :json
expect(JSON.parse(response.body)['error']).to eq(I18n.t("login.invalid_second_factor_code"))
user.reload
end
it 'can be enabled' do
post :update, params: {
username: user.username,
token: ROTP::TOTP.new(second_factor_data).now,
enable: 'true'
}, format: :json
expect(JSON.parse(response.body)['result']).to eq('ok')
user.reload
expect(user.user_second_factor.enabled).to be true
end
it 'can be disabled' do
post :update, params: {
username: user.username,
enable: 'false',
token: ROTP::TOTP.new(second_factor_data).now
}, format: :json
expect(JSON.parse(response.body)['result']).to eq('ok')
user.reload
expect(user.user_second_factor).to be_nil
end
end
end
end