Compare commits
	
		
			2 commits
		
	
	
		
			2d05580ed3
			...
			d88745f46b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d88745f46b | |||
| 866f6c8083 | 
					 23 changed files with 169 additions and 322 deletions
				
			
		|  | @ -1,11 +0,0 @@ | |||
| {% extends "base.html" %} | ||||
| {% load i18n %} | ||||
| {% block title %}{{ block.super }} - {% translate "Welcome" %}{% endblock title %} | ||||
| {% block page_title %}{% translate "Welcome to our customer self service" %}{% endblock page_title %} | ||||
| {% block content %} | ||||
|     <p>{% url 'customer_dashboard' slug=user.username as dashboard_url %} | ||||
|         {% blocktranslate with full_name=user.get_full_name trimmed %} | ||||
|             Hello {{ full_name }},<br/> | ||||
|             You can visit your <a href="{{ dashboard_url }}">Dashboard</a> to view and modify your hosting options. | ||||
|         {% endblocktranslate %}</p> | ||||
| {% endblock content %} | ||||
|  | @ -1,9 +1,9 @@ | |||
| {% extends "base.html" %} | ||||
| {% load i18n %} | ||||
| {% block title %}{{ block.super }} - {% blocktranslate with full_name=dashboard_user.get_full_name trimmed %} | ||||
| {% block title %}{{ block.super }} - {% blocktranslate with full_name=request.user.get_full_name trimmed %} | ||||
|     Dashboard for {{ full_name }} | ||||
| {% endblocktranslate %}{% endblock title %} | ||||
| {% block page_title %}{% blocktranslate with full_name=dashboard_user.get_full_name trimmed %} | ||||
| {% block page_title %}{% blocktranslate with full_name=request.user.get_full_name trimmed %} | ||||
|     Dashboard for {{ full_name }} | ||||
| {% endblocktranslate %}{% endblock page_title %} | ||||
| {% block content %} | ||||
|  | @ -15,37 +15,20 @@ | |||
|                     <thead> | ||||
|                     <tr> | ||||
|                         <th>{% translate "Name" %}</th> | ||||
|                         <th>{% translate "Disk space" %}</th> | ||||
|                         <th>{% translate "Mailboxes" %}</th> | ||||
|                         <th>{% translate "Databases" %}</th> | ||||
|                         <th>{% translate "Setup date" %}</th> | ||||
|                         <th>{% translate "Actions" %}</th> | ||||
|                     </tr> | ||||
|                     </thead> | ||||
|                     <tbody> | ||||
|                     {% for package in hosting_packages %} | ||||
|                         <tr> | ||||
|                             <th><a href="{{ package.get_absolute_url }}" | ||||
|                             <td><a href="{{ package.get_absolute_url }}" | ||||
|                                    title="{% blocktranslate with packagename=package.name trimmed %} | ||||
|                                            Show details for {{ packagename }} | ||||
| {% endblocktranslate %}">{{ package.name }}</a> | ||||
|                             </th> | ||||
|                             <th> | ||||
|                                 {% with diskspace=package.get_disk_space %} | ||||
|                                     <span title="{% blocktranslate trimmed %} | ||||
|                                             The reserved disk space for your hosting package is {{ diskspace }} bytes. | ||||
| {% endblocktranslate %}">{{ diskspace|filesizeformat }}</span> | ||||
|                                 {% endwith %} | ||||
|                             </th> | ||||
|                             <th> | ||||
|                                 {% blocktranslate with num=package.used_mailbox_count total=package.mailbox_count trimmed %} | ||||
|                                     used {{ num }} of {{ total }} | ||||
|                                 {% endblocktranslate %}</th> | ||||
|                             <th>{% for dbtype in package.get_databases %} | ||||
|                                 {{ dbtype.number }} | ||||
|                                 {% include "userdbs/snippets/db_type.html" with db_type=dbtype.db_type %} | ||||
|                                 {% if not forloop.last %} / {% endif %} | ||||
|                             {% endfor %}</th> | ||||
|                             <th></th> | ||||
|                             </td> | ||||
|                             <td>{{ package.created }}</td> | ||||
|                             <td></td> | ||||
|                         </tr> | ||||
|                     {% endfor %} | ||||
|                     </tbody> | ||||
|  | @ -56,7 +39,7 @@ | |||
|                         {% translate "This user has no hosting packages assigned yet." %}{% endif %}</p> | ||||
|             {% endif %} | ||||
|             {% if user.is_staff %} | ||||
|                 <a href="{% url "create_customer_hosting_package" user=object.username %}" | ||||
|                 <a href="{% url "create_customer_hosting_package" user=request.user.username %}" | ||||
|                    class="btn btn-primary">{% translate "Add hosting package" %}</a> | ||||
|             {% endif %} | ||||
|         </div> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| Tests for :py:mod:`dashboard.views`. | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from django import http | ||||
| from django.contrib.auth import get_user_model | ||||
| from django.test import TestCase | ||||
| from django.urls import reverse | ||||
|  | @ -13,65 +13,35 @@ TEST_USER = "test" | |||
| TEST_PASSWORD = "secret" | ||||
| 
 | ||||
| 
 | ||||
| class IndexViewTest(TestCase): | ||||
|     def test_index_view_anonymous(self): | ||||
|         response = self.client.get(reverse("dashboard")) | ||||
|         self.assertRedirects(response, "/accounts/login/?next=/") | ||||
| 
 | ||||
|     def test_index_view(self): | ||||
|         user = User.objects.create(username=TEST_USER) | ||||
|         user.set_password(TEST_PASSWORD) | ||||
|         user.save() | ||||
| 
 | ||||
