aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/gui
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/rpki/gui')
-rw-r--r--rpkid/rpki/gui/app/forms.py86
-rw-r--r--rpkid/rpki/gui/app/glue.py2
-rw-r--r--rpkid/rpki/gui/app/models.py13
-rw-r--r--rpkid/rpki/gui/app/templates/app/ghostbuster_confirm_delete.html20
-rw-r--r--rpkid/rpki/gui/app/templates/app/ghostbuster_detail.html3
-rw-r--r--rpkid/rpki/gui/app/views.py22
6 files changed, 68 insertions, 78 deletions
diff --git a/rpkid/rpki/gui/app/forms.py b/rpkid/rpki/gui/app/forms.py
index 32c89b17..60e2fc8e 100644
--- a/rpkid/rpki/gui/app/forms.py
+++ b/rpkid/rpki/gui/app/forms.py
@@ -49,61 +49,45 @@ class ImportForm(forms.Form):
handle = forms.CharField(max_length=30, help_text='your name for this entity')
xml = forms.FileField(help_text='xml filename')
-def GhostbusterForm(parent_qs, conf=None):
+class GhostbusterRequestForm(forms.ModelForm):
"""
Generate a ModelForm with the subset of parents for the current
resource handle.
-
- The 'conf' argument is required when creating a new object, in
- order to specify the value of the 'conf' field in the new
- Ghostbuster object.
"""
- class wrapped(forms.ModelForm):
- # override parent
- parent = forms.ModelMultipleChoiceField(queryset=parent_qs, required=False,
- help_text='use this record for a specific parent, or leave blank for all parents')
- # override full_name. it is required in the db schema, but we allow the
- # user to skip it and default from family+given name
- full_name = forms.CharField(max_length=40, required=False,
- help_text='automatically generated from family and given names if left blank')
-
- class Meta:
- model = models.Ghostbuster
- exclude = [ 'conf' ]
-
- def clean(self):
- family_name = self.cleaned_data.get('family_name')
- given_name = self.cleaned_data.get('given_name')
- if not all([family_name, given_name]):
- raise forms.ValidationError, 'Family and Given names must be specified'
-
- email = self.cleaned_data.get('email_address')
- postal = self.cleaned_data.get('postal_address')
- telephone = self.cleaned_data.get('telephone')
- if not any([email, postal, telephone]):
- raise forms.ValidationError, 'One of telephone, email or postal address must be specified'
-
- # if the full name is not specified, default to given+family
- fn = self.cleaned_data.get('full_name')
- if not fn:
- self.cleaned_data['full_name'] = '%s %s' % (given_name, family_name)
-
- return self.cleaned_data
-
- def save(self, *args, **kwargs):
- if conf:
- # the generic create_object view doesn't allow us to set
- # the conf field, so wrap the save() method and set it
- # here
- kwargs['commit'] = False
- obj = super(wrapped, self).save(*args, **kwargs)
- obj.conf = conf
- obj.save()
- return obj
- else:
- return super(wrapped, self).save(*args, **kwargs)
-
- return wrapped
+ # override default form field
+ parent = forms.ModelChoiceField(queryset=None, required=False, help_text='Specify specific parent, or none for all parents')
+
+ # override full_name. it is required in the db schema, but we allow the
+ # user to skip it and default from family+given name
+ full_name = forms.CharField(max_length=40, required=False,
+ help_text='automatically generated from family and given names if left blank')
+
+ def __init__(self, issuer, *args, **kwargs):
+ super(GhostbusterRequestForm, self).__init__(*args, **kwargs)
+ self.fields['parent'].queryset = models.Parent.objects.filter(issuer=issuer)
+
+ class Meta:
+ model = models.GhostbusterRequest
+ exclude = ('issuer', 'vcard')
+
+ def clean(self):
+ family_name = self.cleaned_data.get('family_name')
+ given_name = self.cleaned_data.get('given_name')
+ if not all([family_name, given_name]):
+ raise forms.ValidationError, 'Family and Given names must be specified'
+
+ email = self.cleaned_data.get('email_address')
+ postal = self.cleaned_data.get('postal_address')
+ telephone = self.cleaned_data.get('telephone')
+ if not any([email, postal, telephone]):
+ raise forms.ValidationError, 'One of telephone, email or postal address must be specified'
+
+ # if the full name is not specified, default to given+family
+ fn = self.cleaned_data.get('full_name')
+ if not fn:
+ self.cleaned_data['full_name'] = '%s %s' % (given_name, family_name)
+
+ return self.cleaned_data
class ChildForm(forms.ModelForm):
"""
diff --git a/rpkid/rpki/gui/app/glue.py b/rpkid/rpki/gui/app/glue.py
index 079c844d..0319621c 100644
--- a/rpkid/rpki/gui/app/glue.py
+++ b/rpkid/rpki/gui/app/glue.py
@@ -81,7 +81,7 @@ def qualify_path(pfx, fname):
return fname if fname.startswith('/') else os.path.join(pfx, fname)
def ghostbuster_to_vcard(gbr):
- """Convert a Ghostbuster object into a vCard object."""
+ """Convert a GhostbusterRequest object into a vCard object."""
import vobject
vcard = vobject.vCard()
diff --git a/rpkid/rpki/gui/app/models.py b/rpkid/rpki/gui/app/models.py
index 5bfc9e81..87efdf8b 100644
--- a/rpkid/rpki/gui/app/models.py
+++ b/rpkid/rpki/gui/app/models.py
@@ -116,11 +116,15 @@ class ROARequestPrefix(rpki.irdb.models.ROARequestPrefix):
def get_absolute_url(self):
return ('rpki.gui.app.views.roa_detail', [str(self.pk)])
-class GhostbusterRequest(models.Model):
+class GhostbusterRequest(rpki.irdb.models.GhostbusterRequest):
"""
- Stores the information require to fill out a vCard entry to populate
- a ghostbusters record.
+ Stores the information require to fill out a vCard entry to
+ populate a ghostbusters record.
+
+ This model is inherited from the irdb GhostBusterRequest model so
+ that the broken out fields can be included for ease of editing.
"""
+
full_name = models.CharField(max_length=40)
# components of the vCard N type
@@ -143,9 +147,6 @@ class GhostbusterRequest(models.Model):
code = models.CharField(verbose_name='Postal Code', blank=True, null=True, max_length=40)
country = models.CharField(blank=True, null=True, max_length=40)
- # pointer to the IRDB object matching this ghostbuster request
- irdb = models.ForeignKey(rpki.irdb.models.GhostbusterRequest, related_name='app_ghostbusters')
-
def __unicode__(self):
return u"%s's GBR: %s" % (self.issuer.handle, self.full_name)
diff --git a/rpkid/rpki/gui/app/templates/app/ghostbuster_confirm_delete.html b/rpkid/rpki/gui/app/templates/app/ghostbuster_confirm_delete.html
index 8c5cd970..76b1d25a 100644
--- a/rpkid/rpki/gui/app/templates/app/ghostbuster_confirm_delete.html
+++ b/rpkid/rpki/gui/app/templates/app/ghostbuster_confirm_delete.html
@@ -2,13 +2,19 @@
{% block extra %}
-<p>
-Please confirm that you really want to delete this object by clicking Delete.
-</p>
+<div class='alert-message block-message warning'>
+ <p>
+ <strong>Please confirm</strong> that you really want to delete by clicking Delete.
-<form method=POST action='{{ request.get_full_path }}'>
- {% csrf_token %}
- <input type='submit' value='Delete' />
-</form>
+ <div class='alert-actions'>
+ <form method='POST' action='{{ request.get_full_path }}'>
+ {% csrf_token %}
+ <input class='btn danger' type='submit' value='Delete' />
+ <a class='btn' href='{{ object.get_absolute_url }}'>Cancel</a>
+ </form>
+ </div>
+</div>
{% endblock %}
+
+<!-- vim:set sw=2: -->
diff --git a/rpkid/rpki/gui/app/templates/app/ghostbuster_detail.html b/rpkid/rpki/gui/app/templates/app/ghostbuster_detail.html
index 7115a4d7..b86ad852 100644
--- a/rpkid/rpki/gui/app/templates/app/ghostbuster_detail.html
+++ b/rpkid/rpki/gui/app/templates/app/ghostbuster_detail.html
@@ -62,12 +62,13 @@
</table>
+{% block extra %}
<div class='actions'>
<a class='btn' href='{{ object.get_absolute_url }}/edit'>Edit</a>
<a class='btn danger' href='{{ object.get_absolute_url }}/delete'>Delete</a>
</div>
+{% endblock %}
-{% block extra %}{% endblock %}
{% endblock %}
<!-- vim: set sw=2: -->
diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py
index 77d73ce1..0247dec2 100644
--- a/rpkid/rpki/gui/app/views.py
+++ b/rpkid/rpki/gui/app/views.py
@@ -380,8 +380,7 @@ def ghostbusters_list(request):
Display a list of all ghostbuster requests for the current Conf.
"""
conf = request.session['handle']
- qs = models.Ghostbuster.filter(irdb__issuer=conf)
-
+ qs = models.GhostbusterRequest.objects.filter(issuer=conf)
return object_list(request, queryset=qs,
template_name='app/ghostbuster_list.html',
extra_context = { 'page_title': 'Ghostbusters' })
@@ -392,8 +391,7 @@ def ghostbuster_view(request, pk):
Display an individual ghostbuster request.
"""
conf = request.session['handle']
- qs = models.Ghostbuster.filter(irdb__issuer=conf)
-
+ qs = models.GhostbusterRequest.objects.filter(issuer=conf)
return object_detail(request, queryset=qs, object_id=pk, template_name='app/ghostbuster_detail.html')
@handle_required
@@ -401,11 +399,11 @@ def ghostbuster_delete(request, pk):
conf = request.session['handle']
# verify that the object is owned by this conf
- obj = get_object_or_404(models.Ghostbuster, pk=pk, irdb__issuer=conf)
+ obj = get_object_or_404(models.GhostbusterRequest, pk=pk, issuer=conf)
# modeled loosely on the generic delete_object() view.
if request.method == 'POST':
- obj.irdb.delete() # should cause a cascade delete of 'obj'
+ obj.delete() # should cause a cascade delete of 'obj'
return http.HttpResponseRedirect(reverse(ghostbusters_list))
return render('app/ghostbuster_confirm_delete.html', { 'object': obj }, request)
@@ -415,20 +413,20 @@ def _ghostbuster_edit(request, obj=None):
Common code for create/edit.
"""
conf = request.session['handle']
- form_class = forms.GhostbusterForm(conf.parents.all())
+ form_class = forms.GhostbusterRequestForm
if request.method == 'POST':
- form = form_class(request.POST, request.FILES, instance=obj)
+ form = form_class(conf, request.POST, request.FILES, instance=obj)
if form.is_valid():
# use commit=False for the creation case, otherwise form.save()
# will fail due to schema constraint violation because conf is
# NULL
obj = form.save(commit=False)
- obj.conf = conf
+ obj.issuer = conf
+ obj.vcard = glue.ghostbuster_to_vcard(obj)
obj.save()
- glue.configure_resources(request.META['wsgi.errors'], conf)
return http.HttpResponseRedirect(obj.get_absolute_url())
else:
- form = form_class(instance=obj)
+ form = form_class(conf, instance=obj)
return render('app/ghostbuster_form.html', { 'form': form, 'object': obj }, request)
@handle_required
@@ -436,7 +434,7 @@ def ghostbuster_edit(request, pk):
conf = request.session['handle']
# verify that the object is owned by this conf
- obj = get_object_or_404(models.Ghostbuster, pk=pk, conf=conf)
+ obj = get_object_or_404(models.GhostbusterRequest, pk=pk, issuer=conf)
return _ghostbuster_edit(request, obj)