Skip to content

Commit 090cd40

Browse files
committed
Actual fix for Issue 1166. Reworked PageAdmin.change_status and PageForm.clean to check for clashing urls
1 parent 5b6cc3f commit 090cd40

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

cms/admin/forms.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
PageUserGroup)
66
from cms.utils.mail import mail_page_user_change
77
from cms.utils.page import is_valid_page_slug
8-
from cms.utils.page_resolver import get_page_from_path
8+
from cms.utils.page_resolver import get_page_from_path, is_valid_overwrite_url
99
from cms.utils.permissions import (get_current_user, get_subordinate_users,
1010
get_subordinate_groups)
1111
from cms.utils.urlutils import any_path_re
@@ -116,6 +116,22 @@ def clean(self):
116116
if site and not is_valid_page_slug(page, parent, lang, slug, site):
117117
self._errors['slug'] = ErrorList([_('Another page with this slug already exists')])
118118
del cleaned_data['slug']
119+
if self.cleaned_data['published'] and page.title_set.count():
120+
#Check for titles attached to the page makes sense only because
121+
#AdminFormsTests.test_clean_overwrite_url validates the form with when no page instance available
122+
#Looks like just a theoretical corner case
123+
t = page.get_title_obj(lang)
124+
if t:
125+
oldslug = t.slug
126+
t.slug = self.cleaned_data['slug']
127+
t.save()
128+
try:
129+
is_valid_overwrite_url(t.path,page)
130+
except ValidationError,e:
131+
t.slug = oldslug
132+
t.save()
133+
del cleaned_data['published']
134+
self._errors['published'] = ErrorList(e.messages)
119135
return cleaned_data
120136

121137
def clean_slug(self):
@@ -173,15 +189,9 @@ def clean(self):
173189
def clean_overwrite_url(self):
174190
if 'overwrite_url' in self.fields:
175191
url = self.cleaned_data['overwrite_url']
176-
if url:
177-
if not any_path_re.match(url):
178-
raise forms.ValidationError(_('Invalid URL, use /my/url format.'))
179-
page = get_page_from_path(url.strip('/'))
180-
if (page and
181-
page.pk not in [self.instance.pk,
182-
self.instance.publisher_public_id]):
183-
raise forms.ValidationError(_('Page with redirect url %r already exist') % url)
184-
return url
192+
is_valid_overwrite_url(url,self.instance)
193+
# TODO: Check what happens if 'overwrite_url' is NOT in self.fields
194+
return url
185195

186196
class PagePermissionInlineAdminForm(forms.ModelForm):
187197
"""

cms/admin/pageadmin.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
from django.contrib.admin.util import get_deleted_objects
2626
from urllib2 import unquote
2727
from django.contrib.sites.models import Site
28-
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
28+
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
2929
from django.core.urlresolvers import reverse
3030
from django.db import router, transaction, models
3131
from django.forms import CharField
3232
from django.http import (HttpResponseRedirect, HttpResponse, Http404,
33-
HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotAllowed)
33+
HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotAllowed, HttpResponseServerError)
3434
from django.shortcuts import render_to_response, get_object_or_404
3535
from django.template.context import RequestContext
3636
from django.template.defaultfilters import (title, escape, force_escape,
@@ -43,6 +43,8 @@
4343

4444
DJANGO_1_3 = LooseVersion(django.get_version()) < LooseVersion('1.4')
4545

46+
from cms.utils.page_resolver import is_valid_overwrite_url
47+
4648
if 'reversion' in settings.INSTALLED_APPS:
4749
import reversion
4850
from reversion.admin import VersionAdmin as ModelAdmin
@@ -1055,9 +1057,13 @@ def change_status(self, request, page_id):
10551057
return HttpResponseNotAllowed(['POST'])
10561058
page = get_object_or_404(Page, pk=page_id)
10571059
if page.has_publish_permission(request):
1058-
page.published = not page.published
1059-
page.save()
1060-
return admin_utils.render_admin_menu_item(request, page)
1060+
try:
1061+
if page.published or is_valid_overwrite_url(page.get_absolute_url(),page):
1062+
page.published = not page.published
1063+
page.save()
1064+
return admin_utils.render_admin_menu_item(request, page)
1065+
except ValidationError,e:
1066+
return HttpResponseServerError(unicode(e))
10611067
else:
10621068
return HttpResponseForbidden(unicode(_("You do not have permission to publish this page")))
10631069

cms/models/pagemodel.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ def move_page(self, target, position='first-child'):
128128
all the places which are changing page position. Used like an interface
129129
to mptt, but after move is done page_moved signal is fired.
130130
"""
131+
# TODO: Check for slug/overwrite_url clashes upon copying page (in the current page and all children pages)
131132
# make sure move_page does not break when using INHERIT template
132133
if (position in ('left', 'right')
133134
and not target.parent
@@ -155,6 +156,7 @@ def copy_page(self, target, site, position='first-child',
155156
Note: public_copy was added in order to enable the creation of a copy for creating the public page during
156157
the publish operation as it sets the publisher_is_draft=False.
157158
"""
159+
# TODO: Check for slug/overwrite_url clashes upon copying page (in the current page and all children pages)
158160
from cms.utils.moderator import update_moderation_message
159161

160162
page_copy = None

0 commit comments

Comments
 (0)