diff --git a/docs/changelog.rst b/docs/changelog.rst index db3a407..5437e41 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,14 @@ Changelog ========= +* :release:`0.8.0 <2015-01-26>` +* :feature:`-` implement deletion of user database and database users +* :feature:`-` implement password changes for database users +* :feature:`-` implement setup of user databases +* :support:`-` performance improvement for hosting package detail view +* :support:`-` move HostingPackageAndCustomerMixin from managemails.views to + gvawebcore.views + * :release:`0.7.0 <2015-01-25>` * :feature:`-` implement mail address target editing * :feature:`-` implement mail address deletion diff --git a/docs/code/gvawebcore.rst b/docs/code/gvawebcore.rst index 7fdd1b0..db3d760 100644 --- a/docs/code/gvawebcore.rst +++ b/docs/code/gvawebcore.rst @@ -9,3 +9,10 @@ .. automodule:: gvawebcore.forms :members: + + +:py:mod:`views ` +---------------------------------- + +.. automodule:: gvawebcore.views + :members: diff --git a/docs/code/userdbs.rst b/docs/code/userdbs.rst index 3ca1778..c7af8a1 100644 --- a/docs/code/userdbs.rst +++ b/docs/code/userdbs.rst @@ -17,6 +17,13 @@ .. automodule:: userdbs.apps +:py:mod:`forms ` +------------------------------- + +.. automodule:: userdbs.forms + :members: + + :py:mod:`models ` --------------------------------- @@ -34,3 +41,17 @@ .. automodule:: userdbs.templatetags.userdb :members: + + +:py:mod:`urls ` +----------------------------- + +.. automodule:: userdbs.urls + :members: + + +:py:mod:`views ` +------------------------------- + +.. automodule:: userdbs.views + :members: diff --git a/docs/conf.py b/docs/conf.py index 9498dd1..6ff2870 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,9 +60,9 @@ copyright = u'2014, 2015 Jan Dittberner' # built documents. # # The short X.Y version. -version = '0.7' +version = '0.8' # The full version, including alpha/beta/rc tags. -release = '0.7.0' +release = '0.8.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/gnuviechadmin/gnuviechadmin/urls.py b/gnuviechadmin/gnuviechadmin/urls.py index d8f621d..4dad925 100644 --- a/gnuviechadmin/gnuviechadmin/urls.py +++ b/gnuviechadmin/gnuviechadmin/urls.py @@ -10,6 +10,7 @@ urlpatterns = patterns( '', url(r'', include('dashboard.urls')), url(r'^accounts/', include('allauth.urls')), + url(r'^database/', include('userdbs.urls')), url(r'^domains/', include('domains.urls')), url(r'^hosting/', include('hostingpackages.urls')), url(r'^mail/', include('managemails.urls')), diff --git a/gnuviechadmin/gvawebcore/views.py b/gnuviechadmin/gvawebcore/views.py new file mode 100644 index 0000000..6e22e29 --- /dev/null +++ b/gnuviechadmin/gvawebcore/views.py @@ -0,0 +1,26 @@ +""" +This module defines common view code to be used by multiple gnuviechadmin apps. + +""" +from __future__ import absolute_import, unicode_literals + +from django.shortcuts import get_object_or_404 +from hostingpackages.models import CustomerHostingPackage + + +class HostingPackageAndCustomerMixin(object): + """ + Mixin for views that gets the hosting package instance from the URL + keyword argument 'package'. + + """ + hosting_package_kwarg = 'package' + """Keyword argument used to find the hosting package in the URL.""" + + def get_hosting_package(self): + return get_object_or_404( + CustomerHostingPackage, + pk=int(self.kwargs[self.hosting_package_kwarg])) + + def get_customer_object(self): + return self.get_hosting_package().customer diff --git a/gnuviechadmin/hostingpackages/views.py b/gnuviechadmin/hostingpackages/views.py index 455e717..75e7cb8 100644 --- a/gnuviechadmin/hostingpackages/views.py +++ b/gnuviechadmin/hostingpackages/views.py @@ -114,6 +114,12 @@ class CustomerHostingPackageDetails(StaffOrSelfLoginRequiredMixin, DetailView): context.update({ 'customer': self.get_customer_object(), 'uploadserver': settings.OSUSER_UPLOAD_SERVER, + 'databases': context['hostingpackage'].databases, + 'osuser': context['hostingpackage'].osuser, + 'hostingoptions': + context['hostingpackage'].get_hostingoptions(), + 'domains': context['hostingpackage'].domains.all(), + 'mailboxes': context['hostingpackage'].mailboxes, }) return context diff --git a/gnuviechadmin/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/locale/de/LC_MESSAGES/django.po index 703a776..69d5683 100644 --- a/gnuviechadmin/locale/de/LC_MESSAGES/django.po +++ b/gnuviechadmin/locale/de/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: gnuviechadmin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-25 22:13+0100\n" -"PO-Revision-Date: 2015-01-25 22:20+0100\n" +"POT-Creation-Date: 2015-01-26 13:42+0100\n" +"PO-Revision-Date: 2015-01-26 13:51+0100\n" "Last-Translator: Jan Dittberner \n" "Language-Team: Jan Dittberner \n" "Language: de\n" @@ -785,30 +785,38 @@ msgid "Add mailbox" msgstr "Postfach hinzufügen" #: templates/hostingpackages/customerhostingpackage_detail.html:168 -msgid "Database type" -msgstr "Datenbanktyp" - -#: templates/hostingpackages/customerhostingpackage_detail.html:168 -msgid "Type" -msgstr "Typ" - -#: templates/hostingpackages/customerhostingpackage_detail.html:169 msgid "Database name" msgstr "Datenbankname" -#: templates/hostingpackages/customerhostingpackage_detail.html:170 +#: templates/hostingpackages/customerhostingpackage_detail.html:169 msgid "Database user" msgstr "Datenbanknutzer" +#: templates/hostingpackages/customerhostingpackage_detail.html:170 +msgid "Database type" +msgstr "Datenbanktyp" + +#: templates/hostingpackages/customerhostingpackage_detail.html:170 +msgid "Type" +msgstr "Typ" + #: templates/hostingpackages/customerhostingpackage_detail.html:171 msgid "Database actions" msgstr "Datenbankaktionen" -#: templates/hostingpackages/customerhostingpackage_detail.html:186 +#: templates/hostingpackages/customerhostingpackage_detail.html:181 +msgid "Set database user password" +msgstr "Datenbanknutzerpasswort setzen" + +#: templates/hostingpackages/customerhostingpackage_detail.html:182 +msgid "Delete database" +msgstr "Datenbank löschen" + +#: templates/hostingpackages/customerhostingpackage_detail.html:189 msgid "There are no databases assigned to this hosting package yet." msgstr "Diesem Hostingpaket sind noch keine Datenbanken zugeordnet." -#: templates/hostingpackages/customerhostingpackage_detail.html:189 +#: templates/hostingpackages/customerhostingpackage_detail.html:192 msgid "Add database" msgstr "Datenbank hinzufügen" @@ -839,10 +847,12 @@ msgid "Do you really want to delete the mail address %(mailaddress)s?" msgstr "Wollen Sie die E-Mailadresse %(mailaddress)s wirklich löschen?" #: templates/managemails/mailaddress_confirm_delete.html:28 +#: templates/userdbs/userdatabase_confirm_delete.html:29 msgid "Yes, do it!" msgstr "Ja, so soll es sein!" #: templates/managemails/mailaddress_confirm_delete.html:29 +#: templates/userdbs/userdatabase_confirm_delete.html:30 msgid "Cancel" msgstr "Abbrechen" @@ -1021,6 +1031,93 @@ msgstr "" "%(site_name)s zu nutzen. Als letzten Schritt füllen Sie bitte folgendes " "Formular aus:" +#: templates/userdbs/databaseuser_setpassword.html:6 +#, python-format +msgid "Set Database User Password for %(dbuser)s" +msgstr "Neues Datenbanknutzerpasswort für %(dbuser)s setzen" + +#: templates/userdbs/databaseuser_setpassword.html:8 +#, python-format +msgid "Set Database User Password for %(dbuser)s of Customer %(full_name)s" +msgstr "" +"Neues Datenbanknutzerpasswort für %(dbuser)s des Kunden %(full_name)s setzen." + +#: templates/userdbs/databaseuser_setpassword.html:14 +#, python-format +msgid "Set Database User Password for %(dbuser)s" +msgstr "Datenbanknutzerpasswort setzen für %(dbuser)s" + +#: templates/userdbs/databaseuser_setpassword.html:16 +#, python-format +msgid "" +"Set Database User Password for %(dbuser)s of Customer %(full_name)s" +msgstr "" +"Neues Datenbanknutzerpasswort setzen für %(dbuser)s des Kunden " +"%(full_name)s" + +#: templates/userdbs/databaseuser_setpassword.html:21 +msgid "Please specify the new password for your database user." +msgstr "Bitte geben Sie das neue Passwort für Ihren Datenbanknutzer ein." + +#: templates/userdbs/databaseuser_setpassword.html:21 +msgid "Please specify the new password of the database user." +msgstr "Bitte geben Sie das neue Passwort für den Datenbanknutzer ein." + +#: templates/userdbs/userdatabase_confirm_delete.html:6 +#, python-format +msgid "Delete Database %(database)s" +msgstr "Datenbank %(database)s löschen" + +#: templates/userdbs/userdatabase_confirm_delete.html:8 +#, python-format +msgid "Delete Database %(database)s of customer %(full_name)s" +msgstr "Datenbank %(database)s des Kunden %(full_name)s löschen" + +#: templates/userdbs/userdatabase_confirm_delete.html:14 +#, python-format +msgid "Delete Database %(database)s" +msgstr "Datenbank löschen %(database)s" + +#: templates/userdbs/userdatabase_confirm_delete.html:16 +#, python-format +msgid "Delete Database %(database)s of customer %(full_name)s" +msgstr "Datenbank löschen %(database)s des Kunden %(full_name)s" + +#: templates/userdbs/userdatabase_confirm_delete.html:23 +#, python-format +msgid "Do you really want to delete the database %(database)s?" +msgstr "Wollen Sie die Datenbank %(database)s wirklich löschen?" + +#: templates/userdbs/userdatabase_confirm_delete.html:26 +msgid "" +"When you confirm the deletion the database will be removed from the database " +"server. All data in the database will be lost! If the " +"database user assigned to that database has no other databases assigned it " +"will be deleted too." +msgstr "" +"Wenn Sie die Löschung bestätigen, wird die Datenbank vom Datenbankserver " +"entfernt. Alle Daten in der Datenbank gehen verloren! Wenn " +"dem zu dieser Datenbank gehörigen Datenbanknutzer keine weiteren Datenbanken " +"zugeordnet sind, wird er ebenfalls gelöscht." + +#: templates/userdbs/userdatabase_create.html:6 +#: templates/userdbs/userdatabase_create.html:14 +msgid "Add new Database" +msgstr "Neue Datenbank hinzufügen" + +#: templates/userdbs/userdatabase_create.html:8 +#: templates/userdbs/userdatabase_create.html:16 +#, python-format +msgid "Add new Database for Customer %(full_name)s" +msgstr "Neue Datenbank für Kunde %(full_name)s anlegen" + +#: templates/userdbs/userdatabase_create.html:21 +msgid "Please enter a password for a new database user for your database." +msgstr "" +"Bitte geben Sie ein Passwort für den neuen Datenbanknutzer für Ihre " +"Datenbank ein." + #, fuzzy #~| msgid "Password Reset" #~ msgid "Password (again)" diff --git a/gnuviechadmin/managemails/views.py b/gnuviechadmin/managemails/views.py index 8fed77f..e5590b1 100644 --- a/gnuviechadmin/managemails/views.py +++ b/gnuviechadmin/managemails/views.py @@ -15,8 +15,7 @@ from django.views.generic.edit import ( from django.contrib import messages from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin - -from hostingpackages.models import CustomerHostingPackage +from gvawebcore.views import HostingPackageAndCustomerMixin from domains.models import MailDomain from .forms import ( @@ -33,25 +32,6 @@ from .models import ( ) -class HostingPackageAndCustomerMixin(object): - """ - Mixin for views that gets the hosting package instance from the URL - keyword argument 'package'. - - """ - hosting_package_kwarg = 'package' - """Keyword argument used to find the hosting package in the URL.""" - - def get_hosting_package(self): - return get_object_or_404( - CustomerHostingPackage, - pk=int(self.kwargs[self.hosting_package_kwarg])) - - def get_customer_object(self): - return self.get_hosting_package().customer - - - class CreateMailbox( HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView ): diff --git a/gnuviechadmin/static/css/gnuviechadmin.css b/gnuviechadmin/static/css/gnuviechadmin.css index 5be5286..f165388 100644 --- a/gnuviechadmin/static/css/gnuviechadmin.css +++ b/gnuviechadmin/static/css/gnuviechadmin.css @@ -1 +1,10 @@ /*! project specific CSS goes here. */ +table thead th.actions-column { + width: 5em; +} +table thead th.status-column { + width: 5em; +} +table thead th.name-column { + width: 15em; +} diff --git a/gnuviechadmin/templates/hostingpackages/customerhostingpackage_detail.html b/gnuviechadmin/templates/hostingpackages/customerhostingpackage_detail.html index eae6752..0f13250 100644 --- a/gnuviechadmin/templates/hostingpackages/customerhostingpackage_detail.html +++ b/gnuviechadmin/templates/hostingpackages/customerhostingpackage_detail.html @@ -38,8 +38,8 @@
{% trans "Mailboxes" %}
{% blocktrans with num=hostingpackage.used_mailbox_count total=hostingpackage.mailbox_count %}{{ num }} of {{ total }} in use{% endblocktrans %}
-
{% if hostingpackage.osuser.is_sftp_user %}{% trans "SFTP username" %}{% else %}{% trans "SSH/SFTP username" %}{% endif %}
-
{{ hostingpackage.osuser.username }}
+
{% if osuser.is_sftp_user %}{% trans "SFTP username" %}{% else %}{% trans "SSH/SFTP username" %}{% endif %}
+
{{ osuser.username }}
{% trans "Upload server" %}
{{ uploadserver }}
@@ -48,9 +48,9 @@
{% trans "Hosting Package Options" %}
- {% if hostingpackage.customerhostingpackageoption_set.exists %} + {% if hostingoptions %}
    - {% for opt in hostingpackage.get_hostingoptions %} + {% for opt in hostingoptions %}
  • {{ opt }}
  • {% endfor %}
