Projet

Général

Profil

0001-general-add-support-for-importing-permissions-26924.patch

Frédéric Péters, 13 novembre 2018 20:48

Télécharger (8,27 ko)

Voir les différences:

Subject: [PATCH 1/2] general: add support for importing permissions (#26924)

 chrono/agendas/models.py                      | 12 ++++-
 .../management/commands/import_site.py        | 14 ++++--
 chrono/manager/utils.py                       |  2 +-
 chrono/manager/views.py                       | 10 +++-
 tests/test_import_export.py                   | 49 ++++++++++++++++++-
 tests/test_manager.py                         | 11 +++++
 6 files changed, 87 insertions(+), 11 deletions(-)
chrono/agendas/models.py
53 53
    pass
54 54

  
55 55

  
56
class AgendaImportError(Exception):
57
    pass
58

  
59

  
56 60
class Agenda(models.Model):
57 61
    label = models.CharField(_('Label'), max_length=150)
58 62
    slug = models.SlugField(_('Identifier'), max_length=160)
......
130 134
    @classmethod
131 135
    def import_json(cls, data, overwrite=False):
132 136
        data = data.copy()
133
        permissions = data.pop('permissions')
137
        permissions = data.pop('permissions') or {}
134 138
        if data['kind'] == 'events':
135 139
            events = data.pop('events')
136 140
        elif data['kind'] == 'meetings':
137 141
            meetingtypes = data.pop('meetingtypes')
138 142
            desks = data.pop('desks')
143
        for permission in ('view', 'edit'):
144
            if permissions.get(permission):
145
                try:
146
                    data[permission + '_role'] = Group.objects.get(name=permissions[permission])
147
                except Group.DoesNotExist:
148
                    raise AgendaImportError(_('Missing "%s" role') % permissions[permission])
139 149
        agenda, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
140 150
        if data['kind'] == 'events':
141 151
            if overwrite:
chrono/manager/management/commands/import_site.py
17 17
import json
18 18
import sys
19 19

  
20
from django.core.management.base import BaseCommand
20
from django.core.management.base import BaseCommand, CommandError
21 21

  
22
from chrono.agendas.models import AgendaImportError
22 23
from chrono.manager.utils import import_site
23 24

  
24 25

  
......
43 44
            fd = sys.stdin
44 45
        else:
45 46
            fd = open(filename)
46
        import_site(json.load(fd),
47
                    if_empty=options['if_empty'],
48
                    clean=options['clean'],
49
                    overwrite=options['overwrite'])
47
        try:
48
            import_site(json.load(fd),
49
                        if_empty=options['if_empty'],
50
                        clean=options['clean'],
51
                        overwrite=options['overwrite'])
52
        except AgendaImportError as exc:
53
            raise CommandError(u'%s' % exc)
chrono/manager/utils.py
16 16

  
17 17
from django.db import transaction
18 18

  
19
from chrono.agendas.models import Agenda
19
from chrono.agendas.models import Agenda, AgendaImportError
20 20

  
21 21

  
22 22
def export_site():
chrono/manager/views.py
33 33
        MonthArchiveView)
34 34

  
35 35
from chrono.agendas.models import (Agenda, Event, MeetingType, TimePeriod,
36
                                   Booking, Desk, TimePeriodException, ICSError)
36
                                   Booking, Desk, TimePeriodException,
37
                                   ICSError, AgendaImportError)
