You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/03/12 21:45:30 UTC
[allura] 01/02: [#8270] rel=nofollow on any menu items going
external; include current domain as exempt from nofollow
This is an automated email from the ASF dual-hosted git repository.
brondsem pushed a commit to branch db/8270
in repository https://gitbox.apache.org/repos/asf/allura.git
commit 253b4a6cafc67a3cd02ab0d8a09a6df9d2e46b45
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue Mar 12 17:14:51 2019 -0400
[#8270] rel=nofollow on any menu items going external; include current domain as exempt from nofollow
---
.../ext/user_profile/templates/sections/tools.html | 4 ++--
Allura/allura/lib/markdown_extensions.py | 8 +++-----
Allura/allura/lib/utils.py | 9 ++++++++-
Allura/allura/model/project.py | 5 ++++-
Allura/allura/templates/jinja_master/top_nav.html | 4 ++--
Allura/allura/tests/test_utils.py | 16 ++++++++++++++++
6 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/Allura/allura/ext/user_profile/templates/sections/tools.html b/Allura/allura/ext/user_profile/templates/sections/tools.html
index 1a39e91..55aad35 100644
--- a/Allura/allura/ext/user_profile/templates/sections/tools.html
+++ b/Allura/allura/ext/user_profile/templates/sections/tools.html
@@ -28,11 +28,11 @@
<ul>
{% for tool in c.project.grouped_navbar_entries() %}
<li>
- <a href="{{tool.url}}">{{ tool.label }}</a>
+ <a href="{{tool.url}}" {{ tool.extra_html_attrs|xmlattr }}>{{ tool.label }}</a>
{% if tool.children %}
<ul>
{% for child in tool.children %}
- <li><a href="{{child.url}}">{{ child.label }}</a></li>
+ <li><a href="{{child.url}}" {{ child.extra_html_attrs|xmlattr }}>{{ child.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
diff --git a/Allura/allura/lib/markdown_extensions.py b/Allura/allura/lib/markdown_extensions.py
index d025590..09ff02a 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -32,7 +32,7 @@ import emoji
from . import macro
from . import helpers as h
from allura import model as M
-from allura.lib.utils import ForgeHTMLSanitizerFilter
+from allura.lib.utils import ForgeHTMLSanitizerFilter, is_nofollow_url
log = logging.getLogger(__name__)
@@ -473,10 +473,8 @@ class RelativeLinkRewriter(markdown.postprocessors.Postprocessor):
val = val.replace(' ', '%20')
tag[attr] = val
if '://' in val:
- for domain in re.split(r'\s*,\s*', config.get('nofollow_exempt_domains', '')):
- if domain and domain in val:
- return
- tag['rel'] = 'nofollow'
+ if is_nofollow_url(val):
+ tag['rel'] = 'nofollow'
return
if val.startswith('/'):
return
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index e07323c..7198386 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -30,6 +30,7 @@ import magic
from itertools import groupby
import operator as op
import collections
+from urlparse import urlparse
import tg
import emoji
@@ -792,4 +793,10 @@ def get_key_from_value(d, val):
for k, v in d.items():
if val in v:
return k
- return ''
\ No newline at end of file
+ return ''
+
+
+def is_nofollow_url(url):
+ url_domain = urlparse(url).hostname
+ ok_domains = re.split(r'\s*,\s*', tg.config.get('nofollow_exempt_domains', '')) + [tg.config['domain']]
+ return url_domain and url_domain not in ok_domains
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 1a70914..8fa6167 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -33,7 +33,6 @@ import formencode as fe
from webob import exc
import PIL
-from allura.lib.decorators import memoize
from ming import schema as S
from ming.utils import LazyProperty
from ming.orm import ThreadLocalORMSession
@@ -46,8 +45,10 @@ from allura.lib import plugin
from allura.lib import exceptions
from allura.lib import security
from allura.lib import validators as v
+from allura.lib.decorators import memoize
from allura.lib.security import has_access
from allura.lib.search import SearchIndexable
+from allura.lib.utils import is_nofollow_url
from allura.model.types import MarkdownCache
from .session import main_orm_session
@@ -626,6 +627,8 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
entry = sm.bind_app(app)
entry.tool_name = ac.tool_name
entry.ui_icon = 'tool-%s' % entry.tool_name.lower()
+ if is_nofollow_url(entry.url):
+ entry.extra_html_attrs = {'rel': 'nofollow'}
if not self.is_nbhd_project and (entry.tool_name.lower() in anchored_tools.keys()):
ordinal = anchored_tools.keys().index(
entry.tool_name.lower())
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index ae8fefe..ac3727d 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -21,14 +21,14 @@
<ul class="dropdown">
{% for s in c.project.grouped_navbar_entries() %}
<li class="{% if s.matches_url(request) %}selected{% endif %}">
- <a href="{{s.url}}" class="tool-{{(s.tool_name or 'admin').lower()}}-32">
+ <a href="{{s.url}}" class="tool-{{(s.tool_name or 'admin').lower()}}-32" {{ s.extra_html_attrs|xmlattr }}>
{{s.label}}
</a>
{% set grouped_tool_count = s.matching_urls|length %}
{% if grouped_tool_count %}
<ul>
{%for tool in s.children%}
- <li class="{% if tool.matches_url(request) %}selected{% endif %}"><a href="{{tool.url}}">{{tool.label}}</a></li>
+ <li class="{% if tool.matches_url(request) %}selected{% endif %}"><a href="{{tool.url}}" {{ tool.extra_html_attrs|xmlattr }}>{{tool.label}}</a></li>
{%endfor%}
</ul>
{% endif %}
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index 0afc937..5f642a7 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -382,3 +382,19 @@ def unique_attachments():
attachments = [pic1, file1, pic2, file2, pic2, other]
expected = [file2, other, pic2]
assert_equal(expected, ua(attachments))
+
+
+def test_is_nofollow_url():
+ with patch.dict(config, {'domain': 'localhost'}):
+ assert not utils.is_nofollow_url('relative/path')
+ assert not utils.is_nofollow_url('http://localhost/path')
+ assert utils.is_nofollow_url('http://google.com/')
+ assert utils.is_nofollow_url('https://google.com/')
+
+ with patch.dict(config, {'domain': 'localhost',
+ 'nofollow_exempt_domains': 'foo.com, bar.io'}):
+ assert utils.is_nofollow_url('http://google.com/')
+ assert utils.is_nofollow_url('http://xfoo.com/')
+ assert not utils.is_nofollow_url('http://foo.com/')
+ assert not utils.is_nofollow_url('http://bar.io/')
+ assert utils.is_nofollow_url('http://bar.iot/')