0001-add-UI-for-import-export-site-23210.patch
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 |
{% if user.is_superuser %} |
|
10 |
<a class="extra-actions-menu-opener"></a> |
|
11 |
<ul class="extra-actions-menu"> |
|
12 |
<li><a href="{% url 'a2-manager-site-export' %}">{% trans 'Export Site' %}</a></li> |
|
13 |
<li><a href="{% url 'a2-manager-site-import' %}">{% trans 'Import Site' %}</a></li> |
|
14 |
</ul> |
|
15 |
{% endif %} |
|
9 | 16 |
{% endblock %} |
10 | 17 | |
11 | 18 |
{% 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, batch_queryset |
26 | 27 |
from authentic2.decorators import json as json_view |
27 | 28 |
from authentic2 import hooks |
... | ... | |
608 | 609 |
return widget |
609 | 610 | |
610 | 611 |
select2 = Select2View.as_view() |
612 | ||
613 | ||
614 |
class SiteExport(View): |
|
615 | ||
616 |
def get(self, request, *args, **kwargs): |
|
617 |
if not request.user.is_superuser: |
|
618 |
raise PermissionDenied |
|
619 |
return HttpResponse( |
|
620 |
json.dumps(export_site(), indent=4), content_type='application/json') |
|
621 | ||
622 | ||
623 |
site_export = SiteExport.as_view() |
|
624 | ||
625 | ||
626 |
class SiteImportView(FormView): |
|
627 |
form_class = SiteImportForm |
|
628 |
template_name = 'authentic2/manager/site_import.html' |
|
629 |
success_url = reverse_lazy('a2-manager-homepage') |
|
630 | ||
631 |
def form_valid(self, form): |
|
632 |
try: |
|
633 |
json_site = json.load(self.request.FILES['site_json']) |
|
634 |
except ValueError: |
|
635 |
form.add_error('site_json', _('File is not in the expected JSON format.')) |
|
636 |
return self.form_invalid(form) |
|
637 | ||
638 |
try: |
|
639 |
import_site(json_site, ImportContext()) |
|
640 |
except DataImportError as e: |
|
641 |
form.add_error('site_json', unicode(e)) |
|
642 |
return self.form_invalid(form) |
|
643 | ||
644 |
return super(SiteImportView, self).form_valid(form) |
|
645 | ||
646 |
def dispatch(self, request, *args, **kwargs): |
|
647 |
if not request.user.is_superuser: |
|
648 |
raise PermissionDenied |
|
649 |
return super(SiteImportView, self).dispatch(request, *args, **kwargs) |
|
650 | ||
651 | ||
652 |
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): |
|
561 |
response = login(app, superuser, '/manage/site-export/') |
|
562 |
assert 'roles' in response.json |
|
563 |
assert 'ous' in response.json |
|
564 | ||
565 | ||
566 |
def test_manager_site_export_forbidden(app, simple_user): |
|
567 |
login(app, simple_user) |
|
568 |
app.get('/manage/site-export/', status=403) |
|
569 | ||
570 | ||
571 |
def test_manager_site_import(app, db, superuser): |
|
572 |
site_import = login(app, superuser, '/manage/site-import/') |
|
573 |
form = site_import.form |
|
574 |
site_export = { |
|
575 |
'roles': [ |
|
576 |
{ |
|
577 |
"description": "", "service": None, "name": "basic", |
|
578 |
"attributes": [], |
|
579 |
"ou": { |
|
580 |
"slug": "default", |
|
581 |
"uuid": "ba60d9e6c2874636883bdd604b23eab2", |
|
582 |
"name": "Collectivit\u00e9 par d\u00e9faut" |
|
583 |
}, |
|
584 |
"external_id": "", |
|
585 |
"slug": "basic", |
|
586 |
"uuid": "6eb7bbf64bf547119120f925f0e560ac" |
|
587 |
}] |
|
588 |
} |
|
589 |
form['site_json'] = Upload( |
|
590 |
'site_export.json', json.dumps(site_export), 'application/octet-stream') |
|
591 |
res = form.submit() |
|
592 |
assert res.status_code == 302 |
|
593 |
assert get_role_model().objects.get(slug='basic') |
|
594 | ||
595 | ||
596 |
def test_manager_site_import_error(app, db, superuser): |
|
597 |
site_import = login(app, superuser, '/manage/site-import/') |
|
598 |
form = site_import.form |
|
599 |
site_export = { |
|
600 |
'roles': [ |
|
601 |
{ |
|
602 |
"description": "", "service": None, "name": "basic", |
|
603 |
"attributes": [], |
|
604 |
"ou": { |
|
605 |
"slug": "unkown-ou", |
|
606 |
"uuid": "ba60d9e6c2874636883bdd604b23eab2", |
|
607 |
"name": "unkown ou" |
|
608 |
}, |
|
609 |
"external_id": "", |
|
610 |
"slug": "basic", |
|
611 |
"uuid": "6eb7bbf64bf547119120f925f0e560ac" |
|
612 |
}] |
|
613 |
} |
|
614 |
form['site_json'] = Upload( |
|
615 |
'site_export.json', json.dumps(site_export), 'application/octet-stream') |
|
616 |
res = form.submit() |
|
617 |
assert res.status_code == 200 |
|
618 |
assert 'missing Organizational Unit' in res.text |
|
619 |
Role = get_role_model() |
|
620 |
with pytest.raises(Role.DoesNotExist): |
|
621 |
Role.objects.get(slug='basic') |
|
622 | ||
623 | ||
624 |
def test_manager_site_import_forbidden(app, simple_user): |
|
625 |
login(app, simple_user) |
|
626 |
app.get('/manage/site-import/', status=403) |
|
627 | ||
628 | ||
629 |
def test_manager_homepatge_import_export(superuser, app): |
|
630 |
manager_home_page = login(app, superuser, reverse('a2-manager-homepage')) |
|
631 |
assert 'site-import' in manager_home_page.text |
|
632 |
assert 'site-export' in manager_home_page.text |
|
633 | ||
634 | ||
635 |
def test_manager_homepatge_import_export_hidden(admin, app): |
|
636 |
manager_home_page = login(app, admin, reverse('a2-manager-homepage')) |
|
637 |
assert 'site-import' not in manager_home_page.text |
|
638 |
assert 'site-export' not in manager_home_page.text |
|
555 |
- |