37 38

  
38 39
from .forms import (AgendaAddForm, AgendaEditForm, EventForm, NewMeetingTypeForm, MeetingTypeForm,
39 40
                    TimePeriodForm, ImportEventsForm, NewDeskForm, DeskForm, TimePeriodExceptionForm,
......
95 96
            form.add_error('agendas_json', _('File is not in the expected JSON format.'))
96 97
            return self.form_invalid(form)
97 98

  
98
        results = import_site(agendas_json, overwrite=True)
99
        try:
100
            results = import_site(agendas_json, overwrite=True)
101
        except AgendaImportError as exc:
102
            form.add_error('agendas_json', u'%s' % exc)
103
            return self.form_invalid(form)
104

  
99 105
        if results.get('created') == 0 and results.get('updated') == 0:
100 106
            messages.info(self.request, _('No agendas were found.'))
101 107
        else:
tests/test_import_export.py
1
# -*- coding: utf-8 -*-
2

  
1 3
from __future__ import unicode_literals
2 4

  
3 5
import datetime
......
8 10
import tempfile
9 11

  
10 12
import pytest
11
from django.core.management import call_command
13
from django.contrib.auth.models import Group
14
from django.core.management import call_command, CommandError
12 15
from django.utils.encoding import force_bytes
13 16
from django.utils.six import StringIO
14 17
from django.utils.timezone import make_aware
15 18

  
16
from chrono.agendas.models import (Agenda, Event, TimePeriod, Desk, TimePeriodException)
19
from chrono.agendas.models import (Agenda, Event, TimePeriod, Desk,
20
        TimePeriodException, AgendaImportError)
17 21
from chrono.manager.utils import import_site
18 22

  
19 23
from test_api import some_data, meetings_agenda, time_zone, mock_now
......
112 116
    empty_output = get_output_of_command('export_site', output=os.path.join(tempdir, 't.json'))
113 117
    assert os.path.exists(os.path.join(tempdir, 't.json'))
114 118
    shutil.rmtree(tempdir)
119

  
120

  
121
def test_import_export_permissions(app, some_data, meetings_agenda):
122
    group1 = Group(name=u'gé1')
123
    group1.save()
124
    group2 = Group(name=u'gé2')
125
    group2.save()
126

  
127
    meetings_agenda.view_role = group1
128
    meetings_agenda.edit_role = group2
129
    meetings_agenda.save()
130
    output = get_output_of_command('export_site')
131
    assert len(json.loads(output)['agendas']) == 3
132
    import_site(data={}, clean=True)
133
    assert Agenda.objects.count() == 0
134
    Group.objects.all().delete()
135

  
136
    with pytest.raises(AgendaImportError) as excinfo:
137
        import_site(json.loads(output), overwrite=True)
138
    assert u'%s' % excinfo.value == u'Missing "gé1" role'
139

  
140
    group1 = Group(name=u'gé1')
141
    group1.save()
142
    with pytest.raises(AgendaImportError) as excinfo:
143
        import_site(json.loads(output), overwrite=True)
144
    assert u'%s' % excinfo.value == u'Missing "gé2" role'
145

  
146
    with tempfile.NamedTemporaryFile() as f:
147
        f.write(force_bytes(output))
148
        f.flush()
149
        with pytest.raises(CommandError) as excinfo:
150
            call_command('import_site', f.name)
151
        assert u'%s' % excinfo.value == u'Missing "gé2" role'
152

  
153
    group2 = Group(name=u'gé2')
154
    group2.save()
155
    import_site(json.loads(output), overwrite=True)
156

  
157
    agenda = Agenda.objects.get(slug=meetings_agenda.slug)
158
    assert agenda.view_role == group1
159
    assert agenda.edit_role == group2
tests/test_manager.py
1527 1527
    resp = resp.form.submit().follow()
1528 1528
    assert 'An agenda has been created. No agenda updated.' in resp.text
1529 1529
    assert Agenda.objects.count() == 1
1530

  
1531
    # reference to unknown group
1532
    agenda_export_dict = json.loads(agenda_export)
1533
    agenda_export_dict['agendas'][0]['permissions']['view'] = u'gé1'
1534
    agenda_export = json.dumps(agenda_export_dict).encode('utf-8')
1535
    Agenda.objects.all().delete()
1536
    resp = app.get('/manage/', status=200)
1537
    resp = resp.click('Import')
1538
    resp.form['agendas_json'] = Upload('export.json', agenda_export, 'application/json')
1539
    resp = resp.form.submit()
1540
    assert u'Missing "gé1" role' in resp.text
1530
-