0001-general-add-support-for-importing-permissions-26924.patch
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 |
- |