@@ -67,7 +67,7 @@
{% trans "Hosting Package Actions" %}
@@ -76,18 +76,18 @@
{% trans "Domains" %}
- {% if hostingpackage.domains %} + {% if domains %} - + - + - {% for domain in hostingpackage.domains.all %} + {% for domain in domains %} {% if domain.domain.maildomain %} @@ -126,18 +126,18 @@
{% trans "E-Mail-Accounts" %}
- {% if hostingpackage.mailboxes %} + {% if mailboxes %}
{% trans "Domain name" %}{% trans "Domain name" %} {% trans "Mail addresses" %} {% trans "Websites" %}{% trans "Actions" %}{% trans "Actions" %}
{{ domain.domain }}
- + - - + + - {% for mailbox in hostingpackage.mailboxes %} + {% for mailbox in mailboxes %} @@ -161,23 +161,26 @@
{% trans "Databases" %}
- {% if hostingpackage.databases %} + {% if databases %}
{% trans "Mailbox" %}{% trans "Mailbox" %} {% trans "Mail addresses" %}{% trans "Active" %}{% trans "Actions" %}{% trans "Active" %}{% trans "Actions" %}
{{ mailbox.username }} {{ mailbox.mailaddresses|join:", " }}
+ + - - - + - {% for database in hostingpackage.databases %} + {% for database in databases %} - - - + + + {% endfor %} @@ -186,7 +189,7 @@

