diff options
Diffstat (limited to 'portal-gui/rpkigui')
-rw-r--r-- | portal-gui/rpkigui/TODO | 59 | ||||
-rw-r--r-- | portal-gui/rpkigui/__init__.py | 0 | ||||
-rw-r--r-- | portal-gui/rpkigui/manage.py | 11 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/__init__.py | 0 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/admin.py | 32 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/dashboardurls.py | 6 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/forms.py | 17 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/models.py | 94 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/urls.py | 11 | ||||
-rw-r--r-- | portal-gui/rpkigui/myrpki/views.py | 96 | ||||
-rw-r--r-- | portal-gui/rpkigui/settings.py | 93 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/base.html | 26 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/myrpki/cert_confirm_delete.html | 10 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/myrpki/cert_detail.html | 12 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/myrpki/cert_form.html | 13 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/myrpki/cert_list.html | 14 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/myrpki/dashboard.html | 87 | ||||
-rw-r--r-- | portal-gui/rpkigui/templates/registration/login.html | 26 | ||||
-rw-r--r-- | portal-gui/rpkigui/urls.py | 27 |
19 files changed, 634 insertions, 0 deletions
diff --git a/portal-gui/rpkigui/TODO b/portal-gui/rpkigui/TODO new file mode 100644 index 00000000..da4e3edd --- /dev/null +++ b/portal-gui/rpkigui/TODO @@ -0,0 +1,59 @@ +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=1) +minus what we've given to our children or issued roas for +models.AddressRange.objects.filter(child__conf=1) +models.AddressRange.objects.filter(roa__conf=1) +or +>>> from django.db.models import Q +>>> models.AddressRange.objects.filter( Q(child__conf=1) | Q(roa__conf=1) ) + + +and of course the ASN one is easier: +models.Asn.objects.filter(from_parent=1) +minus what we've given to our children +models.Asn.objects.filter(child__conf=1) + +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 new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/portal-gui/rpkigui/__init__.py diff --git a/portal-gui/rpkigui/manage.py b/portal-gui/rpkigui/manage.py new file mode 100644 index 00000000..5e78ea97 --- /dev/null +++ b/portal-gui/rpkigui/manage.py @@ -0,0 +1,11 @@ +#!/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/__init__.py b/portal-gui/rpkigui/myrpki/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/portal-gui/rpkigui/myrpki/__init__.py diff --git a/portal-gui/rpkigui/myrpki/admin.py b/portal-gui/rpkigui/myrpki/admin.py new file mode 100644 index 00000000..a5a91043 --- /dev/null +++ b/portal-gui/rpkigui/myrpki/admin.py @@ -0,0 +1,32 @@ +from django import forms +from django.contrib import admin +from rpki.myrpki import models + +class CertAdmin( admin.ModelAdmin ): + pass + +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 + +admin.site.register( models.Cert, CertAdmin ) +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 ) diff --git a/portal-gui/rpkigui/myrpki/dashboardurls.py b/portal-gui/rpkigui/myrpki/dashboardurls.py new file mode 100644 index 00000000..ed11798e --- /dev/null +++ b/portal-gui/rpkigui/myrpki/dashboardurls.py @@ -0,0 +1,6 @@ +from django.conf.urls.defaults import * +import views + +urlpatterns = patterns('', + (r'^$', views.dashboard ), +) diff --git a/portal-gui/rpkigui/myrpki/forms.py b/portal-gui/rpkigui/myrpki/forms.py new file mode 100644 index 00000000..b91f6acc --- /dev/null +++ b/portal-gui/rpkigui/myrpki/forms.py @@ -0,0 +1,17 @@ +from django import forms +from myrpki import models + +def ConfCertForm( request ): + class CertForm( forms.ModelForm ): + class Meta: + model = models.Cert + exclude = ( 'conf' ) + + def save( self ): + obj = forms.ModelForm.save( self, commit=False ) + obj.conf = request.session[ 'handle' ] + obj.save() + return obj + + return CertForm + diff --git a/portal-gui/rpkigui/myrpki/models.py b/portal-gui/rpkigui/myrpki/models.py new file mode 100644 index 00000000..a8b11a56 --- /dev/null +++ b/portal-gui/rpkigui/myrpki/models.py @@ -0,0 +1,94 @@ +from django.db import models +from django.contrib.auth.models import Group + +# TO DO: +# URL: text? +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 Cert( models.Model ): + '''A certificate, relating to a single configuration.''' + conf = models.ForeignKey( 'Conf', related_name='certs' ) + name = models.CharField( unique=True, max_length=255 ) + data = models.TextField() + def __unicode__( self ): + return "%s's %s" % ( self.conf, self.name ) + +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 ) + repository_bpki_cert = models.ForeignKey( Cert, + related_name='conf_bpki_cert', + null=True, blank=True ) + my_bpki_ta = models.ForeignKey( Cert, related_name='conf_my_ta', + null=True, blank=True ) + repository_handle = HandleField() + owner = models.OneToOneField( Group ) + def __unicode__( self ): + return self.handle + +class AddressRange( models.Model ): + '''An address range / prefix.''' + lo = IPAddressField() + hi = IPAddressField() + parent = models.ForeignKey( 'AddressRange', related_name='children', + blank=True, null=True ) + def __unicode__( self ): + return u"address range %s-%s" % ( self.lo, self.hi ) + +class Asn( models.Model ): + '''An ASN or range thereof.''' + min = models.IntegerField() + max = models.IntegerField() + parent = models.ForeignKey( 'Asn', related_name='children', + blank=True, null=True ) + def __unicode__( self ): + if self.min == self.max: + return u"ASN %d" % ( self.min ) + else: + return u"ASNs %d-%d" % ( self.min, self.max ) + +class Child( models.Model ): + conf = models.ForeignKey( Conf, related_name='children' ) + handle = HandleField() + validity = models.DateTimeField() + bpki_cert = models.ForeignKey( Cert, related_name='child_bpki' ) + address_range = models.ManyToManyField( AddressRange, blank=True ) + asn = models.ManyToManyField( Asn, blank=True ) + def __unicode__( self ): + return u"%s's child %s" % ( self.conf, self.handle ) + class Meta: + verbose_name_plural = "children" + + +class Parent( models.Model ): + conf = models.ForeignKey( Conf, related_name='parents' ) + handle = HandleField( unique=True ) + service_uri = models.URLField( verify_exists=False ) + cms_bpki_cert = models.ForeignKey( Cert, related_name='parent_cms' ) + https_bpki_cert = models.ForeignKey( Cert, related_name='parent_https' ) + my_handle = HandleField() + sia_base = models.URLField( verify_exists=False ) + address_range = models.ManyToManyField( AddressRange, + related_name='from_parent' ) + asn = models.ManyToManyField( Asn, related_name='from_parent' ) + def __unicode__( self ): + return u"%s's parent %s" % ( self.conf, self.handle ) + +class Roa( models.Model ): + conf = models.ForeignKey( Conf, related_name='roas' ) + prefix = models.ManyToManyField( AddressRange ) + max_len = models.IntegerField() + asn = models.IntegerField() + active = models.BooleanField() + comments = models.TextField() + def __unicode__( self ): + return u"%s's ROA for %d" % ( self.conf, self.asn ) diff --git a/portal-gui/rpkigui/myrpki/urls.py b/portal-gui/rpkigui/myrpki/urls.py new file mode 100644 index 00000000..f5ba7c90 --- /dev/null +++ b/portal-gui/rpkigui/myrpki/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import * +from django.views.generic.list_detail import object_list +import views + +urlpatterns = patterns('', + (r'^cert/$', views.cert_list ), + (r'^cert/add/$', views.cert_add ), + (r'^cert/(?P<id>\d+)/$', views.cert_view ), + (r'^cert/(?P<id>\d+)/edit/$', views.cert_edit ), + (r'^cert/(?P<id>\d+)/delete/$', views.cert_delete ), +) diff --git a/portal-gui/rpkigui/myrpki/views.py b/portal-gui/rpkigui/myrpki/views.py new file mode 100644 index 00000000..68cf7eba --- /dev/null +++ b/portal-gui/rpkigui/myrpki/views.py @@ -0,0 +1,96 @@ +from django.views.generic.create_update import create_object, update_object, \ + delete_object +from django.views.generic.list_detail import object_detail, object_list +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 import http +from functools import update_wrapper +import models +import forms + + +# 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. + +class handle_required(object): + '''A decorator to require picking a configuration. __call__ is + decorated with login_required so that we can be sure that the + request has a user. + + We don't support picking the configuration yet -- if multiple + configurations match, we redirect to handle_picker, which should + allow a staff member to pick any handle. + ''' + + def __init__(self, f): + self.f = f + update_wrapper( self, f ) + + @login_required + def __call__(self, request, *args, **kwargs): + if 'handle' not in request.session: + conf = models.Conf.objects.all().filter( + owner__in=request.user.groups.all() ) + if conf.count() == 1: + handle = conf[ 0 ] + else: + # Should reverse the view for this instead of hardcoding + # the URL. + return http.HttpResponseRedirect( '/handle_picker/?next=%s' % + urlquote(request.get_full_path()) ) + request.session[ 'handle' ] = handle + return self.f(request, *args, **kwargs) + +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 reousrces that I have accepted from my parents + # my children + # the resources that I have given my children + # my roas + return render( 'myrpki/dashboard.html', { 'conf': handle }, request ) + +@handle_required +def cert_add( request ): + return create_object( request, form_class=forms.ConfCertForm( request ), + post_save_redirect='/myrpki/cert/' ) + +@handle_required +def cert_view( request, id ): + handle = request.session[ 'handle' ] + queryset = models.Cert.objects.filter( conf=handle ) + return object_detail( request, queryset=queryset, object_id=id, + template_object_name='cert' ) + +@handle_required +def cert_list( request ): + handle = request.session[ 'handle' ] + queryset = models.Cert.objects.filter( conf=handle ) + return object_list( request, queryset=queryset, + template_object_name='cert' ) + +@handle_required +def cert_edit( request, id ): + handle = request.session[ 'handle' ] + cert = get_object_or_404( models.Cert, pk=id, conf=handle ) + return update_object( request, form_class=forms.ConfCertForm( request ), + object_id=id, + post_save_redirect='/myrpki/cert/' ) + +@handle_required +def cert_delete( request, id ): + handle = request.session[ 'handle' ] + cert = get_object_or_404( models.Cert, pk=id, conf=handle ) + return delete_object( request, model=models.Cert, object_id=id, + post_delete_redirect='/dashboard/' ) diff --git a/portal-gui/rpkigui/settings.py b/portal-gui/rpkigui/settings.py new file mode 100644 index 00000000..af8417e8 --- /dev/null +++ b/portal-gui/rpkigui/settings.py @@ -0,0 +1,93 @@ +# Django settings for rpki 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 = '/tmp/rpkiop' # 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/Chicago' + +# 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 = '81d$t*$7hr!&*s6*-@)_b6@(*%3eo82zu342vssj6x4&_(m_+s' + +# 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', +) + +ROOT_URLCONF = 'rpki.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. +#XXX + '/Users/fenner/src/portal-gui/rpki/templates', +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.admin', + 'django.contrib.admindocs', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'rpki.myrpki', + 'rpki.django_extensions', +) + +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", +) diff --git a/portal-gui/rpkigui/templates/base.html b/portal-gui/rpkigui/templates/base.html new file mode 100644 index 00000000..1f6018bf --- /dev/null +++ b/portal-gui/rpkigui/templates/base.html @@ -0,0 +1,26 @@ +<html> +<head> + <title>{% block title %}MyRPKI{% endblock %} + {% block head %}{% endblock %} + <style type="text/css"><!-- + {% block css %}{% endblock %} + // --> + </style> +</head> +<body> + <div id="header"> + <img src="/site_media/img/my.png"> + <img src="/site_media/img/rpki.png"> + </div> + <div id="content"> + {% if user.is_authenticated %} + <span style="float: right; font-size: 80%;">Logged in as {{ user }} | + {% if user.is_staff %}<a href="/admin/">admin</a> |{% endif %} + <a href="{% url django.contrib.auth.views.logout %}">Log Out</a></span> + {% else %} + <span style="float: right; font-size: 80%;"><a href="{% url django.contrib.auth.views.login %}">Log In</a></span> + {% endif %} + {% block content %}{% endblock %} + </div> +</body> +</html> diff --git a/portal-gui/rpkigui/templates/myrpki/cert_confirm_delete.html b/portal-gui/rpkigui/templates/myrpki/cert_confirm_delete.html new file mode 100644 index 00000000..661f4cc0 --- /dev/null +++ b/portal-gui/rpkigui/templates/myrpki/cert_confirm_delete.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Confirm Delete Cert</h1> + +<p>You would like to delete the certificate named {{ object.name }}. +<form action="" method="post"> +<input type="submit" value="Delete" /> +</form> +{% endblock %} diff --git a/portal-gui/rpkigui/templates/myrpki/cert_detail.html b/portal-gui/rpkigui/templates/myrpki/cert_detail.html new file mode 100644 index 00000000..e9d11074 --- /dev/null +++ b/portal-gui/rpkigui/templates/myrpki/cert_detail.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Cert {{ cert.name }}</h1> + +<pre> +{{ cert.data }} +</pre> + +<p><a href="edit/">[edit]</a> | <a href="delete/">[delete]</a> + +{% endblock %} diff --git a/portal-gui/rpkigui/templates/myrpki/cert_form.html b/portal-gui/rpkigui/templates/myrpki/cert_form.html new file mode 100644 index 00000000..2ff95fb0 --- /dev/null +++ b/portal-gui/rpkigui/templates/myrpki/cert_form.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Add/Edit Cert</h1> + +<form action="" method="post"> +<table> +{{ form }} +</table> +<input type="submit" value="Submit" /> +</form> + +{% endblock %} diff --git a/portal-gui/rpkigui/templates/myrpki/cert_list.html b/portal-gui/rpkigui/templates/myrpki/cert_list.html new file mode 100644 index 00000000..882a1301 --- /dev/null +++ b/portal-gui/rpkigui/templates/myrpki/cert_list.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block content %} +<h1>Certificates for {{ request.session.handle }}</h1> + +<p> +<a href="add/">[add]</a> +<p> +<ul> +{% for cert in cert_list %} +<li><a href="{{ cert.id }}/">{{ cert.name }}</a> +{% endfor %} +</ul> +{% endblock %} diff --git a/portal-gui/rpkigui/templates/myrpki/dashboard.html b/portal-gui/rpkigui/templates/myrpki/dashboard.html new file mode 100644 index 00000000..aef2b6cd --- /dev/null +++ b/portal-gui/rpkigui/templates/myrpki/dashboard.html @@ -0,0 +1,87 @@ +{% extends "base.html" %} + +{% block content %} +<div style="border: inset"> +<h1 style="text-align: center">Parents</h1> +<a href="#">[add]</a> +<ul> +{% for parent in request.session.handle.parents.all %} +<li>{{ parent.handle }} (knows me as {{ parent.my_handle }}) +{% if parent.asn.count or parent.address_range.count %} +<p>Accepted resources: +<ul> +{% for asn in parent.asn.all %} +<li>{{ asn }} +{% endfor %} +{% for address in parent.address_range.all %} +<li>{{ address }} +{% endfor %} +</ul> +{% endif %} +{% endfor %} +</ul> +</div> +<span> +<div style="border: outset"> +<h1 style="text-align: center">Children</h1> +<a href="#">[add]</a> +<p> +<ul> +{% for child in request.session.handle.children.all %} +<li>{{ child.handle }} +{% if child.address_range.count or child.asn.count %} +<p>Delegated resources: +<ul> +{% for asn in child.asn.all %} +<li>{{ asn }} +{% endfor %} +{% for address in child.address_range.all %} +<li>{{ address }} +{% endfor %} +</ul> +{% endif %} +{% endfor %} +</ul> +</div> +<div style="border: outset"> +<h1 style="text-align: center">My ROA [request]s</h1> +{% if request.session.handle.roas.count %} +<table style="border: groove; width: 100%" border="1"> +<tr> +<th>Prefix</th> +<th>ASN</th> +<th>Max Len</th> +<th>Active</th> +<th>Comments</th> +</tr> +{% for roa in request.session.handle.roas.all %} +{% for address_range in roa.prefix.all %} +<tr> +<td>{{ address_range }}</td> +<td>{{ roa.asn }}</td> +<td>{{ roa.max_len }}</td> +<td>{{ roa.active }}</td> +<td>{{ roa.comments }}</td> +</tr> +{% endfor %} +{% endfor %} +</table> +{% else %} +<p> +-- none -- +{% endif %} +</div> +<div style="border: outset"> +<h1 style="text-align: center">Un<something> Resources</h1> +<ul> +<li>Address range 172.17.2.0-172.17.255.255 + <a href="#">[subdivide]</a> | + <a href="#">[give to child]</a> | + <a href="#">[issue roa]</a> +<li>ASN 1 <a href="#">[give to child]</a> +<li>ASNs 3-100 <a href="#">[subdivide]</a> | + <a href="#">[give to child]</a> +</ul> +</div> +</span> +{% endblock %} diff --git a/portal-gui/rpkigui/templates/registration/login.html b/portal-gui/rpkigui/templates/registration/login.html new file mode 100644 index 00000000..86b5392a --- /dev/null +++ b/portal-gui/rpkigui/templates/registration/login.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} + +{% block content %} + +{% if form.errors %} +<p>Your username and password didn't match. Please try again.</p> +{% endif %} + +<form method="post" action="{% url django.contrib.auth.views.login %}"> +<table> +<tr> + <td>{{ form.username.label_tag }}</td> + <td>{{ form.username }}</td> +</tr> +<tr> + <td>{{ form.password.label_tag }}</td> + <td>{{ form.password }}</td> +</tr> +</table> + +<input type="submit" value="login" /> +<input type="hidden" name="next" value="{{ next }}" /> +</form> + +{% endblock %} + diff --git a/portal-gui/rpkigui/urls.py b/portal-gui/rpkigui/urls.py new file mode 100644 index 00000000..f754fb23 --- /dev/null +++ b/portal-gui/rpkigui/urls.py @@ -0,0 +1,27 @@ +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'^dashboard/', include('myrpki.dashboardurls')), + (r'^myrpki/', include('myrpki.urls')), + + (r'^accounts/login/$', 'django.contrib.auth.views.login'), + (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), + +#XXX +(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', + {'document_root': '/Users/fenner/src/portal-gui/media/'}), + +) |