From 310505e82c4097294a26a0492b1ca61cb4dda13d Mon Sep 17 00:00:00 2001 From: Frank Sauerburger <frank@sauerburger.com> Date: Sat, 20 Feb 2021 16:06:26 +0100 Subject: [PATCH] Add ssh key add view --- ssh/forms.py | 31 ++++++++++++++++++ ssh/templates/ssh/sshpublickey_create.html | 11 +++++++ ssh/templates/ssh/sshpublickey_list.html | 5 +++ ssh/urls.py | 2 +- ssh/views.py | 37 +++++++++++++++++++--- 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 ssh/forms.py create mode 100644 ssh/templates/ssh/sshpublickey_create.html diff --git a/ssh/forms.py b/ssh/forms.py new file mode 100644 index 0000000..962146d --- /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 0000000..7334027 --- /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 478fd57..0f6195d 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 409a872..8e1257d 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 9725af4..3a8cd2b 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}) -- GitLab