1 | Index: django/contrib/auth/tests/permissions.py
|
---|
2 | ===================================================================
|
---|
3 | --- django/contrib/auth/tests/permissions.py (revision 16342)
|
---|
4 | +++ django/contrib/auth/tests/permissions.py (working copy)
|
---|
5 | @@ -6,16 +6,21 @@
|
---|
6 | from django.contrib.auth.management import create_permissions
|
---|
7 | from django.contrib.auth import models as auth_models
|
---|
8 | from django.contrib.contenttypes import models as contenttypes_models
|
---|
9 | -from django.core.management import call_command
|
---|
10 | +from django.core.management import call_command, CommandError
|
---|
11 | from django.test import TestCase
|
---|
12 |
|
---|
13 |
|
---|
14 | class TestAuthPermissions(TestCase):
|
---|
15 | +
|
---|
16 | + def setUp(self):
|
---|
17 | + self._original_user_permissions = auth_models.User._meta.permissions
|
---|
18 | +
|
---|
19 | def tearDown(self):
|
---|
20 | # These tests mess with content types, but content type lookups
|
---|
21 | # are cached, so we need to make sure the effects of this test
|
---|
22 | # are cleaned up.
|
---|
23 | contenttypes_models.ContentType.objects.clear_cache()
|
---|
24 | + auth_models.User._meta.permissions = self._original_user_permissions
|
---|
25 |
|
---|
26 | def test_permission_register_order(self):
|
---|
27 | """Test that the order of registered permissions doesn't break"""
|
---|
28 | @@ -33,6 +38,34 @@
|
---|
29 | call_command('loaddata', 'test_permissions.json',
|
---|
30 | verbosity=0, commit=False, stderr=stderr)
|
---|
31 | self.assertEqual(stderr.getvalue(), '')
|
---|
32 | +
|
---|
33 | + def test_permission_duplicates_checking(self):
|
---|
34 | + """Test that we show proper error message if we are trying to
|
---|
35 | + create duplicate permissions.
|
---|
36 | + """
|
---|
37 | + auth_models.User._meta.permissions = [
|
---|
38 | + ('change_user', 'Can edit user (duplicate)')]
|
---|
39 | + self.assertRaisesRegexp(CommandError,
|
---|
40 | + 'The permission codename change_user clashes with a builtin '
|
---|
41 | + 'for model auth.User.',
|
---|
42 | + create_permissions, auth_models, [], verbosity=0)
|
---|
43 | +
|
---|
44 | + auth_models.User._meta.permissions = [
|
---|
45 | + ('my_custom_permission', 'Some permission'),
|
---|
46 | + ('other_one', 'Some other permission'),
|
---|
47 | + ('my_custom_permission', 'Some permission with duplicate code'),
|
---|
48 | + ]
|
---|
49 | + self.assertRaisesRegexp(CommandError,
|
---|
50 | + 'The permission codename is duplicated for model auth.User: '
|
---|
51 | + 'my_custom_permission',
|
---|
52 | + create_permissions, auth_models, [], verbosity=0)
|
---|
53 | +
|
---|
54 | + # should not raise anything
|
---|
55 | + auth_models.User._meta.permissions = [
|
---|
56 | + ('my_custom_permission', 'Some permission'),
|
---|
57 | + ('other_one', 'Some other permission'),
|
---|
58 | + ]
|
---|
59 | + create_permissions(auth_models, [], verbosity=0)
|
---|
60 | Index: django/contrib/auth/management/__init__.py
|
---|
61 | ===================================================================
|
---|
62 | --- django/contrib/auth/management/__init__.py (revision 16342)
|
---|
63 | +++ django/contrib/auth/management/__init__.py (working copy)
|
---|
64 | @@ -7,23 +7,52 @@
|
---|
65 | from django.contrib.auth import models as auth_app
|
---|
66 | from django.db.models import get_models, signals
|
---|
67 | from django.contrib.auth.models import User
|
---|
68 | +from django.core.management.base import CommandError
|
---|
69 |
|
---|
70 |
|
---|
71 | +def _check_permissions_clashing(custom, builtin, ctype):
|
---|
72 | + "Raises CommandError if there are duplicate permissions."
|
---|
73 | + pool = set()
|
---|
74 | + builtin_codenames = set(p[0] for p in builtin)
|
---|
75 | + for codename, _name in custom:
|
---|
76 | + if codename in pool:
|
---|
77 | + raise CommandError(
|
---|
78 | + "The permission codename is duplicated for model %s.%s: %s" %
|
---|
79 | + (ctype.app_label, ctype.model_class().__name__, codename))
|
---|
80 | + elif codename in builtin_codenames:
|
---|
81 | + raise CommandError(
|
---|
82 | + "The permission codename %s clashes with a builtin for model "
|
---|
83 | + "%s.%s." %
|
---|
84 | + (codename, ctype.app_label, ctype.model_class().__name__))
|
---|
85 | + pool.add(codename)
|
---|
86 | +
|
---|
87 | +
|
---|
88 | def _get_permission_codename(action, opts):
|
---|
89 | return u'%s_%s' % (action, opts.object_name.lower())
|
---|
90 |
|
---|
91 |
|
---|
92 | -def _get_all_permissions(opts):
|
---|
93 | - "Returns (codename, name) for all permissions in the given opts."
|
---|
94 | +def _get_builtin_permissions(opts):
|
---|
95 | + "Returns (codename, name) for all autogenerated permissions."
|
---|
96 | perms = []
|
---|
97 | for action in ('add', 'change', 'delete'):
|
---|
98 | - perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
|
---|
99 | - return perms + list(opts.permissions)
|
---|
100 | + perms.append(
|
---|
101 | + (_get_permission_codename(action, opts),
|
---|
102 | + u'Can %s %s' % (action, opts.verbose_name_raw)))
|
---|
103 | + return perms
|
---|
104 |
|
---|
105 |
|
---|
106 | +def _get_all_permissions(opts, ctype):
|
---|
107 | + "Returns (codename, name) for all permissions in the given opts."
|
---|
108 | + builtin = _get_builtin_permissions(opts)
|
---|
109 | + custom = list(opts.permissions)
|
---|
110 | + _check_permissions_clashing(custom, builtin, ctype)
|
---|
111 | + return builtin + custom
|
---|
112 | +
|
---|
113 | +
|
---|
114 | def create_permissions(app, created_models, verbosity, **kwargs):
|
---|
115 | from django.contrib.contenttypes.models import ContentType
|
---|
116 |
|
---|
117 | @@ -34,7 +63,7 @@
|
---|
118 | for klass in app_models:
|
---|
119 | ctype = ContentType.objects.get_for_model(klass)
|
---|
120 | ctypes.add(ctype)
|
---|
121 | - for perm in _get_all_permissions(klass._meta):
|
---|
122 | + for perm in _get_all_permissions(klass._meta, ctype):
|
---|
123 | searched_perms.append((ctype, perm))
|
---|
124 |
|
---|
125 | # Find all the Permissions that have a context_type for a model we're
|
---|