From 0080fe7e787fff4abcc1fe2b60902c2d475aa59e Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 31 Jan 2015 22:26:17 +0100 Subject: [PATCH] add administration form and admin class for SshPublicKey --- gnuviechadmin/osusers/admin.py | 98 +++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/gnuviechadmin/osusers/admin.py b/gnuviechadmin/osusers/admin.py index 6fec6e7..2befe02 100644 --- a/gnuviechadmin/osusers/admin.py +++ b/gnuviechadmin/osusers/admin.py @@ -3,7 +3,7 @@ This module contains the Django admin classes of the :py:mod:`osusers` app. """ from django import forms -from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy as _ from django.contrib import admin from gvawebcore.forms import ( @@ -13,9 +13,14 @@ from .models import ( AdditionalGroup, Group, Shadow, + SshPublicKey, User, ) +INVALID_SSH_PUBLIC_KEY = _('Invalid SSH public key data format.') +DUPLICATE_SSH_PUBLIC_KEY_FOR_USER = _( + 'This SSH public key is already assigned to this user.') + class AdditionalGroupInline(admin.TabularInline): """ @@ -216,5 +221,96 @@ class GroupAdmin(admin.ModelAdmin): return actions +class SshPublicKeyCreationForm(forms.ModelForm): + """ + A form for creating :py:class:`SSH public keys + `. + + """ + publickeytext = forms.CharField( + label=_('Key text'), widget=forms.Textarea, + help_text=_('A SSH public key in either OpenSSH or RFC 4716 format')) + + class Meta: + model = SshPublicKey + fields = ['user'] + + def clean_publickeytext(self): + keytext = self.cleaned_data.get('publickeytext') + try: + SshPublicKey.objects.parse_keytext(keytext) + except: + raise forms.ValidationError(INVALID_SSH_PUBLIC_KEY) + return keytext + + def clean(self): + user = self.cleaned_data.get('user') + keytext = self.cleaned_data.get('publickeytext') + if user and keytext: + alg, data, comment = SshPublicKey.objects.parse_keytext(keytext) + if SshPublicKey.objects.filter( + user=user, algorithm=alg, data=data + ).exists(): + self.add_error( + 'publickeytext', + forms.ValidationError(DUPLICATE_SSH_PUBLIC_KEY_FOR_USER)) + + def save(self, commit=True): + """ + Save the provided ssh public key in properly split format. + + :param boolean commit: whether to save the created public key + :return: ssh public key instance + :rtype: :py:class:`osusers.models.SshPublicKey` + + """ + algorithm, keydata, comment = SshPublicKey.objects.parse_keytext( + self.cleaned_data.get('publickeytext')) + self.instance.algorithm = algorithm + self.instance.data = keydata + self.instance.comment = comment + return super(SshPublicKeyCreationForm, self).save(commit) + + +class SshPublicKeyAdmin(admin.ModelAdmin): + """ + Admin class for working with :py:class:`SSH public keys + `. + + """ + add_form = SshPublicKeyCreationForm + list_display = ['user', 'algorithm', 'comment'] + + add_fieldsets = ( + (None, { + 'classes': ('wide',), + 'fields': ('user', 'publickeytext')}), + ) + + def get_form(self, request, obj=None, **kwargs): + """ + Use special form for ssh public key creation." + + :param request: the current HTTP request + :param obj: either a :py:class:`SshPublicKey + ` instance or None for a new SSH + public key + :param kwargs: keyword arguments to be passed to + :py:meth:`django.contrib.admin.ModelAdmin.get_form` + :return: form instance + + """ + defaults = {} + if obj is None: + defaults.update({ + 'form': self.add_form, + 'fields': admin.options.flatten_fieldsets(self.add_fieldsets), + }) + defaults.update(kwargs) + return super(SshPublicKeyAdmin, self).get_form( + request, obj, **defaults) + + admin.site.register(Group, GroupAdmin) admin.site.register(User, UserAdmin) +admin.site.register(SshPublicKey, SshPublicKeyAdmin)