Commit 65bb0c34 authored by Douwe Maan's avatar Douwe Maan

Only allow users to cross-reference and close issues they have access to.

parent e62b5a2b
...@@ -117,8 +117,8 @@ class Commit ...@@ -117,8 +117,8 @@ class Commit
# Discover issues should be closed when this commit is pushed to a project's # Discover issues should be closed when this commit is pushed to a project's
# default branch. # default branch.
def closes_issues(project) def closes_issues(project, current_user = self.committer)
Gitlab::ClosingIssueExtractor.closed_by_message_in_project(safe_message, project) Gitlab::ClosingIssueExtractor.closed_by_message_in_project(safe_message, project, current_user)
end end
# Mentionable override. # Mentionable override.
......
...@@ -51,10 +51,10 @@ module Mentionable ...@@ -51,10 +51,10 @@ module Mentionable
end end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference. # Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
def references(p = project, text = mentionable_text) def references(p = project, current_user = self.author, text = mentionable_text)
return [] if text.blank? return [] if text.blank?
ext = Gitlab::ReferenceExtractor.new(p) ext = Gitlab::ReferenceExtractor.new(p, current_user)
ext.analyze(text) ext.analyze(text)
(ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference] (ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference]
...@@ -83,7 +83,7 @@ module Mentionable ...@@ -83,7 +83,7 @@ module Mentionable
# Only proceed if the saved changes actually include a chance to an attr_mentionable field. # Only proceed if the saved changes actually include a chance to an attr_mentionable field.
return unless mentionable_changed return unless mentionable_changed
preexisting = references(p, original) preexisting = references(p, self.author, original)
create_cross_references!(p, a, preexisting) create_cross_references!(p, a, preexisting)
end end
end end
...@@ -257,11 +257,11 @@ class MergeRequest < ActiveRecord::Base ...@@ -257,11 +257,11 @@ class MergeRequest < ActiveRecord::Base
end end
# Return the set of issues that will be closed if this merge request is accepted. # Return the set of issues that will be closed if this merge request is accepted.
def closes_issues def closes_issues(current_user = self.author)
if target_branch == project.default_branch if target_branch == project.default_branch
issues = commits.flat_map { |c| c.closes_issues(project) } issues = commits.flat_map { |c| c.closes_issues(project, current_user) }
issues.push(*Gitlab::ClosingIssueExtractor. issues.push(*Gitlab::ClosingIssueExtractor.
closed_by_message_in_project(description, project)) closed_by_message_in_project(description, project, current_user))
issues.uniq.sort_by(&:id) issues.uniq.sort_by(&:id)
else else
[] []
......
...@@ -70,7 +70,7 @@ class GitPushService ...@@ -70,7 +70,7 @@ class GitPushService
# Close issues if these commits were pushed to the project's default branch and the commit message matches the # Close issues if these commits were pushed to the project's default branch and the commit message matches the
# closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to # closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to
# a different branch. # a different branch.
issues_to_close = commit.closes_issues(project) issues_to_close = commit.closes_issues(project, user)
# Load commit author only if needed. # Load commit author only if needed.
# For push with 1k commits it prevents 900+ requests in database # For push with 1k commits it prevents 900+ requests in database
...@@ -87,7 +87,7 @@ class GitPushService ...@@ -87,7 +87,7 @@ class GitPushService
# Create cross-reference notes for any other references. Omit any issues that were referenced in an # Create cross-reference notes for any other references. Omit any issues that were referenced in an
# issue-closing phrase, or have already been mentioned from this commit (probably from this commit # issue-closing phrase, or have already been mentioned from this commit (probably from this commit
# being pushed to a different branch). # being pushed to a different branch).
refs = commit.references(project) - issues_to_close refs = commit.references(project, user) - issues_to_close
refs.reject! { |r| commit.has_mentioned?(r) } refs.reject! { |r| commit.has_mentioned?(r) }
if refs.present? if refs.present?
......
...@@ -2,14 +2,14 @@ module Gitlab ...@@ -2,14 +2,14 @@ module Gitlab
module ClosingIssueExtractor module ClosingIssueExtractor
ISSUE_CLOSING_REGEX = Regexp.new(Gitlab.config.gitlab.issue_closing_pattern) ISSUE_CLOSING_REGEX = Regexp.new(Gitlab.config.gitlab.issue_closing_pattern)
def self.closed_by_message_in_project(message, project) def self.closed_by_message_in_project(message, project, current_user = nil)
issues = [] issues = []
unless message.nil? unless message.nil?
md = message.scan(ISSUE_CLOSING_REGEX) md = message.scan(ISSUE_CLOSING_REGEX)
md.each do |ref| md.each do |ref|
extractor = Gitlab::ReferenceExtractor.new(project) extractor = Gitlab::ReferenceExtractor.new(project, current_user)
extractor.analyze(ref[0]) extractor.analyze(ref[0])
issues += extractor.issues issues += extractor.issues
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