diff options
author | Michael Elkins <melkins@tislabs.com> | 2012-11-22 00:19:58 +0000 |
---|---|---|
committer | Michael Elkins <melkins@tislabs.com> | 2012-11-22 00:19:58 +0000 |
commit | fb6fbbb26b7f9d2b7ea2898b716bcd30993533da (patch) | |
tree | ca14eb677aa844a0057d47127aed5d3515cb372b /rpkid/rpki/gui/app/views.py | |
parent | 9f80536e743fa3afc42b6ecc84e621c214847eac (diff) |
commiting work in progress
svn path=/branches/tk329/; revision=4892
Diffstat (limited to 'rpkid/rpki/gui/app/views.py')
-rw-r--r-- | rpkid/rpki/gui/app/views.py | 319 |
1 files changed, 111 insertions, 208 deletions
diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py index f2f911da..1d825000 100644 --- a/rpkid/rpki/gui/app/views.py +++ b/rpkid/rpki/gui/app/views.py @@ -29,10 +29,12 @@ from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, render from django.utils.http import urlquote from django import http -from django.views.generic.list_detail import object_list, object_detail -from django.core.urlresolvers import reverse +from django.views.generic.list_detail import object_detail +from django.core.urlresolvers import reverse, reverse_lazy from django.contrib.auth.models import User from django.contrib.formtools.preview import FormPreview +from django.views.generic import (DetailView, ListView, CreateView, UpdateView, + DeleteView) from rpki.irdb import Zookeeper, ChildASN, ChildNet from rpki.gui.app import models, forms, glue, range_list @@ -205,18 +207,14 @@ def dashboard(request): 'unused_prefixes_v6': unused_prefixes_v6, 'asns': asns, 'prefixes': prefixes, - 'prefixes_v6': prefixes_v6}) - - + 'prefixes_v6': prefixes_v6, + }) + @superuser_required -def conf_list(request): +def conf_list(request, **kwargs): """Allow the user to select a handle.""" - queryset = models.Conf.objects.all() - return object_list(request, queryset, - template_name='app/conf_list.html', - template_object_name='conf', - extra_context={'select_url': reverse(conf_select)}) - + view = ListView.as_view(model=models.Conf) + return view(request, **kwargs) @superuser_required def conf_select(request): @@ -230,7 +228,6 @@ def conf_select(request): request.session['handle'] = get_object_or_404(models.Conf, handle=handle) return http.HttpResponseRedirect(next_url) - def serve_xml(content, basename): """ Generate a HttpResponse object with the content type set to XML. @@ -244,7 +241,6 @@ def serve_xml(content, basename): resp['Content-Disposition'] = 'attachment; filename=%s.xml' % (basename,) return resp - @handle_required def conf_export(request): """Return the identity.xml for the current handle.""" @@ -259,22 +255,12 @@ def parent_import(request): conf = request.session['handle'] return generic_import(request, conf.parents, Zookeeper.configure_parent) - -@handle_required -def parent_list(request): - """List view for parent objects.""" - conf = request.session['handle'] - return object_list(request, queryset=conf.parents.all(), - extra_context={'create_url': reverse(parent_import), - 'create_label': 'Import'}) - - @handle_required -def parent_detail(request, pk): +def parent_detail(*args, **kwargs): """Detail view for a particular parent.""" - conf = request.session['handle'] - return object_detail(request, conf.parents.all(), object_id=pk) - + conf = args[0].session['handle'] + view = DetailView.as_view(queryset=conf.parents) + return view(*args, **kwargs) @handle_required def parent_delete(request, pk): @@ -288,13 +274,12 @@ def parent_delete(request, pk): z = Zookeeper(handle=conf.handle, logstream=log) z.delete_parent(obj.handle) z.synchronize() - return http.HttpResponseRedirect(reverse(parent_list)) + return http.HttpResponseRedirect(reverse(dashboard)) else: form = form_class() return render(request, 'app/parent_detail.html', {'object': obj, 'form': form, 'confirm_delete': True}) - @handle_required def parent_export(request, pk): """Export XML repository request for a given parent.""" @@ -311,26 +296,13 @@ def child_import(request): return generic_import(request, conf.children, Zookeeper.configure_child) -@handle_required -def child_list(request): - """List of children for current user.""" - conf = request.session['handle'] - return object_list(request, queryset=conf.children.all(), - template_name='app/child_list.html', - extra_context={ - 'create_url': reverse(child_import), - 'create_label': 'Import'}) +class ObjectActionPreview(FormPreview): + """Generic base class for confirming an action of an object. + Subclasses should define: + - template_name -class ChildAddResourcePreview(FormPreview): """ - Base class for handling preview of AS/Prefix additions to a child. - Subclasses implement the 'done' method to perform actual work on IRDB. - - """ - - form_template = 'app/child_detail.html' - preview_template = 'app/child_detail.html' def __init__(self, *args, **kwargs): """ @@ -338,9 +310,12 @@ class ChildAddResourcePreview(FormPreview): I don't see how we can set extra information in this class otherwise. """ - self.child = kwargs.pop('child') + self.form_object = kwargs.pop('form_object') self.logstream = kwargs.pop('logstream') - super(ChildAddResourcePreview, self).__init__(*args, **kwargs) + # use the same template for both form edit and preview + self.form_template = self.template_name + self.preview_template = self.template_name + super(ObjectActionPreview, self).__init__(*args, **kwargs) def get_context(self, *args, **kwargs): """" @@ -348,9 +323,9 @@ class ChildAddResourcePreview(FormPreview): form template. """ - d = super(ChildAddResourcePreview, self).get_context(*args, **kwargs) - d['object'] = self.child - d['form_label'] = 'Add Resource' + d = super(ObjectActionPreview, self).get_context(*args, **kwargs) + d['object'] = self.form_object + d['form_label'] = self.form_label return d def process_preview(self, request, form, context): @@ -358,6 +333,16 @@ class ChildAddResourcePreview(FormPreview): context['is_preview'] = True +class ChildAddResourcePreview(ObjectActionPreview): + """ + Base class for handling preview of AS/Prefix additions to a child. + Subclasses implement the 'done' method to perform actual work on IRDB. + + """ + template_name = 'app/child_detail.html' + form_label = 'Add Resource' + + class ChildAddPrefixPreview(ChildAddResourcePreview): def done(self, request, cleaned_data): address_range = cleaned_data.get('address_range') @@ -378,7 +363,7 @@ def child_add_address(request, pk): conf = request.session['handle'] child = get_object_or_404(models.Child, issuer=conf, pk=pk) form = forms.AddNetForm(child) - preview = ChildAddPrefixPreview(form, child=child, logstream=logstream) + preview = ChildAddPrefixPreview(form, form_object=child, logstream=logstream) return preview(request) class ChildAddASNPreview(ChildAddResourcePreview): @@ -395,7 +380,7 @@ def child_add_asn(request, pk): conf = request.session['handle'] child = get_object_or_404(models.Child, issuer=conf, pk=pk) form = forms.AddASNForm(child) - preview = ChildAddASNPreview(form, child=child, logstream=logstream) + preview = ChildAddASNPreview(form, form_object=child, logstream=logstream) return preview(request) @handle_required @@ -406,7 +391,6 @@ def child_view(request, pk): return render(request, 'app/child_detail.html', {'object': child, 'can_edit': True}) - @handle_required def child_edit(request, pk): """Edit the end validity date for a resource handle's child.""" @@ -435,6 +419,45 @@ def child_edit(request, pk): 'form_title': 'Edit Child: ' + child.handle, }) +@handle_required +def child_response(request, pk): + """ + Export the XML file containing the output of the configure_child + to send back to the client. + + """ + conf = request.session['handle'] + child = get_object_or_404(models.Child, issuer=conf, pk=pk) + z = Zookeeper(handle=conf.handle) + xml = z.generate_parental_response(child) + resp = serve_xml(str(xml), child.handle) + return resp + + +class ChildDeletePreview(ObjectActionPreview): + template_name = 'app/child_detail.html' + form_label = 'Delete Child' + + def __init__(self, *args, **kwargs): + self.conf = kwargs.pop('conf') + super(ChildDeletePreview, self).__init__(*args, **kwargs) + + def done(self, request, cleaned_data): + z = Zookeeper(handle=self.conf.handle) + z.delete_child(self.form_object.handle) + z.synchronize() + return http.HttpResponseRedirect(reverse(dashboard)) + +@handle_required +def child_delete(request, pk): + log = request.META['wsgi.errors'] + conf = request.session['handle'] + # verify this child belongs to the current user + obj = get_object_or_404(conf.children, pk=pk) + form_class = forms.UserDeleteForm # FIXME + preview = ChildDeletePreview(form_class, conf=conf, form_object=obj, + logstream=log) + return preview(request) @handle_required def roa_create(request): @@ -520,27 +543,11 @@ def roa_create_confirm(request): prefixlen=rng.prefixlen(), max_prefixlen=max_prefixlen) Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() - return http.HttpResponseRedirect(reverse(roa_list)) + return http.HttpResponseRedirect(reverse(dashboard)) # What should happen when the submission form isn't valid? For now # just fall through and redirect back to the ROA creation form return http.HttpResponseRedirect(reverse(roa_create)) - -@handle_required -def roa_list(request): - """ - Display a list of ROARequestPrefix objects for the current resource - handle. - - """ - - conf = request.session['handle'] - qs = models.ROARequestPrefix.objects.filter(roa_request__issuer=conf).order_by('prefix') - return object_list(request, queryset=qs, - template_name='app/roa_request_list.html', - extra_context={'create_url': reverse(roa_create)}) - - @handle_required def roa_detail(request, pk): """Not implemented. @@ -573,7 +580,7 @@ def roa_delete(request, pk): if not roa.prefixes.exists(): roa.delete() Zookeeper(handle=conf.handle).run_rpkid_now() - return http.HttpResponseRedirect(reverse(roa_list)) + return http.HttpResponseRedirect(reverse(dashboard)) ### Process GET ### @@ -597,94 +604,45 @@ def roa_delete(request, pk): {'object': obj, 'routes': routes}) -@handle_required -def ghostbuster_list(request): - """ - Display a list of all ghostbuster requests for the current Conf. - - """ - conf = request.session['handle'] - qs = models.GhostbusterRequest.objects.filter(issuer=conf) - return object_list(request, queryset=qs) - - -@handle_required -def ghostbuster_view(request, pk): - """ - Display an individual ghostbuster request. - - """ - conf = request.session['handle'] - qs = models.GhostbusterRequest.objects.filter(issuer=conf) - return object_detail(request, queryset=qs, object_id=pk, - extra_context={'can_edit': True}) +class GhostbusterDetailView(DetailView): + def get_queryset(self): + return self.request.session['handle'].ghostbusters -@handle_required -def ghostbuster_delete(request, pk): - """ - Handle deletion of a GhostbusterRequest object. +class GhostbusterDeleteView(DeleteView): + template_name = 'app/object_confirm_delete.html' + success_url = reverse_lazy(dashboard) - """ - conf = request.session['handle'] - log = request.META['wsgi.errors'] - form_class = forms.UserDeleteForm # FIXME - # Ensure the GhosbusterRequest object belongs to the current user. - obj = get_object_or_404(models.GhostbusterRequest, issuer=conf, pk=pk) - if request.method == 'POST': - form = form_class(request.POST, request.FILES) - if form.is_valid(): - obj.delete() - Zookeeper(handle=conf.handle, logstream=log).run_rpkid_now() - return http.HttpResponseRedirect(reverse(ghostbuster_list)) - else: - form = form_class() - return render(request, 'app/ghostbusterrequest_detail.html', - {'object': obj, 'form': form, 'confirm_delete': True}) + def get_queryset(self): + return self.request.session['handle'].ghostbusters + def get_context_data(self, **kwargs): + context = super(GhostbusterDeleteView, self).get_context_data(**kwargs) + context['parent_template'] = 'app/ghostbusterrequest_detail.html' + return context -def _ghostbuster_edit(request, obj=None): - """ - Common code for create/edit. - """ - conf = request.session['handle'] +class GhostbusterCreateView(CreateView): form_class = forms.GhostbusterRequestForm - if request.method == 'POST': - form = form_class(conf, request.POST, request.FILES, instance=obj) - if form.is_valid(): - # use commit=False for the creation case, otherwise form.save() - # will fail due to schema constraint violation because conf is - # NULL - obj = form.save(commit=False) - obj.issuer = conf - obj.vcard = glue.ghostbuster_to_vcard(obj) - obj.save() - Zookeeper(handle=conf.handle).run_rpkid_now() - return http.HttpResponseRedirect(obj.get_absolute_url()) - else: - form = form_class(conf, instance=obj) - return render(request, 'app/app_form.html', { - 'form': form, - 'object': obj, - 'form_title': 'Edit Ghostbuster Request', - }) - + template_name = 'app/app_form.html' -@handle_required -def ghostbuster_edit(request, pk): - conf = request.session['handle'] + def get_form_kwargs(self): + kwargs = super(GhostbusterCreateView, self).get_form_kwargs() + kwargs['conf'] = self.request.session['handle'] + return kwargs - # verify that the object is owned by this conf - obj = get_object_or_404(models.GhostbusterRequest, pk=pk, issuer=conf) - - return _ghostbuster_edit(request, obj) +class GhostbusterEditView(UpdateView): + form_class = forms.GhostbusterRequestForm + template_name = 'app/app_form.html' -@handle_required -def ghostbuster_create(request): - return _ghostbuster_edit(request) + def get_queryset(self): + return self.request.session['handle'].ghostbusters + def get_form_kwargs(self): + kwargs = super(GhostbusterEditView, self).get_form_kwargs() + kwargs['conf'] = self.request.session['handle'] + return kwargs @handle_required def refresh(request): @@ -697,39 +655,6 @@ def refresh(request): return http.HttpResponseRedirect(reverse(dashboard)) -@handle_required -def child_response(request, pk): - """ - Export the XML file containing the output of the configure_child - to send back to the client. - - """ - conf = request.session['handle'] - child = get_object_or_404(models.Child, issuer=conf, pk=pk) - z = Zookeeper(handle=conf.handle) - xml = z.generate_parental_response(child) - resp = serve_xml(str(xml), child.handle) - return resp - - -@handle_required -def child_delete(request, pk): - conf = request.session['handle'] - # verify this child belongs to the current user - obj = get_object_or_404(conf.children, pk=pk) - form_class = forms.UserDeleteForm # FIXME - if request.method == 'POST': - form = form_class(request.POST, request.FILES) - if form.is_valid(): - z = Zookeeper(handle=conf.handle) - z.delete_child(obj.handle) - z.synchronize() - return http.HttpResponseRedirect(reverse(child_list)) - else: - form = form_class() - return render(request, 'app/child_detail.html', - {'object': obj, 'form': form, 'confirm_delete': True}) - def roa_match(rng): """Return a list of tuples of matching routes and roas.""" @@ -822,17 +747,6 @@ def route_roa_list(request, pk): @handle_required -def repository_list(request): - conf = request.session['handle'] - qs = models.Repository.objects.filter(issuer=conf) - return object_list(request, queryset=qs, - template_name='app/repository_list.html', - extra_context={ - 'create_url': reverse(repository_import), - 'create_label': u'Import'}) - - -@handle_required def repository_detail(request, pk): conf = request.session['handle'] qs = models.Repository.objects.filter(issuer=conf) @@ -853,7 +767,7 @@ def repository_delete(request, pk): z = Zookeeper(handle=conf.handle, logstream=log) z.delete_repository(obj.handle) z.synchronize() - return http.HttpResponseRedirect(reverse(repository_list)) + return http.HttpResponseRedirect(reverse(dashboard)) else: form = form_class() return render(request, 'app/repository_detail.html', @@ -867,22 +781,13 @@ def repository_import(request): models.Repository.objects, Zookeeper.configure_repository, form_class=forms.ImportRepositoryForm, - post_import_redirect=reverse(repository_list)) + post_import_redirect=reverse(dashboard)) @superuser_required -def client_list(request): - return object_list(request, queryset=models.Client.objects.all(), - extra_context={ - 'create_url': reverse(client_import), - 'create_label': u'Import'}) - - -@superuser_required def client_detail(request, pk): return object_detail(request, queryset=models.Client.objects, object_id=pk) - @superuser_required def client_delete(request, pk): log = request.META['wsgi.errors'] @@ -894,20 +799,18 @@ def client_delete(request, pk): z = Zookeeper(logstream=log) z.delete_publication_client(obj.handle) z.synchronize() - return http.HttpResponseRedirect(reverse(client_list)) + return http.HttpResponseRedirect(reverse(dashboard)) else: form = form_class() return render(request, 'app/client_detail.html', {'object': obj, 'form': form, 'confirm_delete': True}) - @superuser_required def client_import(request): return generic_import(request, models.Client.objects, Zookeeper.configure_publication_client, form_class=forms.ImportClientForm, - post_import_redirect=reverse(client_list)) - + post_import_redirect=reverse(dashboard)) @superuser_required def client_export(request, pk): |