Projet

Général

Profil

0001-add-UI-for-import-export-site-23210.patch

Emmanuel Cazenave, 02 mai 2018 13:03

Télécharger (8,29 ko)

Voir les différences:

Subject: [PATCH 1/2] add UI for import/export site (#23210)

 src/authentic2/forms.py                       |  4 ++
 .../authentic2/manager/homepage.html          |  8 ++-
 .../authentic2/manager/site_import.html       | 18 ++++++
 src/authentic2/manager/urls.py                |  4 ++
 src/authentic2/manager/views.py               | 39 +++++++++++-
 tests/test_manager.py                         | 62 +++++++++++++++++++
 6 files changed, 132 insertions(+), 3 deletions(-)
 create mode 100644 src/authentic2/manager/templates/authentic2/manager/site_import.html
src/authentic2/forms.py
191 191
            if keys:
192 192
                self.exponential_backoff.success(*keys)
193 193
        return self.cleaned_data
194

  
195

  
196
class SiteImportForm(forms.Form):
197
    site_json = forms.FileField(label=_('Site Export File'))
src/authentic2/manager/templates/authentic2/manager/homepage.html
5 5
{% endblock %}
6 6

  
7 7
{% block appbar %}
8
  {% blocktrans %}Here you can manage objects related to organizational units, users, roles and applications.{% endblocktrans %}
8
  <h2>{% blocktrans %}Here you can manage objects related to organizational units, users, roles and applications.{% endblocktrans %}</h2>
9
<a class="extra-actions-menu-opener"></a>
10
<ul class="extra-actions-menu">
11
 <li><a href="{% url 'a2-manager-site-export' %}">{% trans 'Export Site' %}</a></li>
12
 <li><a href="{% url 'a2-manager-site-import' %}">{% trans 'Import Site' %}</a></li>
13
</ul>
14

  
9 15
{% endblock %}
10 16

  
11 17
{% block content %}
src/authentic2/manager/templates/authentic2/manager/site_import.html
1
{% extends "authentic2/manager/form.html" %}
2
{% load i18n %}
3

  
4
{% block appbar %}
5
<h2>{% trans "Site Import" %}</h2>
6
{% endblock %}
7

  
8
{% block content %}
9

  
10
<form method="post" enctype="multipart/form-data">
11
  {% csrf_token %}
12
  {{ form.as_p }}
13
  <div class="buttons">
14
    <button>{% trans "Import" %}</button>
15
    <a class="cancel" href="{% url 'a2-manager-homepage' %}">{% trans 'Cancel' %}</a>
16
  </div>
17
</form>
18
{% endblock %}
src/authentic2/manager/urls.py
115 115

  
116 116
        # backoffice menu as json
117 117
        url(r'^menu.json$', views.menu_json),
118

  
119
        # general management
120
        url(r'^site-export/$', views.site_export, name='a2-manager-site-export'),
121
        url(r'^site-import/$', views.site_import, name='a2-manager-site-import'),
118 122
    )
119 123
)
120 124

  
src/authentic2/manager/views.py
5 5
from django.views.generic.base import ContextMixin
6 6
from django.views.generic.edit import FormMixinBase
7 7
from django.views.generic import (FormView, UpdateView, CreateView, DeleteView, TemplateView,
8
                                  DetailView)
8
                                  DetailView, View)
9 9
from django.views.generic.detail import SingleObjectMixin
10 10
from django.http import HttpResponse, Http404
11 11
from django.utils.encoding import force_text
......
21 21

  
22 22
from django_rbac.utils import get_ou_model
23 23

  
24
from authentic2.forms import modelform_factory
24
from authentic2.data_transfer import export_site, import_site, DataImportError, ImportContext
25
from authentic2.forms import modelform_factory, SiteImportForm
25 26
from authentic2.utils import redirect
26 27
from authentic2.decorators import json as json_view
27 28
from authentic2 import hooks
......
607 608
        return widget
