diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2016-05-06 17:11:05 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2016-05-11 20:12:32 +0300 |
commit | 2d7ba6c3a2fa0c218519c42d8bfb164873d9186a (patch) | |
tree | 36fe43672545bf52e96c954708d7be07e97498d1 | |
parent | c4b89330cfe9e5e99c8190b1a5520e7ee73b3688 (diff) |
Pass Markdown authors to the "analyze" method
When rendering multiple documents it's not unlikely for these documents
to have different authors. Previously this was not an issue as the
reference extraction pipeline was executed for every individual object,
passing the author to the #initialize method of the reference extractor
classes.
Now that documents are rendered in batches this is no longer possible.
To work around this the author is now passed to the "analyze" method and
its up to the Markdown pipeline to add any extra data to the rendered
HTML document. In this case the UserReferenceFilter class adds a
"data-author" attribute to links used for `@all` references. This in
turn allows the reference parsers to see if the author of the document
has the permissions required to actually reference everybody involved.
-rw-r--r-- | app/controllers/projects/wikis_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 4 | ||||
-rw-r--r-- | app/models/concerns/mentionable.rb | 5 | ||||
-rw-r--r-- | lib/banzai/filter/user_reference_filter.rb | 4 | ||||
-rw-r--r-- | lib/banzai/reference_extractor.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/reference_extractor.rb | 5 | ||||
-rw-r--r-- | spec/lib/banzai/filter/user_reference_filter_spec.rb | 8 |
7 files changed, 21 insertions, 13 deletions
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 0d6c32fabd2..4b404eb03fa 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -91,8 +91,8 @@ class Projects::WikisController < Projects::ApplicationController def markdown_preview text = params[:text] - ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user) - ext.analyze(text) + ext = Gitlab::ReferenceExtractor.new(@project, current_user) + ext.analyze(text, author: current_user) render json: { body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki), diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3768efe142a..f1c89621728 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -202,8 +202,8 @@ class ProjectsController < Projects::ApplicationController def markdown_preview text = params[:text] - ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user) - ext.analyze(text) + ext = Gitlab::ReferenceExtractor.new(@project, current_user) + ext.analyze(text, author: current_user) render json: { body: view_context.markdown(text), diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index b381d225485..334aa57098b 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -44,16 +44,17 @@ module Mentionable end def all_references(current_user = nil, text = nil) - ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author, self.author) + ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author) if text - ext.analyze(text) + ext.analyze(text, author: author) else self.class.mentionable_attrs.each do |attr, options| text = send(attr) context = options.dup context[:cache_key] = [self, attr] if context.delete(:cache) && self.persisted? + context[:author] = author ext.analyze(text, context) end diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb index 31247dd20cf..e70febde5ee 100644 --- a/lib/banzai/filter/user_reference_filter.rb +++ b/lib/banzai/filter/user_reference_filter.rb @@ -79,9 +79,11 @@ module Banzai def link_to_all(link_text: nil) project = context[:project] + author = context[:author] + url = urls.namespace_project_url(project.namespace, project, only_path: context[:only_path]) - data = data_attribute(project: project.id) + data = data_attribute(project: project.id, author: author.id) text = link_text || User.reference_prefix + 'all' link_tag(url, data, text) diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index 02824353e8b..9435accba1f 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -31,9 +31,9 @@ module Banzai @texts << Renderer.render(text, context) end - def references(type, project, current_user = nil, author = nil) + def references(type, project, current_user = nil) processor = Banzai::ReferenceParser[type]. - new(project, current_user, author) + new(project, current_user) processor.process(html_documents) end diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 02a241f09a8..11c0b01f0dc 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -4,10 +4,9 @@ module Gitlab REFERABLES = %i(user issue label milestone merge_request snippet commit commit_range) attr_accessor :project, :current_user, :author - def initialize(project, current_user = nil, author = nil) + def initialize(project, current_user = nil) @project = project @current_user = current_user - @author = author @references = {} @@ -19,7 +18,7 @@ module Gitlab end def references(type) - super(type, project, current_user, author) + super(type, project, current_user) end REFERABLES.each do |type| diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index 29735b941ec..bc00e206ce4 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -31,11 +31,17 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do end it 'supports a special @all mention' do - doc = reference_filter("Hey #{reference}") + doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 expect(doc.css('a').first.attr('href')) .to eq urls.namespace_project_url(project.namespace, project) end + + it 'includes a data-author attribute' do + doc = reference_filter(reference, author: user) + + expect(doc.css('a').first.attr('data-author')).to eq(user.id.to_s) + end end context 'mentioning a user' do |