Merge pull request #4871 from FinnStutzenstein/cleanupPermissions

Cleanup unused permissions
This commit is contained in:
Sean 2019-07-23 14:37:07 +02:00 committed by GitHub
commit 93e37720dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 0 deletions

View File

@ -26,6 +26,7 @@ class CoreAppConfig(AppConfig):
from . import serializers # noqa from . import serializers # noqa
from .signals import ( from .signals import (
autoupdate_for_many_to_many_relations, autoupdate_for_many_to_many_relations,
cleanup_unused_permissions,
delete_django_app_permissions, delete_django_app_permissions,
get_permission_change_data, get_permission_change_data,
permission_change, permission_change,
@ -60,6 +61,9 @@ class CoreAppConfig(AppConfig):
post_permission_creation.connect( post_permission_creation.connect(
delete_django_app_permissions, dispatch_uid="delete_django_app_permissions" delete_django_app_permissions, dispatch_uid="delete_django_app_permissions"
) )
post_permission_creation.connect(
cleanup_unused_permissions, dispatch_uid="cleanup_unused_permissions"
)
permission_change.connect( permission_change.connect(
get_permission_change_data, dispatch_uid="core_get_permission_change_data" get_permission_change_data, dispatch_uid="core_get_permission_change_data"
) )

View File

@ -1,4 +1,7 @@
import logging
import sys import sys
from collections import defaultdict
from typing import Dict, List
from django.apps import apps from django.apps import apps
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
@ -30,6 +33,41 @@ def delete_django_app_permissions(sender, **kwargs):
Permission.objects.filter(content_type__in=contenttypes).delete() Permission.objects.filter(content_type__in=contenttypes).delete()
def cleanup_unused_permissions(sender, **kwargs):
"""
Deletes all permissions, that are not defined in any model meta class
"""
# Maps the content type id to codenames of perms for this content type.
content_type_codename_mapping: Dict[int, List[str]] = defaultdict(list)
# Maps content type ids to the content type.
content_type_id_mapping = {}
# Collect all perms from all apps.
for model in apps.get_models():
content_type = ContentType.objects.get_for_model(
model, for_concrete_model=False
)
content_type_id_mapping[content_type.id] = content_type
for perm in model._meta.permissions:
content_type_codename_mapping[content_type.id].append(perm[0])
# Cleanup perms per content type.
logger = logging.getLogger("openslides.core.migrations")
for content_type_id, codenames in content_type_codename_mapping.items():
app_label = content_type_id_mapping[content_type_id].app_label
unused_perms = Permission.objects.filter(
content_type__pk=content_type_id
).exclude(codename__in=codenames)
if unused_perms.exists():
verbose_permissions = ", ".join(
[f"{app_label}.{perm.codename}" for perm in unused_perms.all()]
)
logger.info(f"cleaning unused permissions: {verbose_permissions}")
unused_perms.delete()
def get_permission_change_data(sender, permissions, **kwargs): def get_permission_change_data(sender, permissions, **kwargs):
""" """
Yields all necessary Cachables if the respective permissions change. Yields all necessary Cachables if the respective permissions change.