Commit 333a8e39 authored by jplang's avatar jplang
Browse files

User link syntax (user:login) doesn't work for logins consisting of an email adress (#26443).

Patch by Marius BALTEANU.

git-svn-id: https://svn.redmine.org/redmine/trunk@17392 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 08b24216
...@@ -153,7 +153,7 @@ module Redmine ...@@ -153,7 +153,7 @@ module Redmine
# Destructively replaces email addresses into clickable links # Destructively replaces email addresses into clickable links
def auto_mailto!(text) def auto_mailto!(text)
text.gsub!(/((?<!@)\b[\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do text.gsub!(/([\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
mail = $1 mail = $1
if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
mail mail
...@@ -162,6 +162,26 @@ module Redmine ...@@ -162,6 +162,26 @@ module Redmine
end end
end end
end end
def restore_redmine_links(html)
# restore wiki links eg. [[Foo]]
html.gsub!(%r{\[<a href="(.*?)">(.*?)</a>\]}) do
"[[#{$2}]]"
end
# restore Redmine links with double-quotes, eg. version:"1.0"
html.gsub!(/(\w):&quot;(.+?)&quot;/) do
"#{$1}:\"#{$2}\""
end
# restore user links with @ in login name eg. [@jsmith@somenet.foo]
html.gsub!(%r{[@\A]<a(\sclass="email")? href="mailto:(.*?)">(.*?)</a>}) do
"@#{$2}"
end
# restore user links with @ in login name eg. [user:jsmith@somenet.foo]
html.gsub!(%r{\buser:<a(\sclass="email")? href="mailto:(.*?)">(.*?)<\/a>}) do
"user:#{$2}"
end
html
end
end end
# Default formatter module # Default formatter module
...@@ -180,6 +200,7 @@ module Redmine ...@@ -180,6 +200,7 @@ module Redmine
t = CGI::escapeHTML(@text) t = CGI::escapeHTML(@text)
auto_link!(t) auto_link!(t)
auto_mailto!(t) auto_mailto!(t)
restore_redmine_links(t)
simple_format(t, {}, :sanitize => false) simple_format(t, {}, :sanitize => false)
end end
end end
......
...@@ -52,24 +52,16 @@ module Redmine ...@@ -52,24 +52,16 @@ module Redmine
end end
class Formatter class Formatter
include Redmine::WikiFormatting::LinksHelper
alias :inline_restore_redmine_links :restore_redmine_links
def initialize(text) def initialize(text)
@text = text @text = text
end end
def to_html(*args) def to_html(*args)
html = formatter.render(@text) html = formatter.render(@text)
# restore wiki links eg. [[Foo]] html = inline_restore_redmine_links(html)
html.gsub!(%r{\[<a href="(.*?)">(.*?)</a>\]}) do
"[[#{$2}]]"
end
# restore Redmine links with double-quotes, eg. version:"1.0"
html.gsub!(/(\w):&quot;(.+?)&quot;/) do
"#{$1}:\"#{$2}\""
end
# restore user links with @ in login name eg. [@jsmith@somenet.foo]
html.gsub!(%r{[@\A]<a href="mailto:(.*?)">(.*?)</a>}) do
"@#{$2}"
end
html html
end end
......
...@@ -27,9 +27,10 @@ module Redmine ...@@ -27,9 +27,10 @@ module Redmine
alias :inline_auto_link :auto_link! alias :inline_auto_link :auto_link!
alias :inline_auto_mailto :auto_mailto! alias :inline_auto_mailto :auto_mailto!
alias :inline_restore_redmine_links :restore_redmine_links
# auto_link rule after textile rules so that it doesn't break !image_url! tags # auto_link rule after textile rules so that it doesn't break !image_url! tags
RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto] RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_restore_redmine_links]
def initialize(*args) def initialize(*args)
super super
......
...@@ -282,6 +282,11 @@ RAW ...@@ -282,6 +282,11 @@ RAW
end end
def test_redmine_links def test_redmine_links
user_with_email_login = User.generate!(:login => 'abcd@example.com')
user_with_email_login_2 = User.generate!(:login => 'foo.bar@example.com')
u_email_id = user_with_email_login.id
u_email_id_2 = user_with_email_login_2.id
issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3}, issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
:class => Issue.find(3).css_classes, :title => 'Bug: Error 281 when updating a recipe (New)') :class => Issue.find(3).css_classes, :title => 'Bug: Error 281 when updating a recipe (New)')
note_link = link_to('#3-14', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'}, note_link = link_to('#3-14', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
...@@ -388,6 +393,10 @@ RAW ...@@ -388,6 +393,10 @@ RAW
'user:jsmith' => link_to_user(User.find_by_id(2)), 'user:jsmith' => link_to_user(User.find_by_id(2)),
'user#2' => link_to_user(User.find_by_id(2)), 'user#2' => link_to_user(User.find_by_id(2)),
'@jsmith' => link_to_user(User.find_by_id(2)), '@jsmith' => link_to_user(User.find_by_id(2)),
'@abcd@example.com' => link_to_user(User.find_by_id(u_email_id)),
'user:abcd@example.com' => link_to_user(User.find_by_id(u_email_id)),
'@foo.bar@example.com' => link_to_user(User.find_by_id(u_email_id_2)),
'user:foo.bar@example.com' => link_to_user(User.find_by_id(u_email_id_2)),
# invalid user # invalid user
'user:foobar' => 'user:foobar', 'user:foobar' => 'user:foobar',
} }
...@@ -395,12 +404,36 @@ RAW ...@@ -395,12 +404,36 @@ RAW
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" } to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
end end
def test_user_links_with_email_as_login_name_should_not_be_parsed def test_user_links_with_email_as_login_name_should_not_be_parsed_textile
u = User.generate!(:login => 'jsmith@somenet.foo') with_settings :text_formatting => 'textile' do
raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" u = User.generate!(:login => 'jsmith@somenet.foo')
assert_match %r{<p><a class="user active".*>#{u.name}</a> should not be parsed in <a class="email" href="mailto:jsmith@somenet.foo">jsmith@somenet.foo</a></p>}, # user link format: @jsmith@somenet.foo
textilizable(raw, :project => Project.find(1)) raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo"
assert_match %r{<p><a class="user active".*>#{u.name}</a> should not be parsed in <a class="email" href="mailto:jsmith@somenet.foo">jsmith@somenet.foo</a></p>},
textilizable(raw, :project => Project.find(1))
# user link format: user:jsmith@somenet.foo
raw = "user:jsmith@somenet.foo should not be parsed in jsmith@somenet.foo"
assert_match %r{<p><a class="user active".*>#{u.name}</a> should not be parsed in <a class="email" href="mailto:jsmith@somenet.foo">jsmith@somenet.foo</a></p>},
textilizable(raw, :project => Project.find(1))
end
end
def test_user_links_with_email_as_login_name_should_not_be_parsed_markdown
with_settings :text_formatting => 'markdown' do
u = User.generate!(:login => 'jsmith@somenet.foo')
# user link format: @jsmith@somenet.foo
raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo"
assert_match %r{<p><a class=\"user active\".*>#{u.name}</a> should not be parsed in <a href=\"mailto:jsmith@somenet.foo\">jsmith@somenet.foo</a></p>},
textilizable(raw, :project => Project.find(1))
# user link format: user:jsmith@somenet.foo
raw = "user:jsmith@somenet.foo should not be parsed in jsmith@somenet.foo"
assert_match %r{<p><a class=\"user active\".*>#{u.name}</a> should not be parsed in <a href=\"mailto:jsmith@somenet.foo\">jsmith@somenet.foo</a></p>},
textilizable(raw, :project => Project.find(1))
end
end end
def test_should_not_parse_redmine_links_inside_link def test_should_not_parse_redmine_links_inside_link
......
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