{% trans "There are no databases assigned to this hosting package yet." %}

{% endif %} {% if hostingpackage.may_add_database %} -

{% trans "Add database" %}

+

{% trans "Add database" %}

{% endif %} diff --git a/gnuviechadmin/templates/userdbs/base.html b/gnuviechadmin/templates/userdbs/base.html new file mode 100644 index 0000000..94d9808 --- /dev/null +++ b/gnuviechadmin/templates/userdbs/base.html @@ -0,0 +1 @@ +{% extends "base.html" %} diff --git a/gnuviechadmin/templates/userdbs/databaseuser_setpassword.html b/gnuviechadmin/templates/userdbs/databaseuser_setpassword.html new file mode 100644 index 0000000..37d58dc --- /dev/null +++ b/gnuviechadmin/templates/userdbs/databaseuser_setpassword.html @@ -0,0 +1,31 @@ +{% extends "userdbs/base.html" %} +{% load i18n crispy_forms_tags %} + +{% block title %}{{ block.super }} - {% spaceless %} +{% if customer == user %} +{% blocktrans with dbuser=dbuser.name %}Set Database User Password for {{ dbuser }}{% endblocktrans %} +{% else %} +{% blocktrans with dbuser=dbuser.name full_name=customer.get_full_name %}Set Database User Password for {{ dbuser }} of Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock title %} + +{% block page_title %}{% spaceless %} +{% if customer == user %} +{% blocktrans with dbuser=dbuser.name %}Set Database User Password for {{ dbuser }}{% endblocktrans %} +{% else %} +{% blocktrans with dbuser=dbuser.name full_name=customer.get_full_name %}Set Database User Password for {{ dbuser }} of Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock page_title %} + +{% block content %} +

{% if customer == user %}{% trans "Please specify the new password for your database user." %}{% else %}{% trans "Please specify the new password of the database user." %}{% endif %} +{% crispy form %} +{% endblock content %} + +{% block extra_js %} + +{% endblock extra_js %} diff --git a/gnuviechadmin/templates/userdbs/userdatabase_confirm_delete.html b/gnuviechadmin/templates/userdbs/userdatabase_confirm_delete.html new file mode 100644 index 0000000..4c71342 --- /dev/null +++ b/gnuviechadmin/templates/userdbs/userdatabase_confirm_delete.html @@ -0,0 +1,34 @@ +{% extends "userdbs/base.html" %} +{% load i18n %} + +{% block title %}{{ block.super }} - {% spaceless %} +{% if user == customer %} +{% blocktrans with database=database.db_name %}Delete Database {{ database }}{% endblocktrans %} +{% else %} +{% blocktrans with database=database.db_name full_name=customer.get_full_name %}Delete Database {{ database }} of customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock title %} + +{% block page_title %}{% spaceless %} +{% if user == customer %} +{% blocktrans with database=database.db_name %}Delete Database {{ database }}{% endblocktrans %} +{% else %} +{% blocktrans with database=database.db_name full_name=customer.get_full_name %}Delete Database {{ database }} of customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock page_title %} + +{% block content %} +

