From 6db1ebeb4f57111b13d889abfb226ab2f4a1a81c Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Wed, 15 Sep 2021 16:40:25 +0200
Subject: [PATCH] pwa: allow absolute redirection url from internal page
 (#56974)

---
 .../pwa/templates/combo/pwa/navigation.html   |  4 +-
 tests/test_pwa.py                             | 41 +++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/combo/apps/pwa/templates/combo/pwa/navigation.html b/combo/apps/pwa/templates/combo/pwa/navigation.html
index 3ce98275..c0828dfd 100644
--- a/combo/apps/pwa/templates/combo/pwa/navigation.html
+++ b/combo/apps/pwa/templates/combo/pwa/navigation.html
@@ -2,17 +2,17 @@
 <div class="pwa-navigation" id="pwa-navigation"
   {% if include_user_name %}data-pwa-user-name="{% skeleton_extra_placeholder user-name %}{{user.get_full_name}}{% end_skeleton_extra_placeholder %}"{% endif %}>
 <div>
 <ul>
   {% for entry in entries %}
   <li class="{{ entry.css_class_names }}{% if entry.link_page in page.get_parents_and_self  %} selected{% endif %}" data-entry-pk="{{ entry.pk }}"
       {% if entry.notification_count %}data-notification-count-url="{{site_base}}/api/notification/count/"{% endif %}
       {% if entry.use_user_name_as_label %}data-include-user-name{% endif %}>
-      <a href="{% if entry.link_page_id %}{{ site_base }}{% endif %}{{ entry.get_url }}"
+      <a href="{% if entry.link_page_id and entry.get_url|slice:":4" != "http"%}{{ site_base }}{% endif %}{{ entry.get_url }}"
          {% if entry.icon %}style="background-image: url({{site_base}}{{entry.icon.url}});"{% endif %}
          ><span>{{ entry.get_label }}</span></a></li>
   {% endfor %}
 </ul>
 </div>
 </div>
 <script>
 $('li[data-include-user-name]').each(function(idx, elem) {
@@ -31,9 +31,9 @@ $('body.authenticated-user li[data-notification-count-url]').each(function(idx,
     crossDomain: true,
     success: function(data) {
       if (data.new) {
         $entry.find('span').append(' <span class="badge">' + data.new + '</span>');
       }
   }});
 });
 </script>
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/tests/test_pwa.py b/tests/test_pwa.py
index 3adf0832..77c4fa20 100644
--- a/tests/test_pwa.py
+++ b/tests/test_pwa.py
@@ -1,10 +1,11 @@
 import base64
 from unittest import mock
+from html.parser import HTMLParser
 
 import pytest
 from django.conf import settings
 from django.core.files import File
 from django.template import Context, Template
 from django.test import override_settings
 from django.test.client import RequestFactory
 from django.urls import reverse
@@ -248,16 +249,56 @@ def test_pwa_navigation_templatetag(app):
         assert nav.count('background-image') == 1
         assert nav.count('data-notification-count-url=') == 1
         assert nav.count('data-pwa-user-name=""') == 1
 
         nav = t.render(Context({'request': request, 'render_skeleton': True}))
         assert 'data-pwa-user-name="{% block placeholder-user-name %}' in nav
 
 
+def test_pwa_navigation_templatetag_internal_redirection(app):
+    page1 = Page(title='One', slug='one')
+    page2 = Page(title='Two', slug='two', redirect_url = 'https://www.example.org/test')
+    page3 = Page(title='Three', slug='three', redirect_url = '../test')
+    page4 = Page(title='Four', slug='four', redirect_url = '{{test_url}}plop')
+    page1.save()
+    page2.save()
+    page3.save()
+    page4.save()
+    entry1 = PwaNavigationEntry(link_page=page1, order=1)
+    entry2 = PwaNavigationEntry(link_page=page2, order=2)
+    entry3 = PwaNavigationEntry(link_page=page3, order=3)
+    entry4 = PwaNavigationEntry(link_page=page4, order=4)
+    entry1.save()
+    entry2.save()
+    entry3.save()
+    entry4.save()
+    t = Template('{% load pwa %}{% pwa_navigation %}')
+    assert t.render(Context({})) == ''
+
+    with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
+        request = RequestFactory().get('/')
+        nav = t.render(Context({'request': request}))
+
+    class MyHTMLParser(HTMLParser):
+        def handle_starttag(self, tag, attrs):
+            if tag == 'a':
+                results.append(attrs[0][1])
+
+    parser = MyHTMLParser()
+    results = []
+    parser.feed(nav)
+    assert results == [
+        'http://testserver/one/',
+        'https://www.example.org/test',
+        'http://testserver/three/',
+        'http://testserver/four/',
+    ]
+
+
 def test_pwa_application_icon(app, admin_user):
     app = login(app)
     with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
         PwaSettings.objects.all().delete()
         resp = app.get('/manage/pwa/')
         resp.form['application_icon'] = Upload(
             'test.png',
             base64.decodebytes(
-- 
2.30.2