|         self.client.login(username=TEST_USER, password=TEST_PASSWORD) | ||||
| 
 | ||||
|         response = self.client.get(reverse("dashboard")) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         self.assertTemplateUsed(response, "dashboard/index.html") | ||||
| 
 | ||||
| 
 | ||||
| class UserDashboardViewTest(TestCase): | ||||
|     def _create_test_user(self): | ||||
|         self.user = User.objects.create(username=TEST_USER) | ||||
|         self.user.set_password(TEST_PASSWORD) | ||||
|         self.user.save() | ||||
| 
 | ||||
|     def test_user_dashboard_view_no_user(self): | ||||
|         response = self.client.get( | ||||
|             reverse("customer_dashboard", kwargs={"slug": TEST_USER}) | ||||
|         ) | ||||
|         self.assertEqual(response.status_code, 404) | ||||
| 
 | ||||
|     def test_user_dashboard_view_anonymous(self): | ||||
|         User.objects.create(username=TEST_USER) | ||||
|         response = self.client.get( | ||||
|             reverse("customer_dashboard", kwargs={"slug": TEST_USER}) | ||||
|         ) | ||||
|         self.assertEqual(response.status_code, 403) | ||||
|         response = self.client.get(reverse("customer_dashboard")) | ||||
|         self.assertEqual(response.status_code, 302) | ||||
|         self.assertRedirects(response, "/accounts/login/?next=/") | ||||
| 
 | ||||
|     def test_user_dashboard_view_logged_in_ok(self): | ||||
|         self._create_test_user() | ||||
|         self.assertTrue(self.client.login(username=TEST_USER, password=TEST_PASSWORD)) | ||||
|         response = self.client.get( | ||||
|             reverse("customer_dashboard", kwargs={"slug": TEST_USER}) | ||||
|         ) | ||||
|         response = self.client.get(reverse("customer_dashboard")) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
| 
 | ||||
|     def test_user_dashboard_view_logged_in_template(self): | ||||
|         self._create_test_user() | ||||
|         self.assertTrue(self.client.login(username=TEST_USER, password=TEST_PASSWORD)) | ||||
|         response = self.client.get( | ||||
|             reverse("customer_dashboard", kwargs={"slug": TEST_USER}) | ||||
|             reverse("customer_dashboard") | ||||
|         ) | ||||
|         self.assertTemplateUsed(response, "dashboard/user_dashboard.html") | ||||
| 
 | ||||
|     def test_user_dashboard_view_logged_in_context_fresh(self): | ||||
|         self._create_test_user() | ||||
|         self.assertTrue(self.client.login(username=TEST_USER, password=TEST_PASSWORD)) | ||||
|         response = self.client.get( | ||||
|             reverse("customer_dashboard", kwargs={"slug": TEST_USER}) | ||||
|         ) | ||||
|         self.assertIn("dashboard_user", response.context) | ||||
|         self.assertEqual(self.user, response.context["dashboard_user"]) | ||||
|         response = self.client.get(reverse("customer_dashboard")) | ||||
|         self.assertIn("hosting_packages", response.context) | ||||
|         self.assertEqual(len(response.context["hosting_packages"]), 0) | ||||
|  |  | |||
|  | @ -1,14 +1,9 @@ | |||
| from __future__ import absolute_import | ||||
| 
 | ||||
| from django.urls import re_path | ||||
| from django.urls import path | ||||
| 
 | ||||
| from .views import IndexView, UserDashboardView | ||||
| from .views import UserDashboardView | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     re_path(r"^$", IndexView.as_view(), name="dashboard"), | ||||
|     re_path( | ||||
|         r"^user/(?P<slug>[\w0-9@.+-_]+)/$", | ||||
|         UserDashboardView.as_view(), | ||||
|         name="customer_dashboard", | ||||
|     ), | ||||
|     path("", UserDashboardView.as_view(), name="customer_dashboard"), | ||||
| ] | ||||
|  |  | |||
|  | @ -4,42 +4,24 @@ This module defines the views for the gnuviechadmin customer dashboard. | |||
| """ | ||||
| from django.contrib.auth import get_user_model | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.shortcuts import redirect | ||||
| from django.views.generic import DetailView, TemplateView | ||||
| from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin | ||||
| 
 | ||||
| from hostingpackages.models import CustomerHostingPackage | ||||
| 
 | ||||
| 
 | ||||
| class IndexView(LoginRequiredMixin, TemplateView): | ||||
|     """ | ||||
|     This is the dashboard view. | ||||
| 
 | ||||
|     """ | ||||
| 
 | ||||
|     template_name = "dashboard/index.html" | ||||
| 
 | ||||
| 
 | ||||
| class UserDashboardView(StaffOrSelfLoginRequiredMixin, DetailView): | ||||
| class UserDashboardView(LoginRequiredMixin, TemplateView): | ||||
|     """ | ||||
|     This is the user dashboard view. | ||||
| 
 | ||||
|     """ | ||||
| 
 | ||||
|     model = get_user_model() | ||||
|     context_object_name = "dashboard_user" | ||||
|     slug_field = "username" | ||||
|     template_name = "dashboard/user_dashboard.html" | ||||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(UserDashboardView, self).get_context_data(**kwargs) | ||||
|         context["hosting_packages"] = CustomerHostingPackage.objects.filter( | ||||
|             customer=self.object | ||||
|             customer=self.request.user | ||||
|         ) | ||||
|         return context | ||||
| 
 | ||||
|     def get_customer_object(self): | ||||
|         """ | ||||
|         Returns the customer object. | ||||
| 
 | ||||
