aboutsummaryrefslogtreecommitdiff
path: root/portal-gui/rpkigui/myrpki/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'portal-gui/rpkigui/myrpki/views.py')
-rw-r--r--portal-gui/rpkigui/myrpki/views.py284
1 files changed, 213 insertions, 71 deletions
diff --git a/portal-gui/rpkigui/myrpki/views.py b/portal-gui/rpkigui/myrpki/views.py
index c7d93779..70c453c1 100644
--- a/portal-gui/rpkigui/myrpki/views.py
+++ b/portal-gui/rpkigui/myrpki/views.py
@@ -8,13 +8,12 @@ from django.shortcuts import get_object_or_404, render_to_response
from django.utils.http import urlquote
from django.template import RequestContext
from django.db import IntegrityError
-from django.db.models import Q
from django import http
from functools import update_wrapper
import models
import forms
-import settings
import glue
+from asnset import asnset
# For each type of object, we have a detail view, a create view and
# an update view. We heavily leverage the generic views, only
@@ -24,9 +23,12 @@ def handle_required(f):
@login_required
def wrapped_fn(request, *args, **kwargs):
if 'handle' not in request.session:
- conf = models.Conf.objects.all().filter(owner__in=request.user.groups.all())
+ if request.user.is_superuser:
+ conf = models.Conf.objects.all()
+ else:
+ conf = models.Conf.objects.filter(owner=request.user)
if conf.count() == 1:
- handle = conf[ 0 ]
+ handle = conf[0]
elif conf.count() == 0:
return http.HttpResponseRedirect('/myrpki/conf/add')
else:
@@ -174,7 +176,10 @@ def dashboard(request):
@login_required
def conf_list(request):
"""Allow the user to select a handle."""
- queryset = models.Conf.objects.filter(owner__in=request.user.groups.all())
+ if request.user.is_superuser:
+ queryset = models.Conf.objects.all()
+ else:
+ queryset = models.Conf.objects.filter(owner__in=request.user.groups.all())
return object_list(request, queryset,
template_name='myrpki/conf_list.html', template_object_name='conf')
@@ -188,11 +193,14 @@ def conf_select(request):
if next_url == '':
next_url = '/myrpki/'
- # since the handle is passed in as a parameter, need to verify that
- # the user is actually in the group
- conf = models.Conf.objects.filter(
- Q(handle__exact=handle) & Q(owner__in=request.user.groups.all()))
- if conf.count() > 0:
+ if request.user.is_superuser:
+ conf = models.Conf.objects.filter(handle=handle)
+ else:
+ # since the handle is passed in as a parameter, need to verify that
+ # the user is actually in the group
+ conf = models.Conf.objects.filter(handle=handle,
+ owner__in=request.user.groups.all())
+ if conf:
request.session['handle'] = conf[0]
return http.HttpResponseRedirect(next_url)
@@ -327,90 +335,224 @@ def get_parents_or_404(handle, obj):
return handle.parents.filter(pk__in=[c.parent.pk for c in cert_set])
-def resource_view(request, object_type, form_type, pk):
- '''view/subdivide an address range.'''
+#def resource_view(request, object_type, form_type, pk, resource_type):
+# '''view/subdivide an address range.'''
+# handle = request.session['handle']
+# obj = get_object_or_404(object_type, pk=pk)
+# # ensure this resource range belongs to a parent of the current conf
+# parent_set = get_parents_or_404(handle, obj)
+#
+# if request.method == 'POST':
+# form = form_type(handle, obj, request.POST)
+# if form.is_valid():
+# if form.cleaned_data['child'] is None:
+# hi = form.cleaned_data['hi']
+# lo = form.cleaned_data['lo']
+# print hi, lo
+# # if a range is given, create a new object
+# if hi and lo:
+# subobj = object_type.objects.create(
+# lo=lo, hi=hi, parent=obj, allocated=None)
+# subobj.save()
+# if obj.allocated:
+# obj.allocated = None
+# obj.save()
+# else:
+# obj.allocated = form.cleaned_data['child']
+# obj.save()
+#
+# glue.configure_resources(handle)
+# else:
+# form = form_type(handle, obj)
+# return render('myrpki/resource_view.html', { 'addr': obj, 'form': form,
+# 'parent': parent_set, 'resource_type': resource_type }, request)
+
+@handle_required
+def address_view(request, pk):
handle = request.session['handle']
- obj = get_object_or_404(object_type, pk=pk)
+ obj = get_object_or_404(models.AddressRange.objects.all(), pk=pk)
# ensure this resource range belongs to a parent of the current conf
parent_set = get_parents_or_404(handle, obj)
- if request.method == 'POST':
- form = form_type(handle, obj, request.POST)
- if form.is_valid():
- if form.cleaned_data['child'] is None:
- hi = form.cleaned_data['hi']
- lo = form.cleaned_data['lo']
- # if a range is given, create a new object
- if hi != '' and lo != '':
- subobj = object_type.objects.create(
- lo=lo, hi=hi, parent=obj, allocated=None)
- subobj.save()
- if obj.allocated:
- obj.allocated = None
- obj.save()
- else:
- obj.allocated = form.cleaned_data['child']
- obj.save()
-
- glue.configure_resources(handle)
- else:
- form = form_type(handle, obj)
- return render('myrpki/resource_view.html', { 'addr': obj, 'form': form,
- 'parent': parent_set }, request)
-
-@handle_required
-def address_view(request, pk):
- '''view/subdivide an address range.'''
- return resource_view(request, models.AddressRange,
- forms.SubOrAssignAddressForm, pk)
+ return render('myrpki/prefix_view.html',
+ { 'addr': obj, 'parent': parent_set }, request)
@handle_required
def asn_view(request, pk):
'''view/subdivide an asn range.'''
- return resource_view(request, models.Asn, forms.SubOrAssignAsnForm, pk)
+ handle = request.session['handle']
+ obj = get_object_or_404(models.Asn.objects, pk=pk)
+ # ensure this resource range belongs to a parent of the current conf
+ parent_set = get_parents_or_404(handle, obj)
+
+ return render('myrpki/_view.html',
+ { 'addr': obj, 'parent': parent_set }, request)
+
+#@handle_required
+#def roa_edit(request, pk=None):
+# '''Create or edit a ROA.'''
+#
+# handle = request.session['handle']
+#
+# if not pk is None:
+# obj = get_object_or_404(models.Roa, pk=pk)
+# if obj.conf != handle:
+# raise http.Http404
+# else:
+# obj = None
+#
+# if request.method == 'POST':
+# form = forms.RoaForm(handle, None, None, None, request.POST)
+# if form.is_valid():
+# if not obj:
+# obj = models.Roa(conf=handle, asn=form.cleaned_data['asn'],
+# comments=form.cleaned_data['comments'], max_len=0)
+# else:
+# obj.asn = form.cleaned_data['asn']
+# obj.comments = form.cleaned_data['comments']
+# obj.save()
+# obj.prefix.clear()
+# obj.prefix.add(*form.cleaned_data['prefix'])
+#
+# glue.configure_resources(handle)
+#
+# return http.HttpResponseRedirect('/myrpki/')
+# else:
+# asn = obj.asn if obj else None
+# comments = obj.comments if obj else None
+# prefix = [o.pk for o in obj.prefix.all()] if obj else []
+# form = forms.RoaForm(handle, asn, comments, prefix)
+# return render('myrpki/roaform.html', { 'form': form }, request)
@handle_required
-def roa_edit(request, pk=None):
- '''Create or edit a ROA.'''
+def child_view(request, child_handle):
+ '''Detail view of child for the currently selected handle.'''
+ handle = request.session['handle']
+ child = get_object_or_404(handle.children.all(), handle__exact=child_handle)
+
+ return render('myrpki/child_view.html', { 'child': child }, request)
+@handle_required
+def prefix_split_view(request, pk):
handle = request.session['handle']
+ prefix = get_object_or_404(models.AddressRange.objects, pk=pk)
+ # ensure this resource range belongs to a parent of the current conf
+ parent_set = get_parents_or_404(handle, prefix)
- if not pk is None:
- obj = get_object_or_404(models.Roa, pk=pk)
- if obj.conf != handle:
- raise http.Http404
+ if request.method == 'POST':
+ form = forms.PrefixSplitForm(prefix, request.POST)
+ if form.is_valid():
+ obj = models.AddressRange.create(form.cleaned_data['lo'], form.cleaned_data['hi'], parent=parent)
+ obj.save()
+ return http.HttpResponseRedirect(obj.get_absolute_url())
else:
- obj = None
+ form = forms.PrefixSplitForm(prefix)
+
+ return render('myrpki/prefix_view.html', { 'form': form,
+ 'addr': prefix, 'form': form, 'parent': parent_set }, request)
+
+@handle_required
+def prefix_allocate_view(request, pk):
+ handle = request.session['handle']
+ prefix = get_object_or_404(models.AddressRange.objects, pk=pk)
+ # ensure this resource range belongs to a parent of the current conf
+ parent_set = get_parents_or_404(handle, prefix)
if request.method == 'POST':
- form = forms.RoaForm(handle, None, None, None, request.POST)
+ form = forms.PrefixAllocateForm(None, handle.children.all(), request.POST)
if form.is_valid():
- if not obj:
- obj = models.Roa(conf=handle, asn=form.cleaned_data['asn'],
- comments=form.cleaned_data['comments'], max_len=0)
- else:
- obj.asn = form.cleaned_data['asn']
- obj.comments = form.cleaned_data['comments']
- obj.save()
- obj.prefix.clear()
- obj.prefix.add(*form.cleaned_data['prefix'])
+ prefix.allocated = form.cleaned_data['child']
+ prefix.save()
+ return http.HttpResponseRedirect(prefix.get_absolute_url())
+ else:
+ form = forms.PrefixAllocateForm(prefix.allocated.pk if prefix.allocated else None,
+ handle.children.all())
+
+ return render('myrpki/prefix_view.html', { 'form': form,
+ 'addr': prefix, 'form': form, 'parent': parent_set }, request)
+
+def common_cert(prefix, prefix_set):
+ '''Return true if prefix is derived from the same resource cert
+ as all the addresses in prefix_set.'''
+ # list of certs for the target prefix
+ certs = prefix.from_cert.all()
+ # all prefixes will have the same cert, so just check the first one
+ prefix_certs = prefix_set[0].from_cert.all()
+ # all we need is one match
+ for c in certs:
+ if c in prefix_certs:
+ return True
+ return False
+
+def update_roas(handle, prefix):
+ '''Recompute the required ROAs for the prefix that was changed.'''
+ # generate the list of ASNs
+ asns = list(asnset(prefix.asns))
+
+ print 'updating roas for %s: asns=%r' % (prefix, asns)
+
+ # remove this prefix from any roa not on the updated list
+ for roa in prefix.from_roa.exclude(asn__in=asns):
+ print 'removing %s from roa for asn %d' % (prefix, roa.asn)
+ roa.prefix.remove(prefix)
+ # if the roa is empty, delete it now
+ if roa.prefix.all().count() == 0:
+ print 'deleting roa for asn %d because it is empty' % (roa.asn,)
+ roa.delete()
+
+ for asid in asns:
+ for roa in handle.roas.filter(asn=asid):
+ # determine if this roa includes prefixes from the same
+ # resource cert as the prefix we just changed
+ if common_cert(prefix, roa.prefix.all()):
+ roa.prefix.add(prefix)
+ break
+ else:
+ # no roa is present for this ASN, create a new one
+ print 'creating new roa for asn %d with %s' % (asid, prefix)
+ roa = models.Roa.objects.create(asn=asid, conf=handle, active=False)
+ roa.save()
+ roa.prefix.add(prefix)
- glue.configure_resources(handle)
+@handle_required
+def prefix_roa_view(request, pk):
+ handle = request.session['handle']
+ obj = get_object_or_404(models.AddressRange.objects, pk=pk)
+ # ensure this resource range belongs to a parent of the current conf
+ parent_set = get_parents_or_404(handle, obj)
- return http.HttpResponseRedirect('/myrpki/')
+ if request.method == 'POST':
+ form = forms.PrefixRoaForm(request.POST)
+ if form.is_valid():
+ obj.asns = form.cleaned_data['asns']
+ obj.save()
+ update_roas(handle, obj)
+ glue.configure_resources(handle)
+ return http.HttpResponseRedirect(obj.get_absolute_url())
else:
- asn = obj.asn if obj else None
- comments = obj.comments if obj else None
- prefix = [o.pk for o in obj.prefix.all()] if obj else []
- form = forms.RoaForm(handle, asn, comments, prefix)
- return render('myrpki/roaform.html', { 'form': form }, request)
+ form = forms.PrefixRoaForm(initial={ 'asns': obj.asns })
+
+ return render('myrpki/prefix_view.html', { 'form': form,
+ 'addr': obj, 'form': form, 'parent': parent_set }, request)
@handle_required
-def child_view(request, child_handle):
- '''Detail view of child for the currently selected handle.'''
+def asn_allocate_view(request, pk):
handle = request.session['handle']
- child = get_object_or_404(handle.children.all(), handle__exact=child_handle)
+ obj = get_object_or_404(models.Asn.objects, pk=pk)
+ # ensure this resource range belongs to a parent of the current conf
+ parent_set = get_parents_or_404(handle, obj)
- return render('myrpki/child_view.html', { 'child': child }, request)
+ if request.method == 'POST':
+ form = forms.PrefixAllocateForm(None, handle.children.all(), request.POST)
+ if form.is_valid():
+ obj.allocated = form.cleaned_data['child']
+ obj.save()
+ return http.HttpResponseRedirect(obj.get_absolute_url())
+ else:
+ form = forms.PrefixAllocateForm(obj.allocated.pk if obj.allocated else None,
+ handle.children.all())
+
+ return render('myrpki/asn_view.html', { 'form': form,
+ 'asn': obj, 'form': form, 'parent': parent_set }, request)
# vim:sw=4 ts=8 expandtab