diff --git a/ssh/forms.py b/ssh/forms.py new file mode 100644 index 0000000000000000000000000000000000000000..962146d0aeca86678a574330fff73de10a660885 --- /dev/null +++ b/ssh/forms.py @@ -0,0 +1,31 @@ + +import re +from django import forms +from django.core.exceptions import ValidationError + +class KeyStringField(forms.CharField): + def __init__(self, *args, **kwds): + kwds["widget"] = forms.Textarea + super().__init__(*args, **kwds) + + def to_python(self, value): + """Split keystring on whitespace""" + if not value: + return [] + + return re.split("\s+", value) + + def validate(self, value): + """Check if there are at least two tokens""" + super().validate(value) + if len(value) < 2: + raise ValidationError("KeyString needs type and key part") + + + +class PublicKeyCreateForm(forms.Form): + keystring = KeyStringField() + hostname = forms.CharField(max_length=128) + port = forms.IntegerField(required=False) + client_cert = forms.BooleanField(required=False) + public = forms.BooleanField(required=False) diff --git a/ssh/templates/ssh/sshpublickey_create.html b/ssh/templates/ssh/sshpublickey_create.html new file mode 100644 index 0000000000000000000000000000000000000000..7334027cb92d9b27fc57cdb37ddcc1f859e6d3cd --- /dev/null +++ b/ssh/templates/ssh/sshpublickey_create.html @@ -0,0 +1,11 @@ +{% extends 'keys/base.html' %} + +{% block content %} +<h2>Add public key</h2> +<form action="" method="post"> + {% csrf_token %} + {{ form.as_p }} + <button type="submit">Add</button> +</form> + +{% endblock %} diff --git a/ssh/templates/ssh/sshpublickey_list.html b/ssh/templates/ssh/sshpublickey_list.html index 478fd5743d6671cd3ad3ebec54c9be26982e357c..0f6195d5f3e45a4829c9ae08b414e3dc06f5bc17 100644 --- a/ssh/templates/ssh/sshpublickey_list.html +++ b/ssh/templates/ssh/sshpublickey_list.html @@ -1,6 +1,11 @@ {% extends 'keys/base.html' %} {% block content %} + +{% if perms.ssh.add_sshpublickey %} +<a href="{% url 'ssh-create' %}">Add public key</a> +{% endif %} + {% if sshpublickey_list %} <ul> {% for publickey in sshpublickey_list %} diff --git a/ssh/urls.py b/ssh/urls.py index 409a87280651c41cdd4e45d18c2f8d7d41cd3b20..8e1257d0b738407be1db6574021e1d614e37118c 100644 --- a/ssh/urls.py +++ b/ssh/urls.py @@ -5,5 +5,5 @@ from . import views urlpatterns = [ path("", views.PublicKeyListView.as_view(), name="ssh-list"), - path("<int:pk>", views.PublicKeyDetailView.as_view(), name="ssh-detail"), + path("new", views.publickey_create, name="ssh-create"), ] diff --git a/ssh/views.py b/ssh/views.py index 9725af443f195cc766bf2402e73b6fa5f0a094e1..3a8cd2bf657d7571ba00ede81e6dc7034832bea8 100644 --- a/ssh/views.py +++ b/ssh/views.py @@ -1,14 +1,43 @@ -from django.shortcuts import render +from django.shortcuts import render, reverse from django.views.generic import DetailView, ListView, CreateView +from django.http import HttpResponseRedirect from guardian.mixins import PermissionRequiredMixin, PermissionListMixin +from guardian.decorators import permission_required +from guardian.shortcuts import assign_perm +from guardian.utils import get_anonymous_user from . import models +from . import forms class PublicKeyListView(PermissionListMixin, ListView): model = models.SSHPublicKey permission_required = ['view_sshpublickey'] -class PublicKeyDetailView(PermissionRequiredMixin, DetailView): - model = models.SSHPublicKey - permission_required = ['view_sshpublickey'] +@permission_required('ssh.add_sshpublickey') +def publickey_create(request): + if request.method == 'POST': + form = forms.PublicKeyCreateForm(request.POST) + if form.is_valid(): + pk = models.SSHPublicKey() + pk.hostname = form.cleaned_data['hostname'] + pk.port = form.cleaned_data['port'] + pk.client_cert = form.cleaned_data['client_cert'] + pk.keytype, pk.key = form.cleaned_data['keystring'][:2] + pk.save() + + assign_perm('view_sshpublickey', request.user, pk) + assign_perm('change_sshpublickey', request.user, pk) + + if form.cleaned_data['public']: + assign_perm('view_sshpublickey', + get_anonymous_user(), + pk) + return HttpResponseRedirect(reverse('ssh-list')) + + # if a GET (or any other method) we'll create a blank form + else: + form = forms.PublicKeyCreateForm() + return render(request, + 'ssh/sshpublickey_create.html', + {'form': form})