|         """ | ||||
|         return self.get_object() | ||||
|  |  | |||
|  | @ -56,15 +56,6 @@ class NavigationContextProcessorTest(TestCase): | |||
|         self._check_static_urls(response.context) | ||||
|         self.assertEqual(response.context["active_item"], "contact") | ||||
| 
 | ||||
|     def test_hostingpackage_page_context(self): | ||||
|         User.objects.create_user("test", password="test") | ||||
|         self.client.login(username="test", password="test") | ||||
|         response = self.client.get(reverse("hosting_packages", kwargs={"user": "test"})) | ||||
|         for item in self.EXPECTED_ITEMS: | ||||
|             self.assertIn(item, response.context) | ||||
|         self._check_static_urls(response.context) | ||||
|         self.assertEqual(response.context["active_item"], "hostingpackage") | ||||
| 
 | ||||
|     def _test_page_context_by_viewmodule(self, viewmodule, expecteditem): | ||||
|         request = HttpRequest() | ||||
|         request.resolver_match = MagicMock() | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ | |||
|                 <th>{% translate "Name" %}</th> | ||||
|                 <th>{% translate "Customer" %}</th> | ||||
|                 <th>{% translate "OS User" %}</th> | ||||
|                 <th>{% translate "Disk space" %}</th> | ||||
|                 <th>{% translate "Mailboxes" %}</th> | ||||
|                 <th>{% translate "Databases" %}</th> | ||||
|                 <th>{% translate "Setup date" %}</th> | ||||
|             </tr> | ||||
|             </thead> | ||||
|  | @ -18,10 +21,24 @@ | |||
|             {% for package in customerhostingpackage_list %} | ||||
|                 <tr> | ||||
|                     <td><a href="{{ package.get_absolute_url }}">{{ package.name }}</a></td> | ||||
|                     <td> | ||||
|                         <a href="{% url 'customer_dashboard' slug=package.customer.username %}">{{ package.customer }}</a> | ||||
|                     </td> | ||||
|                     <td>{{ package.customer }}</td> | ||||
|                     <td>{{ package.osuser.username }}</td> | ||||
|                     <td> | ||||
|                         {% with diskspace=package.get_disk_space %} | ||||
|                             <span title="{% blocktranslate trimmed %} | ||||
|                                             The reserved disk space for your hosting package is {{ diskspace }} bytes. | ||||
| {% endblocktranslate %}">{{ diskspace|filesizeformat }}</span> | ||||
|                         {% endwith %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         {% blocktranslate with num=package.used_mailbox_count total=package.mailbox_count trimmed %} | ||||
|                             used {{ num }} of {{ total }} | ||||
|                         {% endblocktranslate %}</td> | ||||
|                     <td>{% for dbtype in package.get_databases %} | ||||
|                         {{ dbtype.number }} | ||||
|                         {% include "userdbs/snippets/db_type.html" with db_type=dbtype.db_type %} | ||||
|                         {% if not forloop.last %} / {% endif %} | ||||
|                     {% endfor %}</td> | ||||
|                     <td>{{ package.created }}</td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|  |  | |||
|  | @ -1,48 +0,0 @@ | |||
| {% extends "hostingpackages/base.html" %} | ||||
| {% load i18n %} | ||||
| {% block title %}{{ block.super }} - {% spaceless %} | ||||
|     {% if user == customer %} | ||||
|         {% translate "Your hosting packages" %} | ||||
|     {% else %} | ||||
|         {% blocktranslate with customer=customer.get_full_name trimmed %}Hosting Packages of | ||||
|             {{ customer }}{% endblocktranslate %} | ||||
|     {% endif %} | ||||
| {% endspaceless %}{% endblock title %} | ||||
| 
 | ||||
| {% block page_title %}{% spaceless %} | ||||
|     {% if user == customer %} | ||||
|         {% translate "Your hosting packages" %} | ||||
|     {% else %} | ||||
|         {% blocktranslate with customer=customer.get_full_name trimmed %}Hosting Packages | ||||
|             <small>of {{ customer }}</small>{% endblocktranslate %} | ||||
|     {% endif %} | ||||
| {% endspaceless %}{% endblock page_title %} | ||||
| 
 | ||||
| {% block content %} | ||||
|     {% if customerhostingpackage_list %} | ||||
|         <table class="table table-condensed"> | ||||
|             <thead> | ||||
|             <tr> | ||||
|                 <th>{% translate "Name" %}</th> | ||||
|                 <th>{% translate "Setup date" %}</th> | ||||
|             </tr> | ||||
|             </thead> | ||||
|             <tbody> | ||||
|             {% for package in customerhostingpackage_list %} | ||||
|                 <tr> | ||||
|                     <td><a href="{{ package.get_absolute_url }}">{{ package.name }}</a></td> | ||||
|                     <td>{{ package.created }}</td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|             </tbody> | ||||
|         </table> | ||||
|     {% else %} | ||||
|         <p class="text-info"> | ||||
|             {% if user == customer %}{% translate "You have no hosting packages setup yet." %}{% else %} | ||||
|                 {% translate "There are no hosting packages setup for this customer yet." %}{% endif %}</p> | ||||
|     {% endif %} | ||||
|     {% if user.is_staff %} | ||||
|         <p><a href="{% url 'create_customer_hosting_package' user=customer.username %}" | ||||
|               class="btn btn-primary">{% translate "Add hosting package" %}</a></p> | ||||
|     {% endif %} | ||||
| {% endblock content %} | ||||
|  | @ -12,7 +12,6 @@ from .views import ( | |||
|     CreateCustomerHostingPackage, | ||||
|     CreateHostingPackage, | ||||
|     CustomerHostingPackageDetails, | ||||
|     CustomerHostingPackageList, | ||||
|     HostingOptionChoices, | ||||
| ) | ||||
| 
 | ||||
|  | @ -23,11 +22,6 @@ urlpatterns = [ | |||
|         AllCustomerHostingPackageList.as_view(), | ||||
|         name="all_hosting_packages", | ||||
|     ), | ||||
|     re_path( | ||||
|         r"^(?P<user>[-\w0-9@.+_]+)/$", | ||||
|         CustomerHostingPackageList.as_view(), | ||||
|         name="hosting_packages", | ||||
|     ), | ||||
|     re_path( | ||||
|         r"^(?P<user>[-\w0-9@.+_]+)/create$", | ||||
|         CreateCustomerHostingPackage.as_view(), | ||||
|  |  | |||
|  | @ -149,35 +149,6 @@ class AllCustomerHostingPackageList(StaffUserRequiredMixin, ListView): | |||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| class CustomerHostingPackageList(StaffOrSelfLoginRequiredMixin, ListView): | ||||
|     """ | ||||
|     This view is used for showing a list of a customer's hosting packages. | ||||
| 
 | ||||
