diff options
Diffstat (limited to 'portal-gui')
27 files changed, 35 insertions, 1697 deletions
diff --git a/portal-gui/Makefile.in b/portal-gui/Makefile.in index b48f5d34..f8cb2012 100644 --- a/portal-gui/Makefile.in +++ b/portal-gui/Makefile.in @@ -17,24 +17,18 @@ libexecdir=@libexecdir@ PYTHON=@PYTHON@ WEBUSER=@WEBUSER@ -SECRET_KEY=@SECRET_KEY@ -INSTDIR=$(datarootdir)/rpki/gui CONFDIR=$(localstatedir)/rpki/conf DATABASE_PATH=$(localstatedir)/rpki/gui.db -MEDIADIR=$(INSTDIR)/media -MYRPKI=$(sbindir)/myrpki +INSTDIR=$(datarootdir)/rpki/gui TEMPLATEDIR=$(INSTDIR)/templates # automatically built sources -BUILD=rpkigui/settings.py \ - rpkigui/urls.py \ - rpkigui/myrpki/glue.py \ +BUILD=\ scripts/list_resources \ scripts/adduser \ scripts/load_csv \ - apache/rpki.wsgi \ - apache/rpki.conf + apache/rpki.conf all: $(BUILD) @@ -46,28 +40,9 @@ distclean: clean rm -f Makefile edit = sed \ - -e 's|@CONFDIR[@]|$(CONFDIR)|g' \ - -e 's|@DATABASE_PATH[@]|$(DATABASE_PATH)|g' \ - -e 's|@INSTDIR[@]|$(INSTDIR)|g' \ - -e 's|@MEDIADIR[@]|$(MEDIADIR)|g' \ - -e 's|@MYRPKI[@]|$(MYRPKI)|g' \ -e 's|@PYTHON[@]|$(PYTHON)|g' \ - -e 's|@SECRET_KEY[@]|$(SECRET_KEY)|g' \ - -e 's|@TEMPLATEDIR[@]|$(TEMPLATEDIR)|g' \ -e 's|@WEBUSER[@]|$(WEBUSER)|g' -rpkigui/settings.py: $(srcdir)/rpkigui/settings.py.in Makefile - $(edit) $@.in > $@ - -rpkigui/myrpki/glue.py: $(srcdir)/rpkigui/myrpki/glue.py.in Makefile - $(edit) $@.in > $@ - -rpkigui/urls.py: $(srcdir)/rpkigui/urls.py.in Makefile - $(edit) $@.in > $@ - -apache/rpki.wsgi: $(srcdir)/apache/rpki.wsgi.in Makefile - $(edit) $@.in > $@ - apache/rpki.conf: $(srcdir)/apache/rpki.conf.in Makefile $(edit) $@.in > $@ @@ -80,23 +55,7 @@ scripts/load_csv: $(srcdir)/scripts/load_csv.py Makefile scripts/adduser: $(srcdir)/scripts/adduser.py Makefile $(edit) $@.py > $@ -INSTALL_FILES=\ - rpkigui/__init__.py \ - rpkigui/manage.py \ - rpkigui/settings.py \ - rpkigui/urls.py \ - rpkigui/myrpki/AllocationTree.py \ - rpkigui/myrpki/__init__.py \ - rpkigui/myrpki/admin.py \ - rpkigui/myrpki/asnset.py \ - rpkigui/myrpki/forms.py \ - rpkigui/myrpki/glue.py \ - rpkigui/myrpki/misc.py \ - rpkigui/myrpki/models.py \ - rpkigui/myrpki/urls.py \ - rpkigui/myrpki/views.py - -.PHONY: install-perms install-data install install-media install-django install-scripts install-templates +.PHONY: install-perms install-data install install-scripts install-templates install-perms: chown $(WEBUSER) `dirname $(DATABASE_PATH)` @@ -104,11 +63,6 @@ install-perms: mkdir -p $(CONFDIR) chown -R $(WEBUSER) $(CONFDIR) -install-media: - install -m 755 -d $(INSTDIR)/media/img - install -m 644 media/img/my.png $(INSTDIR)/media/img - install -m 644 media/img/rpki.png $(INSTDIR)/media/img - install-apache: install -d -m 755 $(INSTDIR)/apache install -m 644 apache/rpki.conf $(INSTDIR)/apache @@ -128,20 +82,20 @@ install-templates: install -d -m 755 $(TEMPLATEDIR)/registration install -m 644 templates/registration/login.html $(TEMPLATEDIR)/registration -#this will go away once the django app moves into the rpki module -install-django: - for f in $(INSTALL_FILES); do \ - install -D -m 644 $$f $(INSTDIR)/$$f; \ - done - install-scripts: # user scripts install -m 755 scripts/load_csv $(sbindir)/rpkigui-load-csv install -m 755 scripts/adduser $(sbindir)/rpkigui-add-user install -D -m 755 scripts/list_resources $(libexecdir)/rpkigui-list-resources -install-data: $(BUILD) install-apache install-media install-templates install-scripts install-django +install-data: $(BUILD) install-apache install-templates install-scripts mkdir -p `dirname $(DATABASE_PATH)` - cd $(INSTDIR)/rpkigui && $(PYTHON) manage.py syncdb + django-admin syncdb --settings rpki.gui.settings install: install-data install-perms + +uninstall: + rm -r $(INSTDIR) + rm $(sbindir)/rpkigui-load-csv + rm $(sbindir)/rpkigui-add-user + rm $(libexecdir)/rpkigui-list-resources diff --git a/portal-gui/apache/rpki.wsgi.in b/portal-gui/apache/rpki.wsgi index c50fa6b7..0a7797a7 100644 --- a/portal-gui/apache/rpki.wsgi.in +++ b/portal-gui/apache/rpki.wsgi @@ -1,6 +1,6 @@ # $Id$ """ -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions +Copyright (C) 2010, 2011 SPARTA, Inc. dba Cobham Analytic Solutions Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -20,11 +20,8 @@ This is an example wsgi application for use with mod_wsgi and apache. """ import os -import sys -os.environ['DJANGO_SETTINGS_MODULE'] = 'rpkigui.settings' - -sys.path.append('@INSTDIR@') +os.environ['DJANGO_SETTINGS_MODULE'] = 'rpki.gui.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() diff --git a/portal-gui/rpkigui/TODO b/portal-gui/rpkigui/TODO deleted file mode 100644 index b7136397..00000000 --- a/portal-gui/rpkigui/TODO +++ /dev/null @@ -1,60 +0,0 @@ -Use RequestContext (helper function for render_to_response) and a default -list of context processors for the generic functions - -Teach cert_delete about children, conf*, parent* to say what the ramifications -of deleting a cert are. - -Teach cert form about file upload - -Redirect /accounts/profile/ to /dashboard/ - -Teach dashboard view about looking up resources from parent. -There are 3 types of resources: -- Ones we've accepted and match -- Ones we've accepted but don't match - - two subtypes: - * the parent is now giving us a superset of what they used to. - This is relatively easily handled by keeping the subdivisions - we've made and just making the superset resource the new parent - of the existing resource (e.g., we had accepted 18.5.0.0/16 and - they're now giving us 18.0.0.0/8) - * the parent is now giving us a subset (including none) of what they - used to. Two sub-cases: - - The part that they took away is neither delegated nor roa'd. - - The part that they took away is either delegated or roa'd or both. -- Ones we haven't accepted yet - -The roa needs to learn to handle its prefix children. It may need to -create the covering set of prefixes for an address range. - -Un<something>'d resources are: -what we've gotten from our parent: -models.AddressRange.objects.filter(from_parent=myconf.pk) -minus what we've given to our children or issued roas for -models.AddressRange.objects.filter(child__conf=myconf.pk) -models.AddressRange.objects.filter(roa__conf=myconf.pk) -or ->>> from django.db.models import Q ->>> models.AddressRange.objects.filter( Q(child__conf=myconf.pk) | - Q(roa__conf=myconf.pk) ) - - -and of course the ASN one is easier: -models.Asn.objects.filter(from_parent=myconf.pk) -minus what we've given to our children -models.Asn.objects.filter(child__conf=myconf.pk) - -look in -rpki/resource_set.py - - -Adding a handle / resource-holding entity / "conf": -- upload the <identity> that we've generated and are sending to the parent - -Adding a parent: -- upload the <parent> that he sent me - (keep things open to the parent uploading this directly to the web interface) - -Adding a child: -- upload the <identity> that he sent me - diff --git a/portal-gui/rpkigui/__init__.py b/portal-gui/rpkigui/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/portal-gui/rpkigui/__init__.py +++ /dev/null diff --git a/portal-gui/rpkigui/manage.py b/portal-gui/rpkigui/manage.py deleted file mode 100644 index 5e78ea97..00000000 --- a/portal-gui/rpkigui/manage.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff --git a/portal-gui/rpkigui/myrpki/AllocationTree.py b/portal-gui/rpkigui/myrpki/AllocationTree.py deleted file mode 100644 index 13936797..00000000 --- a/portal-gui/rpkigui/myrpki/AllocationTree.py +++ /dev/null @@ -1,148 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -from rpkigui.myrpki import misc, models -from rpki import resource_set - -class AllocationTree(object): - '''Virtual class representing a tree of unallocated resource ranges. - Keeps track of which subsets of a resource range have been - allocated.''' - - def __init__(self, resource): - self.resource = resource - self.range = resource.as_resource_range() - self.need_calc = True - - def calculate(self): - if self.need_calc: - self.children = [] - self.alloc = self.__class__.set_type() - self.unalloc = self.__class__.set_type() - - if self.is_allocated(): - self.alloc.append(self.range) - else: - for child in self.resource.children.all(): - c = self.__class__(child) - if c.unallocated(): - self.children.append(c) - self.alloc = self.alloc.union(c.alloc) - total = self.__class__.set_type() - total.append(self.range) - self.unalloc = total.difference(self.alloc) - self.need_calc=False - - def unallocated(self): - self.calculate() - return self.unalloc - - def as_ul(self): - '''Returns a string of the tree as an unordered HTML list.''' - s = [] - s.append('<a href="%s">%s</a>' % (self.resource.get_absolute_url(), self.resource)) - - # when the unallocated range is a subset of the current range, - # display the missing ranges - u = self.unallocated() - if len(u) != 1 or self.range != u[0]: - s.append(' (missing: ') - s.append(', '.join(str(x) for x in u)) - s.append(')') - - # quick access links - if self.resource.parent: - s.append(' | <a href="%s/delete">delete</a>' % (self.resource.get_absolute_url(),)) - s.append(' | <a href="%s/allocate">give</a>' % (self.resource.get_absolute_url(),)) - if self.range.min != self.range.max: - s.append(' | <a href="%s/split">split</a>' % (self.resource.get_absolute_url(),)) - # add type-specific actions - a = self.supported_actions() - if a: - s.extend(a) - - if self.children: - s.append('\n<ul>\n') - for c in self.children: - s.append('<li>' + c.as_ul()) - s.append('\n</ul>') - - return ''.join(s) - - def supported_actions(self): - '''Virtual method allowing subclasses to add actions to the HTML list.''' - return None - - @classmethod - def from_resource_range(cls, resource): - if isinstance(resource, resource_set.resource_range_as): - return AllocationTreeAS(resource) - if isinstance(resource, resoute_set.resource_range_ip): - return AllocationTreeIP(resource) - raise ValueError, 'Unsupported resource range type' - -class AllocationTreeAS(AllocationTree): - set_type = resource_set.resource_set_as - - def __init__(self, *args, **kwargs): - AllocationTree.__init__(self, *args, **kwargs) - self.conf = misc.top_parent(self.resource).from_cert.all()[0].parent.conf - - def is_allocated(self): - '''Returns true if this AS has been allocated to a child or - used in a ROA request.''' - # FIXME: detect use in ROA requests - - if self.resource.allocated: - return True - - # for individual ASNs - if self.range.min == self.range.max: - # is this ASN used in any roa? - if self.conf.roas.filter(asn=self.range.min): - return True - - return False - -class AllocationTreeIP(AllocationTree): - '''virtual class representing a tree of IP address ranges.''' - - @classmethod - def from_prefix(cls, prefix): - r = prefix.as_resource_range() - if isinstance(r, resource_set.resource_range_ipv4): - return AllocationTreeIPv4(prefix) - elif isinstance(r, resource_set.resource_range_ipv6): - return AllocationTreeIPv6(prefix) - raise ValueError, 'Unsupported IP range type' - - def supported_actions(self): - '''add a link to issue a roa for this IP range''' - return[' | <a href="%s/roa">roa</a>' % (self.resource.get_absolute_url(),)] - - def is_allocated(self): - '''Return True if this IP range is allocated to a child or used - in a ROA request.''' - return self.resource.allocated or self.resource.roa_requests.count() - -class AllocationTreeIPv4(AllocationTreeIP): - set_type = resource_set.resource_set_ipv4 - -class AllocationTreeIPv6(AllocationTreeIP): - set_type = resource_set.resource_set_ipv6 - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/__init__.py b/portal-gui/rpkigui/myrpki/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/portal-gui/rpkigui/myrpki/__init__.py +++ /dev/null diff --git a/portal-gui/rpkigui/myrpki/admin.py b/portal-gui/rpkigui/myrpki/admin.py deleted file mode 100644 index b5d7ab66..00000000 --- a/portal-gui/rpkigui/myrpki/admin.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -from django import forms -from django.contrib import admin -from rpkigui.myrpki import models - -class ConfAdmin( admin.ModelAdmin ): - pass - -class ChildAdmin( admin.ModelAdmin ): - pass - -class AddressRangeAdmin( admin.ModelAdmin ): - pass - -class AsnAdmin( admin.ModelAdmin ): - pass - -class ParentAdmin( admin.ModelAdmin ): - pass - -class RoaAdmin( admin.ModelAdmin ): - pass - -class ResourceCertAdmin(admin.ModelAdmin): - pass - -class RoaRequestAdmin(admin.ModelAdmin): - pass - -admin.site.register(models.Conf, ConfAdmin) -admin.site.register(models.Child, ChildAdmin) -admin.site.register(models.AddressRange, AddressRangeAdmin) -admin.site.register(models.Asn, AsnAdmin) -admin.site.register(models.Parent, ParentAdmin) -admin.site.register(models.Roa, RoaAdmin) -admin.site.register(models.RoaRequest, RoaRequestAdmin) -admin.site.register(models.ResourceCert, ResourceCertAdmin) diff --git a/portal-gui/rpkigui/myrpki/asnset.py b/portal-gui/rpkigui/myrpki/asnset.py deleted file mode 100644 index 6a2d562c..00000000 --- a/portal-gui/rpkigui/myrpki/asnset.py +++ /dev/null @@ -1,40 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -class asnset(object): - """A set-like object for containing sets of ASN values.""" - v = set() - - def __init__(self, init=None): - """ - May be initialized from a comma separated list of positive integers. - """ - if init: - self.v = set(int(x) for x in init.split(',') if x.strip() != '') - if any([x for x in self.v if x < 0]): - raise ValueError, "Can't contain negative values." - - def __str__(self): - return ','.join(str(x) for x in sorted(self.v)) - - def __iter__(self): - return iter(self.v) - - def add(self, n): - assert isinstance(n, int) - assert n > 0 - self.v.add(n) diff --git a/portal-gui/rpkigui/myrpki/forms.py b/portal-gui/rpkigui/myrpki/forms.py deleted file mode 100644 index 959d5a20..00000000 --- a/portal-gui/rpkigui/myrpki/forms.py +++ /dev/null @@ -1,147 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -from django import forms - -import rpki.ipaddrs - -from rpkigui.myrpki import models, misc -from rpkigui.myrpki.asnset import asnset - -class AddConfForm(forms.Form): - handle = forms.CharField(required=True, - help_text='your handle for your rpki instance') - run_rpkid = forms.BooleanField(required=False, initial=True, - label='Run rpkid?', - help_text='do you want to run your own instance of rpkid?') - rpkid_server_host = forms.CharField(initial='rpkid.example.org', - label='rpkid hostname', - help_text='publicly visible hostname for your rpkid instance') - rpkid_server_port = forms.IntegerField(initial=4404, - label='rpkid port') - run_pubd = forms.BooleanField(required=False, initial=False, - label='Run pubd?', - help_text='do you want to run your own instance of pubd?') - pubd_server_host = forms.CharField(initial='pubd.example.org', - label='pubd hostname', - help_text='publicly visible hostname for your pubd instance') - pubd_server_port = forms.IntegerField(initial=4402, label='pubd port') - pubd_contact_info = forms.CharField(initial='repo-man@rpki.example.org', - label='Pubd contact', - help_text='email address for the operator of your pubd instance') - -class ImportForm(forms.Form): - '''Form used for uploading parent/child identity xml files''' - handle = forms.CharField() - xml = forms.FileField() - -def PrefixSplitForm(parent, *args, **kwargs): - class _wrapper(forms.Form): - prefix = forms.CharField(max_length=200, help_text='CIDR or range') - - def clean(self): - p = self.cleaned_data.get('prefix') - try: - r = misc.parse_resource_range(p) - except ValueError, err: - print err - raise forms.ValidationError, 'invalid prefix or range' - # we get AssertionError is the range is misordered (hi before lo) - except AssertionError, err: - print err - raise forms.ValidationError, 'invalid prefix or range' - pr = parent.as_resource_range() - if r.min < pr.min or r.max > pr.max: - raise forms.ValidationError, \ - 'range is outside parent range' - if r.min == pr.min and r.max == pr.max: - raise forms.ValidationError, \ - 'range is equal to parent' - if parent.allocated: - raise forms.ValidationError, 'prefix is assigned to child' - for p in parent.children.all(): - c = p.as_resource_range() - if c.min <= r.min <= c.max or c.min <= r.max <= c.max: - raise forms.ValidationError, \ - 'overlap with another child prefix: %s' % (c,) - - return self.cleaned_data - return _wrapper(*args, **kwargs) - -def PrefixAllocateForm(iv, child_set, *args, **kwargs): - class _wrapper(forms.Form): - child = forms.ModelChoiceField(initial=iv, queryset=child_set, - required=False) - return _wrapper(*args, **kwargs) - -def PrefixRoaForm(prefix, *args, **kwargs): - prefix_range = prefix.as_resource_range() - - class _wrapper(forms.Form): - asns = forms.CharField(max_length=200, required=False, - help_text='Comma-separated list of ASNs') - max_length = forms.IntegerField(required=False, - min_value=prefix_range.prefixlen(), - max_value=prefix_range.datum_type.bits) - - def clean_max_length(self): - v = self.cleaned_data.get('max_length') - if not v: - v = prefix_range.prefixlen() - return v - - def clean_asns(self): - try: - v = asnset(self.cleaned_data.get('asns')) - return ','.join(str(x) for x in sorted(v)) - except ValueError: - raise forms.ValidationError, \ - 'Must be a list of integers separated by commas.' - return self.cleaned_data['asns'] - - def clean(self): - if not prefix.is_prefix(): - raise forms.ValidationError, \ - '%s can not be represented as a prefix.' % (prefix,) - if prefix.allocated: - raise forms.ValidationError, \ - 'Prefix is allocated to a child.' - return self.cleaned_data - - return _wrapper(*args, **kwargs) - -def PrefixDeleteForm(prefix, *args, **kwargs): - class _wrapped(forms.Form): - delete = forms.BooleanField(label='Yes, I want to delete this prefix:') - - def clean(self): - v = self.cleaned_data.get('delete') - if v: - if not prefix.parent: - raise forms.ValidationError, \ - 'Can not delete prefix received from parent' - if prefix.allocated: - raise forms.ValidationError, 'Prefix is allocated to child' - if prefix.roa_requests.all(): - raise forms.ValidationError, 'Prefix is used in your ROAs' - if prefix.children.all(): - raise forms.ValidationError, 'Prefix has been subdivided' - return self.cleaned_data - - return _wrapped(*args, **kwargs) - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/glue.py.in b/portal-gui/rpkigui/myrpki/glue.py.in deleted file mode 100644 index 897b23d4..00000000 --- a/portal-gui/rpkigui/myrpki/glue.py.in +++ /dev/null @@ -1,139 +0,0 @@ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -# $Id$ - -from __future__ import with_statement - -import os -import os.path -import csv -import stat -import sys - -from django.db.models import F - -import rpki -import rpki.config - -from rpkigui.myrpki import models - -confdir = '@CONFDIR@' - -def conf(handle): - return confdir + '/' + handle - -#def form_to_conf(data): -# """Write out a rpki.conf based on the given form data.""" -# handle = data['handle'] -# confdir = settings.MYRPKI_DATA_DIR + '/' + handle -# if os.path.exists(confdir): -# raise RuntimeError, '%s: directory already exists!' % (confdir, ) -# os.makedirs(confdir) -# template = open(settings.MYRPKI_DATA_DIR + '/examples/rpki.conf', 'r').read() -# # stuff the appropriate output directory into the dict -# data['MYRPKI_DATA_DIR'] = confdir -# with open(confdir + '/rpki.conf', 'w') as conf: -# print >>conf, template % data -# invoke_rpki(handle, ['initialize']) - -def invoke_rpki(handle, args): - """Invoke the myrpki cli for the specified configuration.""" - myrpki_dir = confdir(handle) - config = myrpki_dir + '/rpki.conf' - # default rpki.conf uses relative paths, so chdir() to the repo first - cmd = 'cd %s && @MYRPKI@ %s' % (myrpki_dir, ' '.join(['--config=' + config] + args)) - print >>sys.stderr, 'invoking', cmd - os.system(cmd) - -def read_file_from_handle(handle, fname): - """read a filename relative to the directory for the given resource handle. returns - a tuple of (content, mtime)""" - with open(conf(handle) + '/' + fname, 'r') as fp: - data = fp.read() - mtime = os.fstat(fp.fileno())[stat.ST_MTIME] - return data, mtime - -#def read_identity(handle): -# fname = settings.MYRPKI_DATA_DIR + '/' + handle + '/entitydb/identity.xml' -# with open(fname, 'r') as fp: -# data = fp.read() -# return data -read_identity = lambda h: read_file_from_handle(h, 'entitydb/identity.xml')[0] - -def read_child_response(handle, child): - fname = '%s/entitydb/children/%s.xml' % (conf(handle), child) - with open(fname, 'r') as fp: - data = fp.read() - return data - -# FIXME - remove this once rpki.myrpki.csv_writer is an object with a -# .file field -def csv_writer(f): - return csv.writer(f, dialect = csv.get_dialect("excel-tab")) - -def output_asns(path, handle): - '''Write out csv file containing asns delegated to my children.''' - qs = models.Asn.objects.filter(lo=F('hi'), allocated__in=handle.children.all()) - with open(path, 'w') as f: - w = csv_writer(f) - w.writerows([asn.allocated.handle, asn.lo] for asn in qs) - -def output_prefixes(path, handle): - '''Write out csv file containing prefixes delegated to my children.''' - qs = models.AddressRange.objects.filter(allocated__in=handle.children.all()) - with open(path, 'w') as f: - w = csv_writer(f) - w.writerows([p.allocated.handle, p.as_resource_range()] for p in qs) - -def output_roas(path, handle): - '''Write out csv file containing my roas.''' - qs = models.RoaRequest.objects.filter(roa__in=handle.roas.all()) - with open(path, 'w') as f: - w = csv_writer(f) - w.writerows([req.as_roa_prefix(), req.roa.asn, - '%s-group-%d' % (handle.handle, req.roa.pk)] for req in qs) - -def configure_daemons(handle): - args = ['configure_daemons'] - for hosted in handle.hosting.all(): - args.append(conf(hosted.handle) + '/myrpki.xml') - invoke_rpki(handle.handle, args) - -def configure_resources(handle): - '''Write out the csv files and invoke the myrpki.py command line tool.''' - # chdir to the repo dir since the default rpki.conf uses relative - # pathnames.. - os.chdir(conf(handle.handle)) - cfg = rpki.config.parser('rpki.conf', 'myrpki') - output_asns(cfg.get('asn_csv'), handle) - output_prefixes(cfg.get('prefix_csv'), handle) - output_roas(cfg.get('roa_csv'), handle) - run_rpkidemo = cfg.getboolean('run_rpkidemo', False) - if not run_rpkidemo: - run_rpkid = cfg.getboolean('run_rpkid') - if run_rpkid: - configure_daemons(handle) - else: - invoke_rpki(handle.handle, ['configure_resources']) - - # send the myrpki.xml to the rpkid hosting me - configure_daemons(handle.host) - - # process the response - invoke_rpki(handle.handle, ['configure_resources']) - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/misc.py b/portal-gui/rpkigui/myrpki/misc.py deleted file mode 100644 index 5d3cba93..00000000 --- a/portal-gui/rpkigui/myrpki/misc.py +++ /dev/null @@ -1,47 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -import rpki.resource_set -import rpki.ipaddrs - -def str_to_range(lo, hi): - """Convert IP address strings to resource_range_ip.""" - x = rpki.ipaddrs.parse(lo) - y = rpki.ipaddrs.parse(hi) - assert type(x) == type(y) - if isinstance(x, rpki.ipaddrs.v4addr): - return rpki.resource_set.resource_range_ipv4(x, y) - else: - return rpki.resource_set.resource_range_ipv6(x, y) - -def parse_resource_range(s): - '''Parse an IPv4/6 resource range.''' - # resource_set functions only accept str - if isinstance(s, unicode): - s = s.encode() - try: - return rpki.resource_set.resource_range_ipv4.parse_str(s) - except ValueError: - return rpki.resource_set.resource_range_ipv6.parse_str(s) - -def top_parent(prefix): - '''Returns the topmost resource from which the specified argument derives''' - while prefix.parent: - prefix = prefix.parent - return prefix - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/models.py b/portal-gui/rpkigui/myrpki/models.py deleted file mode 100644 index 7db5ef1d..00000000 --- a/portal-gui/rpkigui/myrpki/models.py +++ /dev/null @@ -1,207 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -import socket - -from django.db import models -from django.contrib.auth.models import User - -from rpkigui.myrpki.misc import str_to_range - -import rpki.resource_set -import rpki.exceptions - -class HandleField(models.CharField): - def __init__(self, **kwargs): - models.CharField.__init__(self, max_length=255, **kwargs) - -class IPAddressField(models.CharField): - def __init__( self, **kwargs ): - models.CharField.__init__(self, max_length=40, **kwargs) - -class Conf(models.Model): - '''This is the center of the universe, also known as a place to - have a handle on a resource-holding entity. It's the <self> - in the rpkid schema.''' - handle = HandleField(unique=True, db_index=True) - owner = models.ManyToManyField(User) - - # NULL if self-hosted, otherwise the conf that is hosting us - host = models.ForeignKey('Conf', related_name='hosting', null=True) - - def __unicode__(self): - return self.handle - -class AddressRange(models.Model): - '''An address range/prefix.''' - lo = IPAddressField(blank=False) - hi = IPAddressField(blank=False) - # parent address range - parent = models.ForeignKey('AddressRange', related_name='children', - blank=True, null=True) - # child to which this resource is delegated - allocated = models.ForeignKey('Child', related_name='address_range', - blank=True, null=True) - - def __unicode__(self): - if self.lo == self.hi: - return u"%s" % (self.lo,) - - try: - # pretty print cidr - return unicode(self.as_resource_range()) - except socket.error, err: - print err - # work around for bug when hi/lo get reversed - except AssertionError, err: - print err - return u'%s - %s' % (self.lo, self.hi) - - @models.permalink - def get_absolute_url(self): - return ('rpkigui.myrpki.views.address_view', [str(self.pk)]) - - def as_resource_range(self): - '''Convert to rpki.resource_set.resource_range_ip.''' - return str_to_range(self.lo, self.hi) - - def is_prefix(self): - '''Returns True if this address range can be represented as a - prefix.''' - try: - self.as_resource_range().prefixlen() - except rpki.exceptions.MustBePrefix, err: - print err - return False - return True - -class RoaRequest(models.Model): - roa = models.ForeignKey('Roa', related_name='from_roa_request') - max_length = models.IntegerField() - prefix = models.ForeignKey('AddressRange', related_name='roa_requests') - - def __unicode__(self): - return u'roa request for asn %d on %s-%d' % (self.roa.asn, self.prefix, - self.max_length) - - def as_roa_prefix(self): - '''Convert to a rpki.resouce_set.roa_prefix subclass.''' - r = self.prefix.as_resource_range() - if isinstance(r, rpki.resource_set.resource_set_ipv4): - return rpki.resource_set.roa_prefix_ipv4(r.min, r.prefixlen(), - self.max_length) - else: - return rpki.resource_set.roa_prefix_ipv6(r.min, r.prefixlen(), - self.max_length) - -class Asn(models.Model): - '''An ASN or range thereof.''' - lo = models.IntegerField(blank=False) - hi = models.IntegerField(blank=False) - # parent asn range - parent = models.ForeignKey('Asn', related_name='children', - blank=True, null=True) - # child to which this resource is delegated - allocated = models.ForeignKey('Child', related_name='asn', - blank=True, null=True) - - def __unicode__(self): - if self.lo == self.hi: - return u"ASN %d" % (self.lo,) - else: - return u"ASNs %d - %d" % (self.lo, self.hi) - - @models.permalink - def get_absolute_url(self): - return ('rpkigui.myrpki.views.asn_view', [str(self.pk)]) - - def as_resource_range(self): - # we force conversion to long() here because resource_range_as() wants - # the type of both arguments to be identical, and models.IntegerField - # will be a long when the value is large - return rpki.resource_set.resource_range_as(long(self.lo), long(self.hi)) - -class Child(models.Model): - conf = models.ForeignKey(Conf, related_name='children') - handle = HandleField() # parent's name for child - - def __unicode__(self): - return u"%s's child %s" % (self.conf, self.handle) - - @models.permalink - def get_absolute_url(self): - return ('rpkigui.myrpki.views.child_view', [self.handle]) - - class Meta: - verbose_name_plural = "children" - # children of a specific configuration should be unique - unique_together = ('conf', 'handle') - -class Parent(models.Model): - conf = models.ForeignKey(Conf, related_name='parents') - handle = HandleField() # my name for this parent - - def __unicode__(self): - return u"%s's parent %s" % (self.conf, self.handle) - - @models.permalink - def get_absolute_url(self): - return ('rpkigui.myrpki.views.parent_view', [self.handle]) - - class Meta: - # parents of a specific configuration should be unique - unique_together = ('conf', 'handle') - -class ResourceCert(models.Model): - parent = models.ForeignKey(Parent, related_name='resources') - - # resources granted from my parent - asn = models.ManyToManyField(Asn, related_name='from_cert', blank=True, - null=True) - address_range = models.ManyToManyField(AddressRange, - related_name='from_cert', blank=True, null=True) - - # unique id for this resource certificate - # FIXME: URLField(verify_exists=False) doesn't seem to work - the admin - # editor won't accept a rsync:// scheme as valid - uri = models.CharField(max_length=200) - - # certificate validity period - not_before = models.DateTimeField() - not_after = models.DateTimeField() - - def __unicode__(self): - return u"%s's resource cert from parent %s" % (self.parent.conf.handle, - self.parent.handle) - -class Roa(models.Model): - '''Maps an ASN to the set of prefixes it can originate routes for. - This differs from a real ROA in that prefixes from multiple - parents/resource certs can be selected. The glue module contains - code to split the ROAs into groups by common resource certs.''' - - conf = models.ForeignKey(Conf, related_name='roas') - asn = models.IntegerField() - active = models.BooleanField() - - # the resource cert from which all prefixes for this roa are derived - cert = models.ForeignKey(ResourceCert, related_name='roas') - - def __unicode__(self): - return u"%s's ROA for %d" % (self.conf, self.asn) - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/urls.py b/portal-gui/rpkigui/myrpki/urls.py deleted file mode 100644 index 96d93e2d..00000000 --- a/portal-gui/rpkigui/myrpki/urls.py +++ /dev/null @@ -1,50 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -from django.conf.urls.defaults import * -from django.views.generic.list_detail import object_list -from rpkigui.myrpki import views - -urlpatterns = patterns('', - (r'^$', views.dashboard), -# (r'^conf/add$', views.conf_add), - (r'^conf/export$', views.conf_export), - (r'^conf/list$', views.conf_list), - (r'^conf/select$', views.conf_select), -# (r'^import/parent$', views.parent_import), -# (r'^import/child$', views.child_import), - (r'^parent/(?P<parent_handle>[^/]+)$', views.parent_view), - (r'^child/(?P<child_handle>[^/]+)$', views.child_view), -# (r'^parent/(?P<parent_handle>[^/]+)/address$', views.parent_address), -# (r'^parent/(?P<parent_handle>[^/]+)/asn$', views.parent_asn), - (r'^address/(?P<pk>\d+)$', views.address_view), - (r'^address/(?P<pk>\d+)/split$', views.prefix_split_view), - (r'^address/(?P<pk>\d+)/allocate$', views.prefix_allocate_view), - (r'^address/(?P<pk>\d+)/roa$', views.prefix_roa_view), - (r'^address/(?P<pk>\d+)/delete$', views.prefix_delete_view), - (r'^asn/(?P<pk>\d+)$', views.asn_view), - (r'^asn/(?P<pk>\d+)/allocate$', views.asn_allocate_view), - (r'^roa/(?P<pk>\d+)/delete$', views.roa_request_delete_view), - (r'^demo/down/asns/(?P<self_handle>[^/]+)$', views.download_asns), - (r'^demo/down/prefixes/(?P<self_handle>[^/]+)$', views.download_prefixes), - (r'^demo/down/roas/(?P<self_handle>[^/]+)$', views.download_roas), - (r'^upload-parent-request/(?P<self_handle>[^/]+)$', views.upload_parent_request), - (r'^upload-repository-request/(?P<self_handle>[^/]+)$', views.upload_repository_request), - (r'^upload-myrpki-xml/(?P<self_handle>[^/]+)$', views.upload_myrpki_xml), -) - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/myrpki/views.py b/portal-gui/rpkigui/myrpki/views.py deleted file mode 100644 index f15ebbdd..00000000 --- a/portal-gui/rpkigui/myrpki/views.py +++ /dev/null @@ -1,557 +0,0 @@ -# $Id$ -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -""" - -import email.utils -import os -import os.path -import tempfile -import sys - -from django.contrib.auth.decorators import login_required -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 import http -from django.views.generic.list_detail import object_list -from django.views.decorators.csrf import csrf_exempt -from django.conf import settings -from django.core.urlresolvers import reverse - -from rpkigui.myrpki import models, forms, glue, misc, AllocationTree -from rpkigui.myrpki.asnset import asnset - -debug = False - -# For each type of object, we have a detail view, a create view and -# an update view. We heavily leverage the generic views, only -# adding our own idea of authorization. - -def handle_required(f): - @login_required - def wrapped_fn(request, *args, **kwargs): - if 'handle' not in request.session: - 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] - elif conf.count() == 0: - return render('myrpki/conf_empty.html', {}, request) - #return http.HttpResponseRedirect('/myrpki/conf/add') - else: - # Should reverse the view for this instead of hardcoding - # the URL. - return http.HttpResponseRedirect( - reverse(conf_list) + '?next=' + urlquote(request.get_full_path())) - request.session[ 'handle' ] = handle - return f(request, *args, **kwargs) - return wrapped_fn - -def render(template, context, request): - return render_to_response(template, context, - context_instance=RequestContext(request)) - -@handle_required -def dashboard(request): - '''The user's dashboard.''' - handle = request.session[ 'handle' ] - # ... pick out data for the dashboard and return it - # my parents - # the resources that my parents have given me - # the resources that I have accepted from my parents - # my children - # the resources that I have given my children - # my roas - - # get list of ASNs used in my ROAs - roa_asns = [r.asn for r in handle.roas.all()] - asns=[] - for a in models.Asn.objects.filter(from_cert__parent__in=handle.parents.all()): - f = AllocationTree.AllocationTreeAS(a) - if f.unallocated(): - asns.append(f) - - prefixes = [] - for p in models.AddressRange.objects.filter(from_cert__parent__in=handle.parents.all()): - f = AllocationTree.AllocationTreeIP.from_prefix(p) - if f.unallocated(): - prefixes.append(f) - - asns.sort(key=lambda x: x.range.min) - prefixes.sort(key=lambda x: x.range.min) - - return render('myrpki/dashboard.html', { 'conf': handle, 'asns': asns, - 'ars': prefixes }, request) - -#@login_required -#def conf_add(request): -# '''Allow the user to create a new configuration.''' -# errors = [] -# if request.method == 'POST': -# form = forms.AddConfForm(request.POST) -# if form.is_valid(): -# try: -# handle = form.cleaned_data['handle'] -# # ensure this user is in the group for this handle -# grps = request.user.groups.filter(name=handle) -# if len(grps) == 0: -# errors.append( -# 'You are not in the proper group for that handle.') -# else: -# conf = models.Conf.objects.create( -# handle=form.cleaned_data['handle'], owner=grps[0]) -# conf.save() -# glue.form_to_conf(form.cleaned_data) -# return http.HttpResponseRedirect('/myrpki/') -# # data model will ensure the handle is unique -# except IntegrityError, e: -# print e -# errors.append('That handle already exists.') -# else: -# errors.append("The form wasn't valid.") -# else: -# form = forms.AddConfForm() -# return render_to_response('myrpki/add_conf.html', -# { 'form': form, 'errors': errors }) - -@login_required -def conf_list(request): - """Allow the user to select a handle.""" - if request.user.is_superuser: - queryset = models.Conf.objects.all() - else: - queryset = models.Conf.objects.filter(owner=request.user) - return object_list(request, queryset, - template_name='myrpki/conf_list.html', template_object_name='conf', extra_context={ 'select_url' : reverse(conf_select) }) - -@login_required -def conf_select(request): - '''Change the handle for the current session.''' - if not 'handle' in request.GET: - return http.HttpResponseRedirect('/myrpki/conf/select') - handle = request.GET['handle'] - next_url = request.GET.get('next', reverse(dashboard)) - if next_url == '': - next_url = reverse(dashboard) - - 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=request.user) - if conf: - request.session['handle'] = conf[0] - return http.HttpResponseRedirect(next_url) - - return http.HttpResponseRedirect(reverse(conf_list) + '?next=' + next_url) - -def serve_xml(content, basename): - resp = http.HttpResponse(content , mimetype='application/xml') - resp['Content-Disposition'] = 'attachment; filename=%s.xml' % (basename, ) - return resp - -@handle_required -def conf_export(request): - """Return the identity.xml for the current handle.""" - handle = request.session['handle'] - return serve_xml(glue.read_identity(handle.handle), 'identity') - -@handle_required -def parent_import(request): - handle = request.session['handle'].handle - errs = [] - if request.method == 'POST': - form = forms.ImportForm(request.POST, request.FILES) - if form.is_valid(): - input_file = tempfile.NamedTemporaryFile(delete=False) - try: - parent_handle = form.cleaned_data['handle'] - parent = models.Parent( - conf=request.session['handle'], handle=parent_handle) - parent.save() - - input_file.write(request.FILES['xml'].read()) - input_file.close() - - args = ['configure_parent', '--parent_handle=' + parent_handle, - input_file.name] - glue.invoke_rpki(handle, args) - - return http.HttpResponseRedirect('/myrpki/') - except IntegrityError, e: - print e - errs.append('A parent with that handle already exists.') - finally: - os.remove(input_file.name) - else: - print 'invalid form' - errs.append('The form was invalid.') - else: - form = forms.ImportForm() - return render('myrpki/xml_import.html', { 'form': form, - 'kind': 'parent', 'post_url': '/myrpki/import/parent', - 'errors': errs }, request) - -@handle_required -def parent_view(request, parent_handle): - """Detail view for a particular parent.""" - handle = request.session['handle'] - parent = get_object_or_404(handle.parents, handle__exact=parent_handle) - return render('myrpki/parent_view.html', { 'parent': parent }, request) - -@handle_required -def child_import(request): - handle = request.session['handle'].handle - if request.method == 'POST': - form = forms.ImportForm(request.POST, request.FILES) - if form.is_valid(): - input_file = tempfile.NamedTemporaryFile(delete=False) - try: - child_handle = form.cleaned_data['handle'] - child = models.Child( - conf=request.session['handle'], handle=child_handle, - validity=form.cleaned_data['validity']) - child.save() - - input_file.write(request.FILES['xml'].read()) - input_file.close() - args = ['configure_child', '--child_handle=' + child_handle, - input_file.name] - glue.invoke_rpki(handle, args) - - # send response back to user - return serve_xml(glue.read_child_response(handle, - child_handle), child_handle) - finally: - os.remove(input_file.name) - else: - form = forms.ImportForm() - return render('myrpki/xml_import.html', - { 'form': form, 'kind': 'child', - 'post_url': '/myrpki/import/child'}, request) - -def get_parents_or_404(handle, obj): - '''Return the Parent object(s) that the given address range derives - from, or raise a 404 error.''' - cert_set = misc.top_parent(obj).from_cert.filter(parent__in=handle.parents.all()) - if cert_set.count() == 0: - raise http.Http404, 'Object is not delegated from any parent' - return [c.parent for c in cert_set] - -@handle_required -def asn_view(request, pk): - '''view/subdivide an asn range.''' - 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) - roas = handle.roas.filter(asn=obj.lo) # roas which contain this asn - unallocated = AllocationTree.AllocationTreeAS(obj).unallocated() - - return render('myrpki/asn_view.html', - { 'asn': obj, 'parent': parent_set, 'roas': roas, - 'unallocated' : unallocated }, request) - -@handle_required -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, handle__exact=child_handle) - - return render('myrpki/child_view.html', { 'child': child }, request) - -class PrefixView(object): - '''Extensible view for address ranges/prefixes. This view can be - subclassed to add form handling for editing the prefix.''' - - def __init__(self, request, pk, form_class=None): - self.handle = request.session['handle'] - self.obj = get_object_or_404(models.AddressRange.objects, pk=pk) - # ensure this resource range belongs to a parent of the current conf - self.parent_set = get_parents_or_404(self.handle, self.obj) - self.form = None - self.form_class = form_class - self.request = request - - def __call__(self, *args, **kwargs): - if self.request.method == 'POST': - resp = self.handle_post() - else: - resp = self.handle_get() - - # allow get/post handlers to return a custom response - if resp: - return resp - - u = AllocationTree.AllocationTreeIP.from_prefix(self.obj).unallocated() - - return render('myrpki/prefix_view.html', - { 'addr': self.obj, 'parent': self.parent_set, 'unallocated': u, 'form': self.form }, - self.request) - - def handle_get(self): - '''Virtual method for extending GET handling. Default action is - to call the form class constructor with the prefix object.''' - if self.form_class: - self.form = self.form_class(self.obj) - - def form_valid(self): - '''Virtual method for handling a valid form. Called by the default - implementation of handle_post().''' - pass - - def handle_post(self): - '''Virtual method for extending POST handling. Default implementation - creates a form object using the form_class in the constructor and passing - the prefix object. If the form's is_valid() method is True, it then - invokes this class's form_valid() method.''' - resp = None - if self.form_class: - self.form = self.form_class(self.obj, self.request.POST) - if self.form.is_valid(): - resp = self.form_valid() - return resp - -@handle_required -def address_view(request, pk): - return PrefixView(request, pk)() - -class PrefixSplitView(PrefixView): - '''Class for handling the prefix split form.''' - def form_valid(self): - r = misc.parse_resource_range(self.form.cleaned_data['prefix']) - obj = models.AddressRange(lo=str(r.min), hi=str(r.max), parent=self.obj) - obj.save() - return http.HttpResponseRedirect(obj.get_absolute_url()) - -@handle_required -def prefix_split_view(request, pk): - return PrefixSplitView(request, pk, form_class=forms.PrefixSplitForm)() - -class PrefixAllocateView(PrefixView): - '''Class to handle the allocation to child form.''' - def handle_get(self): - self.form = forms.PrefixAllocateForm( - self.obj.allocated.pk if self.obj.allocated else None, - self.handle.children.all()) - - def handle_post(self): - self.form = forms.PrefixAllocateForm(None, self.handle.children.all(), self.request.POST) - if self.form.is_valid(): - self.obj.allocated = self.form.cleaned_data['child'] - self.obj.save() - glue.configure_resources(self.handle) - return http.HttpResponseRedirect(self.obj.get_absolute_url()) - -@handle_required -def prefix_allocate_view(request, pk): - return PrefixAllocateView(request, pk)() - -def add_roa_requests(handle, prefix, asns, max_length): - for asid in asns: - if debug: - print 'searching for a roa for AS %d containing %s-%d' % (asid, prefix, max_length) - req_set = prefix.roa_requests.filter(roa__asn=asid, max_length=max_length) - if not req_set: - if debug: - print 'no roa for AS %d containing %s-%d' % (asid, prefix, max_length) - - # find ROAs for prefixes derived from the same resource cert - # as this prefix - certs = misc.top_parent(prefix).from_cert.all() - roa_set = handle.roas.filter(asn=asid, cert__in=certs) - - # FIXME: currently only creates a ROA/request for the first - # resource cert, not all of them - if roa_set: - roa = roa_set[0] - else: - if debug: - print 'creating new roa for AS %d containg %s-%d' % (asid, prefix, max_length) - # no roa is present for this ASN, create a new one - roa = models.Roa.objects.create(asn=asid, conf=handle, - active=False, cert=certs[0]) - roa.save() - - req = models.RoaRequest.objects.create(prefix=prefix, roa=roa, - max_length=max_length) - req.save() - -class PrefixRoaView(PrefixView): - '''Class for handling the ROA creation form.''' - def form_valid(self): - asns = asnset(self.form.cleaned_data['asns']) - add_roa_requests(self.handle, self.obj, asns, self.form.cleaned_data['max_length']) - glue.configure_resources(self.handle) - return http.HttpResponseRedirect(self.obj.get_absolute_url()) - -@handle_required -def prefix_roa_view(request, pk): - return PrefixRoaView(request, pk, form_class=forms.PrefixRoaForm)() - -class PrefixDeleteView(PrefixView): - def form_valid(self): - if self.form.cleaned_data['delete']: - self.obj.delete() - return http.HttpResponseRedirect('/myrpki/') - -@handle_required -def prefix_delete_view(request, pk): - return PrefixDeleteView(request, pk, form_class=forms.PrefixDeleteForm)() - -@handle_required -def roa_request_delete_view(request, pk): - '''Remove a roa request from a particular prefix.''' - handle = request.session['handle'] - obj = get_object_or_404(models.RoaRequest.objects, pk=pk) - prefix = obj.prefix - # ensure this resource range belongs to a parent of the current conf - parent_set = get_parents_or_404(handle, prefix) - - roa = obj.roa - obj.delete() - if not roa.from_roa_request.all(): - roa.delete() - glue.configure_resources(handle) - - return http.HttpResponseRedirect(prefix.get_absolute_url()) - -@handle_required -def asn_allocate_view(request, 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) - - 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() - glue.configure_resources(handle) - 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) - -# this is similar to handle_required, except that the handle is given in URL -def handle_or_404(request, handle): - "ensure the requested handle is available to this user" - if request.user.is_superuser: - conf_set = models.Conf.objects.filter(handle=handle) - else: - conf_set = models.Conf.objects.filter(owner=request.user, handle=handle) - if not conf_set: - raise http.Http404, 'resource handle not found' - return conf_set[0] - -def serve_file(handle, fname, content_type): - content, mtime = glue.read_file_from_handle(handle, fname) - resp = http.HttpResponse(content , mimetype=content_type) - resp['Content-Disposition'] = 'attachment; filename=%s' % (os.path.basename(fname), ) - resp['Last-Modified'] = email.utils.formatdate(mtime, usegmt=True) - return resp - -@login_required -def download_csv(request, self_handle, fname): - conf = handle_or_404(request, self_handle) - return serve_file(conf.handle, fname + '.csv', 'text/csv') - -def download_asns(request, self_handle): - return download_csv(request, self_handle, 'asns') - -def download_roas(request, self_handle): - return download_csv(request, self_handle, 'roas') - -def download_prefixes(request, self_handle): - return download_csv(request, self_handle, 'prefixes') - -def get_parent_handle(conf): - "determine who my parent is. for now just assume its hardcoded into the django db" - parent_set = models.Parent.objects.filter(conf=conf) - if parent_set: - return parent_set[0].handle - else: - raise http.Http404, 'you have no parents' - -@csrf_exempt -@login_required -def upload_parent_request(request, self_handle): - conf = handle_or_404(request, self_handle) - parent_handle = get_parent_handle(conf) - - if request.method == 'POST': - input_file = tempfile.NamedTemporaryFile(delete=False) - input_file.write(request.raw_post_data) - input_file.close() - - args = ['configure_child', input_file.name ] - glue.invoke_rpki(parent_handle, args) - - os.remove(input_file.name) - - return serve_file(parent_handle, 'entitydb/children/%s.xml' % self_handle, 'application/xml') - -@csrf_exempt -@login_required -def upload_repository_request(request, self_handle): - conf = handle_or_404(request, self_handle) - parent_handle = get_parent_handle(conf) - - if request.method == 'POST': - input_file = tempfile.NamedTemporaryFile(delete=False) - input_file.write(request.raw_post_data) - input_file.close() - - args = ['configure_publication_client', input_file.name ] - glue.invoke_rpki(parent_handle, args) - - os.remove(input_file.name) - - # FIXME: this assumes that the parent is running pubd. the actual filename - # will be different if the parent is not running pubd. see - # rpki.myrpki.do_configure_publication_client() - return serve_file(parent_handle, 'entitydb/pubclients/%s.%s.xml' % (parent_handle, self_handle), 'application/xml') - -@csrf_exempt -@login_required -def upload_myrpki_xml(request, self_handle): - "handles POST of the myrpki.xml file for a given resource handle." - conf = handle_or_404(request, self_handle) - - if request.method == 'POST': - try: - fname = '%s/%s/myrpki.xml' % (settings.MYRPKI_DATA_DIR, self_handle,) - print >>sys.stderr, 'writing ', fname - myrpki_xml = open(fname, 'w') - myrpki_xml.write(request.raw_post_data) - myrpki_xml.close() - - glue.configure_daemons(conf.host) - except: - print >>sys.stderr, ''.join(sys.exc_info()) - - return serve_file(self_handle, 'myrpki.xml', 'application/xml') - -# vim:sw=4 ts=8 expandtab diff --git a/portal-gui/rpkigui/settings.py.in b/portal-gui/rpkigui/settings.py.in deleted file mode 100644 index ef7d4541..00000000 --- a/portal-gui/rpkigui/settings.py.in +++ /dev/null @@ -1,107 +0,0 @@ -# $Id$ -# -# Django settings for rpkigui project. -# - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@domain.com'), -) - -MANAGERS = ADMINS - -DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. -DATABASE_NAME = '@DATABASE_PATH@' # Or path to database file if using sqlite3. -DATABASE_USER = '' # Not used with sqlite3. -DATABASE_PASSWORD = '' # Not used with sqlite3. -DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. -DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Los_Angeles' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '' - -# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a -# trailing slash. -# Examples: "http://rpki.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = '@SECRET_KEY@' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.load_template_source', - 'django.template.loaders.app_directories.load_template_source', -# 'django.template.loaders.eggs.load_template_source', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - - # order is important here. if csrfmidware is put before condgetmidware, - # the returned pages get truncated for some reason! - 'django.middleware.http.ConditionalGetMiddleware', - - 'django.middleware.csrf.CsrfMiddleware', -) - -ROOT_URLCONF = 'rpkigui.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - '@TEMPLATEDIR@' -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.admin', - 'django.contrib.admindocs', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'rpkigui.myrpki' -) - -TEMPLATE_CONTEXT_PROCESSORS = ( - "django.core.context_processors.auth", - "django.core.context_processors.debug", - "django.core.context_processors.i18n", - "django.core.context_processors.media", - "django.core.context_processors.request" -) - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', -) - -# where to redirect from /accounts/login/ after successful authentication -LOGIN_REDIRECT_URL = '/myrpki/' diff --git a/portal-gui/rpkigui/urls.py.in b/portal-gui/rpkigui/urls.py.in deleted file mode 100644 index bd32090a..00000000 --- a/portal-gui/rpkigui/urls.py.in +++ /dev/null @@ -1,44 +0,0 @@ -# $Id$ - -""" -Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - -""" - -from django.conf.urls.defaults import * - -from django.contrib import admin -admin.autodiscover() - -urlpatterns = patterns('', - # Example: - # (r'^foo/', include('foo.foo.urls')), - - # Uncomment the admin/doc line below and add 'django.contrib.admindocs' - # to INSTALLED_APPS to enable admin documentation: - (r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - (r'^admin/', include(admin.site.urls)), - - (r'^myrpki/', include('rpkigui.myrpki.urls')), - - (r'^accounts/login/$', 'django.contrib.auth.views.login'), - (r'^accounts/logout/$', 'django.contrib.auth.views.logout', - { 'next_page': '/myrpki/' }), - - (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', - {'document_root': '@MEDIADIR@'}) -) diff --git a/portal-gui/scripts/adduser.py b/portal-gui/scripts/adduser.py index 6d6f0c2c..20b395ea 100644 --- a/portal-gui/scripts/adduser.py +++ b/portal-gui/scripts/adduser.py @@ -22,13 +22,12 @@ # # DO NOT EDIT! This script is automatically generated from adduser.py -import os, sys -sys.path.append('@INSTDIR@') -os.environ['DJANGO_SETTINGS_MODULE'] = 'rpkigui.settings' +import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'rpki.gui.settings' from django.contrib.auth.models import User from django.conf import settings -from rpkigui.myrpki.models import Conf +from rpki.gui.app.models import Conf # The username that apache runs as. This is required so that we can chown # the csv files that the portal-gui needs to write. @@ -86,7 +85,7 @@ if __name__ == '__main__': print >>sys.stderr, '%s is self-hosted' % username conf.save() - myrpki_dir = '%s/%s' % (settings.MYRPKI_DATA_DIR, username) + myrpki_dir = '%s/%s' % (settings.CONFDIR, username) print 'myrpki_dir=', myrpki_dir if not os.path.exists(myrpki_dir): print 'creating ', myrpki_dir diff --git a/portal-gui/scripts/list_resources.py b/portal-gui/scripts/list_resources.py index 54845563..b425facc 100644 --- a/portal-gui/scripts/list_resources.py +++ b/portal-gui/scripts/list_resources.py @@ -31,10 +31,9 @@ # later import sys -sys.path.append('@INSTDIR@') import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'rpkigui.settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'rpki.gui.settings' from datetime import datetime import getopt @@ -48,7 +47,7 @@ import rpki.async import rpki.left_right import rpki.resource_set -from rpkigui.myrpki import models +from rpki.gui.app import models verbose = False version = '$Id$' diff --git a/portal-gui/scripts/load_csv.py b/portal-gui/scripts/load_csv.py index 29938b2d..f4738539 100755 --- a/portal-gui/scripts/load_csv.py +++ b/portal-gui/scripts/load_csv.py @@ -25,8 +25,7 @@ # import sys, os -sys.path.append('@INSTDIR@') -os.environ['DJANGO_SETTINGS_MODULE'] = 'rpkigui.settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'rpki.gui.settings' import csv import socket # for socket.error @@ -36,8 +35,8 @@ import rpki.resource_set import rpki.ipaddrs from rpki.myrpki import csv_reader -from rpkigui.myrpki import models -from rpkigui.myrpki.views import add_roa_requests +from rpki.gui.app import models +from rpki.gui.app.views import add_roa_requests cfg_file = os.getenv("RPKI_CONF", "rpki.conf") cfg = rpki.config.parser(cfg_file, "myrpki") diff --git a/portal-gui/scripts/roa_check.py b/portal-gui/scripts/roa_check.py index b952c50f..c280d935 100755 --- a/portal-gui/scripts/roa_check.py +++ b/portal-gui/scripts/roa_check.py @@ -13,7 +13,7 @@ from rpki.resource_set import roa_prefix_set_ipv4, roa_prefix_set_ipv6 from rpki.resource_set import resource_range_ipv4, resource_range_ipv6 from rpki.ipaddrs import v4addr, v6addr -from rpkigui.myrpki.models import Roa +from rpki.gui.app.models import Roa # build up a list of all the authenticated roa's using the asn as the key roaiter = rcynic_xml_iterator( diff --git a/portal-gui/templates/base.html b/portal-gui/templates/base.html index 7645cf9f..a096cdca 100644 --- a/portal-gui/templates/base.html +++ b/portal-gui/templates/base.html @@ -8,8 +8,7 @@ </head> <body> <div id="header"> - <img src="/site_media/img/my.png"/> - <img src="/site_media/img/rpki.png"/> + <h1>RPKI Portal GUI</h1> </div> <div id="content"> {% if user.is_authenticated %} diff --git a/portal-gui/templates/myrpki/asn_view.html b/portal-gui/templates/myrpki/asn_view.html index ef020355..d78237c5 100644 --- a/portal-gui/templates/myrpki/asn_view.html +++ b/portal-gui/templates/myrpki/asn_view.html @@ -7,7 +7,7 @@ td { border: solid 1px; text-align: center; padding-left: 1em; padding-right: 1e {% endblock %} {% block content %} -<p>Handle: <a href="{% url rpkigui.myrpki.views.dashboard %}">{{ request.session.handle }}</a> +<p>Handle: <a href="{% url rpki.gui.app.views.dashboard %}">{{ request.session.handle }}</a> <h1>ASN View</h1> diff --git a/portal-gui/templates/myrpki/child_view.html b/portal-gui/templates/myrpki/child_view.html index 62709f0d..0721cc65 100644 --- a/portal-gui/templates/myrpki/child_view.html +++ b/portal-gui/templates/myrpki/child_view.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block content %} -<p>Handle: <a href="{% url rpkigui.myrpki.views.dashboard %}">{{ request.session.handle.handle }}</a> +<p>Handle: <a href="{% url rpki.gui.app.views.dashboard %}">{{ request.session.handle.handle }}</a> <h1>Child View</h1> <p>Child: {{ child.handle }} diff --git a/portal-gui/templates/myrpki/dashboard.html b/portal-gui/templates/myrpki/dashboard.html index af99e89e..116ea792 100644 --- a/portal-gui/templates/myrpki/dashboard.html +++ b/portal-gui/templates/myrpki/dashboard.html @@ -8,8 +8,8 @@ td { border: solid 1px; text-align: center; padding-left: 1em; padding-right: 1e {% block content %} <p>Handle: {{ request.session.handle }} -| <a href="{% url rpkigui.myrpki.views.conf_export %}">export identity</a> -| <a href="{% url rpkigui.myrpki.views.conf_list %}">select</a> +| <a href="{% url rpki.gui.app.views.conf_export %}">export identity</a> +| <a href="{% url rpki.gui.app.views.conf_list %}">select</a> <div style="border: inset"> <h1 style="text-align: center">Parents</h1> @@ -54,7 +54,7 @@ td { border: solid 1px; text-align: center; padding-left: 1em; padding-right: 1e {% if request.session.handle.children.all %} <ul> {% for child in request.session.handle.children.all %} -<li><a href="{% url rpkigui.myrpki.views.child_view child.handle %}">{{ child.handle }}</a> +<li><a href="{% url rpki.gui.app.views.child_view child.handle %}">{{ child.handle }}</a> {% if child.address_range.count or child.asn.count %} <p>Delegated resources: <ul> @@ -76,8 +76,8 @@ td { border: solid 1px; text-align: center; padding-left: 1em; padding-right: 1e {% endif %} <p> -Export (csv): <a href="{% url rpkigui.myrpki.views.download_asns request.session.handle %}">asns</a> | -<a href="{% url rpkigui.myrpki.views.download_prefixes request.session.handle %}">prefixes</a> +Export (csv): <a href="{% url rpki.gui.app.views.download_asns request.session.handle %}">asns</a> | +<a href="{% url rpki.gui.app.views.download_prefixes request.session.handle %}">prefixes</a> </div> @@ -101,7 +101,7 @@ Export (csv): <a href="{% url rpkigui.myrpki.views.download_asns request.session {% endfor %} </table> -<p><a href="{% url rpkigui.myrpki.views.download_roas request.session.handle %}">export (csv)</a> +<p><a href="{% url rpki.gui.app.views.download_roas request.session.handle %}">export (csv)</a> </div><!-- roas --> diff --git a/portal-gui/templates/myrpki/parent_view.html b/portal-gui/templates/myrpki/parent_view.html index e1852245..13a9d848 100644 --- a/portal-gui/templates/myrpki/parent_view.html +++ b/portal-gui/templates/myrpki/parent_view.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block content %} -<p>Handle: <a href="{% url rpkigui.myrpki.views.dashboard %}">{{ request.session.handle.handle }}</a> +<p>Handle: <a href="{% url rpki.gui.app.views.dashboard %}">{{ request.session.handle.handle }}</a> <h1>Parent View</h1> <p>Parent: {{ parent.handle }} <h2>Delegated Addresses</h2> diff --git a/portal-gui/templates/myrpki/prefix_view.html b/portal-gui/templates/myrpki/prefix_view.html index 1e1ca797..aabc0a39 100644 --- a/portal-gui/templates/myrpki/prefix_view.html +++ b/portal-gui/templates/myrpki/prefix_view.html @@ -7,7 +7,7 @@ td { border: solid 1px; text-align: center; padding-left: 1em; padding-right: 1e {% endblock %} {% block content %} -<p>Handle: <a href="{% url rpkigui.myrpki.views.dashboard %}">{{ request.session.handle }}</a> +<p>Handle: <a href="{% url rpki.gui.app.views.dashboard %}">{{ request.session.handle }}</a> <h1>Prefix View</h1> |