Skip to content

Commit

Permalink
Better cache eviction and testing (#635)
Browse files Browse the repository at this point in the history
  • Loading branch information
qeternity authored and ad-m committed Sep 8, 2019
1 parent 2246cd8 commit d3a3c60
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 2 deletions.
4 changes: 2 additions & 2 deletions guardian/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_version():

def monkey_patch_user():
from django.contrib.auth import get_user_model
from .utils import get_anonymous_user
from .utils import get_anonymous_user, evict_obj_perms_cache
from .models import UserObjectPermission
User = get_user_model()
# Prototype User and Group methods
Expand All @@ -27,4 +27,4 @@ def monkey_patch_user():
lambda self, perm, obj: UserObjectPermission.objects.assign_perm(perm, self, obj))
setattr(User, 'del_obj_perm',
lambda self, perm, obj: UserObjectPermission.objects.remove_perm(perm, self, obj))
setattr(User, 'evict_obj_perm_cache', lambda self: delattr(self, '_guardian_perms_cache'))
setattr(User, 'evict_obj_perms_cache', evict_obj_perms_cache)
21 changes: 21 additions & 0 deletions guardian/testapp/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from guardian.models import UserObjectPermission, GroupObjectPermission
from guardian.shortcuts import assign_perm
from guardian.management import create_anonymous_user
from guardian.utils import evict_obj_perms_cache

from guardian.testapp.models import Project, ProjectUserObjectPermission, ProjectGroupObjectPermission

Expand Down Expand Up @@ -457,6 +458,13 @@ def test_autoprefetch_user_perms(self):
assign_groups = [self.group, group1]
for group in assign_groups:
assign_perm("change_group", user, group)

# Faux monkeypatching
setattr(User, 'evict_obj_perms_cache', evict_obj_perms_cache)

# Try to evict non-existent cache, should return false
self.assertFalse(user.evict_obj_perms_cache())

checker = ObjectPermissionChecker(user)

pre_query_count = len(connection.queries)
Expand Down Expand Up @@ -494,6 +502,19 @@ def test_autoprefetch_user_perms(self):
# not hit DB
self.assertFalse(checker.has_perm("change_group", group2))
self.assertEqual(len(connection.queries), query_count)

# Evict cache and verify that reloaded perms have changed
self.assertTrue(user.evict_obj_perms_cache())
self.assertFalse(hasattr(user, '_guardian_perms_cache'))
assign_perm("delete_group", user, self.group)
query_count = len(connection.queries)
# New checker object so that we reload perms from db
checker = ObjectPermissionChecker(user)
self.assertTrue(checker.has_perm("delete_group", self.group))
# Two more queries should have been executed
self.assertEqual(len(connection.queries), query_count + 2)


finally:
settings.DEBUG = False
guardian_settings.AUTO_PREFETCH = False
Expand Down
5 changes: 5 additions & 0 deletions guardian/testapp/tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,15 @@ class CustomUserTestClass(AbstractUser):
self.assertFalse(getattr(CustomUserTestClass, 'get_anonymous', False))
self.assertFalse(getattr(CustomUserTestClass, 'add_obj_perm', False))
self.assertFalse(getattr(CustomUserTestClass, 'del_obj_perm', False))
self.assertFalse(getattr(CustomUserTestClass, 'evict_obj_perms_cache', False))

# Monkey Patch
guardian.monkey_patch_user()

self.assertTrue(getattr(CustomUserTestClass, 'get_anonymous', False))
self.assertTrue(getattr(CustomUserTestClass, 'add_obj_perm', False))
self.assertTrue(getattr(CustomUserTestClass, 'del_obj_perm', False))
self.assertTrue(getattr(CustomUserTestClass, 'evict_obj_perms_cache', False))

user = CustomUserTestClass()
self.assertFalse(user.evict_obj_perms_cache())
7 changes: 7 additions & 0 deletions guardian/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,10 @@ def get_group_obj_perms_model(obj):
from guardian.models import GroupObjectPermissionBase
from guardian.models import GroupObjectPermission
return get_obj_perms_model(obj, GroupObjectPermissionBase, GroupObjectPermission)


def evict_obj_perms_cache(obj):
if hasattr(obj, '_guardian_perms_cache'):
delattr(obj, '_guardian_perms_cache')
return True
return False

0 comments on commit d3a3c60

Please sign in to comment.