Repository: django-cms/django-cms

Issue:
Toolbar middleware breaks custom logout template
If you customize the standard `registration/logged_out.html` template, this cannot inherit from a base template that has `{% cms_toolbar %}`. If you do, you'll get:

```
TypeError: int() argument must be a string or a number, not 'AnonymousUser'
```

If you refresh the page, the error goes away. This is because the middleware sets attributes on the request object during process_request at which point the user is still logged in because the logout view hasn't been called yet. The tag picks up from there assuming all is good but of course is not.



Discussion:

Resolving patch:
diff --git a/cms/toolbar/toolbar.py b/cms/toolbar/toolbar.py
--- a/cms/toolbar/toolbar.py
+++ b/cms/toolbar/toolbar.py
@@ -231,7 +231,9 @@ def populate(self):
             return
         self.populated = True
         # never populate the toolbar on is_staff=False
-        if not self.is_staff:
+        # FIXME: In 3.1 we should really update the request/staff status
+        # when toolbar is used in the cms_toolbar templatetag
+        if not self.request.user.is_staff:
             return
         if self.request.session.get('cms_log_latest', False):
             del self.request.session['cms_log_latest']
@@ -242,7 +244,9 @@ def post_template_populate(self):
         if self.post_template_populated:
             return
         self.post_template_populated = True
-        if not self.is_staff:
+        # FIXME: In 3.1 we should really update the request/staff status
+        # when toolbar is used in the cms_toolbar templatetag
+        if not self.request.user.is_staff:
             return
         self._call_toolbar('post_template_populate')
 


Test patch:
diff --git a/cms/test_utils/project/templates/registration/logged_out.html b/cms/test_utils/project/templates/registration/logged_out.html
new file mode 100644
--- /dev/null
+++ b/cms/test_utils/project/templates/registration/logged_out.html
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+
+{% block content %}
+
+<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
+
+
+{% endblock %}
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -183,6 +183,26 @@ def test_hide_toolbar_non_staff(self):
         self.assertFalse(request.session.get('cms_build', True))
         self.assertFalse(request.session.get('cms_edit', True))
 
+    def test_show_toolbar_login_anonymous(self):
+        create_page("toolbar-page", "nav_playground.html", "en", published=True)
+        response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, 'cms_form-login')
+
+    def test_hide_toolbar_login_nonstaff(self):
+        create_page("toolbar-page", "nav_playground.html", "en", published=True)
+        with self.login_user_context(self.get_nonstaff()):
+            response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
+        self.assertEqual(response.status_code, 200)
+        self.assertNotContains(response, 'cms_form-login')
+        self.assertNotContains(response, 'cms_toolbar')
+
+    def test_admin_logout_staff(self):
+        with SettingsOverride(CMS_PERMISSION=True):
+            with self.login_user_context(self.get_staff()):
+                response = self.client.get('/en/admin/logout/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
+                self.assertTrue(response.status_code, 200)
+
     def test_show_toolbar_without_edit(self):
         page = create_page("toolbar-page", "nav_playground.html", "en",
                            published=True)