1from __future__ import unicode_literals
2
3from django.apps import apps as django_apps
4auth_app = django_apps.get_app_config("auth")
5
6from django.contrib.contenttypes.models import ContentType
7from django.core.management import call_command
8from django.test import TestCase
9
10from guardian.compat import get_user_model, create_permissions, get_model_name
11from guardian.utils import clean_orphan_obj_perms
12from guardian.shortcuts import assign_perm
13from guardian.models import Group
14from guardian.testapp.tests.conf import skipUnlessTestApp
15
16
17User = get_user_model()
18user_module_name = get_model_name(User)
19
20
21@skipUnlessTestApp
22class OrphanedObjectPermissionsTest(TestCase):
23
24    def setUp(self):
25        # Create objects for which we would assing obj perms
26        self.target_user1 = User.objects.create(username='user1')
27        self.target_group1 = Group.objects.create(name='group1')
28        self.target_obj1 = ContentType.objects.create(
29            model='foo', app_label='fake-for-guardian-tests')
30        self.target_obj2 = ContentType.objects.create(
31            model='bar', app_label='fake-for-guardian-tests')
32        # Required if MySQL backend is used :/
33        create_permissions(auth_app, [], 1)
34
35        self.user = User.objects.create(username='user')
36        self.group = Group.objects.create(name='group')
37
38    def test_clean_perms(self):
39
40        # assign obj perms
41        target_perms = {
42            self.target_user1: ["change_%s" % user_module_name],
43            self.target_group1: ["delete_group"],
44            self.target_obj1: ["change_contenttype", "delete_contenttype"],
45            self.target_obj2: ["change_contenttype"],
46        }
47        obj_perms_count = sum([len(val) for key, val in target_perms.items()])
48        for target, perms in target_perms.items():
49            target.__old_pk = target.pk  # Store pkeys
50            for perm in perms:
51                assign_perm(perm, self.user, target)
52
53        # Remove targets
54        for target, perms in target_perms.items():
55            target.delete()
56
57        # Clean orphans
58        removed = clean_orphan_obj_perms()
59        self.assertEqual(removed, obj_perms_count)
60
61        # Recreate targets and check if user has no permissions
62        for target, perms in target_perms.items():
63            target.pk = target.__old_pk
64            target.save()
65            for perm in perms:
66                self.assertFalse(self.user.has_perm(perm, target))
67
68    def test_clean_perms_command(self):
69        """
70        Same test as the one above but rather function directly, we call
71        management command instead.
72        """
73
74        # assign obj perms
75        target_perms = {
76            self.target_user1: ["change_%s" % user_module_name],
77            self.target_group1: ["delete_group"],
78            self.target_obj1: ["change_contenttype", "delete_contenttype"],
79            self.target_obj2: ["change_contenttype"],
80        }
81        for target, perms in target_perms.items():
82            target.__old_pk = target.pk  # Store pkeys
83            for perm in perms:
84                assign_perm(perm, self.user, target)
85
86        # Remove targets
87        for target, perms in target_perms.items():
88            target.delete()
89
90        # Clean orphans
91        call_command("clean_orphan_obj_perms", verbosity=0)
92
93        # Recreate targets and check if user has no permissions
94        for target, perms in target_perms.items():
95            target.pk = target.__old_pk
96            target.save()
97            for perm in perms:
98                self.assertFalse(self.user.has_perm(perm, target))
99