Commit 340384fe authored by Małgorzata Ksionek's avatar Małgorzata Ksionek

Add validations that respect new allow_mfa_for_subgroups setting

Add specs for new validation

Add validation in group

Add specs for new requires_two_factor_validation

WIP

Update validations for namespace setting
parent c5017785
...@@ -76,6 +76,7 @@ class Group < Namespace ...@@ -76,6 +76,7 @@ class Group < Namespace
validate :visibility_level_allowed_by_projects validate :visibility_level_allowed_by_projects
validate :visibility_level_allowed_by_sub_groups validate :visibility_level_allowed_by_sub_groups
validate :visibility_level_allowed_by_parent validate :visibility_level_allowed_by_parent
validate :two_factor_authentication_allowed
validates :variables, variable_duplicates: true validates :variables, variable_duplicates: true
validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 } validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 }
...@@ -589,6 +590,16 @@ class Group < Namespace ...@@ -589,6 +590,16 @@ class Group < Namespace
errors.add(:visibility_level, "#{visibility} is not allowed since there are sub-groups with higher visibility.") errors.add(:visibility_level, "#{visibility} is not allowed since there are sub-groups with higher visibility.")
end end
def two_factor_authentication_allowed
return if parent_id.nil?
return unless require_two_factor_authentication
ancestor_settings = ancestors.find_by(parent_id: nil).namespace_settings
return if ancestor_settings.allow_mfa_for_subgroups
errors.add(:require_two_factor_authentication, "require two factor authentication is forbidden by a parent group")
end
def members_from_self_and_ancestor_group_shares def members_from_self_and_ancestor_group_shares
group_group_link_table = GroupGroupLink.arel_table group_group_link_table = GroupGroupLink.arel_table
group_member_table = GroupMember.arel_table group_member_table = GroupMember.arel_table
......
...@@ -4,6 +4,7 @@ class NamespaceSetting < ApplicationRecord ...@@ -4,6 +4,7 @@ class NamespaceSetting < ApplicationRecord
belongs_to :namespace, inverse_of: :namespace_settings belongs_to :namespace, inverse_of: :namespace_settings
validate :default_branch_name_content validate :default_branch_name_content
validate :allow_mfa_for_group, on: :update, if: :allow_mfa_for_subgroups_changed?
NAMESPACE_SETTINGS_PARAMS = [:default_branch_name].freeze NAMESPACE_SETTINGS_PARAMS = [:default_branch_name].freeze
...@@ -16,6 +17,12 @@ class NamespaceSetting < ApplicationRecord ...@@ -16,6 +17,12 @@ class NamespaceSetting < ApplicationRecord
errors.add(:default_branch_name, "can not be an empty string") errors.add(:default_branch_name, "can not be an empty string")
end end
end end
def allow_mfa_for_group
if namespace&.parent_id
errors.add(:allow_mfa_for_subgroups, "allow MFA setting is not allowed since group is not top-level group.")
end
end
end end
NamespaceSetting.prepend_if_ee('EE::NamespaceSetting') NamespaceSetting.prepend_if_ee('EE::NamespaceSetting')
...@@ -7,6 +7,7 @@ FactoryBot.define do ...@@ -7,6 +7,7 @@ FactoryBot.define do
type { 'Group' } type { 'Group' }
owner { nil } owner { nil }
project_creation_level { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS } project_creation_level { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS }
association :namespace_settings, factory: :namespace_settings
after(:create) do |group| after(:create) do |group|
if group.owner if group.owner
...@@ -23,7 +24,7 @@ FactoryBot.define do ...@@ -23,7 +24,7 @@ FactoryBot.define do
end end
trait :internal do trait :internal do
visibility_level {Gitlab::VisibilityLevel::INTERNAL } visibility_level { Gitlab::VisibilityLevel::INTERNAL }
end end
trait :private do trait :private do
......
...@@ -222,6 +222,36 @@ RSpec.describe Group do ...@@ -222,6 +222,36 @@ RSpec.describe Group do
end end
end end
end end
describe '#two_factor_authentication_allowed' do
let_it_be(:group) { create(:group) }
context 'for a parent group' do
it 'is valid' do
group.require_two_factor_authentication = true
expect(group).to be_valid
end
end
context 'for a child group' do
let_it_be(:sub_group) { create(:group, parent: group) }
it 'is valid when parent group allows' do
sub_group.require_two_factor_authentication = true
expect(sub_group).to be_valid
end
it 'is invalid when parent group blocks' do
group.namespace_settings.update!(allow_mfa_for_subgroups: false)
sub_group.require_two_factor_authentication = true
expect(sub_group).to be_invalid
expect(sub_group.errors[:require_two_factor_authentication]).to include('require two factor authentication is forbidden by a parent group')
end
end
end
end end
describe '.without_integration' do describe '.without_integration' do
......
...@@ -5,7 +5,9 @@ require 'spec_helper' ...@@ -5,7 +5,9 @@ require 'spec_helper'
RSpec.describe NamespaceSetting, type: :model do RSpec.describe NamespaceSetting, type: :model do
# Relationships # Relationships
# #
describe "Associations" do
it { is_expected.to belong_to(:namespace) } it { is_expected.to belong_to(:namespace) }
end
describe "validations" do describe "validations" do
describe "#default_branch_name_content" do describe "#default_branch_name_content" do
...@@ -43,5 +45,23 @@ RSpec.describe NamespaceSetting, type: :model do ...@@ -43,5 +45,23 @@ RSpec.describe NamespaceSetting, type: :model do
end end
end end
end end
describe '#allow_mfa_for_group' do
context 'group is top-level group' do
let(:group) { create(:group) }
it 'is valid when updated' do
expect(group.namespace_settings.update(allow_mfa_for_subgroups: false)).to eq(true)
end
end
context 'group is a subgroup' do
let(:group) { create(:group, parent: create(:group)) }
it 'is invalid when updated' do
expect(group.namespace_settings.update(allow_mfa_for_subgroups: false)).to eq(false)
end
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment