diff options
author | Rubén Dávila <ruben@gitlab.com> | 2017-08-23 11:51:11 -0500 |
---|---|---|
committer | Mike Greiling <mike@pixelcog.com> | 2017-08-26 03:30:01 -0500 |
commit | b2b9d63f9b7301cbef9d1e1b8d4ad3cefeacf35d (patch) | |
tree | c91cefa8b0d2afd67eeffd818415818b8f8fc972 | |
parent | d413f8e4e426e2cb2dc61d5a72d84a7dc67a28c8 (diff) | |
download | gitlab-ce-b2b9d63f9b7301cbef9d1e1b8d4ad3cefeacf35d.tar.gz |
Add validation to check visibility level of sub groups.
-rw-r--r-- | app/models/group.rb | 20 | ||||
-rw-r--r-- | spec/models/group_spec.rb | 44 |
2 files changed, 60 insertions, 4 deletions
diff --git a/app/models/group.rb b/app/models/group.rb index 15355418d05..fdd175341b3 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -26,6 +26,7 @@ class Group < Namespace validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? } validate :visibility_level_allowed_by_projects + validate :visibility_level_allowed_by_sub_groups, if: :visibility_level_changed? validate :visibility_level_allowed_by_parent validates :avatar, file_size: { maximum: 200.kilobytes.to_i } @@ -112,14 +113,25 @@ class Group < Namespace end def visibility_level_allowed_by_projects - allowed_by_projects = self.projects.where('visibility_level > ?', self.visibility_level).none? + check_visibility_level_for(:projects) + end + + def visibility_level_allowed_by_sub_groups + check_visibility_level_for(:children) + end - unless allowed_by_projects + def check_visibility_level_for(children_type) + base_query = public_send(children_type) + children_have_higher_visibility = base_query.where('visibility_level > ?', visibility_level).exists? + + if children_have_higher_visibility + children_label = children_type == :projects ? 'projects' : 'sub groups' level_name = Gitlab::VisibilityLevel.level_name(visibility_level).downcase - self.errors.add(:visibility_level, "#{level_name} is not allowed since there are projects with higher visibility.") + + self.errors.add(:visibility_level, "#{level_name} is not allowed since there are #{children_label} with higher visibility.") end - allowed_by_projects + children_have_higher_visibility end def avatar_url(**args) diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index a3310cf1dce..c3342afb7fd 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -117,6 +117,50 @@ describe Group do end end end + + describe '#visibility_level_allowed_by_projects' do + let!(:internal_group) { create(:group, :internal) } + let!(:internal_project) { create(:project, :internal, group: internal_group) } + + context 'when group has a lower visibility' do + it 'is invalid' do + internal_group.visibility_level = Gitlab::VisibilityLevel::PRIVATE + + expect(internal_group).to be_invalid + expect(internal_group.errors[:visibility_level]).to include('private is not allowed since there are projects with higher visibility.') + end + end + + context 'when group has a higher visibility' do + it 'is valid' do + internal_group.visibility_level = Gitlab::VisibilityLevel::PUBLIC + + expect(internal_group).to be_valid + end + end + end + + describe '#visibility_level_allowed_by_sub_groups' do + let!(:internal_group) { create(:group, :internal) } + let!(:internal_sub_group) { create(:group, :internal, parent: internal_group) } + + context 'when parent group has a lower visibility' do + it 'is invalid' do + internal_group.visibility_level = Gitlab::VisibilityLevel::PRIVATE + + expect(internal_group).to be_invalid + expect(internal_group.errors[:visibility_level]).to include('private is not allowed since there are sub groups with higher visibility.') + end + end + + context 'when parent group has a higher visibility' do + it 'is valid' do + internal_group.visibility_level = Gitlab::VisibilityLevel::PUBLIC + + expect(internal_group).to be_valid + end + end + end end describe '.visible_to_user' do |