Remove EE checks from 2FA

pull/11424/head
Oliver Günther 2 years ago
parent caa92bf395
commit ee87ce1613
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 2
      docs/system-admin-guide/authentication/two-factor-authentication/README.md
  2. 7
      modules/two_factor_authentication/app/controllers/two_factor_authentication/two_factor_settings_controller.rb
  3. 2
      modules/two_factor_authentication/lib/open_project/two_factor_authentication/token_strategy_manager.rb
  4. 4
      modules/two_factor_authentication/spec/controllers/two_factor_authentication/authentication_controller_spec.rb
  5. 2
      modules/two_factor_authentication/spec/controllers/two_factor_authentication/forced_registration/two_factor_devices_controller_spec.rb
  6. 2
      modules/two_factor_authentication/spec/controllers/two_factor_authentication/my/two_factor_devices_controller_spec.rb
  7. 2
      modules/two_factor_authentication/spec/controllers/two_factor_authentication/users/two_factor_devices_controller_spec.rb
  8. 1
      modules/two_factor_authentication/spec/features/account_activation_spec.rb
  9. 1
      modules/two_factor_authentication/spec/features/admin_edit_two_factor_devices_spec.rb
  10. 2
      modules/two_factor_authentication/spec/features/backup_codes/generate_backup_codes_spec.rb
  11. 2
      modules/two_factor_authentication/spec/features/backup_codes/login_with_backup_code_spec.rb
  12. 1
      modules/two_factor_authentication/spec/features/login/login_enforced_2fa_spec.rb
  13. 1
      modules/two_factor_authentication/spec/features/login/login_with_2fa_spec.rb
  14. 2
      modules/two_factor_authentication/spec/features/login/login_without_2fa_spec.rb
  15. 1
      modules/two_factor_authentication/spec/features/login/switch_available_devices_spec.rb
  16. 1
      modules/two_factor_authentication/spec/features/my_two_factor_devices_spec.rb
  17. 1
      modules/two_factor_authentication/spec/features/password_change_spec.rb
  18. 1
      modules/two_factor_authentication/spec/features/remember_cookie/login_with_remember_cookie_spec.rb
  19. 2
      modules/two_factor_authentication/spec/lib/token_strategies/message_bird_spec.rb
  20. 158
      modules/two_factor_authentication/spec/lib/token_strategy_manager_spec.rb
  21. 2
      modules/two_factor_authentication/spec/models/devices/default_device_spec.rb
  22. 2
      modules/two_factor_authentication/spec/models/devices/totp_spec.rb
  23. 2
      modules/two_factor_authentication/spec/models/login_token_spec.rb
  24. 2
      modules/two_factor_authentication/spec/models/user_spec.rb
  25. 2
      modules/two_factor_authentication/spec/services/token_delivery/message_bird_spec.rb
  26. 2
      modules/two_factor_authentication/spec/services/token_delivery/sns_spec.rb
  27. 2
      modules/two_factor_authentication/spec/services/token_delivery/totp_spec.rb
  28. 2
      modules/two_factor_authentication/spec/services/token_service_spec.rb
  29. 15
      modules/two_factor_authentication/spec/spec_helper.rb

@ -7,8 +7,6 @@ keywords: two-factor authentication
---
# Two-factor authentication (2FA)
Note: This feature is available for the Enterprise on-premises only. For more information and differences to Community Edition, [see this page](https://www.openproject.org/pricing/).
## Basic 2FA using TOTP
To activate and **configure two-factor authentication** for OpenProject, navigate to -> *Administration* -> *Authentication* and choose -> *two-factor authentication*.

@ -3,7 +3,6 @@ module ::TwoFactorAuthentication
include EnterpriseTrialHelper
before_action :require_admin
before_action :check_enabled
before_action :check_ee
layout 'admin'
menu_item :two_factor_authentication
@ -49,12 +48,6 @@ module ::TwoFactorAuthentication
render_403 unless manager.configurable_by_ui?
end
def check_ee
unless EnterpriseToken.allows_to?(:two_factor_authentication)
render template: 'two_factor_authentication/upsale'
end
end
def manager
::OpenProject::TwoFactorAuthentication::TokenStrategyManager
end

@ -39,7 +39,7 @@ module OpenProject::TwoFactorAuthentication
##
# Whether any active strategy exists
def enabled?
!active_strategies.empty? && EnterpriseToken.allows_to?(:two_factor_authentication)
!active_strategies.empty?
end
##

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative './authentication_controller_shared_examples'
describe ::TwoFactorAuthentication::AuthenticationController, with_2fa_ee: true, with_settings: { login_required?: true } do
describe ::TwoFactorAuthentication::AuthenticationController, with_settings: { login_required?: true } do
let(:valid_credentials) do
{ username: 'foobar', password: 'AAA1111!!!!' }
end
@ -27,7 +27,7 @@ describe ::TwoFactorAuthentication::AuthenticationController, with_2fa_ee: true,
before do
allow(OpenProject::TwoFactorAuthentication::TokenStrategyManager)
.to receive(:add_default_strategy?)
.and_return false
.and_return false
session[:authenticated_user_id] = user.id
get :request_otp
end

@ -1,7 +1,7 @@
require_relative '../../../spec_helper'
require_relative './../authentication_controller_shared_examples'
describe ::TwoFactorAuthentication::ForcedRegistration::TwoFactorDevicesController, with_2fa_ee: true do
describe ::TwoFactorAuthentication::ForcedRegistration::TwoFactorDevicesController do
let(:user) { create(:user, login: 'foobar') }
let(:logged_in_user) { User.anonymous }
let(:active_strategies) { [] }

@ -1,7 +1,7 @@
require_relative '../../../spec_helper'
require_relative './../authentication_controller_shared_examples'
describe ::TwoFactorAuthentication::My::TwoFactorDevicesController, with_2fa_ee: true do
describe ::TwoFactorAuthentication::My::TwoFactorDevicesController do
let(:user) { create(:user, login: 'foobar') }
let(:other_user) { create(:user) }
let(:logged_in_user) { user }

@ -1,7 +1,7 @@
require_relative '../../../spec_helper'
require_relative './../authentication_controller_shared_examples'
describe ::TwoFactorAuthentication::Users::TwoFactorDevicesController, with_2fa_ee: true do
describe ::TwoFactorAuthentication::Users::TwoFactorDevicesController do
let(:admin) { create :admin }
let(:user) { create(:user, login: 'foobar') }
let(:other_user) { create(:user) }

@ -2,7 +2,6 @@ require_relative '../spec_helper'
require_relative './shared_2fa_examples'
describe 'activating an invited account',
with_2fa_ee: true,
type: :feature,
js: true,
with_settings: {

@ -1,7 +1,6 @@
require_relative '../spec_helper'
describe 'Admin 2FA management',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: { 'active_strategies' => %i[developer totp] }

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Generate 2FA backup codes', with_2fa_ee: true, type: :feature,
describe 'Generate 2FA backup codes', type: :feature,
with_config: { '2fa': { active_strategies: [:developer] } },
js: true do
let(:user_password) { 'bob!' * 4 }

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Login with 2FA backup code', with_2fa_ee: true, type: :feature,
describe 'Login with 2FA backup code', type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: { 'active_strategies' => [:developer] }
},

@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Login with enforced 2FA',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: {

@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Login with 2FA device',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: {

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Login with no required OTP', with_2fa_ee: true, type: :feature,
describe 'Login with no required OTP', type: :feature,
with_config: { '2fa': { active_strategies: [:developer] } },
js: true do
let(:user_password) { 'bob!' * 4 }

@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative '../shared_2fa_examples'
describe 'Login by switching 2FA device',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: { 'active_strategies' => %i[developer totp] }

@ -1,7 +1,6 @@
require_relative '../spec_helper'
describe 'My Account 2FA configuration',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: { 'active_strategies' => %i[developer totp] }

@ -1,7 +1,6 @@
require_relative '../spec_helper'
describe 'Password change with OTP',
with_2fa_ee: true,
type: :feature,
with_settings: {
plugin_openproject_two_factor_authentication: {

@ -3,7 +3,6 @@ require_relative '../shared_2fa_examples'
describe 'Login with 2FA remember cookie',
type: :feature,
with_2fa_ee: true,
with_settings: {
plugin_openproject_two_factor_authentication: {
active_strategies: [:developer],

@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require 'messagebird'
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::MessageBird, with_2fa_ee: true do
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::MessageBird do
let(:channel) { :sms }
let(:locale) { 'en' }
let(:user) { create :user, language: locale }

@ -1,6 +1,5 @@
require_relative '../spec_helper'
# rubocop:disable RSpec/NestedGroups
describe ::OpenProject::TwoFactorAuthentication::TokenStrategyManager do
let(:dev_strategy) { ::OpenProject::TwoFactorAuthentication::TokenStrategy::Developer }
let(:totp_strategy) { ::OpenProject::TwoFactorAuthentication::TokenStrategy::Totp }
@ -12,129 +11,110 @@ describe ::OpenProject::TwoFactorAuthentication::TokenStrategyManager do
end
let(:enforced) { false }
context 'without EE' do
include_context 'with settings' do
let(:settings) do
{
plugin_openproject_two_factor_authentication: {
'active_strategies' => %i[developer]
}
}
end
end
it 'is not enabled' do
expect(described_class).not_to be_enabled
include_context 'with settings' do
let(:settings) do
{
plugin_openproject_two_factor_authentication: configuration
}
end
end
context 'with EE', with_2fa_ee: true do
include_context 'with settings' do
let(:settings) do
{
plugin_openproject_two_factor_authentication: configuration
}
end
end
describe '#find_matching_strategy' do
subject { described_class.find_matching_strategy(:sms) }
describe '#find_matching_strategy' do
subject { described_class.find_matching_strategy(:sms) }
context 'when no strategy is set' do
let(:active_strategies) { [] }
context 'when no strategy is set' do
let(:active_strategies) { [] }
it 'returns nil' do
expect(subject).to be_nil
end
it 'returns nil' do
expect(subject).to be_nil
end
end
context 'when matching strategy exists' do
let(:active_strategies) { [:developer] }
context 'when matching strategy exists' do
let(:active_strategies) { [:developer] }
it 'returns the strategy' do
expect(subject).to eq(dev_strategy)
end
it 'returns the strategy' do
expect(subject).to eq(dev_strategy)
end
end
context 'when non-matching strategy exists' do
let(:active_strategies) { [:totp] }
context 'when non-matching strategy exists' do
let(:active_strategies) { [:totp] }
it 'returns the strategy' do
expect(subject).to be_nil
end
it 'returns the strategy' do
expect(subject).to be_nil
end
end
end
describe '#active_strategies' do
context 'with bogus strategy' do
let(:active_strategies) { [:doesnotexist] }
describe '#active_strategies' do
context 'with bogus strategy' do
let(:active_strategies) { [:doesnotexist] }
it 'raises when accessing' do
expect { described_class.active_strategies }.to raise_error(ArgumentError)
end
it 'raises when accessing' do
expect { described_class.active_strategies }.to raise_error(ArgumentError)
end
it 'raises when validating' do
expect { described_class.validate_active_strategies! }.to raise_error(ArgumentError)
end
it 'raises when validating' do
expect { described_class.validate_active_strategies! }.to raise_error(ArgumentError)
end
end
end
describe '#validate_active_strategies!' do
subject { described_class.validate_active_strategies! }
describe '#validate_active_strategies!' do
subject { described_class.validate_active_strategies! }
context 'when no strategy is set' do
let(:active_strategies) { [] }
context 'when no strategy is set' do
let(:active_strategies) { [] }
before do
allow(OpenProject::TwoFactorAuthentication::TokenStrategyManager)
.to receive(:add_default_strategy?)
.and_return false
end
before do
allow(OpenProject::TwoFactorAuthentication::TokenStrategyManager)
.to receive(:add_default_strategy?)
.and_return false
end
context 'when enforced is false' do
let(:enforced) { false }
context 'when enforced is false' do
let(:enforced) { false }
it 'accepts that' do
expect { subject }.not_to raise_error
expect(described_class).not_to be_enabled
expect(described_class).not_to be_enforced
end
it 'accepts that' do
expect { subject }.not_to raise_error
expect(described_class).not_to be_enabled
expect(described_class).not_to be_enforced
end
end
context 'when enforced is true' do
let(:enforced) { true }
context 'when enforced is true' do
let(:enforced) { true }
it 'raises and error that a strategy is needed' do
expect { subject }.to raise_error(ArgumentError)
expect(described_class).not_to be_enabled
expect(described_class).to be_enforced
end
it 'raises and error that a strategy is needed' do
expect { subject }.to raise_error(ArgumentError)
expect(described_class).not_to be_enabled
expect(described_class).to be_enforced
end
end
end
context 'when a strategy is set' do
let(:active_strategies) { [:developer] }
context 'when a strategy is set' do
let(:active_strategies) { [:developer] }
context 'when it is valid' do
it 'returns that' do
expect { subject }.not_to raise_error
expect(described_class.active_strategies).to eq([dev_strategy])
expect(described_class).to be_enabled
expect(described_class).not_to be_enforced
end
context 'when it is valid' do
it 'returns that' do
expect { subject }.not_to raise_error
expect(described_class.active_strategies).to eq([dev_strategy])
expect(described_class).to be_enabled
expect(described_class).not_to be_enforced
end
end
context 'when it is invalid' do
it 'raises' do
allow(dev_strategy).to receive(:validate!).and_raise 'Error!'
context 'when it is invalid' do
it 'raises' do
allow(dev_strategy).to receive(:validate!).and_raise 'Error!'
expect { subject }.to raise_error 'Error!'
expect(described_class).to be_enabled
expect(described_class).not_to be_enforced
end
expect { subject }.to raise_error 'Error!'
expect(described_class).to be_enabled
expect(described_class).not_to be_enforced
end
end
end
end
end
# rubocop:enable RSpec/NestedGroups

@ -1,6 +1,6 @@
require 'spec_helper'
describe 'Default device', with_2fa_ee: true, type: :model do
describe 'Default device', type: :model do
let(:user) { create :user }
let(:subject) { build :two_factor_authentication_device_totp, user:, default: true }
let(:other_otp) { build :two_factor_authentication_device_totp, user:, default: true }

@ -1,7 +1,7 @@
require 'spec_helper'
require 'timecop'
describe ::TwoFactorAuthentication::Device::Totp, with_2fa_ee: true, type: :model do
describe ::TwoFactorAuthentication::Device::Totp, type: :model do
let(:user) { create :user }
let(:channel) { :totp }

@ -1,6 +1,6 @@
require_relative '../spec_helper'
describe TwoFactorAuthentication::LoginToken, with_2fa_ee: true do
describe TwoFactorAuthentication::LoginToken do
before do
@user = build_stubbed(:user, login: "john", password: "doe")
allow(@user).to receive(:new_record?).and_return(false)

@ -2,7 +2,7 @@ require_relative '../spec_helper'
module OpenProject::TwoFactorAuthentication::Patches
module UserSpec
describe User, with_2fa_ee: true do
describe User do
def create_user(auth_source_id = nil)
@user = build(:user)
@username = @user.login

@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require 'messagebird'
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::MessageBird, with_2fa_ee: true do
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::MessageBird do
describe 'sending messages' do
let!(:user) { create :user, language: locale }
let!(:locale) { 'en' }

@ -1,6 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::Sns, with_2fa_ee: true do
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::Sns do
describe 'sending messages' do
let(:phone) { '+49 123456789' }
let!(:user) { create :user }

@ -1,6 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::Totp, with_2fa_ee: true do
describe ::OpenProject::TwoFactorAuthentication::TokenStrategy::Totp do
describe 'sending messages' do
let!(:user) { create :user }
let!(:device) { create :two_factor_authentication_device_totp, user:, default: true }

@ -1,6 +1,6 @@
require_relative '../spec_helper'
describe ::TwoFactorAuthentication::TokenService, with_2fa_ee: true do
describe ::TwoFactorAuthentication::TokenService do
describe 'sending messages' do
let(:user) { create(:user) }
let(:dev_strategy) { ::OpenProject::TwoFactorAuthentication::TokenStrategy::Developer }

@ -1,17 +1,2 @@
# -- load spec_helper from OpenProject core
require "spec_helper"
RSpec.configure do |config|
config.before do |example|
next unless example.metadata[:with_2fa_ee]
allow(EnterpriseToken)
.to receive(:allows_to?)
.and_call_original
allow(EnterpriseToken)
.to receive(:allows_to?)
.with(:two_factor_authentication)
.and_return true
end
end

Loading…
Cancel
Save