|     """ | ||||
| 
 | ||||
|     model = CustomerHostingPackage | ||||
|     customer = None | ||||
| 
 | ||||
|     def get_customer_object(self): | ||||
|         if self.customer is None: | ||||
|             self.customer = get_object_or_404( | ||||
|                 get_user_model(), username=self.kwargs["user"] | ||||
|             ) | ||||
|         return self.customer | ||||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(CustomerHostingPackageList, self).get_context_data(**kwargs) | ||||
|         context["customer"] = self.get_customer_object() | ||||
|         return context | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         return ( | ||||
|             super(CustomerHostingPackageList, self) | ||||
|             .get_queryset() | ||||
|             .filter(customer__username=self.kwargs["user"]) | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| class HostingOptionChoices(StaffUserRequiredMixin, DetailView): | ||||
|     """ | ||||
|     This view displays choices of hosting options for a customer hosting | ||||
|  |  | |||
|  | @ -212,7 +212,7 @@ class GroupTest(TestCaseWithCeleryTasks): | |||
|         group.delete() | ||||
|         self.assertEqual(len(Group.objects.all()), 0) | ||||
|         self.assertEqual(len(TaskResult.objects.all()), 2) | ||||
|         tr = TaskResult.objects.first() | ||||
|         tr = TaskResult.objects.order_by("created").first() | ||||
|         self.assertEqual(tr.creator, "handle_group_created") | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ class FetchTaskResultsCommandTest(TestCase): | |||
|         aresult.state = "PENDING" | ||||
|         aresult.ready.return_value = False | ||||
| 
 | ||||
|         Command().handle() | ||||
|         Command().handle(verbosity=0) | ||||
| 
 | ||||
|         tr = TaskResult.objects.get(task_id=TEST_TASK_UUID) | ||||
|         self.assertTrue(asyncresult.called_with(TEST_TASK_UUID)) | ||||
|  | @ -55,7 +55,7 @@ class FetchTaskResultsCommandTest(TestCase): | |||
|         aresult.ready.return_value = True | ||||
|         aresult.get.return_value = TEST_TASK_RESULT | ||||
| 
 | ||||
|         Command().handle() | ||||
|         Command().handle(verbosity=0) | ||||
| 
 | ||||
|         tr = TaskResult.objects.get(task_id=TEST_TASK_UUID) | ||||
|         self.assertTrue(asyncresult.called_with(TEST_TASK_UUID)) | ||||
|  |  | |||
|  | @ -4,72 +4,87 @@ | |||
| {% block page_title %}{% translate "E-mail Addresses" %}{% endblock page_title %} | ||||
| 
 | ||||
