plug users and hosting packages together

- document new feature in changelog
- add autogenerated documentation for osusers.urls and osusers.views
- add osuser URLs to gnuviechadmin.urls
- implement get_absolute_url in hostingpackages.models.CustomerHostingPackage
- use set_ldap_user_password instead of create_ldap_user for existing OS users
  in osusers.models.User.set_password
- add URL pattern set_osuser_password in osusers.urls
- implement osusers.views.SetOsUserPassword to set the password of an existing
  operating system user
- link to hosting package detail view on user dashboard
- add template hostingpackages/customerhostingpackage_detail.html
- add template osusers/user_setpassword.html
This commit is contained in:
Jan Dittberner 2015-01-24 16:26:32 +01:00
parent 0d08d9876b
commit 150366a524
11 changed files with 181 additions and 6 deletions

View File

@ -1,6 +1,8 @@
Changelog
=========
* :feature:`-` add frontend functionality to set an os users' sftp password
(needs gvaldap >= 0.4.0 on the LDAP side)
* :support:`-` remove unused dashboard.views.LogoutView and the corresponding
URL in dashboard.urls
* :feature:`-` add new task stub to set an ldap user's password

View File

@ -30,3 +30,16 @@
.. automodule:: osusers.models
:members:
:py:mod:`urls <osusers.urls>`
-----------------------------
.. automodule:: osusers.urls
:py:mod:`views <osusers.views>`
-------------------------------
.. automodule:: osusers.views
:members:

View File

@ -11,6 +11,7 @@ urlpatterns = patterns(
url(r'', include('dashboard.urls')),
url(r'^accounts/', include('allauth.urls')),
url(r'^hosting/', include('hostingpackages.urls')),
url(r'^osuser/', include('osusers.urls')),
url(r'^admin/', include(admin.site.urls)),
)

View File

@ -5,6 +5,7 @@ This module contains the hosting package models.
from __future__ import absolute_import, unicode_literals
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import transaction
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@ -218,6 +219,12 @@ class CustomerHostingPackage(HostingPackageBase):
name=self.name, customer=self.customer
)
def get_absolute_url(self):
return reverse('hosting_package_details', kwargs={
'user': self.customer.username,
'pk': self.id,
})
def copy_template_attributes(self):
"""
Copy the attributes of the hosting package's template to the package.

View File

@ -29,6 +29,7 @@ from ldaptasks.tasks import (
delete_ldap_group,
delete_ldap_user,
remove_ldap_user_from_group,
set_ldap_user_password,
)
from fileservertasks.tasks import (
@ -245,15 +246,26 @@ class User(TimeStampedModel, models.Model):
"""
if hasattr(self, 'shadow'):
self.shadow.set_password(password)
success = set_ldap_user_password.delay(
self.username, password).get()
if success:
_LOGGER.info(
"successfully set LDAP password for %s", self.username)
else:
_LOGGER.error(
"setting the LDAP password for %s failed", self.username)
return success
else:
self.shadow = Shadow.objects.create_shadow(
user=self, password=password
)
dn = create_ldap_user.delay(
self.username, self.uid, self.group.gid, self.gecos,
self.homedir, self.shell, password
).get()
logging.info("set LDAP password for %s", dn)
dn = create_ldap_user.delay(
self.username, self.uid, self.group.gid, self.gecos,
self.homedir, self.shell, password
).get()
_LOGGER.info("set LDAP password for %s", dn)
return True
@transaction.atomic
def save(self, *args, **kwargs):

View File

@ -0,0 +1,16 @@
"""
This module defines the URL patterns for operating system user related views.
"""
from __future__ import absolute_import, unicode_literals
from django.conf.urls import patterns, url
from .views import SetOsUserPassword
urlpatterns = patterns(
'',
url(r'^(?P<slug>[\w0-9@.+-_]+)/setpassword$', SetOsUserPassword.as_view(),
name='set_osuser_password'),
)

View File

@ -0,0 +1,45 @@
"""
This module defines the views for gnuviechadmin operating system user handling.
"""
from __future__ import unicode_literals, absolute_import
from django.shortcuts import redirect
from django.views.generic import UpdateView
from django.utils.translation import ugettext as _
from django.contrib import messages
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
from .forms import ChangeOsUserPasswordForm
from .models import User
class SetOsUserPassword(StaffOrSelfLoginRequiredMixin, UpdateView):
"""
This view is used for setting a new operating system user password.
"""
model = User
slug_field = 'username'
template_name_suffix = '_setpassword'
context_object_name = 'osuser'
form_class = ChangeOsUserPasswordForm
def get_customer_object(self):
return self.get_object().customer
def get_context_data(self, *args, **kwargs):
context = super(SetOsUserPassword, self).get_context_data(
*args, **kwargs)
context['customer'] = self.get_customer_object()
return context
def form_valid(self, form):
osuser = form.save()
messages.success(
self.request,
_("New password for {username} has been set successfully.").format(
username=osuser.username
))
return redirect(osuser.customerhostingpackage)

