Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos / iam / management.py
Size: Mime:
from functools import reduce

from django.db.migrations import RunPython
from django.db.models import Q


class RunPythonCreateGroup(RunPython):
    group_model = 'auth.Group'
    permission_model = 'auth.Permission'

    def get_group_model(self, apps):
        return apps.get_model(self.group_model)

    def get_permission_model(self, apps):
        return apps.get_model(self.permission_model)

    def __init__(self, name, perms):
        group_name = self.get_group_name(name)
        permission_keys = self._get_permission_keys(perms)

        def forward(apps, schema_editor):
            db_alias = schema_editor.connection.alias
            Group = self.get_group_model(apps)
            Permission = self.get_permission_model(apps)

            group = Group.objects.using(db_alias).create(name=group_name)
            permissions = Permission.objects.using(db_alias).filter(
                reduce(self._reduce_function, permission_keys, Q())
            )
            group.permissions.add(*permissions)

        def reverse(apps, schema_editor):
            db_alias = schema_editor.connection.alias
            Group = self.get_group_model(apps)
            Group.objects.using(db_alias).filter(name=group_name).delete()

        super().__init__(forward, reverse)

    @staticmethod
    def get_group_name(name):
        return 'system::' + name

    @staticmethod
    def _get_permission_keys(perms):
        """
        :param perms: a sequence of strings in the format of 'app.action_model' or 'action_model'
        :return:
        """
        keys = []
        for p_f in perms:
            s = p_f.split('.')
            if len(s) > 1:
                keys.append((s[0], s[1]))
            else:
                keys.append((None, s[0]))
        return keys

    @staticmethod
    def _reduce_function(acc: Q, curr: tuple):
        app_label, codename = curr
        if app_label is None:
            q = Q(codename=codename)
        else:
            q = Q(codename=codename, content_type__app_label=app_label)

        return acc | q