add view osusers.views.AddSshPublicKey
- implement new form osusers.forms.AddSshPublicKeyForm - move message texts from osusers.admin to osusers.forms - add new view osusers.views.AddSshPublicKey - add new URL patter 'add_ssh_key' to osusers.urls - add new template osusers/sshpublickey_create.html - link from hosting package detail template to 'add_ssh_key' - add changelog entry for new feature
This commit is contained in:
parent
79b460c4a6
commit
0c7bb79109
7 changed files with 159 additions and 9 deletions
|
@ -1,6 +1,7 @@
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
* :feature:`-` add ability to add SSH public keys for operating system users
|
||||||
* :support:`-` make tests in osusers.tests work again
|
* :support:`-` make tests in osusers.tests work again
|
||||||
* :support:`-` minor HTML improvements
|
* :support:`-` minor HTML improvements
|
||||||
* :support:`-` add API for gvafile task set_file_ssh_authorized_keys (requires
|
* :support:`-` add API for gvafile task set_file_ssh_authorized_keys (requires
|
||||||
|
|
|
@ -12,6 +12,10 @@ from gvawebcore.forms import (
|
||||||
)
|
)
|
||||||
from taskresults.models import TaskResult
|
from taskresults.models import TaskResult
|
||||||
|
|
||||||
|
from .forms import (
|
||||||
|
INVALID_SSH_PUBLIC_KEY,
|
||||||
|
DUPLICATE_SSH_PUBLIC_KEY_FOR_USER,
|
||||||
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
AdditionalGroup,
|
AdditionalGroup,
|
||||||
Group,
|
Group,
|
||||||
|
@ -20,10 +24,6 @@ from .models import (
|
||||||
User,
|
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):
|
class AdditionalGroupInline(admin.TabularInline):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,7 +13,14 @@ from crispy_forms.layout import Submit
|
||||||
|
|
||||||
from gvawebcore.forms import PasswordModelFormMixin
|
from gvawebcore.forms import PasswordModelFormMixin
|
||||||
|
|
||||||
from .models import User
|
from .models import (
|
||||||
|
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 ChangeOsUserPasswordForm(PasswordModelFormMixin, forms.ModelForm):
|
class ChangeOsUserPasswordForm(PasswordModelFormMixin, forms.ModelForm):
|
||||||
|
@ -43,3 +50,63 @@ class ChangeOsUserPasswordForm(PasswordModelFormMixin, forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
self.instance.set_password(self.cleaned_data['password1'])
|
self.instance.set_password(self.cleaned_data['password1'])
|
||||||
return super(ChangeOsUserPasswordForm, self).save(commit=commit)
|
return super(ChangeOsUserPasswordForm, self).save(commit=commit)
|
||||||
|
|
||||||
|
|
||||||
|
class AddSshPublicKeyForm(forms.ModelForm):
|
||||||
|
"""
|
||||||
|
A form for creating :py:class:`SSH public keys
|
||||||
|
<osusers.models.SshPublicKey>`.
|
||||||
|
|
||||||
|
"""
|
||||||
|
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 = []
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
hosting_package = kwargs.pop('hostingpackage')
|
||||||
|
self.osuser = hosting_package.osuser
|
||||||
|
super(AddSshPublicKeyForm, self).__init__(*args, **kwargs)
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_action = reverse(
|
||||||
|
'add_ssh_key', kwargs={'package': hosting_package.id})
|
||||||
|
self.helper.add_input(Submit('submit', _('Add SSH public key')))
|
||||||
|
|
||||||
|
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):
|
||||||
|
keytext = self.cleaned_data.get('publickeytext')
|
||||||
|
alg, data, comment = SshPublicKey.objects.parse_keytext(keytext)
|
||||||
|
if SshPublicKey.objects.filter(
|
||||||
|
user=self.osuser, 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.user = self.osuser
|
||||||
|
self.instance.algorithm = algorithm
|
||||||
|
self.instance.data = keydata
|
||||||
|
self.instance.comment = comment
|
||||||
|
return super(AddSshPublicKeyForm, self).save(commit)
|
||||||
|
|
|
@ -6,11 +6,16 @@ from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.conf.urls import patterns, url
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
from .views import SetOsUserPassword
|
from .views import (
|
||||||
|
AddSshPublicKey,
|
||||||
|
SetOsUserPassword,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'^(?P<slug>[\w0-9@.+-_]+)/setpassword$', SetOsUserPassword.as_view(),
|
url(r'^(?P<slug>[\w0-9@.+-_]+)/setpassword$', SetOsUserPassword.as_view(),
|
||||||
name='set_osuser_password'),
|
name='set_osuser_password'),
|
||||||
|
url(r'^(?P<package>\d+)/add-ssh-key$', AddSshPublicKey.as_view(),
|
||||||
|
name='add_ssh_key'),
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,14 +5,24 @@ This module defines the views for gnuviechadmin operating system user handling.
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.views.generic import UpdateView
|
from django.views.generic import (
|
||||||
|
UpdateView,
|
||||||
|
CreateView,
|
||||||
|
)
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
|
||||||
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
|
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
|
||||||
|
from gvawebcore.views import HostingPackageAndCustomerMixin
|
||||||
|
|
||||||
from .forms import ChangeOsUserPasswordForm
|
from .forms import (
|
||||||
from .models import User
|
AddSshPublicKeyForm,
|
||||||
|
ChangeOsUserPasswordForm,
|
||||||
|
)
|
||||||
|
from .models import (
|
||||||
|
SshPublicKey,
|
||||||
|
User,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
|
class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
|
||||||
|
@ -43,3 +53,39 @@ class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
|
||||||
username=osuser.username
|
username=osuser.username
|
||||||
))
|
))
|
||||||
return redirect(osuser.customerhostingpackage)
|
return redirect(osuser.customerhostingpackage)
|
||||||
|
|
||||||
|
|
||||||
|
class AddSshPublicKey(
|
||||||
|
HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
This view is used to add an SSH key for an existing hosting account's
|
||||||
|
operating system user.
|
||||||
|
|
||||||
|
"""
|
||||||
|
model = SshPublicKey
|
||||||
|
context_object_name = 'key'
|
||||||
|
template_name_suffix = '_create'
|
||||||
|
form_class = AddSshPublicKeyForm
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(AddSshPublicKey, self).get_form_kwargs()
|
||||||
|
kwargs['hostingpackage'] = self.get_hosting_package()
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(AddSshPublicKey, self).get_context_data(**kwargs)
|
||||||
|
context.update({
|
||||||
|
'customer': self.get_customer_object(),
|
||||||
|
'osuser': self.get_hosting_package().osuser.username,
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
key = form.save()
|
||||||
|
messages.success(
|
||||||
|
self.request,
|
||||||
|
_('Successfully added new {algorithm} SSH public key').format(
|
||||||
|
algorithm=key.algorithm)
|
||||||
|
)
|
||||||
|
return redirect(self.get_hosting_package())
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-item"><a href="#" title="{% trans "Edit Hosting Package Description" %}">{% trans "Edit description" %}</a></li>
|
<li class="list-group-item"><a href="#" title="{% trans "Edit Hosting Package Description" %}">{% trans "Edit description" %}</a></li>
|
||||||
<li class="list-group-item"><a href="{% url "set_osuser_password" slug=osuser.username %}">{% if osuser.is_sftp_user %}{% trans "Set SFTP password" %}{% else %}{% trans "Set SSH/SFTP password" %}{% endif %}</a></li>
|
<li class="list-group-item"><a href="{% url "set_osuser_password" slug=osuser.username %}">{% if osuser.is_sftp_user %}{% trans "Set SFTP password" %}{% else %}{% trans "Set SSH/SFTP password" %}{% endif %}</a></li>
|
||||||
|
<li class="list-group-item"><a href="{% url "add_ssh_key" package=hostingpackage.id %}" title="{% blocktrans %}Add an SSH public key that can be used as an alternative for password{% endblocktrans %}">{% trans "Add SSH public key" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
30
gnuviechadmin/templates/osusers/sshpublickey_create.html
Normal file
30
gnuviechadmin/templates/osusers/sshpublickey_create.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{% extends "osusers/base.html" %}
|
||||||
|
{% load i18n crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ block.super }} - {% spaceless %}
|
||||||
|
{% if user == customer %}
|
||||||
|
{% blocktrans %}Add new SSH Public Key{% endblocktrans %}
|
||||||
|
{% else %}
|
||||||
|
{% blocktrans with full_name=customer.get_full_name %}Add a new SSH Public Key for Operating System User {{ osuser }} of Customer {{ full_name }}{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% endspaceless %}{% endblock title %}
|
||||||
|
|
||||||
|
{% block page_title %}{% spaceless %}
|
||||||
|
{% if user == customer %}
|
||||||
|
{% blocktrans %}Add new SSH Public Key{% endblocktrans %}
|
||||||
|
{% else %}
|
||||||
|
{% blocktrans with full_name=customer.get_full_name %}Add a new SSH Public Key <small>for Operating System User {{ osuser }} of Customer {{ full_name }}</small>{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% endspaceless %}{% endblock page_title %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% crispy form %}
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block extra_js %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('textarea').first().focus();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock extra_js %}
|
Loading…
Reference in a new issue