Skip to content

Commit fc59f73

Browse files
committed
Add listener to m2m_changed signal to invalidate permissions cache if group assignment of a user is changed
1 parent 0f81cea commit fc59f73

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

cms/signals/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
pre_save_group,
2828
pre_save_pagepermission,
2929
pre_save_user,
30+
user_m2m_changed,
3031
)
3132
from cms.utils.conf import get_cms_setting
3233

@@ -89,6 +90,7 @@ def check_v4_confirmation(**kwargs):
8990
signals.pre_save.connect(pre_save_user, sender=User, dispatch_uid='cms_pre_save_user')
9091
signals.post_save.connect(post_save_user, sender=User, dispatch_uid='cms_post_save_user')
9192
signals.pre_delete.connect(pre_delete_user, sender=User, dispatch_uid='cms_pre_delete_user')
93+
signals.m2m_changed.connect(user_m2m_changed, sender=User.groups.through, dispatch_uid='cms_user_m2m_changed')
9294

9395
signals.pre_save.connect(pre_save_user, sender=PageUser, dispatch_uid='cms_pre_save_pageuser')
9496
signals.pre_delete.connect(pre_delete_user, sender=PageUser, dispatch_uid='cms_pre_delete_pageuser')

cms/signals/permissions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
from django.contrib.auth import get_user_model
2+
13
from cms.cache.permissions import clear_user_permission_cache
24
from cms.models import PageUser, PageUserGroup
35
from menus.menu_pool import menu_pool
46

7+
User = get_user_model()
8+
59

610
def post_save_user(instance, raw, created, **kwargs):
711
"""Signal called when new user is created, required only when CMS_PERMISSION.
812
Assigns creator of the user to PageUserInfo model, so we know who had created
913
this user account.
1014
15+
Flushes permission cache for the user.
16+
1117
requires: CurrentUserMiddleware
1218
"""
1319
from cms.utils.permissions import get_current_user
@@ -21,6 +27,8 @@ def post_save_user(instance, raw, created, **kwargs):
2127
page_user.__dict__.update(instance.__dict__)
2228
page_user.save()
2329

30+
clear_user_permission_cache(instance
31+
)
2432

2533
def post_save_user_group(instance, raw, created, **kwargs):
2634
"""The same like post_save_user, but for Group, required only when
@@ -62,6 +70,11 @@ def pre_delete_group(instance, **kwargs):
6270
clear_user_permission_cache(user)
6371

6472

73+
def user_m2m_changed(instance, action, reverse, model, pk_set, sender, **kwargs):
74+
if action in ('pre_add', 'pre_remove',) and not reverse:
75+
clear_user_permission_cache(instance)
76+
77+
6578
def _clear_users_permissions(instance):
6679
if instance.user:
6780
clear_user_permission_cache(instance.user)

cms/tests/test_page_admin.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2647,7 +2647,7 @@ def test_user_cant_delete_page_view_restrictions(self):
26472647

26482648
def test_permissions_cache_invalidation(self):
26492649
"""
2650-
Test permission cache clearing on page save
2650+
Permission cache clears on page save
26512651
"""
26522652
page = self.get_permissions_test_page()
26532653
staff_user = self.get_staff_user_with_std_permissions()
@@ -2660,6 +2660,42 @@ def test_permissions_cache_invalidation(self):
26602660
self.client.post(endpoint, data)
26612661
self.assertIsNone(get_permission_cache(staff_user, "change_page"))
26622662

2663+
def test_permission_cache_invalidation_on_group_add(self):
2664+
"""
2665+
Permissions cache is invalidated if the group relationship of a user is changed
2666+
"""
2667+
from django.contrib.auth.models import Group
2668+
2669+
page = self.get_permissions_test_page()
2670+
staff_user = self.get_staff_user_with_std_permissions()
2671+
set_permission_cache(staff_user, "change_page", [page.pk])
2672+
2673+
group = Group(name="test_group")
2674+
group.save()
2675+
staff_user.groups.add(group)
2676+
2677+
self.assertIsNone(get_permission_cache(staff_user, "change_page"))
2678+
2679+
2680+
def test_permission_cache_invalidation_on_group_remove(self):
2681+
"""
2682+
Permissions cache is invalidated if the group relationship of a user is changed
2683+
"""
2684+
from django.contrib.auth.models import Group
2685+
2686+
page = self.get_permissions_test_page()
2687+
staff_user = self.get_staff_user_with_std_permissions()
2688+
group = Group(name="test_group")
2689+
group.save()
2690+
staff_user.groups.add(group)
2691+
2692+
set_permission_cache(staff_user, "change_page", [page.pk])
2693+
2694+
staff_user.groups.remove(group)
2695+
2696+
self.assertIsNone(get_permission_cache(staff_user, "change_page"))
2697+
2698+
26632699
def test_user_can_copy_page(self):
26642700
"""
26652701
Test that a page can be copied via the admin

0 commit comments

Comments
 (0)