From 0ed20d5cc4bf94646ffd4e4fcbd963b9916039cd Mon Sep 17 00:00:00 2001 From: Joeri Bekker Date: Sun, 8 Mar 2015 13:33:22 +0100 Subject: [PATCH] Fixed #23926 -- Improved validation error for custom permissions that are too long. --- django/contrib/auth/management/__init__.py | 24 ++++++++++++++++------ tests/auth_tests/test_management.py | 18 ++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index ea05d2b497..a8b69f66d5 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -71,6 +71,9 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ from django.contrib.contenttypes.models import ContentType + permission_name_max_length = Permission._meta.get_field('name').max_length + verbose_name_max_length = permission_name_max_length - 11 # len('Can change ') prefix + # This will hold the permissions we're looking for as # (content_type, (codename, name)) searched_perms = list() @@ -80,6 +83,16 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ # Force looking up the content types in the current database # before creating foreign keys to them. ctype = ContentType.objects.db_manager(using).get_for_model(klass) + + if len(klass._meta.verbose_name) > verbose_name_max_length: + raise exceptions.ValidationError( + "The verbose_name of %s.%s is longer than %s characters" % ( + ctype.app_label, + ctype.model, + verbose_name_max_length, + ) + ) + ctypes.add(ctype) for perm in _get_all_permissions(klass._meta, ctype): searched_perms.append((ctype, perm)) @@ -98,17 +111,16 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ for ct, (codename, name) in searched_perms if (ct.pk, codename) not in all_perms ] - # Validate the permissions before bulk_creation to avoid cryptic - # database error when the verbose_name is longer than 50 characters - permission_name_max_length = Permission._meta.get_field('name').max_length - verbose_name_max_length = permission_name_max_length - 11 # len('Can change ') prefix + # Validate the permissions before bulk_creation to avoid cryptic database + # error when the name is longer than 255 characters for perm in perms: if len(perm.name) > permission_name_max_length: raise exceptions.ValidationError( - "The verbose_name of %s.%s is longer than %s characters" % ( + "The permission name %s of %s.%s is longer than %s characters" % ( + perm.name, perm.content_type.app_label, perm.content_type.model, - verbose_name_max_length, + permission_name_max_length, ) ) Permission.objects.using(using).bulk_create(perms) diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 0e2fe8d0e7..d3b2ff18c5 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -565,3 +565,21 @@ class PermissionTestCase(TestCase): six.assertRaisesRegex(self, exceptions.ValidationError, "The verbose_name of auth.permission is longer than 244 characters", create_permissions, auth_app_config, verbosity=0) + + def test_custom_permission_name_length(self): + auth_app_config = apps.get_app_config('auth') + + ContentType.objects.get_by_natural_key('auth', 'permission') + custom_perm_name = 'a' * 256 + models.Permission._meta.permissions = [ + ('my_custom_permission', custom_perm_name), + ] + try: + msg = ( + "The permission name %s of auth.permission is longer than " + "255 characters" % custom_perm_name + ) + with self.assertRaisesMessage(exceptions.ValidationError, msg): + create_permissions(auth_app_config, verbosity=0) + finally: + models.Permission._meta.permissions = []