+
+ {% blocktrans with database=database.db_name %}Do you really want to delete the database {{ database }}?{% endblocktrans %} +
+
+

{% blocktrans %}When you confirm the deletion the database will be removed from the database server. All data in the database will be lost! If the database user assigned to that database has no other databases assigned it will be deleted too.{% endblocktrans %}

+
+ {% csrf_token %} + + {% trans "Cancel" %} + +
+
+{% endblock content %} diff --git a/gnuviechadmin/templates/userdbs/userdatabase_create.html b/gnuviechadmin/templates/userdbs/userdatabase_create.html new file mode 100644 index 0000000..48356a4 --- /dev/null +++ b/gnuviechadmin/templates/userdbs/userdatabase_create.html @@ -0,0 +1,31 @@ +{% extends "userdbs/base.html" %} +{% load i18n crispy_forms_tags %} + +{% block title %}{{ block.super }} - {% spaceless %} +{% if user == customer %} +{% blocktrans %}Add new Database{% endblocktrans %} +{% else %} +{% blocktrans with full_name=customer.get_full_name %}Add new Database for Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock title %} + +{% block page_title %}{% spaceless %} +{% if user == customer %} +{% blocktrans %}Add new Database{% endblocktrans %} +{% else %} +{% blocktrans with full_name=customer.get_full_name %}Add new Database for Customer {{ full_name }}{% endblocktrans %} +{% endif %} +{% endspaceless %}{% endblock page_title %} + +{% block content %} +

{% blocktrans %}Please enter a password for a new database user for your database.{% endblocktrans %}

