general: add support for importing permissions (#26924)
This commit is contained in:
parent
aa7e887dec
commit
9e41e9d77c
|
@ -53,6 +53,10 @@ class ICSError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class AgendaImportError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Agenda(models.Model):
|
||||
label = models.CharField(_('Label'), max_length=150)
|
||||
slug = models.SlugField(_('Identifier'), max_length=160)
|
||||
|
@ -130,12 +134,18 @@ class Agenda(models.Model):
|
|||
@classmethod
|
||||
def import_json(cls, data, overwrite=False):
|
||||
data = data.copy()
|
||||
permissions = data.pop('permissions')
|
||||
permissions = data.pop('permissions') or {}
|
||||
if data['kind'] == 'events':
|
||||
events = data.pop('events')
|
||||
elif data['kind'] == 'meetings':
|
||||
meetingtypes = data.pop('meetingtypes')
|
||||
desks = data.pop('desks')
|
||||
for permission in ('view', 'edit'):
|
||||
if permissions.get(permission):
|
||||
try:
|
||||
data[permission + '_role'] = Group.objects.get(name=permissions[permission])
|
||||
except Group.DoesNotExist:
|
||||
raise AgendaImportError(_('Missing "%s" role') % permissions[permission])
|
||||
agenda, created = cls.objects.get_or_create(slug=data['slug'], defaults=data)
|
||||
if data['kind'] == 'events':
|
||||
if overwrite:
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
import json
|
||||
import sys
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from chrono.agendas.models import AgendaImportError
|
||||
from chrono.manager.utils import import_site
|
||||
|
||||
|
||||
|
@ -43,7 +44,10 @@ class Command(BaseCommand):
|
|||
fd = sys.stdin
|
||||
else:
|
||||
fd = open(filename)
|
||||
import_site(json.load(fd),
|
||||
if_empty=options['if_empty'],
|
||||
clean=options['clean'],
|
||||
overwrite=options['overwrite'])
|
||||
try:
|
||||
import_site(json.load(fd),
|
||||
if_empty=options['if_empty'],
|
||||
clean=options['clean'],
|
||||
overwrite=options['overwrite'])
|
||||
except AgendaImportError as exc:
|
||||
raise CommandError(u'%s' % exc)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
from django.db import transaction
|
||||
|
||||
from chrono.agendas.models import Agenda
|
||||
from chrono.agendas.models import Agenda, AgendaImportError
|
||||
|
||||
|
||||
def export_site():
|
||||
|
|
|
@ -33,7 +33,8 @@ from django.views.generic import (DetailView, CreateView, UpdateView,
|
|||
MonthArchiveView)
|
||||
|
||||
from chrono.agendas.models import (Agenda, Event, MeetingType, TimePeriod,
|
||||
Booking, Desk, TimePeriodException, ICSError)
|
||||
Booking, Desk, TimePeriodException,
|
||||
ICSError, AgendaImportError)
|
||||
|
||||
from .forms import (AgendaAddForm, AgendaEditForm, EventForm, NewMeetingTypeForm, MeetingTypeForm,
|
||||
TimePeriodForm, ImportEventsForm, NewDeskForm, DeskForm, TimePeriodExceptionForm,
|
||||
|
@ -95,7 +96,12 @@ class AgendasImportView(FormView):
|
|||
form.add_error('agendas_json', _('File is not in the expected JSON format.'))
|
||||
return self.form_invalid(form)
|
||||
|
||||
results = import_site(agendas_json, overwrite=True)
|
||||
try:
|
||||
results = import_site(agendas_json, overwrite=True)
|
||||
except AgendaImportError as exc:
|
||||
form.add_error('agendas_json', u'%s' % exc)
|
||||
return self.form_invalid(form)
|
||||
|
||||
if results.get('created') == 0 and results.get('updated') == 0:
|
||||
messages.info(self.request, _('No agendas were found.'))
|
||||
else:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
|
@ -8,12 +10,14 @@ import sys
|
|||
import tempfile
|
||||
|
||||
import pytest
|
||||
from django.core.management import call_command
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.management import call_command, CommandError
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.six import StringIO
|
||||
from django.utils.timezone import make_aware
|
||||
|
||||
from chrono.agendas.models import (Agenda, Event, TimePeriod, Desk, TimePeriodException)
|
||||
from chrono.agendas.models import (Agenda, Event, TimePeriod, Desk,
|
||||
TimePeriodException, AgendaImportError)
|
||||
from chrono.manager.utils import import_site
|
||||
|
||||
from test_api import some_data, meetings_agenda, time_zone, mock_now
|
||||
|
@ -112,3 +116,44 @@ def test_import_export(app, some_data, meetings_agenda):
|
|||
empty_output = get_output_of_command('export_site', output=os.path.join(tempdir, 't.json'))
|
||||
assert os.path.exists(os.path.join(tempdir, 't.json'))
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
|
||||
def test_import_export_permissions(app, some_data, meetings_agenda):
|
||||
group1 = Group(name=u'gé1')
|
||||
group1.save()
|
||||
group2 = Group(name=u'gé2')
|
||||
group2.save()
|
||||
|
||||
meetings_agenda.view_role = group1
|
||||
meetings_agenda.edit_role = group2
|
||||
meetings_agenda.save()
|
||||
output = get_output_of_command('export_site')
|
||||
assert len(json.loads(output)['agendas']) == 3
|
||||
import_site(data={}, clean=True)
|
||||
assert Agenda.objects.count() == 0
|
||||
Group.objects.all().delete()
|
||||
|
||||
with pytest.raises(AgendaImportError) as excinfo:
|
||||
import_site(json.loads(output), overwrite=True)
|
||||
assert u'%s' % excinfo.value == u'Missing "gé1" role'
|
||||
|
||||
group1 = Group(name=u'gé1')
|
||||
group1.save()
|
||||
with pytest.raises(AgendaImportError) as excinfo:
|
||||
import_site(json.loads(output), overwrite=True)
|
||||
assert u'%s' % excinfo.value == u'Missing "gé2" role'
|
||||
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
f.write(force_bytes(output))
|
||||
f.flush()
|
||||
with pytest.raises(CommandError) as excinfo:
|
||||
call_command('import_site', f.name)
|
||||
assert u'%s' % excinfo.value == u'Missing "gé2" role'
|
||||
|
||||
group2 = Group(name=u'gé2')
|
||||
group2.save()
|
||||
import_site(json.loads(output), overwrite=True)
|
||||
|
||||
agenda = Agenda.objects.get(slug=meetings_agenda.slug)
|
||||
assert agenda.view_role == group1
|
||||
assert agenda.edit_role == group2
|
||||
|
|
|
@ -1529,3 +1529,14 @@ def test_import_agenda(app, admin_user):
|
|||
resp = resp.form.submit().follow()
|
||||
assert 'An agenda has been created. No agenda updated.' in resp.text
|
||||
assert Agenda.objects.count() == 1
|
||||
|
||||
# reference to unknown group
|
||||
agenda_export_dict = json.loads(agenda_export)
|
||||
agenda_export_dict['agendas'][0]['permissions']['view'] = u'gé1'
|
||||
agenda_export = json.dumps(agenda_export_dict).encode('utf-8')
|
||||
Agenda.objects.all().delete()
|
||||
resp = app.get('/manage/', status=200)
|
||||
resp = resp.click('Import')
|
||||
resp.form['agendas_json'] = Upload('export.json', agenda_export, 'application/json')
|
||||
resp = resp.form.submit()
|
||||
assert u'Missing "gé1" role' in resp.text
|
||||
|
|
Loading…
Reference in New Issue