Skip to content

Commit

Permalink
Started working on django-cms#1019, it should prevent the issue in mo…
Browse files Browse the repository at this point in the history
…st cases,

however it's really insanely hard to cover edge-cases (especially for
home-pages) since it's not trivial to check if a page will be the
homepage or not.
  • Loading branch information
Jonas Obrist committed Oct 14, 2011
1 parent 7865ae9 commit bf448a1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 3 deletions.
29 changes: 29 additions & 0 deletions cms/admin/forms.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -170,6 +170,35 @@ def clean(self):
raise forms.ValidationError(_('A page with this reverse URL id exists already.')) raise forms.ValidationError(_('A page with this reverse URL id exists already.'))
return cleaned_data return cleaned_data


def clean_redirect(self):
"""
Prevent infinite redirects
"""
redirect = self.cleaned_data.get('redirect', None)
if not redirect:
return redirect
slug = self.cleaned_data.get('slug', None)
if not slug:
return redirect
parent_id = self.cleaned_data.get('parent', None)
old_slug = self.instance.get_slug()
if old_slug == slug and self.instance.parent_id == parent_id:
url = self.instance.get_absolute_url()
else:
if parent_id:
url = Page.objects.get(pk=parent_id).get_absolute_url()
else:
url = '/'
if parent_id:
url += slug
elif not self.instance.is_home():
url += slug
if not url.endswith('/'):
url += '/'
if url == redirect:
raise forms.ValidationError("Inifinite redirect, please chose a different redirect")
return redirect

def clean_overwrite_url(self): def clean_overwrite_url(self):
if 'overwrite_url' in self.fields: if 'overwrite_url' in self.fields:
url = self.cleaned_data['overwrite_url'] url = self.cleaned_data['overwrite_url']
Expand Down
17 changes: 15 additions & 2 deletions cms/api.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
from cms.utils.permissions import _thread_locals from cms.utils.permissions import _thread_locals




#==============================================================================
# Exceptions
#==============================================================================

class InfiniteRedirectLoop(Exception): pass

#=============================================================================== #===============================================================================
# Constants # Constants
#=============================================================================== #===============================================================================
Expand Down Expand Up @@ -193,7 +199,7 @@ def create_page(title, template, language, menu_title=None, slug=None,
if settings.CMS_MODERATOR and _thread_locals.user: if settings.CMS_MODERATOR and _thread_locals.user:
page.pagemoderator_set.create(user=_thread_locals.user) page.pagemoderator_set.create(user=_thread_locals.user)


create_title( title = create_title(
language=language, language=language,
title=title, title=title,
menu_title=menu_title, menu_title=menu_title,
Expand All @@ -207,8 +213,15 @@ def create_page(title, template, language, menu_title=None, slug=None,
) )


del _thread_locals.user del _thread_locals.user
return page


redirect = page.get_redirect(language)
if redirect and redirect == page.get_absolute_url(language):
title.delete()
page.delete()
raise InfiniteRedirectLoop()

return page

def create_title(language, title, page, menu_title=None, slug=None, def create_title(language, title, page, menu_title=None, slug=None,
apphook=None, redirect=None, meta_description=None, apphook=None, redirect=None, meta_description=None,
meta_keywords=None, parent=None, overwrite_url=None): meta_keywords=None, parent=None, overwrite_url=None):
Expand Down
21 changes: 21 additions & 0 deletions cms/tests/admin.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -967,3 +967,24 @@ def test_clean_overwrite_url(self):
Title.objects.set_or_create(request, instance, form, 'en') Title.objects.set_or_create(request, instance, form, 'en')
form = PageForm(data, instance=instance) form = PageForm(data, instance=instance)
self.assertTrue(form.is_valid(), form.errors.as_text()) self.assertTrue(form.is_valid(), form.errors.as_text())

def test_infinite_redirect(self):
user = AnonymousUser()
user.is_superuser = True
user.pk = 1
site = Site.objects.get_current()
template = settings.CMS_TEMPLATES[0][0]
instance = create_page('Test Page', template, 'en', site=site, published=True)
with SettingsOverride(CMS_MODERATOR=False):
data = {
'title': 'TestPage',
'slug': 'test-page',
'language': 'en',
'redirect': '/',
'site': site.pk,
'template': template,
'published': True
}

form = PageForm(data, instance=instance)
self.assertFalse(form.is_valid(), form.errors.as_text())
7 changes: 6 additions & 1 deletion cms/tests/api.py
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import with_statement from __future__ import with_statement
from cms.api import (_generate_valid_slug, create_page, _verify_plugin_type, from cms.api import (_generate_valid_slug, create_page, _verify_plugin_type,
assign_user_to_page, publish_page) assign_user_to_page, InfiniteRedirectLoop)
from cms.apphook_pool import apphook_pool from cms.apphook_pool import apphook_pool
from cms.models.pagemodel import Page from cms.models.pagemodel import Page
from cms.plugin_base import CMSPluginBase from cms.plugin_base import CMSPluginBase
Expand Down Expand Up @@ -186,3 +186,8 @@ def test_create_page_can_overwrite_url(self):
page = create_page(**page_attrs) page = create_page(**page_attrs)
self.assertTrue(page.get_title_obj_attribute('has_url_overwrite')) self.assertTrue(page.get_title_obj_attribute('has_url_overwrite'))
self.assertEqual(page.get_title_obj_attribute('path'), 'test/home') self.assertEqual(page.get_title_obj_attribute('path'), 'test/home')

def test_create_page_infinite_redirect(self):
self.assertRaises(InfiniteRedirectLoop, create_page, "one",
"nav_playground.html", "en", published=True,
redirect='/')

0 comments on commit bf448a1

Please sign in to comment.