Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/models/auth_app_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def mfa_enabled?

def selection_presenters
if mfa_enabled?
[TwoFactorAuthentication::AuthAppSelectionPresenter.new(user:, configuration: self)]
[TwoFactorAuthentication::SignInAuthAppSelectionPresenter.new(user:, configuration: self)]
else
[]
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module TwoFactorAuthentication
class AuthAppSelectionPresenter < SelectionPresenter
class SetUpAuthAppSelectionPresenter < SetUpSelectionPresenter
def method
:auth_app
end
Expand All @@ -8,4 +8,4 @@ def mfa_configuration_count
user.auth_app_configurations.count
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module TwoFactorAuthentication
class SetUpSelectionPresenter
include ActionView::Helpers::TranslationHelper

attr_reader :user

def initialize(user:)
@user = user
end

def render_in(view_context, &block)
view_context.capture(&block)
end

def type
method.to_s
end

def label
case type
when 'auth_app'
Comment thread
mdiarra3 marked this conversation as resolved.
Outdated
t('two_factor_authentication.two_factor_choice_options.auth_app')
when 'backup_code'
t('two_factor_authentication.two_factor_choice_options.backup_code')
when 'piv_cac'
t('two_factor_authentication.two_factor_choice_options.piv_cac')
when 'phone'
t('two_factor_authentication.two_factor_choice_options.phone')
when 'sms'
t('two_factor_authentication.two_factor_choice_options.sms')
when 'voice'
t('two_factor_authentication.two_factor_choice_options.voice')
when 'webauthn'
t('two_factor_authentication.two_factor_choice_options.webauthn')
when 'webauthn_platform'
t('two_factor_authentication.two_factor_choice_options.webauthn_platform')
else
raise "Unsupported setup method: #{type}"
end
end

def info
case type
when 'auth_app'
t('two_factor_authentication.two_factor_choice_options.auth_app_info')
when 'backup_code'
t('two_factor_authentication.two_factor_choice_options.backup_code_info')
when 'piv_cac'
t('two_factor_authentication.two_factor_choice_options.piv_cac_info')
when 'webauthn'
t('two_factor_authentication.two_factor_choice_options.webauthn_info')
when 'webauthn_platform'
t(
'two_factor_authentication.two_factor_choice_options.webauthn_platform_info',
app_name: APP_NAME,
)
else
raise "Unsupported setup method: #{type}"
end
end

def mfa_added_label
if single_configuration_only?
''
else
"(#{mfa_configuration_description})"
end
end

def single_configuration_only?
false
end

def mfa_configuration_count
0
end

def mfa_configuration_description
return '' if mfa_configuration_count == 0
if single_configuration_only?
t('two_factor_authentication.two_factor_choice_options.no_count_configuration_added')
else
t(
'two_factor_authentication.two_factor_choice_options.configurations_added',
count: mfa_configuration_count,
)
end
end

def disabled?
single_configuration_only? && mfa_configuration_count > 0
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module TwoFactorAuthentication
class SignInAuthAppSelectionPresenter < SignInSelectionPresenter
def method
:auth_app
end
end
end
Comment thread
mdiarra3 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module TwoFactorAuthentication
class SignInSelectionPresenter
include ActionView::Helpers::TranslationHelper

attr_reader :configuration, :user

def initialize(user:, configuration:)
@user = user
@configuration = configuration
end

def render_in(view_context, &block)
view_context.capture(&block)
end

def type
method.to_s
end

def label
case type
when 'auth_app'
t('two_factor_authentication.login_options.auth_app')
when 'backup_code'
t('two_factor_authentication.login_options.backup_code')
when 'personal_key'
t('two_factor_authentication.login_options.personal_key')
when 'piv_cac'
t('two_factor_authentication.login_options.piv_cac')
when 'sms'
t('two_factor_authentication.login_options.sms')
when 'voice'
t('two_factor_authentication.login_options.voice')
when 'webauthn'
t('two_factor_authentication.login_options.webauthn')
when 'webauthn_platform'
t('two_factor_authentication.login_options.webauthn_platform')
else
raise "Unsupported login method: #{type}"
end
end

def info
case type
when 'auth_app'
t('two_factor_authentication.login_options.auth_app_info')
when 'backup_code'
t('two_factor_authentication.login_options.backup_code_info')
when 'personal_key'
t('two_factor_authentication.login_options.personal_key_info')
when 'piv_cac'
t('two_factor_authentication.login_options.piv_cac_info')
when 'webauthn'
t('two_factor_authentication.login_options.webauthn_info')
when 'webauthn_platform'
t('two_factor_authentication.login_options.webauthn_platform_info', app_name: APP_NAME)
else
raise "Unsupported login method: #{type}"
end
end
Comment thread
aduth marked this conversation as resolved.
end
end
2 changes: 1 addition & 1 deletion app/presenters/two_factor_options_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def phone_options

def totp_option
return [] if piv_cac_required? || phishing_resistant_only?
[TwoFactorAuthentication::AuthAppSelectionPresenter.new(user: user)]
[TwoFactorAuthentication::SetUpAuthAppSelectionPresenter.new(user: user)]
end

def backup_code_option
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
require 'rails_helper'

