From f902860955813645d70f669c3961ebd35d4ed9a1 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Wed, 7 Jun 2017 20:10:57 +0000 Subject: [PATCH] Link to user in wiki syntax (#4179). Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@16636 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/helpers/application_helper.rb | 34 +++++++++++++++---- lib/redmine/wiki_formatting.rb | 6 ++-- .../wiki_formatting/markdown/formatter.rb | 4 +++ test/unit/helpers/application_helper_test.rb | 15 +++++++- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f1241d8b7..2a5c6d05d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -224,7 +224,7 @@ module ApplicationHelper image_tag( thumbnail_path(attachment), :srcset => "#{thumbnail_path(attachment, :size => Setting.thumbnails_size.to_i * 2)} 2x", - :width => Setting.thumbnails_size + :width => Setting.thumbnails_size ), named_attachment_path( attachment, @@ -810,6 +810,9 @@ module ApplicationHelper # Projects: # project:someproject -> Link to project named "someproject" # project#3 -> Link to project with id 3 + # Users: + # user:jsmith -> Link to user with login jsmith + # @jsmith -> Link to user with login jsmith # # Links can refer other objects from other projects, using project identifier: # identifier:r52 @@ -826,8 +829,8 @@ module ApplicationHelper prefix = $~[:prefix] repo_prefix = $~[:repo_prefix] repo_identifier = $~[:repo_identifier] - sep = $~[:sep1] || $~[:sep2] || $~[:sep3] - identifier = $~[:identifier1] || $~[:identifier2] + sep = $~[:sep1] || $~[:sep2] || $~[:sep3] || $~[:sep4] + identifier = $~[:identifier1] || $~[:identifier2] || $~[:identifier3] comment_suffix = $~[:comment_suffix] comment_id = $~[:comment_id] @@ -899,9 +902,7 @@ module ApplicationHelper end end elsif sep == ':' - # removes the double quotes if any - name = identifier.gsub(%r{^"(.*)"$}, "\\1") - name = CGI.unescapeHTML(name) + name = remove_double_quotes(identifier) case prefix when 'document' if project && document = project.documents.visible.find_by_title(name) @@ -957,7 +958,14 @@ module ApplicationHelper if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first link = link_to_project(p, {:only_path => only_path}, :class => 'project') end + when 'user' + u = User.visible.where(:login => name, :type => 'User').first + link = link_to_user(u) if u end + elsif "@" + name = remove_double_quotes(identifier) + u = User.visible.where(:login => name, :type => 'User').first + link = link_to_user(u) if u end end (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) @@ -971,7 +979,7 @@ module ApplicationHelper (?[\s\(,\-\[\>]|^) (?!)? (?(?[a-z0-9\-_]+):)? - (?attachment|document|version|forum|news|message|project|commit|source|export)? + (?attachment|document|version|forum|news|message|project|commit|source|export|user)? ( ( (?\#)| @@ -987,8 +995,14 @@ module ApplicationHelper -(?\d+) )? )| + ( (?:) (?[^"\s<>][^\s<>]*?|"[^"]+?") + )| + ( + (?@) + (?[a-z0-9_\-@\.]*) + ) ) (?= (?=[[:punct:]][^A-Za-z0-9_/])| @@ -1465,4 +1479,10 @@ module ApplicationHelper extend helper return self end + + # remove double quotes if any + def remove_double_quotes(identifier) + name = identifier.gsub(%r{^"(.*)"$}, "\\1") + return CGI.unescapeHTML(name) + end end diff --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb index 17348d16e..03129aa21 100644 --- a/lib/redmine/wiki_formatting.rb +++ b/lib/redmine/wiki_formatting.rb @@ -37,7 +37,7 @@ module Redmine args : %w(Formatter Helper HtmlParser).map {|m| "Redmine::WikiFormatting::#{name.classify}::#{m}".constantize rescue nil} - raise "A formatter class is required" if formatter.nil? + raise "A formatter class is required" if formatter.nil? @@formatters[name] = { :formatter => formatter, @@ -153,7 +153,7 @@ module Redmine # Destructively replaces email addresses into clickable links def auto_mailto!(text) - text.gsub!(/([\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do + text.gsub!(/((?]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) mail @@ -161,7 +161,7 @@ module Redmine %().html_safe end end - end + end end # Default formatter module diff --git a/lib/redmine/wiki_formatting/markdown/formatter.rb b/lib/redmine/wiki_formatting/markdown/formatter.rb index bfb04774c..ba7f7c0c9 100644 --- a/lib/redmine/wiki_formatting/markdown/formatter.rb +++ b/lib/redmine/wiki_formatting/markdown/formatter.rb @@ -66,6 +66,10 @@ module Redmine html.gsub!(/(\w):"(.+?)"/) do "#{$1}:\"#{$2}\"" end + # restore user links with @ in login name eg. [@jsmith@somenet.foo] + html.gsub!(%r{[@\A](.*?)}) do + "@#{$2}" + end html end diff --git a/test/unit/helpers/application_helper_test.rb b/test/unit/helpers/application_helper_test.rb index 500fbd86e..678dcfda5 100644 --- a/test/unit/helpers/application_helper_test.rb +++ b/test/unit/helpers/application_helper_test.rb @@ -383,12 +383,25 @@ RAW # invalid expressions 'source:' => 'source:', # url hash - "http://foo.bar/FAQ#3" => 'http://foo.bar/FAQ#3', + "http://foo.bar/FAQ#3" => 'http://foo.bar/FAQ#3', + # user + 'user:jsmith' => link_to_user(User.find_by_id(2)), + '@jsmith' => link_to_user(User.find_by_id(2)), + # invalid user + 'user:foobar' => 'user:foobar', } @project = Project.find(1) to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text), "#{text} failed" } end + def test_user_links_with_email_as_login_name_should_not_be_parsed + u = User.generate!(:login => 'jsmith@somenet.foo') + raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + + assert_match %r{

#{u.name} should not be parsed in

}, + textilizable(raw, :project => Project.find(1)) + end + def test_should_not_parse_redmine_links_inside_link raw = "r1 should not be parsed in http://example.com/url-r1/" assert_match %r{

r1 should not be parsed in http://example.com/url-r1/

}, -- 2.39.5