mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #31200 -- Added system checks for permissions codenames max length.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							b423873cb7
						
					
				
				
					commit
					5a68a223c7
				
			| @@ -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( | ||||
|   | ||||
| @@ -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`` | ||||
| ---------------- | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user