From 888a2463c437dbcfe5343c760b7aa8818d4d67f0 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 22 Jan 2015 00:19:30 +0100 Subject: [PATCH] create system user when creating a new hosting package --- gnuviechadmin/gnuviechadmin/settings/base.py | 1 + gnuviechadmin/hostingpackages/admin.py | 1 + gnuviechadmin/hostingpackages/models.py | 64 +++++++++++++++++-- .../hostingpackages/tests/__init__.py | 0 .../hostingpackages/tests/test_models.py | 31 +++++++++ gnuviechadmin/hostingpackages/views.py | 23 +++++-- 6 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 gnuviechadmin/hostingpackages/tests/__init__.py create mode 100644 gnuviechadmin/hostingpackages/tests/test_models.py diff --git a/gnuviechadmin/gnuviechadmin/settings/base.py b/gnuviechadmin/gnuviechadmin/settings/base.py index 09b75ad..3237cb2 100644 --- a/gnuviechadmin/gnuviechadmin/settings/base.py +++ b/gnuviechadmin/gnuviechadmin/settings/base.py @@ -352,4 +352,5 @@ OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID')) OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX') OSUSER_HOME_BASEPATH = get_env_variable('GVA_OSUSER_HOME_BASEPATH') OSUSER_DEFAULT_SHELL = get_env_variable('GVA_OSUSER_DEFAULT_SHELL') +OSUSER_DEFAULT_GROUPS = ['sftponly'] ########## END CUSTOM APP CONFIGURATION diff --git a/gnuviechadmin/hostingpackages/admin.py b/gnuviechadmin/hostingpackages/admin.py index a5fd3a7..53ba97a 100644 --- a/gnuviechadmin/hostingpackages/admin.py +++ b/gnuviechadmin/hostingpackages/admin.py @@ -96,6 +96,7 @@ class CustomerHostingPackageAdmin(admin.ModelAdmin): CustomerMailboxOptionInline, CustomerUserDatabaseOptionInline, ] + list_display = ['name', 'customer', 'osuser'] def get_form(self, request, obj=None, **kwargs): """ diff --git a/gnuviechadmin/hostingpackages/models.py b/gnuviechadmin/hostingpackages/models.py index 20698ef..b665162 100644 --- a/gnuviechadmin/hostingpackages/models.py +++ b/gnuviechadmin/hostingpackages/models.py @@ -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.db import transaction from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _, ungettext @@ -13,7 +14,11 @@ from model_utils import Choices from model_utils.models import TimeStampedModel from managemails.models import Mailbox -from osusers.models import User as OsUser +from osusers.models import ( + AdditionalGroup, + Group, + User as OsUser, +) from userdbs.models import DB_TYPES @@ -175,14 +180,14 @@ class CustomerHostingPackageManager(models.Manager): """ package = CustomerHostingPackage( customer=customer, template=template, name=name) - for attrname in ('description', 'diskspace', 'diskspace_unit', - 'mailboxcount'): - setattr(package, attrname, getattr(template, attrname)) + package.description = template.description + package.copy_template_attributes() if 'commit' in kwargs and kwargs['commit'] is True: package.save(**kwargs) return package +@python_2_unicode_compatible class CustomerHostingPackage(HostingPackageBase): """ This class defines customer specific hosting packages. @@ -208,7 +213,20 @@ class CustomerHostingPackage(HostingPackageBase): verbose_name = _('customer hosting package') verbose_name_plural = _('customer hosting packages') - def get_disk_space(self): + def __str__(self): + return _("{name} for {customer}").format( + name=self.name, customer=self.customer + ) + + def copy_template_attributes(self): + """ + Copy the attributes of the hosting package's template to the package. + + """ + for attrname in ('diskspace', 'diskspace_unit', 'mailboxcount'): + setattr(self, attrname, getattr(self.template, attrname)) + + def get_disk_space(self, unit=None): """ Get the total disk space reserved for this hosting package and all its additional disk space options. @@ -233,7 +251,16 @@ class CustomerHostingPackage(HostingPackageBase): DISK_SPACE_FACTORS[min_unit][option.diskspace_unit] * diskspace) + option.diskspace min_unit = option.diskspace_unit - return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024**2 + if unit is None: + return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024**2 + if unit > min_unit: + return DISK_SPACE_FACTORS[unit][min_unit] * diskspace + return DISK_SPACE_FACTORS[min_unit][unit] * diskspace + + def get_quota(self): + soft = 1024 * self.get_disk_space(DISK_SPACE_UNITS.M) + hard = soft * 105 / 100 + return (soft, hard) def get_used_mailboxes(self): """ @@ -269,6 +296,31 @@ class CustomerHostingPackage(HostingPackageBase): number=models.Sum('number') ).all() + @transaction.atomic + def save(self, *args, **kwargs): + """ + Save the hosting package to the database. + + If this is a new hosting package a new operating system user is + created and assigned to the hosting package. + + :param args: positional arguments to be passed on to + :py:meth:`django.db.Model.save` + :param kwargs: keyword arguments to be passed on to + :py:meth:`django.db.Model.save` + :return: self + :rtype: :py:class:`CustomerHostingPackage` + + """ + if self.pk is None: + self.copy_template_attributes() + self.osuser = OsUser.objects.create_user(self.customer) + for group in settings.OSUSER_DEFAULT_GROUPS: + AdditionalGroup.objects.create( + user=self.osuser, group=Group.objects.get(groupname=group) + ) + return super(CustomerHostingPackage, self).save(*args, **kwargs) + class CustomerHostingPackageOption(TimeStampedModel): """ diff --git a/gnuviechadmin/hostingpackages/tests/__init__.py b/gnuviechadmin/hostingpackages/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gnuviechadmin/hostingpackages/tests/test_models.py b/gnuviechadmin/hostingpackages/tests/test_models.py new file mode 100644 index 0000000..b762d05 --- /dev/null +++ b/gnuviechadmin/hostingpackages/tests/test_models.py @@ -0,0 +1,31 @@ +""" +Test for models. + +""" + +from django.test import TestCase + +from hostingpackages.models import ( + DISK_SPACE_UNITS, + CustomerHostingPackage, +) + + +class CustomerHostingPackageTest(TestCase): + def test_get_disk_space_bytes(self): + package = CustomerHostingPackage( + diskspace=10, diskspace_unit=DISK_SPACE_UNITS.G + ) + self.assertEqual(package.get_disk_space(), 10 * 1024 * 1024**2) + + def test_get_disk_space_mib(self): + package = CustomerHostingPackage( + diskspace=10, diskspace_unit=DISK_SPACE_UNITS.G + ) + self.assertEqual(package.get_disk_space(DISK_SPACE_UNITS.M), 10 * 1024) + + def test_get_quota(self): + package = CustomerHostingPackage( + diskspace=256, diskspace_unit=DISK_SPACE_UNITS.M + ) + self.assertEqual(package.get_quota(), (262144, 275251)) diff --git a/gnuviechadmin/hostingpackages/views.py b/gnuviechadmin/hostingpackages/views.py index 3a4a077..a29c098 100644 --- a/gnuviechadmin/hostingpackages/views.py +++ b/gnuviechadmin/hostingpackages/views.py @@ -5,8 +5,11 @@ This module defines views related to hosting packages. from __future__ import absolute_import, unicode_literals from django.core.urlresolvers import reverse +from django.shortcuts import redirect +from django.utils.translation import ugettext as _ from django.views.generic.edit import CreateView from django.contrib.auth import get_user_model +from django.contrib import messages from braces.views import ( LoginRequiredMixin, @@ -34,14 +37,26 @@ class CreateHostingPackage( kwargs.update(self.kwargs) return kwargs + def _get_customer(self): + return get_user_model().objects.get(username=self.kwargs['user']) + + def get_context_data(self, **kwargs): context = super(CreateHostingPackage, self).get_context_data(**kwargs) - customer = get_user_model().objects.get(username=self.kwargs['user']) - context['customer'] = customer + context['customer'] = self._get_customer() return context def get_success_url(self): - return reverse('customer_dashboard', slug=self.kwargs['user']) + return reverse( + 'customer_dashboard', kwargs={'slug': self.kwargs['user']}) def form_valid(self, form): - return super(CreateHostingPackage, self).form_valid(form) + hostingpackage = form.save(commit=False) + hostingpackage.customer = self._get_customer() + hostingpackage.save() + messages.success( + self.request, + _('Started setup of new hosting package {name}.').format( + name=hostingpackage.name) + ) + return redirect(self.get_success_url())