diff options
author | Michael Elkins <melkins@tislabs.com> | 2012-01-21 01:42:14 +0000 |
---|---|---|
committer | Michael Elkins <melkins@tislabs.com> | 2012-01-21 01:42:14 +0000 |
commit | cb3e16840ce29c8e46789abd083803f4f9cfd2b5 (patch) | |
tree | cf1b7b563d38bf950734a680b90669b59d5dd0ba | |
parent | f25bac0b0473490d84198e6a28185182530550c5 (diff) |
require double confirmation for roa creation
display list of matching routes with validation status for second confirmation
svn path=/branches/tk161/; revision=4254
-rw-r--r-- | rpkid/rpki/gui/app/forms.py | 10 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html | 2 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/templates/app/roarequest_form.html | 42 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/views.py | 45 |
4 files changed, 80 insertions, 19 deletions
diff --git a/rpkid/rpki/gui/app/forms.py b/rpkid/rpki/gui/app/forms.py index 375e8e67..69d4b335 100644 --- a/rpkid/rpki/gui/app/forms.py +++ b/rpkid/rpki/gui/app/forms.py @@ -151,9 +151,11 @@ class ROARequest(forms.Form): Handles both IPv4 and IPv6.""" - asn = forms.IntegerField() + asn = forms.IntegerField(label='AS') prefix = forms.CharField(max_length=50) - max_prefixlen = forms.CharField(required=False) + max_prefixlen = forms.CharField(required=False, + label='Max Prefix Length') + confirmed = forms.BooleanField(widget=forms.HiddenInput, required=False) def _as_resource_range(self): prefix = self.cleaned_data.get('prefix') @@ -192,8 +194,8 @@ class ROARequest(forms.Form): max_prefixlen = self.cleaned_data.get('max_prefixlen') max_prefixlen = int(max_prefixlen) if max_prefixlen else r.prefixlen() if max_prefixlen < r.prefixlen(): - raise (forms.ValidationError, - 'max prefix length must be greater than or equal to the prefix length') + raise forms.ValidationError, \ + 'max prefix length must be greater than or equal to the prefix length' if max_prefixlen > r.datum_type.bits: raise forms.ValidationError, \ 'max prefix length (%d) is out of range for IP version (%d)' % (max_prefixlen, r.datum_type.bits) diff --git a/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html b/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html index e4bc432b..a0e4b54d 100644 --- a/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html +++ b/rpkid/rpki/gui/app/templates/app/roa_request_confirm_delete.html @@ -48,7 +48,7 @@ that are covered by this ROA request will be if this ROA request is deleted: <tr> <td>{{ r.get_prefix_display }}</td> <td>{{ r.asn }}</td> - <td><span class='label {{ r.status_label }}'>{{ r.status }}</span> + <td><span class='label {{ r.status_label }}'>{{ r.status }}</span></td> </tr> {% endfor %} </table> diff --git a/rpkid/rpki/gui/app/templates/app/roarequest_form.html b/rpkid/rpki/gui/app/templates/app/roarequest_form.html new file mode 100644 index 00000000..83759120 --- /dev/null +++ b/rpkid/rpki/gui/app/templates/app/roarequest_form.html @@ -0,0 +1,42 @@ +{% extends "app/app_base.html" %} + +{% block content %} + +<div class='page-title'> + <h1>Create ROA</h1> +</div> + +<div class='row'> + <div class='span8'> + <form method='POST' action='{{ request.get_full_path }}'> + {% csrf_token %} + {% include "app/bootstrap_form.html" %} + <div class='actions'> + <input class='btn primary' type='submit' value='Create'/> + <a class='btn' href='{% url rpki.gui.app.views.roa_list %}'>Cancel</a> + </div> + </form> + </div> + <div class='span8 offset8'> + <p>Matched Routes + + <table style='zebra-striped condensed-table'> + <tr> + <th>Prefix</th> + <th>Origin AS</th> + <th>Validation Status</th> + </tr> + {% for r in routes %} + <tr> + <td>{{ r.get_prefix_display }}</td> + <td>{{ r.asn }}</td> + <td><span class='label {{ r.status_label }}'>{{ r.status }}</span></td> + </tr> + {% endfor %} + </table> + </div> +</div> + +{% endblock content %} + +{# vim:set sw=2: #} diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py index 70696eea..9f7e6df3 100644 --- a/rpkid/rpki/gui/app/views.py +++ b/rpkid/rpki/gui/app/views.py @@ -429,29 +429,46 @@ def roa_create(request): Doesn't use the generic create_object() form because we need to create both the ROARequest and ROARequestPrefix objects.""" + routes = [] if request.method == 'POST': form = forms.ROARequest(request.POST, request.FILES) if form.is_valid(): asn = form.cleaned_data.get('asn') conf = request.session['handle'] - roarequests = models.ROARequest.objects.filter(issuer=conf, asn=asn) - if roarequests: - # FIXME need to handle the case where there are multiple ROAs - # for the same AS due to prefixes delegated from different - # resource certs. - roa = roarequests[0] - else: - roa = models.ROARequest.objects.create(issuer=conf, asn=asn) rng = form._as_resource_range() # FIXME calling "private" method max_prefixlen = int(form.cleaned_data.get('max_prefixlen')) - version = 'IPv4' if isinstance(rng, - resource_set.resource_range_ipv4) else 'IPv6' - roa.prefixes.create(version=version, prefix=str(rng.min), - prefixlen=rng.prefixlen(), max_prefixlen=max_prefixlen) - return http.HttpResponseRedirect(reverse(roa_list)) + + if form.cleaned_data.get('confirmed'): + roarequests = models.ROARequest.objects.filter(issuer=conf, asn=asn) + if roarequests: + # FIXME need to handle the case where there are multiple ROAs + # for the same AS due to prefixes delegated from different + # resource certs. + roa = roarequests[0] + else: + roa = models.ROARequest.objects.create(issuer=conf, asn=asn) + version = 'IPv4' if isinstance(rng, + resource_set.resource_range_ipv4) else 'IPv6' + roa.prefixes.create(version=version, prefix=str(rng.min), + prefixlen=rng.prefixlen(), max_prefixlen=max_prefixlen) + return http.HttpResponseRedirect(reverse(roa_list)) + else: + form = forms.ROARequest(initial={ + 'asn': form.cleaned_data.get('asn'), + 'prefix': form.cleaned_data.get('prefix'), + 'max_prefixlen': form.cleaned_data.get('max_prefixlen'), + 'confirmed': True}) + + # find list of matching routes + match = roa_match(rng) + for route, roas in match: + validate_route(route, roas) + routes.append(route) else: form = forms.ROARequest() - return render('app/roarequest_form.html', {'form': form}, request) + + return render('app/roarequest_form.html', {'form': form, 'routes': routes}, + request) @handle_required |