dynamicweb/cms/tests/test_permmod.py

764 lines
32 KiB
Python

from unittest.mock import patch
from django.contrib.admin.sites import site
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Group, Permission
from django.contrib.sites.models import Site
from django.db.models import Q
from django.test.client import RequestFactory
from django.test.utils import override_settings
from cms.admin.forms import save_permissions
from cms.api import assign_user_to_page, create_page, create_page_user
from cms.cms_menus import get_visible_page_contents
from cms.models import ACCESS_PAGE, CMSPlugin, Page, PageContent
from cms.models.permissionmodels import (
ACCESS_PAGE_AND_DESCENDANTS,
GlobalPagePermission,
PagePermission,
)
from cms.test_utils.testcases import CMSTestCase
from cms.test_utils.util.context_managers import override_placeholder_conf
from cms.test_utils.util.fuzzy_int import FuzzyInt
from cms.utils.page_permissions import user_can_view_page
from cms.utils.urlutils import admin_reverse
@override_settings(CMS_PERMISSION=True)
class PermissionModeratorTests(CMSTestCase):
"""Permissions and moderator together
Fixtures contains 3 users and 1 published page and some other stuff
Users:
1. `super`: superuser
2. `master`: user with permissions to all applications
3. `slave`: user assigned to page `slave-home`
Pages:
1. `home`:
- published page
- master can do anything on its subpages, but not on home!
2. `master`:
- published page
- created by super
- `master` can do anything on it and its descendants
- subpages:
3. `slave-home`:
- not published
- assigned slave user which can add/change/delete/
move/publish this page and its descendants
- `master` user want to moderate this page and all descendants
4. `pageA`:
- created by super
- master can add/change/delete on it and descendants
"""
# TODO: Split this test case into one that tests publish functionality, and
# TODO: one that tests permission inheritance. This is too complex.
def setUp(self):
# create super user
self.user_super = self._create_user("super", is_staff=True, is_superuser=True)
self.user_staff = self._create_user("staff", is_staff=True, add_default_permissions=True)
self.add_permission(self.user_staff, 'publish_page')
self.user_master = self._create_user("master", is_staff=True, add_default_permissions=True)
self.add_permission(self.user_master, 'publish_page')
self.user_slave = self._create_user("slave", is_staff=True, add_default_permissions=True)
self.user_normal = self._create_user("normal", is_staff=False)
self.user_normal.user_permissions.add(Permission.objects.get(codename='publish_page'))
with self.login_user_context(self.user_super):
self.home_page = create_page("home", "nav_playground.html", "en",
created_by=self.user_super)
# master page & master user
self.master_page = create_page("master", "nav_playground.html", "en")
# create non global, non staff user
self.user_non_global = self._create_user("nonglobal")
# assign master user under home page
assign_user_to_page(self.home_page, self.user_master,
grant_on=ACCESS_PAGE_AND_DESCENDANTS, grant_all=True)
# and to master page
assign_user_to_page(self.master_page, self.user_master,
grant_on=ACCESS_PAGE_AND_DESCENDANTS, grant_all=True)
# slave page & slave user
self.slave_page = create_page("slave-home", "col_two.html", "en",
parent=self.master_page, created_by=self.user_super)
assign_user_to_page(self.slave_page, self.user_slave, grant_all=True)
# create page_b
self.page_b = create_page("pageB", "nav_playground.html", "en", created_by=self.user_super)
# Normal user
# it's allowed for the normal user to view the page
assign_user_to_page(self.page_b, self.user_normal, can_view=True)
# create page_a - sample page from master
page_a = create_page("pageA", "nav_playground.html", "en",
created_by=self.user_super)
assign_user_to_page(page_a, self.user_master,
can_add=True, can_change=True, can_delete=True, can_publish=True,
can_move_page=True)
def _add_plugin(self, user, page):
"""
Add a plugin using the test client to check for permissions.
"""
with self.login_user_context(user):
placeholder = page.get_placeholders('en')[0]
data = {'name': 'A Link', 'external_link': 'https://www.django-cms.org'}
endpoint = self.get_add_plugin_uri(
placeholder=placeholder,
plugin_type='LinkPlugin',
language='en',
)
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
return response.content.decode('utf8')
def test_super_can_add_page_to_root(self):
with self.login_user_context(self.user_super):
response = self.client.get(self.get_page_add_uri('en'))
self.assertEqual(response.status_code, 200)
def test_master_cannot_add_page_to_root(self):
with self.login_user_context(self.user_master):
response = self.client.get(self.get_page_add_uri('en'))
self.assertEqual(response.status_code, 403)
def test_slave_cannot_add_page_to_root(self):
with self.login_user_context(self.user_slave):
response = self.client.get(self.get_page_add_uri('en'))
self.assertEqual(response.status_code, 403)
@override_placeholder_conf(
{
'col_left': {
'default_plugins': [
{
'plugin_type': 'TextPlugin',
'values': {
'body': 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa, repellendus, '
'delectus, quo quasi ullam inventore quod quam aut voluptatum aliquam voluptatibus '
'harum officiis officia nihil minus unde accusamus dolorem repudiandae.'
},
},
]
},
},
)
def test_default_plugins(self):
with self.login_user_context(self.user_slave):
self.assertEqual(CMSPlugin.objects.count(), 0)
response = self.client.get(self.slave_page.get_absolute_url(), {'edit': 1})
self.assertEqual(response.status_code, 200)
self.assertEqual(CMSPlugin.objects.count(), 1)
def test_super_can_add_plugin(self):
self._add_plugin(self.user_super, page=self.slave_page)
def test_master_can_add_plugin(self):
self._add_plugin(self.user_master, page=self.slave_page)
def test_slave_can_add_plugin(self):
self._add_plugin(self.user_slave, page=self.slave_page)
def test_superuser_can_view(self):
url = self.page_b.get_absolute_url(language='en')
with self.login_user_context(self.user_super):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_staff_can_view(self):
url = self.page_b.get_absolute_url(language='en')
all_view_perms = PagePermission.objects.filter(can_view=True)
# verify that the user_staff has access to this page
has_perm = False
for perm in all_view_perms:
if perm.page == self.page_b:
if perm.user == self.user_staff:
has_perm = True
self.assertEqual(has_perm, False)
login_ok = self.client.login(username=getattr(self.user_staff, get_user_model().USERNAME_FIELD),
password=getattr(self.user_staff, get_user_model().USERNAME_FIELD))
self.assertTrue(login_ok)
# really logged in
self.assertTrue('_auth_user_id' in self.client.session)
login_user_id = self.client.session.get('_auth_user_id')
user = get_user_model().objects.get(pk=self.user_staff.pk)
self.assertEqual(str(login_user_id), str(user.id))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_user_normal_can_view(self):
url = self.page_b.get_absolute_url(language='en')
all_view_perms = PagePermission.objects.filter(can_view=True)
# verify that the normal_user has access to this page
normal_has_perm = False
for perm in all_view_perms:
if perm.page == self.page_b:
if perm.user == self.user_normal:
normal_has_perm = True
self.assertTrue(normal_has_perm)
with self.login_user_context(self.user_normal):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
# verify that the user_non_global has not access to this page
non_global_has_perm = False
for perm in all_view_perms:
if perm.page == self.page_b:
if perm.user == self.user_non_global:
non_global_has_perm = True
self.assertFalse(non_global_has_perm)
with self.login_user_context(self.user_non_global):
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
# non logged in user
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_user_globalpermission(self):
# Global user
user_global = self._create_user("global")
with self.login_user_context(self.user_super):
user_global = create_page_user(user_global, user_global)
user_global.is_staff = False
user_global.save() # Prevent is_staff permission
global_page = create_page("global", "nav_playground.html", "en")
# Removed call since global page user doesn't have publish permission
# global_page = publish_page(global_page, user_global)
# it's allowed for the normal user to view the page
assign_user_to_page(global_page, user_global, global_permission=True, can_view=True)
url = global_page.get_absolute_url('en')
all_view_perms = PagePermission.objects.filter(can_view=True)
has_perm = False
for perm in all_view_perms:
if perm.page == self.page_b and perm.user == user_global:
has_perm = True
self.assertEqual(has_perm, False)
global_page_perm_q = Q(user=user_global) & Q(can_view=True)
global_view_perms = GlobalPagePermission.objects.filter(global_page_perm_q).exists()
self.assertEqual(global_view_perms, True)
# user_global
with self.login_user_context(user_global):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
# self.non_user_global
has_perm = False
for perm in all_view_perms:
if perm.page == self.page_b and perm.user == self.user_non_global:
has_perm = True
self.assertEqual(has_perm, False)
global_page_perm_q = Q(user=self.user_non_global) & Q(can_view=True)
global_view_perms = GlobalPagePermission.objects.filter(global_page_perm_q).exists()
self.assertEqual(global_view_perms, False)
with self.login_user_context(self.user_non_global):
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_anonymous_user_public_for_all(self):
url = self.page_b.get_absolute_url('en')
with self.settings(CMS_PUBLIC_FOR='all'):
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_anonymous_user_public_for_none(self):
# default of when to show pages to anonymous user doesn't take
# global permissions into account
url = self.page_b.get_absolute_url('en')
with self.settings(CMS_PUBLIC_FOR=None):
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_page_content_reflects_page_publish_permission(self):
"""
Test that the page content object gets its publish permission from the
page object.
"""
page = create_page('test', 'nav_playground.html', 'en')
page_content = page.get_content_obj("en")
user = self.get_standard_user()
assign_user_to_page(page, user, can_publish=True)
with patch.object(page, "has_publish_permission") as page_has_publish_permission:
self.assertTrue(page_content.has_publish_permission(user))
page_has_publish_permission.assert_called_once_with(user)
class ViewPermissionBaseTests(CMSTestCase):
def setUp(self):
self.page = create_page('testpage', 'nav_playground.html', 'en')
self.page_content = self.page.get_content_obj("en")
self.site = Site.objects.get_current()
def get_request(self, user=None):
attrs = {
'user': user or AnonymousUser(),
'REQUEST': {},
'POST': {},
'GET': {},
'session': {},
}
return type('Request', (object,), attrs)
def assertViewAllowed(self, page, user=None):
if not user:
user = AnonymousUser()
self.assertTrue(user_can_view_page(user, page))
def assertViewNotAllowed(self, page, user=None):
if not user:
user = AnonymousUser()
self.assertFalse(user_can_view_page(user, page))
@override_settings(
CMS_PERMISSION=False,
CMS_PUBLIC_FOR='staff',
)
class BasicViewPermissionTests(ViewPermissionBaseTests):
"""
Test functionality with CMS_PERMISSION set to false, as this is the
normal use case
"""
@override_settings(CMS_PUBLIC_FOR="all")
def test_unauth_public(self):
request = self.get_request()
with self.assertNumQueries(0):
self.assertViewAllowed(self.page)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [self.page_content])
def test_unauth_non_access(self):
request = self.get_request()
with self.assertNumQueries(0):
self.assertViewNotAllowed(self.page)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [])
@override_settings(CMS_PUBLIC_FOR="all")
def test_staff_public_all(self):
user = self.get_staff_user_with_no_permissions()
request = self.get_request(user)
with self.assertNumQueries(0):
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site),
[self.page_content])
def test_staff_public_staff(self):
user = self.get_staff_user_with_no_permissions()
request = self.get_request(user)
with self.assertNumQueries(0):
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site),
[self.page_content])
def test_staff_basic_auth(self):
user = self.get_staff_user_with_no_permissions()
request = self.get_request(user)
with self.assertNumQueries(0):
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site),
[self.page_content])
@override_settings(CMS_PUBLIC_FOR="all")
def test_normal_basic_auth(self):
user = self.get_standard_user()
request = self.get_request(user)
with self.assertNumQueries(0):
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [self.page_content])
@override_settings(
CMS_PERMISSION=True,
CMS_PUBLIC_FOR='none'
)
class UnrestrictedViewPermissionTests(ViewPermissionBaseTests):
"""
Test functionality with CMS_PERMISSION set to True but no restrictions
apply to this specific page
"""
def test_unauth_non_access(self):
request = self.get_request()
with self.assertNumQueries(1):
"""
The query is:
PagePermission query for the affected page (is the page restricted?)
"""
self.assertViewNotAllowed(self.page)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [])
def test_global_access(self):
user = self.get_standard_user()
GlobalPagePermission.objects.create(can_view=True, user=user)
request = self.get_request(user)
with self.assertNumQueries(4):
"""The queries are:
PagePermission query for the affected page (is the page restricted?)
Generic django permission lookup
content type lookup by permission lookup
GlobalPagePermission query for the page site
"""
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [self.page_content])
def test_normal_denied(self):
user = self.get_standard_user()
request = self.get_request(user)
with self.assertNumQueries(4):
"""
The queries are:
PagePermission query for the affected page (is the page restricted?)
GlobalPagePermission query for the page site
User permissions query
Content type query
"""
self.assertViewNotAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, [self.page_content], self.site), [])
@override_settings(
CMS_PERMISSION=True,
CMS_PUBLIC_FOR='all'
)
class RestrictedViewPermissionTests(ViewPermissionBaseTests):
"""
Test functionality with CMS_PERMISSION set to True and view restrictions
apply to this specific page
"""
def setUp(self):
super().setUp()
self.group = Group.objects.create(name='testgroup')
self.pages = [self.page]
self.page_contents = [self.page.get_content_obj("en")]
self.expected = [self.page.get_content_obj("en")]
PagePermission.objects.create(page=self.page, group=self.group, can_view=True, grant_on=ACCESS_PAGE)
def test_unauthed(self):
request = self.get_request()
with self.assertNumQueries(1):
"""The queries are:
PagePermission query for the affected page (is the page restricted?)
"""
self.assertViewNotAllowed(self.page)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), [])
def test_page_permissions(self):
user = self.get_standard_user()
request = self.get_request(user)
PagePermission.objects.create(can_view=True, user=user, page=self.page, grant_on=ACCESS_PAGE)
with self.assertNumQueries(5):
"""
The queries are:
PagePermission query (is this page restricted)
content type lookup (x2)
GlobalpagePermission query for user
PagePermission query for this user
"""
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), self.expected)
def test_page_group_permissions(self):
user = self.get_standard_user()
user.groups.add(self.group)
request = self.get_request(user)
with self.assertNumQueries(5):
"""
The queries are:
PagePermission query (is this page restricted)
content type lookup (x2)
GlobalpagePermission query for user
PagePermission query for user
"""
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), self.expected)
def test_global_permission(self):
user = self.get_standard_user()
GlobalPagePermission.objects.create(can_view=True, user=user)
request = self.get_request(user)
with self.assertNumQueries(4):
"""
The queries are:
PagePermission query (is this page restricted)
Generic django permission lookup
content type lookup by permission lookup
GlobalpagePermission query for user
"""
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), self.expected)
def test_basic_perm_denied(self):
user = self.get_staff_user_with_no_permissions()
request = self.get_request(user)
with self.assertNumQueries(5):
"""
The queries are:
PagePermission query (is this page restricted)
content type lookup x2
GlobalpagePermission query for user
PagePermission query for this user
"""
self.assertViewNotAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), [])
def test_basic_perm(self):
user = self.get_standard_user()
user.user_permissions.add(Permission.objects.get(codename='view_page'))
request = self.get_request(user)
with self.assertNumQueries(3):
"""
The queries are:
PagePermission query (is this page restricted)
Generic django permission lookup
content type lookup by permission lookup
"""
self.assertViewAllowed(self.page, user)
self.assertEqual(get_visible_page_contents(request, self.page_contents, self.site), self.expected)
class GlobalPermissionTests(CMSTestCase):
def test_emulate_admin_index(self):
""" Call methods that emulate the adminsite instance's index.
This test was basically the reason for the new manager, in light of the
problem highlighted in ticket #1120, which asserts that giving a user
no site-specific rights when creating a GlobalPagePermission should
allow access to all sites.
"""
# create and then ignore this user.
superuser = self._create_user("super", is_staff=True, is_active=True,
is_superuser=True)
superuser.set_password("super")
superuser.save()
site_1 = Site.objects.get(pk=1)
site_2 = Site.objects.create(domain='example2.com', name='example2.com')
SITES = [site_1, site_2]
# create 2 staff users
USERS = [
self._create_user("staff", is_staff=True, is_active=True),
self._create_user("staff_2", is_staff=True, is_active=True),
]
for user in USERS:
user.set_password('staff')
# reuse the same methods the UserPage form does.
# Note that it internally calls .save(), as we've not done so.
save_permissions({
'can_add_page': True,
'can_change_page': True,
'can_delete_page': False
}, user)
GlobalPagePermission.objects.create(can_add=True, can_change=True,
can_delete=False, user=USERS[0])
# we're querying here to ensure that even though we've created two users
# above, we should have successfully filtered to just one perm.
self.assertEqual(1, GlobalPagePermission.objects.with_user(USERS[0]).count())
# this will confirm explicit permissions still work, by adding the first
# site instance to the many2many relationship 'sites'
GlobalPagePermission.objects.create(can_add=True, can_change=True,
can_delete=False,
user=USERS[1]).sites.add(SITES[0])
self.assertEqual(1, GlobalPagePermission.objects.with_user(USERS[1]).count())
create_page(title="master", template="nav_playground.html",
language="en", in_navigation=True, slug='/')
with self.settings(CMS_PERMISSION=True):
# for all users, they should have access to site 1
request = RequestFactory().get(path='/')
# Fake session
request.session = {}
request.current_page = None
for user in USERS:
request.user = user
# Note, the query count is inflated by doing additional lookups
# because there's a site param in the request.
# max_queries = 5 for >dj21 because it's introduce default view permissions
max_queries = 5
with self.assertNumQueries(FuzzyInt(3, max_queries)):
# internally this calls PageAdmin.has_[add|change|delete|view]_permission()
expected_perms = {'add': True, 'change': True, 'delete': False}
expected_perms.update({'view': expected_perms['change']})
self.assertEqual(expected_perms, site._registry[PageContent].get_model_perms(request))
# can't use the above loop for this test, as we're testing that
# user 1 has access, but user 2 does not, as they are only assigned
# to site 1
request = RequestFactory().get(path=f'/?site={site_2.pk}')
request.current_page = None
request.session = {}
# Refresh internal user cache
USERS[0] = self.reload(USERS[0])
USERS[1] = self.reload(USERS[1])
# As before, the query count is inflated by doing additional lookups
# because there's a site param in the request
with self.assertNumQueries(FuzzyInt(5, 15)):
# this user shouldn't have access to site 2
request.user = USERS[1]
expected_perms = {'add': False, 'change': False, 'delete': False}
expected_perms.update({'view': False})
self.assertEqual(expected_perms, site._registry[PageContent].get_model_perms(request))
# but, going back to the first user, they should.
request = RequestFactory().get('/', data={'site__exact': site_2.pk})
request.user = USERS[0]
request.current_page = None
request.session = {}
expected_perms = {'add': True, 'change': True, 'delete': False}
expected_perms.update({'view': expected_perms['change']})
self.assertEqual(expected_perms, site._registry[PageContent].get_model_perms(request))
def test_has_page_add_permission_with_target(self):
page = create_page('Test', 'nav_playground.html', 'en')
user = self._create_user('user')
request = RequestFactory().get('/', data={'target': page.pk})
request.session = {}
request.user = user
has_perm = site._registry[Page].has_add_permission(request)
self.assertFalse(has_perm)
@override_settings(CMS_PERMISSION=True)
class AddPageParentPermissionTests(CMSTestCase):
"""The parent a page is created under is submitted in the POST body, while
``PageAdmin.has_add_permission`` only sees the one in the query string. Both
have to be checked, otherwise an editor confined to one subtree can point the
permission check at a page they may edit and create the page elsewhere."""
def setUp(self):
self.home = create_page('home', 'nav_playground.html', 'en')
self.allowed = create_page('allowed', 'nav_playground.html', 'en', parent=self.home)
self.forbidden = create_page('forbidden', 'nav_playground.html', 'en', parent=self.home)
self.editor = self._create_user('editor', is_staff=True)
self.editor.user_permissions.add(*Permission.objects.filter(
codename__in=[
'add_page', 'change_page', 'view_page',
'add_pagecontent', 'change_pagecontent', 'view_pagecontent',
]
))
PagePermission.objects.create(
page=self.allowed,
user=self.editor,
can_add=True,
can_change=True,
grant_on=ACCESS_PAGE_AND_DESCENDANTS,
)
def _add_page(self, slug, query_parent=None, body_parent=None):
url = admin_reverse('cms_pagecontent_add') + '?language=en'
if query_parent:
url += f'&parent_page={query_parent.pk}'
return self.client.post(url, {
'title': slug,
'slug': slug,
'parent_page': str(body_parent.pk) if body_parent else '',
})
def test_add_below_allowed_parent(self):
with self.login_user_context(self.editor):
response = self._add_page('ok', query_parent=self.allowed, body_parent=self.allowed)
self.assertEqual(response.status_code, 302)
self.assertEqual(Page.objects.filter(parent=self.allowed).count(), 1)
def test_add_below_forbidden_parent_is_denied(self):
with self.login_user_context(self.editor):
response = self._add_page('nope', query_parent=self.forbidden, body_parent=self.forbidden)
self.assertEqual(response.status_code, 403)
self.assertFalse(Page.objects.filter(parent=self.forbidden).exists())
def test_forbidden_parent_in_body_is_denied(self):
"""The query string points at a page the editor may add to, the body at one they may not."""
with self.login_user_context(self.editor):
response = self._add_page('nope', query_parent=self.allowed, body_parent=self.forbidden)
self.assertContains(response, 'You do not have permission to add a page here.')
self.assertFalse(Page.objects.filter(parent=self.forbidden).exists())
def test_empty_parent_in_body_is_denied(self):
"""An empty parent in the body would create a root page."""
root_pages = Page.objects.filter(parent=None).count()
with self.login_user_context(self.editor):
response = self._add_page('nope', query_parent=self.allowed, body_parent=None)
self.assertContains(response, 'You do not have permission to add a page here.')
self.assertEqual(Page.objects.filter(parent=None).count(), root_pages)
def test_add_translation_ignores_the_parent(self):
"""Adding a translation submits no parent, the permission is checked
against ``cms_page`` instead. The empty parent must not deny it."""
editor = self._create_user('global_editor', is_staff=True)
editor.user_permissions.add(*Permission.objects.filter(
codename__in=[
'add_page', 'change_page', 'view_page',
'add_pagecontent', 'change_pagecontent', 'view_pagecontent',
]
))
GlobalPagePermission.objects.create(user=editor, can_add=True, can_change=True)
url = admin_reverse('cms_pagecontent_add') + f'?language=de&cms_page={self.allowed.pk}'
with self.login_user_context(editor):
response = self.client.post(url, {
'title': 'erlaubt',
'slug': 'erlaubt',
'cms_page': str(self.allowed.pk),
'parent_page': '',
})
self.assertEqual(response.status_code, 302)
self.assertTrue(self.allowed.has_translation('de'))