Fixed #31200 -- Added system checks for permissions codenames max length.

This commit is contained in:
Michael Mulholland 2020-01-22 21:14:24 -05:00 committed by Mariusz Felisiak
parent b423873cb7
commit 5a68a223c7
3 changed files with 76 additions and 0 deletions

View File

@ -102,6 +102,7 @@ def check_models_permissions(app_configs=None, **kwargs):
Permission = apps.get_model('auth', 'Permission')
permission_name_max_length = Permission._meta.get_field('name').max_length
permission_codename_max_length = Permission._meta.get_field('codename').max_length
errors = []
for model in models:
@ -126,6 +127,29 @@ def check_models_permissions(app_configs=None, **kwargs):
id='auth.E007',
)
)
# Check builtin permission codename length.
max_builtin_permission_codename_length = (
max(len(codename) for codename in builtin_permissions.keys())
if builtin_permissions else 0
)
if max_builtin_permission_codename_length > permission_codename_max_length:
model_name_max_length = permission_codename_max_length - (
max_builtin_permission_codename_length - len(opts.model_name)
)
errors.append(
checks.Error(
"The name of model '%s.%s' must be at most %d characters "
"for its builtin permission codenames to be at most %d "
"characters." % (
opts.app_label,
opts.object_name,
model_name_max_length,
permission_codename_max_length,
),
obj=model,
id='auth.E011',
)
)
codenames = set()
for codename, name in opts.permissions:
# Check custom permission name length.
@ -139,6 +163,21 @@ def check_models_permissions(app_configs=None, **kwargs):
id='auth.E008',
)
)
# Check custom permission codename length.
if len(codename) > permission_codename_max_length:
errors.append(
checks.Error(
"The permission codenamed '%s' of model '%s.%s' is "
"longer than %d characters." % (
codename,
opts.app_label,
opts.object_name,
permission_codename_max_length,
),
obj=model,
id='auth.E012',
)
)
# Check custom permissions codename clashing.
if codename in builtin_permissions:
errors.append(

View File

@ -724,6 +724,10 @@ The following checks are performed on the default
* **auth.C010**: ``<User model>.is_authenticated`` must be an attribute or
property rather than a method. Ignoring this is a security issue as anonymous
users will be treated as authenticated!
* **auth.E011**: The name of model ``<model>`` must be at most 93 characters
for its builtin permission names to be at most 100 characters.
* **auth.E012**: The permission codenamed ``<codename>`` of model ``<model>``
is longer than 100 characters.
``contenttypes``
----------------

View File

@ -176,6 +176,20 @@ class ModelsPermissionsChecksTests(SimpleTestCase):
),
])
def test_model_name_max_length(self):
model_name = 'X' * 94
model = type(model_name, (models.Model,), {'__module__': self.__module__})
errors = checks.run_checks(self.apps.get_app_configs())
self.assertEqual(errors, [
checks.Error(
"The name of model 'auth_tests.%s' must be at most 93 "
"characters for its builtin permission codenames to be at "
"most 100 characters." % model_name,
obj=model,
id='auth.E011',
),
])
def test_custom_permission_name_max_length(self):
custom_permission_name = 'some ridiculously long verbose name that is out of control' * 5
@ -194,6 +208,25 @@ class ModelsPermissionsChecksTests(SimpleTestCase):
),
])
def test_custom_permission_codename_max_length(self):
custom_permission_codename = 'x' * 101
class Checked(models.Model):
class Meta:
permissions = [
(custom_permission_codename, 'Custom permission'),
]
errors = checks.run_checks(self.apps.get_app_configs())
self.assertEqual(errors, [
checks.Error(
"The permission codenamed '%s' of model 'auth_tests.Checked' "
"is longer than 100 characters." % custom_permission_codename,
obj=Checked,
id='auth.E012',
),
])
def test_empty_default_permissions(self):
class Checked(models.Model):
class Meta: