diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2019-03-05 15:40:28 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2019-03-05 15:40:28 +0300 |
commit | 5cdcd339fadb6cd818c35548ae8aa3d44a9ae9d0 (patch) | |
tree | 5d8073faa4e7b9a557c129df226815618a0a8bab | |
parent | 025015048f7eaad29ee7816c6040fb3e0c06eb8d (diff) | |
parent | 434cb1d96f43c90f32427c60a82308307a9181e8 (diff) |
Merge branch 'security-2774-milestones-detail' into 'master'
Display only information visible to current user on Milestone detail
See merge request gitlab/gitlabhq!2803
-rw-r--r-- | app/models/concerns/milestoneish.rb | 12 | ||||
-rw-r--r-- | app/views/shared/milestones/_tabs.html.haml | 4 | ||||
-rw-r--r-- | changelogs/unreleased/security-2774-milestones-detail.yml | 5 | ||||
-rw-r--r-- | spec/models/concerns/milestoneish_spec.rb | 95 |
4 files changed, 112 insertions, 4 deletions
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 39372c4f68b..dff8b3af608 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -53,6 +53,18 @@ module Milestoneish end end + def issue_participants_visible_by_user(user) + User.joins(:issue_assignees) + .where('issue_assignees.issue_id' => issues_visible_to_user(user).select(:id)) + .distinct + end + + def issue_labels_visible_by_user(user) + Label.joins(:label_links) + .where('label_links.target_id' => issues_visible_to_user(user).select(:id), 'label_links.target_type' => 'Issue') + .distinct + end + def sorted_issues(user) issues_visible_to_user(user).preload_associations.sort_by_attribute('label_priority') end diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 55460acab8f..3b435847172 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -21,11 +21,11 @@ %li.nav-item = link_to '#tab-participants', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do Participants - %span.badge.badge-pill= milestone.participants.count + %span.badge.badge-pill= milestone.issue_participants_visible_by_user(current_user).count %li.nav-item = link_to '#tab-labels', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do Labels - %span.badge.badge-pill= milestone.labels.count + %span.badge.badge-pill= milestone.issue_labels_visible_by_user(current_user).count - issues = milestone.sorted_issues(current_user) - show_project_name = local_assigns.fetch(:show_project_name, false) diff --git a/changelogs/unreleased/security-2774-milestones-detail.yml b/changelogs/unreleased/security-2774-milestones-detail.yml new file mode 100644 index 00000000000..faf56fee01e --- /dev/null +++ b/changelogs/unreleased/security-2774-milestones-detail.yml @@ -0,0 +1,5 @@ +--- +title: Display only information visible to current user on the Milestone page +merge_request: +author: +type: security diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb index 4647eecbdef..81ca5b638fe 100644 --- a/spec/models/concerns/milestoneish_spec.rb +++ b/spec/models/concerns/milestoneish_spec.rb @@ -9,8 +9,10 @@ describe Milestone, 'Milestoneish' do let(:admin) { create(:admin) } let(:project) { create(:project, :public) } let(:milestone) { create(:milestone, project: project) } - let!(:issue) { create(:issue, project: project, milestone: milestone) } - let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone) } + let(:label1) { create(:label, project: project) } + let(:label2) { create(:label, project: project) } + let!(:issue) { create(:issue, project: project, milestone: milestone, assignees: [member], labels: [label1]) } + let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone, labels: [label2]) } let!(:security_issue_2) { create(:issue, :confidential, project: project, assignees: [assignee], milestone: milestone) } let!(:closed_issue_1) { create(:issue, :closed, project: project, milestone: milestone) } let!(:closed_issue_2) { create(:issue, :closed, project: project, milestone: milestone) } @@ -42,6 +44,95 @@ describe Milestone, 'Milestoneish' do end end + context 'attributes visibility' do + using RSpec::Parameterized::TableSyntax + + let(:users) do + { + anonymous: nil, + non_member: non_member, + guest: guest, + member: member, + assignee: assignee + } + end + + let(:project_visibility_levels) do + { + public: Gitlab::VisibilityLevel::PUBLIC, + internal: Gitlab::VisibilityLevel::INTERNAL, + private: Gitlab::VisibilityLevel::PRIVATE + } + end + + describe '#issue_participants_visible_by_user' do + where(:visibility, :user_role, :result) do + :public | nil | [:member] + :public | :non_member | [:member] + :public | :guest | [:member] + :public | :member | [:member, :assignee] + :internal | nil | [] + :internal | :non_member | [:member] + :internal | :guest | [:member] + :internal | :member | [:member, :assignee] + :private | nil | [] + :private | :non_member | [] + :private | :guest | [:member] + :private | :member | [:member, :assignee] + end + + with_them do + before do + project.update(visibility_level: project_visibility_levels[visibility]) + end + + it 'returns the proper participants' do + user = users[user_role] + participants = result.map { |role| users[role] } + + expect(milestone.issue_participants_visible_by_user(user)).to match_array(participants) + end + end + end + + describe '#issue_labels_visible_by_user' do + let(:labels) do + { + label1: label1, + label2: label2 + } + end + + where(:visibility, :user_role, :result) do + :public | nil | [:label1] + :public | :non_member | [:label1] + :public | :guest | [:label1] + :public | :member | [:label1, :label2] + :internal | nil | [] + :internal | :non_member | [:label1] + :internal | :guest | [:label1] + :internal | :member | [:label1, :label2] + :private | nil | [] + :private | :non_member | [] + :private | :guest | [:label1] + :private | :member | [:label1, :label2] + end + + with_them do + before do + project.update(visibility_level: project_visibility_levels[visibility]) + end + + it 'returns the proper participants' do + user = users[user_role] + expected_labels = result.map { |label| labels[label] } + + expect(milestone.issue_labels_visible_by_user(user)).to match_array(expected_labels) + end + end + end + end + describe '#sorted_merge_requests' do it 'sorts merge requests by label priority' do merge_request_1 = create(:labeled_merge_request, labels: [label_2], source_project: project, source_branch: 'branch_1', milestone: milestone) |