View File

@ -22,7 +22,7 @@
<tbody>
{% for package in hosting_packages %}
<tr>
<th>{{ package.name }}</th>
<th><a href="{{ package.get_absolute_url }}" title="{% blocktrans with packagename=package.name %}Show details for {{ packagename }}{% endblocktrans %}">{{ package.name }}</a></th>
<th>
{% with diskspace=package.get_disk_space %}
<span title="{% blocktrans %}The reserved disk space for your hosting package is {{ diskspace }} bytes.{% endblocktrans %}">{{ diskspace|filesizeformat }}</span>

View File

@ -0,0 +1,48 @@
{% extends "hostingpackages/base.html" %}
{% load i18n %}
{% block title %}{{ block.super }} - {% spaceless %}
{% if user == customer %}
{% blocktrans with package=hostingpackage.name %}Details for your Hosting Package {{ package }}{% endblocktrans %}
{% else %}
{% blocktrans with package=hostingpackage.name full_name=customer.get_full_name %}Details for Hosting Package {{ package }} of {{ full_name }}{% endblocktrans %}
{% endif %}
{% endspaceless %}{% endblock title %}
{% block page_title %}{% blocktrans with package=hostingpackage.name %}Details of Hosting Package {{ package }}{% endblocktrans %}{% endblock page_title %}
{% block content %}
<div class="row">
<div class="col-lg-6 col-md-6 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading">
{% trans "Hosting Package Information" %}<div class="pull-right"><a class="panel-title" href="#" title="{% trans "Edit Hosting Package Information" %}"><i class="glyphicon glyphicon-cog"></i></a></div>
</div>
<dl class="panel-body dl-horizontal">
<dt>{% trans "Name" %}</dt>
<dd>{{ hostingpackage.name }}</dd>
<dt>{% trans "Description" %}</dt>
<dd>{{ hostingpackage.description|default:"-" }}</dd>
<dt>{% trans "Disk space" %}</dt>
{% with diskspace=hostingpackage.get_disk_space %}
<dd title="{% blocktrans %}The reserved disk space for your hosting package is {{ diskspace }} bytes.{% endblocktrans %}">{{ diskspace|filesizeformat }}</dd>
{% endwith %}
<dt>{% trans "Mailboxes" %}</dt>
<dd>{% blocktrans with num=hostingpackage.get_used_mailboxes total=hostingpackage.get_mailboxes %}{{ num }} of {{ total }} in use{% endblocktrans %}</dd>
<dt>{% if hostingpackage.osuser.is_sftp_user %}{% trans "SFTP username" %}{% else %}{% trans "SSH/SFTP username" %}{% endif %}</dt>
<dd>{{ hostingpackage.osuser.username }}</dd>
<dt>{% trans "Upload server" %}</dt>
<dd>{{ uploadserver }}</dd>
</dl>
</div>
</div>
<div class="col-lg-6 col-md-6 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading">{% trans "Hosting Package Actions" %}</div>
<ul class="list-group">
<li class="list-group-item"><a href="{% url "set_osuser_password" slug=hostingpackage.osuser.username %}">{% if hostingpackage.osuser.is_sftp %}{% trans "Set SFTP password" %}{% else %}{% trans "Set SSH/SFTP password" %}{% endif %}</a></li>
</ul>
</div>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1 @@
{% extends "base.html" %}

View File

@ -0,0 +1,30 @@
{% extends "osusers/base.html" %}
{% load i18n crispy_forms_tags %}
{% block title %}{{ block.super }} - {% spaceless %}
{% if customer == user %}
{% blocktrans with osuser=osuser.username %}Set new password for user {{ osuser }}{% endblocktrans %}
{% else %}
{% blocktrans with osuser=osuser.username full_name=customer.get_full_name %}Set new password for user {{ osuser }} of customer {{ full_name }}{% endblocktrans %}
{% endif %}
{% endspaceless %}{% endblock title %}
{% block page_title %}{% spaceless %}
{% if customer == user %}
{% blocktrans with osuser=osuser.username %}Set new password for user {{ osuser }}{% endblocktrans %}
{% else %}
{% blocktrans with osuser=osuser.username full_name=customer.get_full_name %}Set new password for user {{ osuser }} of customer {{ full_name }}{% endblocktrans %}
{% endif %}
{% endspaceless %}{% endblock page_title %}
{% block content %}
{% crispy form %}
{% endblock content %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$('input[type=password]').val('');
$('input[type=password]').first().focus();
});
</script>
{% endblock extra_js %}