From a4a3ef8147f3dfcb36df0a0067924da00dc8b11e Mon Sep 17 00:00:00 2001 From: Eric Drechsel Date: Wed, 21 Jan 2015 10:49:25 -0800 Subject: [PATCH 1/4] #901 allow absolute path references in External link chooser tab --- wagtail/wagtailadmin/forms.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/forms.py b/wagtail/wagtailadmin/forms.py index f62d7ae31..de07ac01c 100644 --- a/wagtail/wagtailadmin/forms.py +++ b/wagtail/wagtailadmin/forms.py @@ -1,4 +1,6 @@ from django import forms +from django.core import validators +from django.forms.widgets import TextInput from django.contrib.auth import get_user_model from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm from django.utils.translation import ugettext as _ @@ -6,6 +8,25 @@ from django.utils.translation import ungettext, ugettext_lazy from wagtail.wagtailadmin.widgets import AdminPageChooser from wagtail.wagtailcore.models import Page +class URLOrAbsolutePathValidator(validators.URLValidator): + @staticmethod + def is_absolute_path(value): + return value.startswith('/') + + def __call__(self, value): + if URLOrAbsolutePathValidator.is_absolute_path(value): + return None + else: + return super(URLOrAbsolutePathValidator, self).__call__(value) + +class URLOrAbsolutePathField(forms.URLField): + widget = TextInput + default_validators = [URLOrAbsolutePathValidator()] + + def to_python(self, value): + if not URLOrAbsolutePathValidator.is_absolute_path(value): + value = super(URLOrAbsolutePathField, self).to_python(value) + return value class SearchForm(forms.Form): def __init__(self, *args, **kwargs): @@ -22,11 +43,11 @@ class SearchForm(forms.Form): class ExternalLinkChooserForm(forms.Form): - url = forms.URLField(required=True) + url = URLOrAbsolutePathField(required=True) class ExternalLinkChooserWithLinkTextForm(forms.Form): - url = forms.URLField(required=True) + url = URLOrAbsolutePathField(required=True) link_text = forms.CharField(required=True) From b73404214009151b4a7d4c817c5024190bf37a6c Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:39:47 +0000 Subject: [PATCH 2/4] Unit test for #917 --- .../wagtailadmin/tests/test_page_chooser.py | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_page_chooser.py b/wagtail/wagtailadmin/tests/test_page_chooser.py index 475e4f7b1..834acde8c 100644 --- a/wagtail/wagtailadmin/tests/test_page_chooser.py +++ b/wagtail/wagtailadmin/tests/test_page_chooser.py @@ -101,9 +101,24 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils): self.assertEqual(self.get({'prompt_for_link_text': 'foo'}).status_code, 200) def test_create_link(self): - request = self.post({'url': 'http://www.example.com'}) - self.assertContains(request, "'url': 'http://www.example.com/',") - self.assertContains(request, "'title': 'http://www.example.com/'") + response = self.post({'url': 'http://www.example.com'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'onload'") # indicates success / post back to calling page + self.assertContains(response, "'url': 'http://www.example.com/',") + self.assertContains(response, "'title': 'http://www.example.com/'") + + def test_invalid_url(self): + response = self.post({'url': 'ntp://www.example.com'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'html'") # indicates failure / show error message + self.assertContains(response, "Enter a valid URL.") + + def test_allow_local_url(self): + response = self.post({'url': '/admin/'}) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "'onload'") # indicates success / post back to calling page + self.assertContains(response, "'url': '/admin/',") + self.assertContains(response, "'title': '/admin/'") class TestChooserEmailLink(TestCase, WagtailTestUtils): From c92102370203379be089c752b52af425e4ce3b16 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:49:01 +0000 Subject: [PATCH 3/4] release note for #917 --- CHANGELOG.txt | 1 + docs/releases/0.9.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 81e123571..8cdf5ca0d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -23,6 +23,7 @@ Changelog * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 + * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site (Eric Drechsel) 0.8.5 (xx.xx.20xx) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index e265150ae..d0893095a 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -32,6 +32,7 @@ Minor features * Page model fields without a FieldPanel are no longer displayed in the form * No longer need to specify the base model on InlinePanel definitions * The project template Vagrantfile now listens on port 8000 + * The external link chooser in rich text areas now accepts URLs of the form '/some/local/path', to allow linking to non-Wagtail-controlled URLs within the local site Bug fixes From 77e99e951dfab77f942f9c87010a303f7d8d0ebf Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 16 Feb 2015 13:51:14 +0000 Subject: [PATCH 4/4] fix italic vs code formatting mismatches --- docs/releases/0.9.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index d0893095a..2482d718d 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -23,10 +23,10 @@ Minor features * Dropped Python 2.6 and 3.2 support * Dropped Elasticsearch 0.90.x support * Search view accepts "page" GET parameter in line with pagination - * Removed the dependency on `LOGIN_URL` and `LOGIN_REDIRECT_URL` settings + * Removed the dependency on ``LOGIN_URL`` and ``LOGIN_REDIRECT_URL`` settings * Password reset view names namespaced to wagtailadmin * Removed the need to add permission check on admin views (now automated) - * Reversing `django.contrib.auth.admin.login` will no longer lead to Wagtails login view (making it easier to have front end views) + * Reversing ``django.contrib.auth.admin.login`` will no longer lead to Wagtails login view (making it easier to have front end views) * Added cache-control headers to all admin views. This allows Varnish/Squid/CDN to run on vanilla settings in front of a Wagtail site * Added validation to prevent pages being created with only whitespace characters in their title fields * Page model fields without a FieldPanel are no longer displayed in the form