summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2019-02-27 14:22:14 +0000
committerYorick Peterse <yorickpeterse@gmail.com>2019-02-27 14:22:14 +0000
commit8449d4eee0c36d2040366973a26ba812ef0204a3 (patch)
treee9f17cfbf6f24965aa36f7c3b717e9d327dbab96
parent28420780996f5103a9145e1deffdebae521978d5 (diff)
parent08e64d68462ba1403216b029581efe02fd37011f (diff)
downloadgitlab-ce-8449d4eee0c36d2040366973a26ba812ef0204a3.tar.gz
Merge branch '11-6-security-2797-milestone-mrs' into '11-6-stable'
Show only MRs visible to user on milestone detail See merge request gitlab/gitlabhq!2925
-rw-r--r--app/controllers/concerns/milestone_actions.rb2
-rw-r--r--app/models/concerns/milestoneish.rb11
-rw-r--r--app/models/global_milestone.rb6
-rw-r--r--app/models/group_milestone.rb4
-rw-r--r--app/models/milestone.rb1
-rw-r--r--changelogs/unreleased/security-2797-milestone-mrs.yml5
-rw-r--r--spec/models/concerns/milestoneish_spec.rb47
7 files changed, 72 insertions, 4 deletions
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index eccbe35577b..c0c0160a827 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -8,7 +8,7 @@ module MilestoneActions
format.html { redirect_to milestone_redirect_path }
format.json do
render json: tabs_json("shared/milestones/_merge_requests_tab", {
- merge_requests: @milestone.sorted_merge_requests, # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ merge_requests: @milestone.sorted_merge_requests(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables
show_project_name: true
})
end
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index e44a069b730..65e28d15b06 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -46,12 +46,19 @@ module Milestoneish
end
end
+ def merge_requests_visible_to_user(user)
+ memoize_per_user(user, :merge_requests_visible_to_user) do
+ MergeRequestsFinder.new(user, {})
+ .execute.where(milestone_id: milestoneish_id)
+ end
+ end
+
def sorted_issues(user)
issues_visible_to_user(user).preload_associations.sort_by_attribute('label_priority')
end
- def sorted_merge_requests
- merge_requests.sort_by_attribute('label_priority')
+ def sorted_merge_requests(user)
+ merge_requests_visible_to_user(user).sort_by_attribute('label_priority')
end
def upcoming?
diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb
index 085ffd16c6a..03653aac3b8 100644
--- a/app/models/global_milestone.rb
+++ b/app/models/global_milestone.rb
@@ -9,6 +9,8 @@ class GlobalMilestone
attr_accessor :title, :milestones
alias_attribute :name, :title
+ delegate :milestoneish_id, to: :milestone
+
def for_display
@first_milestone
end
@@ -48,6 +50,10 @@ class GlobalMilestone
@first_milestone = milestones.find {|m| m.description.present? } || milestones.first
end
+ def milestone
+ milestones.first
+ end
+
def milestoneish_ids
milestones.select(:id)
end
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
index 9dfaebacc83..5874a745d70 100644
--- a/app/models/group_milestone.rb
+++ b/app/models/group_milestone.rb
@@ -22,4 +22,8 @@ class GroupMilestone < GlobalMilestone
def legacy_group_milestone?
true
end
+
+ def milestone
+ @milestone ||= milestones.find { |m| m.description.present? } || milestones.first
+ end
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 3cc8e2c44bb..bc39a483753 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -73,6 +73,7 @@ class Milestone < ActiveRecord::Base
end
alias_attribute :name, :title
+ alias_attribute :milestoneish_id, :milestoneish_ids
class << self
# Searches for milestones matching the given query.
diff --git a/changelogs/unreleased/security-2797-milestone-mrs.yml b/changelogs/unreleased/security-2797-milestone-mrs.yml
new file mode 100644
index 00000000000..5bb104ec403
--- /dev/null
+++ b/changelogs/unreleased/security-2797-milestone-mrs.yml
@@ -0,0 +1,5 @@
+---
+title: Show only merge requests visible to user on milestone detail page
+merge_request:
+author:
+type: security
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index 87bf731340f..4647eecbdef 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -48,7 +48,7 @@ describe Milestone, 'Milestoneish' do
merge_request_2 = create(:labeled_merge_request, labels: [label_1], source_project: project, source_branch: 'branch_2', milestone: milestone)
merge_request_3 = create(:labeled_merge_request, labels: [label_3], source_project: project, source_branch: 'branch_3', milestone: milestone)
- merge_requests = milestone.sorted_merge_requests
+ merge_requests = milestone.sorted_merge_requests(member)
expect(merge_requests.first).to eq(merge_request_2)
expect(merge_requests.second).to eq(merge_request_1)
@@ -56,6 +56,51 @@ describe Milestone, 'Milestoneish' do
end
end
+ describe '#merge_requests_visible_to_user' do
+ let(:merge_request) { create(:merge_request, source_project: project, milestone: milestone) }
+
+ context 'when project is private' do
+ before do
+ project.update(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ it 'does not return any merge request for a non member' do
+ merge_requests = milestone.merge_requests_visible_to_user(non_member)
+ expect(merge_requests).to be_empty
+ end
+
+ it 'returns milestone merge requests for a member' do
+ merge_requests = milestone.merge_requests_visible_to_user(member)
+ expect(merge_requests).to contain_exactly(merge_request)
+ end
+ end
+
+ context 'when project is public' do
+ context 'when merge requests are available to anyone' do
+ it 'returns milestone merge requests for a non member' do
+ merge_requests = milestone.merge_requests_visible_to_user(non_member)
+ expect(merge_requests).to contain_exactly(merge_request)
+ end
+ end
+
+ context 'when merge requests are available to project members' do
+ before do
+ project.project_feature.update(merge_requests_access_level: ProjectFeature::PRIVATE)
+ end
+
+ it 'does not return any merge request for a non member' do
+ merge_requests = milestone.merge_requests_visible_to_user(non_member)
+ expect(merge_requests).to be_empty
+ end
+
+ it 'returns milestone merge requests for a member' do
+ merge_requests = milestone.merge_requests_visible_to_user(member)
+ expect(merge_requests).to contain_exactly(merge_request)
+ end
+ end
+ end
+ end
+
describe '#closed_items_count' do
it 'does not count confidential issues for non project members' do
expect(milestone.closed_items_count(non_member)).to eq 2