Repository: django-cms/django-cms

Issue:
2.4 ?edit makes a page go 404
So I tried the develop branch on demo.django-cms.org and had a very weird experience.

Justi hitting /en/ shows me the nice "tutorial", adding ?edit to the URL gives us our default "404" page (The "go to admin and add pages" page). This really shouldn't happen.



Discussion:

Resolving patch:
diff --git a/cms/cms_toolbar.py b/cms/cms_toolbar.py
--- a/cms/cms_toolbar.py
+++ b/cms/cms_toolbar.py
@@ -91,7 +91,7 @@ def can_change(self):
 
     @property
     def edit_mode(self):
-        return self.is_staff and self.edit_mode_switcher.get_state(self.request)
+        return self.is_staff and self.edit_mode_switcher.get_state(self.request) and self.can_change
 
     @property
     def show_toolbar(self):
diff --git a/cms/utils/page_resolver.py b/cms/utils/page_resolver.py
--- a/cms/utils/page_resolver.py
+++ b/cms/utils/page_resolver.py
@@ -25,8 +25,8 @@ def use_draft(request):
     """
     preview_draft = 'preview' in request.GET and 'draft' in request.GET
     edit_mode = 'edit' in request.GET
-
-    return preview_draft or edit_mode
+    authenticated = request.user.is_authenticated() and request.user.is_staff
+    return (preview_draft or edit_mode) and authenticated
 
 
 def get_page_queryset(request=None):
@@ -129,11 +129,6 @@ def get_page_from_request(request, use_path=None):
 
     draft = use_draft(request)
     preview = 'preview' in request.GET
-    # If non-staff user, any request for preview/edit results in a "not found"
-    # This is to avoid confusing the toolbar logic into thinking it has an
-    # editable version
-    if draft and not request.user.is_authenticated():
-        return None
 
     # If use_path is given, someone already did the path cleaning
     if use_path is not None:
@@ -154,7 +149,7 @@ def get_page_from_request(request, use_path=None):
 
     page = get_page_from_path(path, preview, draft)
     if draft and page and not page.has_change_permission(request):
-        return None
+        page = get_page_from_path(path, preview, draft=False)
 
     request._current_page_cache = page
     return page


Test patch:
diff --git a/cms/tests/multilingual.py b/cms/tests/multilingual.py
--- a/cms/tests/multilingual.py
+++ b/cms/tests/multilingual.py
@@ -193,6 +193,7 @@ def test_detail_view_404_when_no_language_is_found(self):
                 method='GET',
                 COOKIES={},
                 META={},
+                user=User(),
             )
             self.assertRaises(Http404, details, request, '')
 
@@ -222,6 +223,7 @@ def test_detail_view_fallback_language(self):
                 method='GET',
                 COOKIES={},
                 META={},
+                user=User(),
             )
 
             response = details(request, '')
diff --git a/cms/tests/templatetags.py b/cms/tests/templatetags.py
--- a/cms/tests/templatetags.py
+++ b/cms/tests/templatetags.py
@@ -19,6 +19,7 @@
 from django.template import RequestContext, Context
 from django.template.base import Template
 from django.utils.html import escape
+from django.contrib.auth.models import User
 
 
 class TemplatetagTests(TestCase):
@@ -127,6 +128,7 @@ def test_show_placeholder_for_page_placeholder_does_not_exist(self):
             request = HttpRequest()
             request.REQUEST = {}
             request.session = {}
+            request.user = User()
             self.assertRaises(Placeholder.DoesNotExist,
                               _show_placeholder_for_page,
                               RequestContext(request),
@@ -214,7 +216,7 @@ def test_show_placeholder_for_page_marks_output_safe(self):
         request = RequestFactory().get('/')
         template = Template("{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'en' 1 %}{% render_block 'js' %}")
         context = RequestContext(request, {'page': page, 'slot': placeholder.slot})
-        with self.assertNumQueries(5):
+        with self.assertNumQueries(4):
             output = template.render(context)
         self.assertIn('<b>Test</b>', output)
         context = RequestContext(request, {'page': page, 'slot': placeholder.slot})
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -305,7 +305,7 @@ def test_toolbar_no_change_button(self):
         toolbar = CMSToolbar(request)
         self.assertFalse(page.has_change_permission(request))
         self.assertFalse(page.has_publish_permission(request))
-        self.assertTrue(toolbar.edit_mode)
+        self.assertFalse(toolbar.edit_mode)
         items = toolbar.get_items({})
         # Logo + page-menu + admin-menu + logout
         self.assertEqual(len(items), 4)
diff --git a/cms/tests/views.py b/cms/tests/views.py
--- a/cms/tests/views.py
+++ b/cms/tests/views.py
@@ -127,14 +127,13 @@ def test_edit_permission(self):
 
         # Anon user
         response = self.client.get("/en/?edit")
-        self.assertEqual(response.status_code, 404)
+        self.assertContains(response, "'edit_mode': false,", 1, 200)
 
         # Superuser
         user = self.get_superuser()
         self.client.login(username=user.username, password=user.username)
         response = self.client.get("/en/?edit")
-        #response = details(request, '')
-        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, "'edit_mode': true,", 1, 200)
 
         # Admin but with no permission
         user = self.get_staff_user_with_no_permissions()
@@ -142,8 +141,8 @@ def test_edit_permission(self):
 
         self.client.login(username=user.username, password=user.username)
         response = self.client.get("/en/?edit")
-        self.assertEqual(response.status_code, 404)
+        self.assertContains(response, "'edit_mode': false,", 1, 200)
 
         PagePermission.objects.create(can_change=True, user=user, page=page)
         response = self.client.get("/en/?edit")
-        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, "'edit_mode': true,", 1, 200)