Add view to create mailbox

This commit is contained in:
Santiago L 2021-10-05 13:10:53 +02:00
parent ed5460c4b1
commit 9e51457069
6 changed files with 96 additions and 3 deletions

View file

@ -83,7 +83,7 @@ class Orchestra(object):
response.raise_for_status() response.raise_for_status()
status = response.status_code status = response.status_code
if render_as == "json": if status < 500 and render_as == "json":
output = response.json() output = response.json()
else: else:
output = response.content output = response.content
@ -164,6 +164,10 @@ class Orchestra(object):
url = urllib.parse.urljoin(self.base_url, path) url = urllib.parse.urljoin(self.base_url, path)
return self.request("DELETE", url=url, render_as=None) return self.request("DELETE", url=url, render_as=None)
def create_mailbox(self, data):
resource = '{}-list'.format(Mailbox.api_name)
return self.request("POST", resource=resource, data=data, raise_exception=False)
def retrieve_mailbox_list(self): def retrieve_mailbox_list(self):
mailboxes = self.retrieve_service_list(Mailbox.api_name) mailboxes = self.retrieve_service_list(Mailbox.api_name)
return [Mailbox.new_from_json(mailbox_data) for mailbox_data in mailboxes] return [Mailbox.new_from_json(mailbox_data) for mailbox_data in mailboxes]

View file

@ -2,6 +2,7 @@
from django import forms from django import forms
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from . import api from . import api
@ -57,3 +58,39 @@ class MailForm(forms.Form):
"forward": self.cleaned_data["forward"], "forward": self.cleaned_data["forward"],
} }
return serialized_data return serialized_data
class MailboxCreateForm(forms.Form):
error_messages = {
'password_mismatch': _('The two password fields didnt match.'),
}
name = forms.CharField()
password = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
)
def clean_password2(self):
password = self.cleaned_data.get("password")
password2 = self.cleaned_data.get("password2")
if password and password2 and password != password2:
raise ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def serialize(self):
assert self.is_valid()
serialized_data = {
"name": self.cleaned_data["name"],
"password": self.cleaned_data["password2"],
}
return serialized_data

View file

@ -0,0 +1,20 @@
{% extends "musician/base.html" %}
{% load bootstrap4 i18n %}
{% block content %}
<h1 class="service-name">{{ service.verbose_name }}</h1>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<a class="btn btn-light mr-2" href="{% url 'musician:mailbox-list' %}">{% trans "Cancel" %}</a>
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
{% if form.instance %}
<div class="float-right">
<a class="btn btn-danger" href="{# TODO url 'musician:mailbox-delete' view.kwargs.pk #}">{% trans "Delete" %}</a>
</div>
{% endif %}
{% endbuttons %}
</form>
{% endblock %}

View file

@ -35,6 +35,8 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
{% include "musician/components/table_paginator.html" %} {% include "musician/components/table_paginator.html" %}
</div> </table>
<a class="btn btn-primary mt-4 mb-4" href="{% url 'musician:mailbox-create' %}">{% trans "New mailbox" %}</a>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -24,6 +24,7 @@ urlpatterns = [
path('address/<int:pk>/', views.MailUpdateView.as_view(), name='address-update'), path('address/<int:pk>/', views.MailUpdateView.as_view(), name='address-update'),
path('address/<int:pk>/delete/', views.AddressDeleteView.as_view(), name='address-delete'), path('address/<int:pk>/delete/', views.AddressDeleteView.as_view(), name='address-delete'),
path('mailboxes/', views.MailboxesView.as_view(), name='mailbox-list'), path('mailboxes/', views.MailboxesView.as_view(), name='mailbox-list'),
path('mailboxes/new/', views.MailboxCreateView.as_view(), name='mailbox-create'),
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'), path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
path('databases/', views.DatabasesView.as_view(), name='database-list'), path('databases/', views.DatabasesView.as_view(), name='database-list'),
path('saas/', views.SaasView.as_view(), name='saas-list'), path('saas/', views.SaasView.as_view(), name='saas-list'),

View file

@ -1,3 +1,5 @@
import logging
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
@ -16,7 +18,7 @@ from requests.exceptions import HTTPError
from . import api, get_version from . import api, get_version
from .auth import login as auth_login from .auth import login as auth_login
from .auth import logout as auth_logout from .auth import logout as auth_logout
from .forms import LoginForm, MailForm from .forms import LoginForm, MailForm, MailboxCreateForm
from .mixins import (CustomContextMixin, ExtendedPaginationMixin, from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
UserTokenRequiredMixin) UserTokenRequiredMixin)
from .models import (Address, Bill, DatabaseService, Mailbox, MailinglistService, from .models import (Address, Bill, DatabaseService, Mailbox, MailinglistService,
@ -25,6 +27,9 @@ from .settings import ALLOWED_RESOURCES
from .utils import get_bootstraped_percent from .utils import get_bootstraped_percent
logger = logging.getLogger(__name__)
class DashboardView(CustomContextMixin, UserTokenRequiredMixin, TemplateView): class DashboardView(CustomContextMixin, UserTokenRequiredMixin, TemplateView):
template_name = "musician/dashboard.html" template_name = "musician/dashboard.html"
extra_context = { extra_context = {
@ -315,6 +320,30 @@ class MailboxesView(ServiceListView):
} }
class MailboxCreateView(CustomContextMixin, UserTokenRequiredMixin, FormView):
service_class = Mailbox
template_name = "musician/mailbox_form.html"
form_class = MailboxCreateForm
success_url = reverse_lazy("musician:mailbox-list")
extra_context = {'service': service_class}
def form_valid(self, form):
serialized_data = form.serialize()
status, response = self.orchestra.create_mailbox(serialized_data)
if status >= 400:
if status == 400:
# handle errors & add to form (they will be rendered)
form.add_error(field=None, error=response)
return self.form_invalid(form)
else:
logger.error("{}: {}".format(status, response[:120]))
msg = "Sorry, an error occurred while processing your request ({})".format(status)
form.add_error(field='__all__', error=msg)
return super().form_valid(form)
class DatabasesView(ServiceListView): class DatabasesView(ServiceListView):
template_name = "musician/databases.html" template_name = "musician/databases.html"
service_class = DatabaseService service_class = DatabaseService