RSpec.describe TwoFactorAuthentication::AuthAppSelectionPresenter do
RSpec.describe TwoFactorAuthentication::SetUpAuthAppSelectionPresenter do
let(:configuration) {}
let(:user_without_mfa) { create(:user) }
let(:user_with_mfa) { create(:user, :with_authentication_app) }
let(:presenter_without_mfa) do
described_class.new(configuration: configuration, user: user_without_mfa)
described_class.new(user: user_without_mfa)
end
let(:presenter_with_mfa) do
described_class.new(configuration: configuration, user: user_with_mfa)
described_class.new(user: user_with_mfa)
end

describe '#type' do
Expand All @@ -17,7 +17,7 @@
end
end

describe '#mfa_configruation' do
describe '#mfa_configuration' do
it 'return an empty string when user has not configured this authenticator' do
expect(presenter_without_mfa.mfa_configuration_description).to eq('')
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
require 'rails_helper'

RSpec.describe TwoFactorAuthentication::SetUpSelectionPresenter do
class PlaceholderPresenter < TwoFactorAuthentication::SetUpSelectionPresenter
def method
:missing
end
end

let(:user) { build(:user) }

subject(:presenter) { described_class.new(user: user) }

describe '#render_in' do
it 'renders captured block content' do
view_context = ActionController::Base.new.view_context

expect(view_context).to receive(:capture) do |*args, &block|
expect(block.call).to eq('content')
end

presenter.render_in(view_context) { 'content' }
end
end

describe '#disabled?' do
let(:single_configuration_only) {}
let(:mfa_configuration_count) {}

before do
allow(presenter).to receive(:single_configuration_only?).and_return(single_configuration_only)
allow(presenter).to receive(:mfa_configuration_count).and_return(mfa_configuration_count)
end

context 'without single configuration restriction' do
let(:single_configuration_only) { false }

it 'is an mfa that allows multiple configurations' do
expect(presenter.disabled?).to eq(false)
end
end

context 'with single configuration only' do
let(:single_configuration_only) { true }

context 'with default mfa count implementation' do
before do
allow(presenter).to receive(:mfa_configuration_count).and_call_original
end

it 'is mfa with unimplemented mfa count and single config' do
expect(presenter.disabled?).to eq(false)
end
end

context 'with no configured mfas' do
let(:mfa_configuration_count) { 0 }

it 'is configured with no mfa' do
expect(presenter.disabled?).to eq(false)
end
end

context 'with at least one configured mfa' do
let(:mfa_configuration_count) { 1 }

it 'is mfa with at least one configured' do
expect(presenter.disabled?).to eq(true)
end
end
end
end

describe '#mfa_added_label' do
subject(:mfa_added_label) { presenter.mfa_added_label }
before do
allow(presenter).to receive(:mfa_configuration_count).and_return('1')
end
it 'is a count of configured MFAs' do
expect(presenter.mfa_added_label).to include('added')
end

context 'with single configuration only' do
before do
allow(presenter).to receive(:single_configuration_only?).and_return(true)
end

it 'is an empty string' do
expect(presenter.mfa_added_label).to eq('')
end
end
end

describe '#label' do
it 'raises with missing translation' do
expect { PlaceholderPresenter.new(user: user).label }.to raise_error(RuntimeError)
end
end

describe '#info' do
it 'raises with missing translation' do
expect { PlaceholderPresenter.new(user: user).info }.to raise_error(RuntimeError)
end
end
end
6 changes: 3 additions & 3 deletions spec/presenters/two_factor_options_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
describe '#options' do
it 'supplies all the options for a user' do
expect(presenter.options.map(&:class)).to eq [
TwoFactorAuthentication::AuthAppSelectionPresenter,
TwoFactorAuthentication::SetUpAuthAppSelectionPresenter,
TwoFactorAuthentication::PhoneSelectionPresenter,
TwoFactorAuthentication::BackupCodeSelectionPresenter,
TwoFactorAuthentication::WebauthnSelectionPresenter,
Expand Down Expand Up @@ -61,7 +61,7 @@

it 'supplies all the options except phone' do
expect(presenter.options.map(&:class)).to eq [
TwoFactorAuthentication::AuthAppSelectionPresenter,
TwoFactorAuthentication::SetUpAuthAppSelectionPresenter,
TwoFactorAuthentication::BackupCodeSelectionPresenter,
TwoFactorAuthentication::WebauthnSelectionPresenter,
TwoFactorAuthentication::PivCacSelectionPresenter,
Expand All @@ -77,7 +77,7 @@
it 'supplies all the options except webauthn' do
expect(presenter.options.map(&:class)).to eq [
TwoFactorAuthentication::WebauthnPlatformSelectionPresenter,
TwoFactorAuthentication::AuthAppSelectionPresenter,
TwoFactorAuthentication::SetUpAuthAppSelectionPresenter,
TwoFactorAuthentication::PhoneSelectionPresenter,
TwoFactorAuthentication::BackupCodeSelectionPresenter,
TwoFactorAuthentication::WebauthnSelectionPresenter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
render partial: 'mfa_selection', locals: {
form: form_builder,
option: presenter.options.find do |option|
option.is_a?(TwoFactorAuthentication::AuthAppSelectionPresenter)
option.is_a?(TwoFactorAuthentication::SetUpAuthAppSelectionPresenter)
end,
}
end
Expand Down