summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorArthur Rio <arthurio@users.noreply.github.com>2019-01-16 16:07:28 +0100
committerTim Graham <timograham@gmail.com>2019-01-16 10:07:28 -0500
commit181fb60159e54d442d3610f4afba6f066a6dac05 (patch)
tree087646be10e537b2a9808e5351d30bd489e76273 /django
parentdbcf2ffa77af24642c035c58199e6058d91d8e35 (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__.py2
-rw-r--r--django/contrib/auth/migrations/0011_update_proxy_permissions.py48
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),
+ ]