+{% crispy form %} +{% endblock content %} + +{% block extra_js %} + +{% endblock %} diff --git a/gnuviechadmin/userdbs/forms.py b/gnuviechadmin/userdbs/forms.py new file mode 100644 index 0000000..2c24743 --- /dev/null +++ b/gnuviechadmin/userdbs/forms.py @@ -0,0 +1,92 @@ +""" +This module defines form classes for user database editing. + +""" +from __future__ import absolute_import, unicode_literals + +from django import forms +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext_lazy as _ + +from crispy_forms.helper import FormHelper +from crispy_forms.layout import ( + Submit, +) + +from .models import ( + DB_TYPES, + DatabaseUser, + UserDatabase, +) +from gvawebcore.forms import PasswordModelFormMixin + + +class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin): + """ + This form is used to create new user database instances. + + """ + db_type = forms.TypedChoiceField( + label=_('Database type'), + choices=DB_TYPES, + widget=forms.RadioSelect, + coerce=int, + ) + + class Meta: + model = UserDatabase + fields = [] + + def __init__(self, *args, **kwargs): + self.hosting_package = kwargs.pop('hostingpackage') + self.available_dbtypes = kwargs.pop('dbtypes') + super(AddUserDatabaseForm, self).__init__(*args, **kwargs) + self.fields['db_type'].choices = self.available_dbtypes + if len(self.available_dbtypes) == 1: + self.fields['db_type'].initial = self.available_dbtypes[0][0] + self.fields['db_type'].widget = forms.HiddenInput() + self.helper = FormHelper() + self.helper.form_action = reverse( + 'add_userdatabase', kwargs={'package': self.hosting_package.id}) + self.helper.add_input(Submit('submit', _('Create database'))) + + def save(self, commit=True): + """ + Setup a new database with a new database user with the specified + password. + + :param boolean commit: whether to save the created database + :return: database instance + :rtype: :py:class:`userdbs.models.UserDatabase` + + """ + data = self.cleaned_data + self.instance = UserDatabase.objects.create_userdatabase_with_user( + data['db_type'], self.hosting_package.osuser, + password=data['password1'], commit=commit) + return super(AddUserDatabaseForm, self).save(commit) + + +class ChangeDatabaseUserPasswordForm(forms.ModelForm, PasswordModelFormMixin): + """ + This form is used to change the password of a database user. + + """ + class Meta: + model = DatabaseUser + fields = [] + + def __init__(self, *args, **kwargs): + self.hosting_package = kwargs.pop('hostingpackage') + super(ChangeDatabaseUserPasswordForm, self).__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.form_action = reverse( + 'change_dbuser_password', kwargs={ + 'slug': self.instance.name, + 'package': self.hosting_package.id, + }) + self.helper.add_input(Submit('submit', _('Set password'))) + + def save(self, commit=True): + self.instance.set_password(self.cleaned_data['password1']) + return super(ChangeDatabaseUserPasswordForm, self).save() diff --git a/gnuviechadmin/userdbs/locale/de/LC_MESSAGES/django.po b/gnuviechadmin/userdbs/locale/de/LC_MESSAGES/django.po index d203608..c05e5d4 100644 --- a/gnuviechadmin/userdbs/locale/de/LC_MESSAGES/django.po +++ b/gnuviechadmin/userdbs/locale/de/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: gnuviechadmin userdbs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-17 15:59+0100\n" -"PO-Revision-Date: 2015-01-17 16:00+0100\n" +"POT-Creation-Date: 2015-01-26 13:42+0100\n" +"PO-Revision-Date: 2015-01-26 13:44+0100\n" "Last-Translator: Jan Dittberner \n" "Language-Team: Jan Dittberner \n" "Language: de\n" @@ -31,6 +31,18 @@ msgstr "Ausgewählte Nutzerdatenbanken löschen" msgid "Database Users and their Databases" msgstr "Datenbanknutzer und ihre Datenbanken" +#: userdbs/forms.py:30 +msgid "Database type" +msgstr "Datenbanktyp" + +#: userdbs/forms.py:51 +msgid "Create database" +msgstr "Datenbank anlegen" + +#: userdbs/forms.py:88 +msgid "Set password" +msgstr "Passwort setzen" + #: userdbs/models.py:32 msgid "PostgreSQL" msgstr "PostgreSQL" @@ -47,7 +59,7 @@ msgstr "Benutzername" msgid "database type" msgstr "Datenbanktyp" -#: userdbs/models.py:114 userdbs/models.py:230 +#: userdbs/models.py:114 userdbs/models.py:250 msgid "database user" msgstr "Datenbanknutzer" @@ -55,14 +67,29 @@ msgstr "Datenbanknutzer" msgid "database users" msgstr "Datenbanknutzer" -#: userdbs/models.py:229 +#: userdbs/models.py:249 msgid "database name" msgstr "Datenbankname" -#: userdbs/models.py:236 +#: userdbs/models.py:256 msgid "user database" msgstr "Nutzerdatenbank" -#: userdbs/models.py:237 +#: userdbs/models.py:257 msgid "user specific database" msgstr "nutzerspezifische Datenbank" + +#: userdbs/views.py:63 +#, python-brace-format +msgid "Successfully create new {type} database {dbname} for user {dbuser}" +msgstr "" +"Neue {type}-Datenbank {dbname} für Benutzer {dbuser} erfolgreich angelegt" + +#: userdbs/views.py:100 +#, python-brace-format +msgid "Successfully changed password of database user {dbuser}" +msgstr "Passwort des Datenbanknutzers {dbuser} wurde erfolgreich geändert." + +#: userdbs/views.py:129 +msgid "Database deleted" +msgstr "Datenbank gelöscht" diff --git a/gnuviechadmin/userdbs/models.py b/gnuviechadmin/userdbs/models.py index c678a31..4cc2b76 100644 --- a/gnuviechadmin/userdbs/models.py +++ b/gnuviechadmin/userdbs/models.py @@ -202,6 +202,26 @@ class UserDatabaseManager(models.Manager): break return nextname + @transaction.atomic + def create_userdatabase_with_user( + self, db_type, osuser, password=None, commit=True): + """ + Creates a new user database with a new user. + + :param db_type: database type from :py:data:`DB_TYPES` + :param osuser: :py:class:`osusers.models.OsUser` instance + :param str password: the password of the new database user + :param boolean commit: whether the user and the database should be + persisted + :return: database instance + :rtype: :py:class:`UserDatabase` + + """ + dbuser = DatabaseUser.objects.create_database_user( + osuser, db_type, password=password, commit=commit) + database = self.create_userdatabase(dbuser, commit=commit) + return database + @transaction.atomic def create_userdatabase(self, db_user, db_name=None, commit=True): """ @@ -267,10 +287,13 @@ class UserDatabase(TimeStampedModel, models.Model): :py:meth:`django.db.models.Model.delete` """ - if self.db_user.db_type == DB_TYPES.pgsql: + db_user = self.db_user + if db_user.db_type == DB_TYPES.pgsql: delete_pgsql_database.delay(self.db_name).get() - elif self.db_user.db_type == DB_TYPES.mysql: - delete_mysql_database.delay(self.db_name, self.db_user.name).get() + elif db_user.db_type == DB_TYPES.mysql: + delete_mysql_database.delay(self.db_name, db_user.name).get() else: raise ValueError('Unknown database type %d' % self.db_type) super(UserDatabase, self).delete(*args, **kwargs) + if not db_user.userdatabase_set.exists(): + db_user.delete() diff --git a/gnuviechadmin/userdbs/urls.py b/gnuviechadmin/userdbs/urls.py new file mode 100644 index 0000000..c31cf4d --- /dev/null +++ b/gnuviechadmin/userdbs/urls.py @@ -0,0 +1,23 @@ +""" +This module defines the URL patterns for user database views. + +""" +from __future__ import absolute_import, unicode_literals + +from django.conf.urls import patterns, url + +from .views import ( + AddUserDatabase, + ChangeDatabaseUserPassword, + DeleteUserDatabase, +) + +urlpatterns = patterns( + '', + url(r'^(?P\d+)/create$', + AddUserDatabase.as_view(), name='add_userdatabase'), + url(r'^(?P\d+)/(?P[\w0-9]+)/setpassword', + ChangeDatabaseUserPassword.as_view(), name='change_dbuser_password'), + url(r'^(?P\d+)/(?P[\w0-9]+)/delete', + DeleteUserDatabase.as_view(), name='delete_userdatabase'), +) diff --git a/gnuviechadmin/userdbs/views.py b/gnuviechadmin/userdbs/views.py new file mode 100644 index 0000000..e8794d6 --- /dev/null +++ b/gnuviechadmin/userdbs/views.py @@ -0,0 +1,131 @@ +""" +This module defines views for user database handling. + +""" +from __future__ import absolute_import, unicode_literals + +from django.shortcuts import redirect +from django.utils.translation import ugettext as _ +from django.views.generic.edit import ( + CreateView, + DeleteView, + UpdateView, +) +from django.contrib import messages + +from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin +from gvawebcore.views import HostingPackageAndCustomerMixin + +from .forms import ( + AddUserDatabaseForm, + ChangeDatabaseUserPasswordForm, +) +from .models import ( + DB_TYPES, + DatabaseUser, + UserDatabase, +) + + +class AddUserDatabase( + HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, CreateView +): + """ + This view is used to setup new user databases. + + """ + model = UserDatabase + context_object_name = 'database' + template_name_suffix = '_create' + form_class = AddUserDatabaseForm + + def _get_dbtypes(self, hostingpackage): + retval = [] + db_options = hostingpackage.get_databases() + for opt in db_options: + dbs_of_type = UserDatabase.objects.filter( + db_user__osuser=hostingpackage.osuser, + db_user__db_type=opt['db_type']).count() + if dbs_of_type < opt['number']: + retval.append((opt['db_type'], DB_TYPES[opt['db_type']])) + return retval + + def get_form_kwargs(self): + kwargs = super(AddUserDatabase, self).get_form_kwargs() + kwargs['hostingpackage'] = self.get_hosting_package() + kwargs['dbtypes'] = self._get_dbtypes(kwargs['hostingpackage']) + return kwargs + + def form_valid(self, form): + userdatabase = form.save() + messages.success( + self.request, + _('Successfully create new {type} database {dbname} for user ' + '{dbuser}').format( + type=userdatabase.db_user.db_type, + dbname=userdatabase.db_name, dbuser=userdatabase.db_user) + ) + return redirect(self.get_hosting_package()) + + +class ChangeDatabaseUserPassword( + HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, UpdateView +): + """ + This view is used to change a database user's password. + + """ + model = DatabaseUser + slug_field = 'name' + context_object_name = 'dbuser' + template_name_suffix = '_setpassword' + form_class = ChangeDatabaseUserPasswordForm + + def get_form_kwargs(self): + kwargs = super(ChangeDatabaseUserPassword, self).get_form_kwargs() + kwargs['hostingpackage'] = self.get_hosting_package() + return kwargs + + def get_context_data(self, **kwargs): + context = super(ChangeDatabaseUserPassword, self).get_context_data( + **kwargs) + context['hostingpackage'] = self.get_hosting_package() + context['customer'] = self.get_customer_object() + return context + + def form_valid(self, form): + db_user = form.save() + messages.success( + self.request, + _('Successfully changed password of database user {dbuser}' + ).format(dbuser=db_user.name) + ) + return redirect(self.get_hosting_package()) + + +class DeleteUserDatabase( + HostingPackageAndCustomerMixin, StaffOrSelfLoginRequiredMixin, DeleteView +): + """ + This view is used to delete user databases and databases users if they have + no more databases assigned. + + """ + model = UserDatabase + slug_field = 'db_name' + context_object_name = 'database' + + def get_context_data(self, **kwargs): + context = super(DeleteUserDatabase, self).get_context_data(**kwargs) + context.update({ + 'hostingpackage': self.get_hosting_package(), + 'customer': self.get_customer_object(), + }) + return context + + def get_success_url(self): + messages.success( + self.request, + _('Database deleted'), + ) + return self.get_hosting_package().get_absolute_url()
{% trans "Database name" %}{% trans "Database user" %} {% trans "Type" %}{% trans "Database name" %}{% trans "Database user" %}{% trans "Actions" %}{% trans "Actions" %}
{% include "userdbs/snippets/db_type.html" with db_type=database.db_user.db_type %} {{ database.db_name }}{{ database.db_user.username }}{{ database.db_user.name }}{% include "userdbs/snippets/db_type.html" with db_type=database.db_user.db_type %} + {% trans "Set database user password" %} + {% trans "Delete database" %} +