Projet

Général

Profil

0001-add-roles-import-export-command-16514.patch

Josué Kouka, 27 septembre 2017 18:15

Télécharger (7,17 ko)

Voir les différences:

Subject: [PATCH] add roles import/export command (#16514)

 src/authentic2/a2_rbac/models.py                   | 63 ++++++++++++++++++++++
 src/authentic2/management/commands/export-roles.py | 26 +++++++++
 src/authentic2/management/commands/import-roles.py | 21 ++++++++
 src/authentic2/models.py                           | 13 +++++
 src/authentic2/utils.py                            | 25 +++++++++
 5 files changed, 148 insertions(+)
 create mode 100644 src/authentic2/management/commands/export-roles.py
 create mode 100644 src/authentic2/management/commands/import-roles.py
src/authentic2/a2_rbac/models.py
80 80
    def natural_key(self):
81 81
        return [self.slug]
82 82

  
83
    @classmethod
84
    def get_ou_or_default(cls, uuid, slug, name):
85
        try:
86
            ou = cls.objects.get(uuid=uuid)
87
            return ou
88
        except cls.DoesNotExist:
89
            ou = cls.objects.get(slug=slug)
90
            return ou
91
        except cls.DoesNotExist:
92
            ou = cls.objects.get(name=name)
93
            return ou
94
        return rbac_utils.get_default_ou()
95

  
83 96

  
84 97
class Permission(PermissionAbstractBase):
85 98
    class Meta:
......
195 208
            'ou__slug': self.ou.slug if self.ou else None,
196 209
        }
197 210

  
211
    @classmethod
212
    def import_json(cls, data):
213
        from authentic2.models import Service
214
        ou_json = data.pop('ou', {})
215
        service_json = data.pop('service', {})
216
        attributes_json = data.pop('attributes', {})
217

  
218
        ou = OrganizationalUnit.get_ou_or_default(**ou_json)
219
        kwargs = {'uuid': data['uuid'], 'slug': data['slug'], 'name': data['name']}
220
        role, created = cls.objects.get_or_create(ou=ou, **kwargs)
221
        # set attributes
222
        for attr in attributes_json:
223
            attribute, created = RoleAttribute.objects.get_or_create(
224
                role=role, name=attr['name'], kind=attr['kind'], defaults={
225
                    'value': attr['value']})
226
            if created:
227
                attribute.value = attr['value']
228
                attribute.save()
229
        # set service if any
230
        if service_json:
231
            service_json.pop('ou')
232
            Service.import_json(ou=ou, **service_json)
233

  
234
    def export_json(self):
235
        data = {
236
            'uuid': self.uuid,
237
            'slug': self.slug,
238
            'name': self.name,
239
        }
240
        if self.ou:
241
            data['ou'] = {
242
                'uuid': self.ou.uuid,
243
                'name': self.ou.name,
244
                'slug': self.ou.slug
245
            }
246

  
247
        attributes = []
248
        for attr in self.attributes.all():
249
            attributes.append({
250
                'name': attr.name, 'kind': attr.kind,
251
                'value': attr.value})
252
        data['attributes'] = attributes
253

  
254
        parents = []
255
        for parent in self.parents(include_self=False):
256
            parents.append({
257
                'uuid': parent.uuid, 'slug': parent.slug, 'name': parent.name})
258
        data['parents'] = parents
259
        return data
260

  
198 261

  
199 262
class RoleParenting(RoleParentingAbstractBase):
200 263
    class Meta(RoleParentingAbstractBase.Meta):
src/authentic2/management/commands/export-roles.py
1
import json
2
from optparse import make_option
3
import sys
4

  
5
from django.core.management import BaseCommand
6

  
7
from authentic2.utils import export_roles
8

  
9

  
10
class Command(BaseCommand):
11
    help = 'Export roles as json'
12

  
13
    args = '<filename>'
14

  
15
    option_list = BaseCommand.option_list + (
16
        make_option('--ou', dest='ou', default=None, type=str,
17
                    help='restrict to the organizational unit slug'),)
18

  
19
    def handle(self, *args, **options):
20
        if len(args) < 1:
21
            output = sys.stdout
22
        else:
23
            output = open(args[0], 'w')
24

  
25
        data = export_roles(ou_slug=options['ou'])
26
        json.dump(data, output, encoding='utf-8', indent=4)
src/authentic2/management/commands/import-roles.py
1
import json
2
from optparse import make_option
3

  
4
from django.core.management.base import BaseCommand
5

  
6
from authentic2.utils import import_roles
7

  
8

  
9
class Command(BaseCommand):
10
    help = 'Import roles from json file'
11

  
12
    args = '<filename>'
13

  
14
    option_list = BaseCommand.option_list + (
15
        make_option('--ou', dest='ou', default=None, type=str,
16
                    help='restrict to the organizational unit slug'),)
17

  
18
    def handle(self, *args, **options):
19
        if args:
20
            fd = open(args[0])
21
            import_roles(json.load(fd), ou_slug=options['ou'])
src/authentic2/models.py
399 399
            'roles': [role.to_json() for role in roles],
400 400
        }
401 401

  
402
    @classmethod
403
    def import_json(cls, data):
404
        ou = data.pop('ou')
405
        cls.objects.get_or_create(ou=ou, **data)
406

  
407
    def export_json(self):
408
        return {
409
            'name': self.name, 'slug': self.slug,
410
            'ou': {
411
                'uuid': self.ou.uuid, 'slug': self.ou.slug, 'name': self.ou.name
412
            }
413
        }
414

  
402 415

  
403 416
class AuthorizedRole(models.Model):
404 417
    service = models.ForeignKey(Service, on_delete=models.CASCADE)
src/authentic2/utils.py
942 942
    user = copy.deepcopy(user)
943 943
    user.backend = backend
944 944
    return login(request, user, method, **kwargs)
945

  
946

  
947
def export_roles(ou_slug=None):
948
    from django_rbac.utils import get_role_model
949
    Role = get_role_model()
950
    filters = {'slug__startswith': '_'}
951
    if ou_slug:
952
        roles = Role.objects.filter(ou__slug=ou_slug).exclude(**filters)
953
    else:
954
        roles = Role.objects.exclude(**filters)
955
    return [role.export_json() for role in roles]
956

  
957

  
958
def import_roles(data, ou_slug=None):
959
    from django_rbac.utils import get_role_model
960
    Role = get_role_model()
961
    if ou_slug:
962
        data = [datum for datum in data if datum['ou']['slug'] == ou_slug]
963
    for role_json in data:
964
        Role.import_json(role_json)
965
    # once all roles are created, set their relationships
966
    for role_json in data:
967
        role = Role.objects.get(uuid=role_json['uuid'])
968
        for parent in role_json.get('parents', []):
969
            role.add_parent(Role.objects.get(uuid=parent['uuid']))
945
-