| {% block content %} | ||||
| {% if user.emailaddress_set.all %} | ||||
| <p>{% translate 'The following e-mail addresses are associated with your account:' %}</p> | ||||
| <form action="{% url 'account_email' %}" class="email_list" method="post"> | ||||
|   {% csrf_token %} | ||||
|   <table class="table table-condensed"> | ||||
|     <thead> | ||||
|       <tr> | ||||
|         <th>{% translate "Email address" %}</th> | ||||
|         <th>{% translate "Verified" %}</th> | ||||
|         <th>{% translate "Primary" %}</th> | ||||
|       </tr> | ||||
|     </thead> | ||||
|     <tbody> | ||||
|     {% for emailaddress in user.emailaddress_set.all %} | ||||
|       <tr> | ||||
|         <td>{{ emailaddress.email }}</td> | ||||
|         <td> | ||||
|           {% if emailaddress.verified %} | ||||
|             <span class="verified">{% translate "Verified" %}</span> | ||||
|           {% else %} | ||||
|             <span class="unverified">{% translate "Unverified" %}</span> | ||||
|           {% endif %} | ||||
|         </td> | ||||
|         <td> | ||||
|           {% if emailaddress.primary %} | ||||
|           <span class="glyphicon glyphicon-star" title="{% translate "This is the current primary Email address" %}"></span> | ||||
|           {% else %} | ||||
|           <span class="glyphicon glyphicon-star-empty"></span> | ||||
|           {% endif %} | ||||
|         <input id="email_radio_{{forloop.counter}}" type="radio" name="email" {% if emailaddress.primary %}checked="checked"{%endif %} value="{{emailaddress.email}}" /> | ||||
|         </td> | ||||
|       </tr> | ||||
|     {% endfor %} | ||||
|     </tbody> | ||||
|   </table> | ||||
|   <p> | ||||
|     <button class="btn btn-default" type="submit" name="action_primary" >{% translate 'Make Primary' %}</button> | ||||
|     <button class="btn btn-default" type="submit" name="action_send" >{% translate 'Re-send Verification' %}</button> | ||||
|     <button class="btn btn-warning" type="submit" name="action_remove" >{% translate 'Remove' %}</button> | ||||
|   </p> | ||||
| </form> | ||||
| {% else %} | ||||
| <p class="text-warning"><strong>{% translate 'Warning:'%}</strong> {% translate "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}</p> | ||||
| {% endif %} | ||||
|     {% if user.emailaddress_set.all %} | ||||
|         <p>{% translate 'The following e-mail addresses are associated with your account:' %}</p> | ||||
|         <form action="{% url 'account_email' %}" class="email_list" method="post"> | ||||
|             {% csrf_token %} | ||||
|             <table class="table table-condensed"> | ||||
|                 <thead> | ||||
|                 <tr> | ||||
|                     <th>{% translate "Email address" %}</th> | ||||
|                     <th>{% translate "Verified" %}</th> | ||||
|                     <th>{% translate "Primary" %}</th> | ||||
|                     <th>{% translate "Selection" %}</th> | ||||
|                 </tr> | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                 {% for emailaddress in user.emailaddress_set.all %} | ||||
|                     <tr> | ||||
|                         <td>{{ emailaddress.email }}</td> | ||||
|                         <td> | ||||
|                             {% if emailaddress.verified %} | ||||
|                                 <span class="text-success"><i class="bi-check-circle-fill" title="{% translate "Verified" %}"></i></span> | ||||
|                             {% else %} | ||||
|                                 <span class="text-warning"><i class="bi-dash-circle-fill" title="{% translate "Unverified" %}"></i></span> | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             {% if emailaddress.primary %} | ||||
|                                 <span class="text-success"><i class="bi-check-circle-fill" title="{% translate "This is the current primary Email address" %}"></i></span> | ||||
|                             {% else %} | ||||
|                                 <span class="text-secondary"><i class="bi-circle"></i></span> | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <input id="email_radio_{{ forloop.counter }}" type="radio" name="email" | ||||
|                                    {% if emailaddress.primary %}checked="checked"{% endif %} | ||||
|                                    value="{{ emailaddress.email }}"/><label | ||||
|                                 for="email_radio_{{ forloop.counter }}" | ||||
|                                 aria-label="{% blocktranslate trimmed with address=emailaddress.email %} | ||||
|                                 Select {{ address }} | ||||
| {% endblocktranslate %}"></label> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 {% endfor %} | ||||
|                 </tbody> | ||||
|             </table> | ||||
|             <p> | ||||
|                 {% if user.emailaddress_set.count > 1 %} | ||||
|                     <button class="btn btn-secondary" type="submit" | ||||
|                             name="action_primary">{% translate 'Make Primary' %}</button> | ||||
|                 {% endif %} | ||||
|                 <button class="btn btn-secondary" type="submit" | ||||
|                         name="action_send">{% translate 'Re-send Verification' %}</button> | ||||
|                 <button class="btn btn-warning" type="submit" name="action_remove">{% translate 'Remove' %}</button> | ||||
|             </p> | ||||
|         </form> | ||||
|     {% else %} | ||||
|         <p class="text-warning"> | ||||
|             <strong>{% translate 'Warning:' %}</strong> {% translate "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %} | ||||
|         </p> | ||||
|     {% endif %} | ||||
| 
 | ||||
| <h2>{% translate "Add E-mail Address" %}</h2> | ||||
|     <h2>{% translate "Add E-mail Address" %}</h2> | ||||
| 
 | ||||
| <form method="post" action="{% url 'account_email' %}" class="add_email"> | ||||
|   {% csrf_token %} | ||||
|   {{ form | crispy }} | ||||
|   <button name="action_add" type="submit" class="btn btn-primary">{% translate "Add E-mail" %}</button> | ||||
| </form> | ||||
|     <form method="post" action="{% url 'account_email' %}" class="add_email"> | ||||
|         {% csrf_token %} | ||||
|         {{ form | crispy }} | ||||
|         <button name="action_add" type="submit" class="btn btn-primary">{% translate "Add E-mail" %}</button> | ||||
|     </form> | ||||
| {% endblock content %} | ||||
| 
 | ||||
| {% block extra_js %} | ||||
| <script type="text/javascript"> | ||||
| (function() { | ||||
|   var message = "{% translate 'Do you really want to remove the selected e-mail address?' %}"; | ||||
|   var actions = document.getElementsByName('action_remove'); | ||||
|   if (actions.length) { | ||||
|     actions[0].addEventListener("click", function(e) { | ||||
|       if (! confirm(message)) { | ||||
|         e.preventDefault(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| })(); | ||||
| </script> | ||||
|     <script type="text/javascript"> | ||||
|         (function () { | ||||
|             const message = "{% translate 'Do you really want to remove the selected e-mail address?' %}"; | ||||
|             let actions = document.getElementsByName('action_remove'); | ||||
|             if (actions.length) { | ||||
|                 actions[0].addEventListener("click", function (e) { | ||||
|                     if (!confirm(message)) { | ||||
|                         e.preventDefault(); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         })(); | ||||
|     </script> | ||||
| {% endblock extra_js %} | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
|         {% endblocktranslate %}</p> | ||||
|         <form method="post" action="{% url 'account_confirm_email' confirmation.key %}"> | ||||
|             {% csrf_token %} | ||||
|             <button type="submit" class="btn btn-default">{% translate 'Confirm' %}</button> | ||||
|             <button type="submit" class="btn btn-primary">{% translate 'Confirm' %}</button> | ||||
|         </form> | ||||
|     {% else %} | ||||
|         {% url 'account_email' as email_url %} | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
|                 {% if redirect_field_value %} | ||||
|                     <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}"/> | ||||
|                 {% endif %} | ||||
|                 <a class="btn btn-default" href="{% url 'account_reset_password' %}">{% translate "Forgot Password?" %}</a> | ||||
|                 <a class="btn btn-secondary" href="{% url 'account_reset_password' %}">{% translate "Forgot Password?" %}</a> | ||||
|                 <button class="btn btn-primary" type="submit">{% translate "Sign In" %}</button> | ||||
|             </form> | ||||
|         </div> | ||||
|  |  | |||
|  | @ -23,13 +23,7 @@ | |||
| <body> | ||||
| <nav class="navbar navbar-expand-lg sticky-top navbar-dark bg-dark"> | ||||
|     <div class="container"> | ||||
|         <a class="navbar-brand" href="{% spaceless %} | ||||
|         {% if user.is_authenticated %} | ||||
|             {% url 'customer_dashboard' slug=user.username %} | ||||
|         {% else %} | ||||
|             {% url 'dashboard' %} | ||||
|         {% endif %} | ||||
|         {% endspaceless %}" title="{% translate "Dashboard" %}">gnuviechadmin</a> | ||||
|         <a class="navbar-brand" href="{% url "customer_dashboard" %}" title="{% translate "Dashboard" %}">gnuviechadmin</a> | ||||
|         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" | ||||
|                 aria-controls="navbarContent" aria-expanded="false" aria-label="{% translate "Toggle navigation" %}"> | ||||
|             <span class="navbar-toggler-icon"></span> | ||||
|  | @ -37,41 +31,34 @@ | |||
|         <div class="collapes navbar-collapse" id="navbarContent"> | ||||
|             <ul class="navbar-nav me-auto mb-2 mg-lg-0"> | ||||
|                 {% if user.is_staff %} | ||||
|                     <li class="nav-item dropdown{% if active_item == 'hostingpackage' %} active{% endif %}"> | ||||
|                     <li class="nav-item{% if active_item == "hosting" %} active{% endif %}"> | ||||
|                         <a class="nav-link" href="{% url 'all_hosting_packages' %}"> | ||||
|                             <i class="bi-boxes"></i> {% translate "Hosting" %}</a> | ||||
|                     </li> | ||||
|                 {% endif %} | ||||
|                 {% if user.is_authenticated %} | ||||
|                     <li class="nav-item dropdown"> | ||||
|                         <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" | ||||
|                            aria-expanded="false"><i class="bi-server"></i> {% translate "Hosting" %}</a> | ||||
|                            aria-expanded="false"><i class="bi-link"></i> {% translate "Links" %} </a> | ||||
|                         <ul class="dropdown-menu" role="menu"> | ||||
|                             <li><a class="dropdown-item" href="{% url 'hosting_packages' user=user.username %}"><i | ||||
|                                     class="bi-box2-fill"></i> {% translate "Your hosting packages" %}</a></li> | ||||
|                             <li><a class="dropdown-item" href="{% url 'all_hosting_packages' %}"><i | ||||
|                                     class="bi-boxes"></i> {% translate "All hosting packages" %}</a></li> | ||||
|                             <li><a class="dropdown-item" href="{{ webmail_url }}" | ||||
|                                    title="{% translate "Web based mail system" %}"><i | ||||
|                                     class="bi-envelope-at"></i> {% translate "Webmail" %}</a></li> | ||||
|                             <li><a class="dropdown-item" href="{{ phpmyadmin_url }}" | ||||
|                                    title="{% translate "phpMyAdmin - MySQL database administration tool" %}"><i | ||||
|                                     class="icon-mysql"></i> {% translate "phpMyAdmin" %}</a></li> | ||||
|                             <li><a class="dropdown-item" href="{{ phppgadmin_url }}" | ||||
|                                    title="{% translate "phpPgAdmin - PostgreSQL database administration tool" %}"><i | ||||
|                                     class="icon-postgres"></i> {% translate "phpPgAdmin" %}</a></li> | ||||
|                         </ul> | ||||
|                     </li> | ||||
|                 {% elif user.is_authenticated %} | ||||
|                     <li class="nav-item{% if active_item == 'hostingpackage' %} active{% endif %}"><a | ||||
|                             class="nav-link" href="{% url 'hosting_packages' user=user.username %}"><i | ||||
|                             class="bi-server"></i> {% translate "Hosting" %}</a></li> | ||||
|                 {% endif %} | ||||
|                 <li class="nav-item dropdown"> | ||||
|                     <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" | ||||
|                        aria-expanded="false"><i class="bi-link"></i> {% translate "Links" %} </a> | ||||
|                     <ul class="dropdown-menu" role="menu"> | ||||
|                         <li><a class="dropdown-item" href="{{ webmail_url }}" | ||||
|                                title="{% translate "Web based mail system" %}"><i | ||||
|                                 class="bi-envelope-at"></i> {% translate "Webmail" %}</a></li> | ||||
|                         <li><a class="dropdown-item" href="{{ phpmyadmin_url }}" | ||||
|                                title="{% translate "phpMyAdmin - MySQL database administration tool" %}"><i | ||||
|                                 class="icon-mysql"></i> {% translate "phpMyAdmin" %}</a></li> | ||||
|                         <li><a class="dropdown-item" href="{{ phppgadmin_url }}" | ||||
|                                title="{% translate "phpPgAdmin - PostgreSQL database administration tool" %}"><i | ||||
|                                 class="icon-postgres"></i> {% translate "phpPgAdmin" %}</a></li> | ||||
|                     </ul> | ||||
|                 </li> | ||||
|                 <li class="nav-item{% if active_item == 'imprint' %} active{% endif %}"><a | ||||
|                         class="nav-link" href="{% url 'imprint' %}"><i class="bi-info"></i> {% translate "Imprint" %} | ||||
|                 </a></li> | ||||
|                 <li class="nav-item{% if active_item == 'privacy' %} active{% endif %}"><a | ||||
|                         class="nav-link" href="{% url 'privacy' %}"><i class="bi-file-text"></i> {% translate "Privacy policy" %} | ||||
|                         class="nav-link" href="{% url 'privacy' %}"><i | ||||
|                         class="bi-file-text"></i> {% translate "Privacy policy" %} | ||||
|                 </a></li> | ||||
|                 <li class="nav-item{% if active_item == 'contact' %} active{% endif %}"><a | ||||
|                         class="nav-link" href="{% url 'contact_form' %}"><i | ||||
|  | @ -79,7 +66,7 @@ | |||
|             </ul> | ||||
|             {% if user.is_authenticated %} | ||||
|                 {% user_display user as user_display %} | ||||
|                 {% url 'user_profile' slug=user.username as profile_url %} | ||||
|                 {% url "customer_dashboard" as profile_url %} | ||||
|                 {% if user.is_impersonate %} | ||||
|                     {% user_display user.impersonator as impersonator_display %} | ||||
|                     {% url 'impersonate-stop' as stop_impersonation_url %} | ||||
|  | @ -87,7 +74,8 @@ | |||
|                         Signed in as | ||||
|                         <a href="{{ profile_url }}" class="navbar-link" title="My Profile">{{ user_display }}</a> | ||||
|                         <i class="bi-incognito" title="impersonated by {{ impersonator_display }}"></i> | ||||
|                         <a href="{{ stop_impersonation_url }}" class="navbar-link"><i class="bi-sign-stop" title="stop impersonation"></i></a> | ||||
|                         <a href="{{ stop_impersonation_url }}" class="navbar-link"><i class="bi-sign-stop" | ||||
|                                                                                       title="stop impersonation"></i></a> | ||||
|                     {% endblocktranslate %}</span> | ||||
|                 {% else %} | ||||
|                     <span class="navbar-text justify-content-end">{% blocktranslate trimmed %} | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ | |||
|     {% if page.object_list %} | ||||
|         <ul class="list-group"> | ||||
|             {% for user in page.object_list %} | ||||
|                 <li class="list-group-item"><a href="{% url 'impersonate-start' user.pk %}{{ redirect }}">{{ user }}</a> | ||||
|                     - Impersonate | ||||
|                 <li class="list-group-item"><a href="{% url 'impersonate-start' user.pk %}{{ redirect }}"> | ||||
|                     {% blocktranslate %}Impersonate {{ user }}{% endblocktranslate %}</a> | ||||
|                 </li> | ||||
|             {% endfor %} | ||||
|         </ul> | ||||
|  |  | |||
|  | @ -13,15 +13,15 @@ | |||
|                    placeholder="{% translate "user name part" %}" value="{% if query %}{{ query }}{% endif %}"> | ||||
|         </div> | ||||
|         <button type="submit" class="btn btn-primary">{% translate "Search" %}</button> | ||||
|         <a class="btn btn-secondary" href="{% url 'impersonate-list' %}">{% translate "List all users" %}</a> | ||||
|         <a class="btn btn-link" href="{% url 'impersonate-list' %}">{% translate "List all users" %}</a> | ||||
|     </form> | ||||
| 
 | ||||
|     <p> | ||||
|         {% if query and page.object_list %} | ||||
|             <ul class="list-group"> | ||||
|                 {% for user in page.object_list %} | ||||
|                     <li class="list-group-item"><a | ||||
|                             href="{% url 'impersonate-start' user.pk %}{{ redirect }}">{{ user }}</a> - Impersonate | ||||
|                     <li class="list-group-item"><a href="{% url 'impersonate-start' user.pk %}{{ redirect }}"> | ||||
|                         {% blocktranslate %}Impersonate {{ user }}{% endblocktranslate %}</a> | ||||
|                     </li> | ||||
|                 {% endfor %} | ||||
|             </ul> | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ | |||
|                   method="post"> | ||||
|                 {% csrf_token %} | ||||
|                 <input class="btn btn-warning" type="submit" value="{% translate "Yes, do it!" %}"/> | ||||
|                 <a class="btn btn-default" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|                 <a class="btn btn-secondary" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|             </form> | ||||
|         </div> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ | |||
|             <form action="{% url 'delete_ssh_key' package=hostingpackage.id pk=key.id %}" method="post"> | ||||
|                 {% csrf_token %} | ||||
|                 <input class="btn btn-warning" type="submit" value="{% translate "Yes, do it!" %}"/> | ||||
|                 <a class="btn btn-default" href="{% url 'list_ssh_keys' package=hostingpackage.id %}" | ||||
|                 <a class="btn btn-secondary" href="{% url 'list_ssh_keys' package=hostingpackage.id %}" | ||||
|                    title="{% translate "Cancel and go back to the SSH key list" %}">{% translate "Cancel" %}</a> | ||||
|             </form> | ||||
|         </div> | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ | |||
|                   method="post"> | ||||
|                 {% csrf_token %} | ||||
|                 <input class="btn btn-warning" type="submit" value="{% translate "Yes, do it!" %}"/> | ||||
|                 <a class="btn btn-default" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|                 <a class="btn btn-secondary" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|             </form> | ||||
|         </div> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ | |||
|                   method="post" class="form"> | ||||
|                 {% csrf_token %} | ||||
|                 <input class="btn btn-warning" type="submit" value="{% translate "Yes, do it!" %}"/> | ||||
|                 <a class="btn btn-default" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|                 <a class="btn btn-secondary" href="{{ hostingpackage.get_absolute_url }}">{% translate "Cancel" %}</a> | ||||
|             </form> | ||||
|         </div> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -94,7 +94,7 @@ class DatabaseUserManagerTest(TestCaseWithCeleryTasks): | |||
|         self.assertEqual(dbu.name, "{user}db01".format(user=self.osuser.username)) | ||||
|         self.assertEqual(dbu.osuser, self.osuser) | ||||
|         self.assertEqual(dbu.db_type, DB_TYPES.mysql) | ||||
|         taskres = TaskResult.objects.all() | ||||
|         taskres = TaskResult.objects.order_by("created").all() | ||||
|         self.assertEqual(len(taskres), 4) | ||||
|         self.assertEqual(taskres[0].creator, "handle_dbuser_created") | ||||
|         self.assertEqual(taskres[0].notes, "mysql user creation") | ||||
|  | @ -154,7 +154,7 @@ class DatabaseUserTest(TestCaseWithCeleryTasks): | |||
|         dbid = db.id | ||||
|         self.dbu.delete() | ||||
|         self.assertFalse(UserDatabase.objects.filter(id=dbid).exists()) | ||||
|         taskres = TaskResult.objects.all() | ||||
|         taskres = TaskResult.objects.order_by("created").all() | ||||
|         self.assertEqual(len(taskres), 3) | ||||
|         self.assertEqual(taskres[0].creator, "handle_userdb_created") | ||||
|         self.assertEqual(taskres[0].notes, "pgsql database creation") | ||||
|  | @ -187,7 +187,7 @@ class UserDatabaseManagerTest(TestCaseWithCeleryTasks): | |||
|         self.assertEqual( | ||||
|             db.db_user.name, "{user}db01".format(user=self.osuser.username) | ||||
|         ) | ||||
|         taskres = TaskResult.objects.all() | ||||
|         taskres = TaskResult.objects.order_by("created").all() | ||||
|         self.assertEqual(len(taskres), 2) | ||||
|         self.assertEqual(taskres[0].creator, "handle_dbuser_created") | ||||
|         self.assertEqual(taskres[0].notes, "mysql user creation") | ||||
|  | @ -202,7 +202,7 @@ class UserDatabaseManagerTest(TestCaseWithCeleryTasks): | |||
|         self.assertEqual( | ||||
|             db.db_user.name, "{user}db01".format(user=self.osuser.username) | ||||
|         ) | ||||
|         taskres = TaskResult.objects.all() | ||||
|         taskres = TaskResult.objects.order_by("created").all() | ||||
|         self.assertEqual(len(taskres), 2) | ||||
|         self.assertEqual(taskres[0].creator, "handle_dbuser_created") | ||||
|         self.assertEqual(taskres[0].notes, "pgsql user creation") | ||||
|  | @ -267,20 +267,20 @@ class UserDatabaseTest(TestCaseWithCeleryTasks): | |||
| 
 | ||||
|     def test___str__(self): | ||||
|         customer = Customer.objects.create_user(username="testcustomer") | ||||
|         osuser = User.objects.create_user(customer=customer) | ||||
|         db = UserDatabase.objects.create_userdatabase_with_user(DB_TYPES.pgsql, osuser) | ||||
|         os_user = User.objects.create_user(customer=customer) | ||||
|         db = UserDatabase.objects.create_userdatabase_with_user(DB_TYPES.pgsql, os_user) | ||||
|         self.assertEqual( | ||||
|             str(db), | ||||
|             "{user}db01 ({dbuser})".format(user=osuser.username, dbuser=db.db_user), | ||||
|             "{user}db01 ({dbuser})".format(user=os_user.username, dbuser=db.db_user), | ||||
|         ) | ||||
| 
 | ||||
|     def test_delete_mysql_db(self): | ||||
|         customer = Customer.objects.create_user(username="testcustomer") | ||||
|         osuser = User.objects.create_user(customer=customer) | ||||
|         os_user = User.objects.create_user(customer=customer) | ||||
|         TaskResult.objects.all().delete() | ||||
|         db = UserDatabase.objects.create_userdatabase_with_user(DB_TYPES.mysql, osuser) | ||||
|         db = UserDatabase.objects.create_userdatabase_with_user(DB_TYPES.mysql, os_user) | ||||
|         db.delete() | ||||
|         taskres = TaskResult.objects.all() | ||||
|         self.assertEqual(len(taskres), 3) | ||||
|         self.assertEqual(taskres[2].creator, "handle_userdb_deleted") | ||||
|         self.assertEqual(taskres[2].notes, "mysql database deletion") | ||||
|         task_result = TaskResult.objects.order_by("created").all() | ||||
|         self.assertEqual(len(task_result), 3) | ||||
|         self.assertEqual(task_result[2].creator, "handle_userdb_deleted") | ||||
|         self.assertEqual(task_result[2].notes, "mysql database deletion") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue