mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 05:43:38 +08:00
9ebabc1de8
Previously we would bypass touching `Topic.updated_at` for whispers and post recovery / deletions. This meant that certain types of caching can not be done where we rely on this information for cache accuracy. For example if we know we have zero unread topics as of yesterday and whisper is made I need to bump this date so the cache remains accurate This is only half of a larger change but provides the groundwork. Confirmed none of our serializers leak out Topic.updated_at so this is safe spot for this info At the moment edits still do not change this but it is not relevant for the unread cache. This commit also cleans up some specs to use the new `eq_time` matcher for millisecond fidelity comparison of times Previously `freeze_time` would fudge this which is not that clean.
195 lines
5.9 KiB
Ruby
195 lines
5.9 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe SecondFactorManager do
|
|
let(:user_second_factor_totp) { Fabricate(:user_second_factor_totp) }
|
|
let(:user) { user_second_factor_totp.user }
|
|
let(:another_user) { Fabricate(:user) }
|
|
|
|
let(:user_second_factor_backup) { Fabricate(:user_second_factor_backup) }
|
|
let(:user_backup) { user_second_factor_backup.user }
|
|
|
|
describe '#totp' do
|
|
it 'should return the right data' do
|
|
totp = nil
|
|
|
|
expect do
|
|
totp = another_user.totp
|
|
end.to change { UserSecondFactor.count }.by(1)
|
|
|
|
expect(totp.issuer).to eq(SiteSetting.title)
|
|
expect(totp.secret).to eq(another_user.reload.user_second_factors.totp.data)
|
|
end
|
|
end
|
|
|
|
describe '#create_totp' do
|
|
it 'should create the right record' do
|
|
second_factor = another_user.create_totp(enabled: true)
|
|
|
|
expect(second_factor.method).to eq(UserSecondFactor.methods[:totp])
|
|
expect(second_factor.data).to be_present
|
|
expect(second_factor.enabled).to eq(true)
|
|
end
|
|
|
|
describe 'when user has a second factor' do
|
|
it 'should return nil' do
|
|
expect(user.create_totp).to eq(nil)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#totp_provisioning_uri' do
|
|
it 'should return the right uri' do
|
|
expect(user.totp_provisioning_uri).to eq(
|
|
"otpauth://totp/#{SiteSetting.title}:#{user.email}?secret=#{user_second_factor_totp.data}&issuer=#{SiteSetting.title}"
|
|
)
|
|
end
|
|
end
|
|
|
|
describe '#authenticate_totp' do
|
|
it 'should be able to authenticate a token' do
|
|
freeze_time do
|
|
expect(user.user_second_factors.totp.last_used).to eq(nil)
|
|
|
|
token = user.totp.now
|
|
|
|
expect(user.authenticate_totp(token)).to eq(true)
|
|
expect(user.user_second_factors.totp.last_used).to eq_time(DateTime.now)
|
|
expect(user.authenticate_totp(token)).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe 'when token is blank' do
|
|
it 'should be false' do
|
|
expect(user.authenticate_totp(nil)).to eq(false)
|
|
expect(user.user_second_factors.totp.last_used).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe 'when token is invalid' do
|
|
it 'should be false' do
|
|
expect(user.authenticate_totp('111111')).to eq(false)
|
|
expect(user.user_second_factors.totp.last_used).to eq(nil)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#totp_enabled?' do
|
|
describe 'when user does not have a second factor record' do
|
|
it 'should return false' do
|
|
expect(another_user.totp_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "when user's second factor record is disabled" do
|
|
it 'should return false' do
|
|
user.user_second_factors.totp.update!(enabled: false)
|
|
expect(user.totp_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "when user's second factor record is enabled" do
|
|
it 'should return true' do
|
|
expect(user.totp_enabled?).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe 'when SSO is enabled' do
|
|
it 'should return false' do
|
|
SiteSetting.sso_url = 'http://someurl.com'
|
|
SiteSetting.enable_sso = true
|
|
|
|
expect(user.totp_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe 'when local login is disabled' do
|
|
it 'should return false' do
|
|
SiteSetting.enable_local_logins = false
|
|
|
|
expect(user.totp_enabled?).to eq(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'backup codes' do
|
|
describe '#generate_backup_codes' do
|
|
it 'should generate and store 10 backup codes' do
|
|
backup_codes = user.generate_backup_codes
|
|
|
|
expect(backup_codes.length).to be 10
|
|
expect(user_backup.user_second_factors.backup_codes).to be_present
|
|
expect(user_backup.user_second_factors.backup_codes.pluck(:method).uniq[0]).to eq(UserSecondFactor.methods[:backup_codes])
|
|
expect(user_backup.user_second_factors.backup_codes.pluck(:enabled).uniq[0]).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe '#create_backup_codes' do
|
|
it 'should create 10 backup code records' do
|
|
raw_codes = Array.new(10) { SecureRandom.hex(8) }
|
|
backup_codes = another_user.create_backup_codes(raw_codes)
|
|
|
|
expect(another_user.user_second_factors.backup_codes.length).to be 10
|
|
end
|
|
end
|
|
|
|
describe '#authenticate_backup_code' do
|
|
it 'should be able to authenticate a backup code' do
|
|
backup_code = "iAmValidBackupCode"
|
|
|
|
expect(user_backup.authenticate_backup_code(backup_code)).to eq(true)
|
|
expect(user_backup.authenticate_backup_code(backup_code)).to eq(false)
|
|
end
|
|
|
|
describe 'when code is blank' do
|
|
it 'should be false' do
|
|
expect(user_backup.authenticate_backup_code(nil)).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe 'when code is invalid' do
|
|
it 'should be false' do
|
|
expect(user_backup.authenticate_backup_code("notValidBackupCode")).to eq(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#backup_codes_enabled?' do
|
|
describe 'when user does not have a second factor backup enabled' do
|
|
it 'should return false' do
|
|
expect(another_user.backup_codes_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "when user's second factor backup codes have been used" do
|
|
it 'should return false' do
|
|
user_backup.user_second_factors.backup_codes.update_all(enabled: false)
|
|
expect(user_backup.backup_codes_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "when user's second factor code is available" do
|
|
it 'should return true' do
|
|
expect(user_backup.backup_codes_enabled?).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe 'when SSO is enabled' do
|
|
it 'should return false' do
|
|
SiteSetting.sso_url = 'http://someurl.com'
|
|
SiteSetting.enable_sso = true
|
|
|
|
expect(user_backup.backup_codes_enabled?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe 'when local login is disabled' do
|
|
it 'should return false' do
|
|
SiteSetting.enable_local_logins = false
|
|
|
|
expect(user_backup.backup_codes_enabled?).to eq(false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|