608 609

  
609 610
select2 = Select2View.as_view()
611

  
612

  
613
class SiteExport(View):
614

  
615
    def get(self, request, *args, **kwargs):
616
        return HttpResponse(
617
            json.dumps(export_site(), indent=4), content_type='application/json')
618

  
619

  
620
site_export = SiteExport.as_view()
621

  
622

  
623
class SiteImportView(FormView):
624
    form_class = SiteImportForm
625
    template_name = 'authentic2/manager/site_import.html'
626
    success_url = reverse_lazy('a2-manager-homepage')
627

  
628
    def form_valid(self, form):
629
        try:
630
            json_site = json.load(self.request.FILES['site_json'])
631
        except ValueError:
632
            form.add_error('site_json', _('File is not in the expected JSON format.'))
633
            return self.form_invalid(form)
634

  
635
        try:
636
            import_site(json_site, ImportContext())
637
        except DataImportError as e:
638
            form.add_error('site_json', unicode(e))
639
            return self.form_invalid(form)
640

  
641
        return super(SiteImportView, self).form_valid(form)
642

  
643

  
644
site_import = SiteImportView.as_view()
tests/test_manager.py
1 1
import pytest
2
import json
2 3
from urlparse import urlparse
3 4

  
4 5
from django.core.urlresolvers import reverse
5 6
from django.core import mail
6 7

  
8
from webtest import Upload
9

  
7 10
from authentic2.a2_rbac.utils import get_default_ou
8 11

  
9 12
from django_rbac.utils import get_ou_model, get_role_model
......
552 555
        assert set(names) == {u'Auto Admin Role'}
553 556

  
554 557
    test_user_listing_auto_admin_role(user_with_auto_admin_role)
558

  
559

  
560
def test_manager_site_export(app, superuser_or_admin):
561
    response = login(app, superuser_or_admin, '/manage/site-export/')
562
    assert 'roles' in response.json
563
    assert 'ous' in response.json
564

  
565

  
566
def test_manager_site_import(app, db, superuser_or_admin):
567
    site_import = login(app, superuser_or_admin, '/manage/site-import/')
568
    form = site_import.form
569
    site_export = {
570
        'roles': [
571
            {
572
                "description": "", "service": None, "name": "basic",
573
                "attributes": [],
574
                "ou": {
575
                    "slug": "default",
576
                    "uuid": "ba60d9e6c2874636883bdd604b23eab2",
577
                    "name": "Collectivit\u00e9 par d\u00e9faut"
578
                },
579
                "external_id": "",
580
                "slug": "basic",
581
                "uuid": "6eb7bbf64bf547119120f925f0e560ac"
582
            }]
583
    }
584
    form['site_json'] = Upload(
585
        'site_export.json', json.dumps(site_export), 'application/octet-stream')
586
    res = form.submit()
587
    assert res.status_code == 302
588
    assert get_role_model().objects.get(slug='basic')
589

  
590

  
591
def test_manager_site_import_error(app, db, superuser_or_admin):
592
    site_import = login(app, superuser_or_admin, '/manage/site-import/')
593
    form = site_import.form
594
    site_export = {
595
        'roles': [
596
            {
597
                "description": "", "service": None, "name": "basic",
598
                "attributes": [],
599
                "ou": {
600
                    "slug": "unkown-ou",
601
                    "uuid": "ba60d9e6c2874636883bdd604b23eab2",
602
                    "name": "unkown ou"
603
                },
604
                "external_id": "",
605
                "slug": "basic",
606
                "uuid": "6eb7bbf64bf547119120f925f0e560ac"
607
            }]
608
    }
609
    form['site_json'] = Upload(
610
        'site_export.json', json.dumps(site_export), 'application/octet-stream')
611
    res = form.submit()
612
    assert res.status_code == 200
613
    assert 'missing Organizational Unit' in res.text
614
    Role = get_role_model()
615
    with pytest.raises(Role.DoesNotExist):
616
        Role.objects.get(slug='basic')
555
-