mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
Add ability to require 2FA for specific roles (including Everybody) (#37701)
This commit is contained in:
@@ -13,16 +13,19 @@ RSpec.describe 'Log in' do
|
||||
|
||||
before do
|
||||
as_a_registered_user
|
||||
visit new_user_session_path
|
||||
end
|
||||
|
||||
it 'A valid email and password user is able to log in' do
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in_auth_details(email, password)
|
||||
|
||||
expect(subject).to have_css('div.app-holder')
|
||||
end
|
||||
|
||||
it 'A invalid email and password user is not able to log in' do
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in_auth_details('invalid_email', 'invalid_password')
|
||||
|
||||
expect(subject).to have_css('.flash-message', text: /#{failure_message_invalid}/i)
|
||||
@@ -32,12 +35,53 @@ RSpec.describe 'Log in' do
|
||||
let(:confirmed_at) { nil }
|
||||
|
||||
it 'A unconfirmed user is able to log in' do
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in_auth_details(email, password)
|
||||
|
||||
expect(subject).to have_css('.title', text: I18n.t('auth.setup.title'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user role requires 2FA' do
|
||||
before do
|
||||
bob.role.update!(require_2fa: true)
|
||||
end
|
||||
|
||||
context 'when the user has not configured 2FA' do
|
||||
it 'they are redirected to 2FA setup' do
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in_auth_details(email, password)
|
||||
|
||||
expect(subject).to have_no_css('div.app-holder')
|
||||
expect(subject).to have_title(I18n.t('settings.two_factor_authentication'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user has configured 2FA' do
|
||||
before do
|
||||
bob.update!(otp_required_for_login: true, otp_secret: User.generate_otp_secret)
|
||||
end
|
||||
|
||||
it 'they are able to log in' do
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in_auth_details(email, password)
|
||||
fill_in_otp_details(bob.current_otp)
|
||||
|
||||
expect(subject).to have_css('div.app-holder')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fill_in_otp_details(value)
|
||||
fill_in 'user_otp_attempt', with: value
|
||||
click_on I18n.t('auth.login')
|
||||
end
|
||||
|
||||
def failure_message_invalid
|
||||
keys = User.authentication_keys.map { |key| User.human_attribute_name(key) }
|
||||
I18n.t('devise.failure.invalid', authentication_keys: keys.join('support.array.words_connector'))
|
||||
|
||||
@@ -121,6 +121,46 @@ RSpec.describe 'Using OAuth from an external app' do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user has yet to enable TOTP' do
|
||||
let(:new_otp_secret) { ROTP::Base32.random(User.otp_secret_length) }
|
||||
|
||||
before do
|
||||
allow(User).to receive(:generate_otp_secret).and_return(new_otp_secret)
|
||||
user.role.update!(require_2fa: true)
|
||||
end
|
||||
|
||||
it 'when accepting the authorization request' do
|
||||
subject
|
||||
|
||||
# It presents the user with the 2FA setup page
|
||||
expect(page).to have_content(I18n.t('two_factor_authentication.role_requirement', domain: local_domain_uri.host))
|
||||
click_on I18n.t('otp_authentication.setup')
|
||||
|
||||
# Fill in challenge form
|
||||
fill_in 'form_challenge_current_password', with: user.password
|
||||
click_on I18n.t('challenge.confirm')
|
||||
|
||||
# It presents the user with the TOTP confirmation screen
|
||||
expect(page).to have_title(I18n.t('settings.two_factor_authentication'))
|
||||
|
||||
fill_in 'form_two_factor_confirmation_otp_attempt', with: ROTP::TOTP.new(new_otp_secret).at(Time.now.utc)
|
||||
click_on I18n.t('otp_authentication.enable')
|
||||
|
||||
# It presents the user with recovery codes
|
||||
click_on I18n.t('two_factor_authentication.resume_app_authorization')
|
||||
|
||||
# It presents the user with an authorization page
|
||||
expect(page).to have_content(oauth_authorize_text)
|
||||
|
||||
# It grants the app access to the account
|
||||
expect { click_on oauth_authorize_text }
|
||||
.to change { user_has_grant_with_client_app? }.to(true)
|
||||
|
||||
# Upon authorizing, it redirects to the apps' callback URL
|
||||
expect(page).to redirect_to_callback_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user