diff options
| author | Arthur Rio <arthurio@users.noreply.github.com> | 2019-01-16 16:07:28 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2019-01-16 10:07:28 -0500 |
| commit | 181fb60159e54d442d3610f4afba6f066a6dac05 (patch) | |
| tree | 087646be10e537b2a9808e5351d30bd489e76273 /django | |
| parent | dbcf2ffa77af24642c035c58199e6058d91d8e35 (diff) | |
Fixed #11154, #22270 -- Made proxy model permissions use correct content type.
Co-Authored-By: Simon Charette <charette.s@gmail.com>
Co-Authored-By: Antoine Catton <acatton@fusionbox.com>
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/auth/management/__init__.py | 2 | ||||
| -rw-r--r-- | django/contrib/auth/migrations/0011_update_proxy_permissions.py | 48 |
2 files changed, 49 insertions, 1 deletions
diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 14c25a7399..deda238c78 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -60,7 +60,7 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ for klass in app_config.get_models(): # 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) + ctype = ContentType.objects.db_manager(using).get_for_model(klass, for_concrete_model=False) ctypes.add(ctype) for perm in _get_all_permissions(klass._meta): diff --git a/django/contrib/auth/migrations/0011_update_proxy_permissions.py b/django/contrib/auth/migrations/0011_update_proxy_permissions.py new file mode 100644 index 0000000000..0e66649695 --- /dev/null +++ b/django/contrib/auth/migrations/0011_update_proxy_permissions.py @@ -0,0 +1,48 @@ +from django.db import migrations +from django.db.models import Q + + +def update_proxy_model_permissions(apps, schema_editor, reverse=False): + """ + Update the content_type of proxy model permissions to use the ContentType + of the proxy model. + """ + Permission = apps.get_model('auth', 'Permission') + ContentType = apps.get_model('contenttypes', 'ContentType') + for Model in apps.get_models(): + opts = Model._meta + if not opts.proxy: + continue + proxy_default_permissions_codenames = [ + '%s_%s' % (action, opts.model_name) + for action in opts.default_permissions + ] + permissions_query = Q(codename__in=proxy_default_permissions_codenames) + for codename, name in opts.permissions: + permissions_query = permissions_query | Q(codename=codename, name=name) + concrete_content_type = ContentType.objects.get_for_model(Model, for_concrete_model=True) + proxy_content_type = ContentType.objects.get_for_model(Model, for_concrete_model=False) + old_content_type = proxy_content_type if reverse else concrete_content_type + new_content_type = concrete_content_type if reverse else proxy_content_type + Permission.objects.filter( + permissions_query, + content_type=old_content_type, + ).update(content_type=new_content_type) + + +def revert_proxy_model_permissions(apps, schema_editor): + """ + Update the content_type of proxy model permissions to use the ContentType + of the concrete model. + """ + update_proxy_model_permissions(apps, schema_editor, reverse=True) + + +class Migration(migrations.Migration): + dependencies = [ + ('auth', '0010_alter_group_name_max_length'), + ('contenttypes', '0002_remove_content_type_name'), + ] + operations = [ + migrations.RunPython(update_proxy_model_permissions, revert_proxy_model_permissions), + ] |
