(Draft) Add view to create addresses

This commit is contained in:
Santiago L 2021-06-23 13:47:27 +02:00
parent 30bb572589
commit f635721831
7 changed files with 82 additions and 6 deletions

View file

@ -62,7 +62,7 @@ class Orchestra(object):
return response.json().get("token", None)
def request(self, verb, resource=None, url=None, render_as="json", querystring=None, raise_exception=True):
def request(self, verb, resource=None, url=None, data=None, render_as="json", querystring=None, raise_exception=True):
assert verb in ["HEAD", "GET", "POST", "PATCH", "PUT", "DELETE"]
if resource is not None:
url = self.build_absolute_uri(resource)
@ -73,8 +73,11 @@ class Orchestra(object):
url = "{}?{}".format(url, querystring)
verb = getattr(self.session, verb.lower())
response = verb(url, headers={"Authorization": "Token {}".format(
self.auth_token)}, allow_redirects=False)
headers = {
"Authorization": "Token {}".format(self.auth_token),
"Content-Type": "application/json",
}
response = verb(url, json=data, headers=headers, allow_redirects=False)
if raise_exception:
response.raise_for_status()
@ -109,6 +112,15 @@ class Orchestra(object):
raise Http404(_("No domain found matching the query"))
return bill_pdf
def create_mail_address(self, data):
resource = '{}-list'.format(MailService.api_name)
# transform form data to expected format
data["domain"] = {"url": data["domain"]}
data["mailboxes"] = [{"url": mbox} for mbox in data["mailboxes"]]
return self.request("POST", resource=resource, data=data)
def retrieve_mail_address_list(self, querystring=None):
def get_mailbox_id(value):
mailboxes = value.get('mailboxes')
@ -139,7 +151,7 @@ class Orchestra(object):
# PATCH to include Pangea addresses not shown by orchestra
# described on issue #4
raw_mailboxes = self.retrieve_service_list('mailbox')
raw_mailboxes = self.retrieve_mailbox_list()
for mailbox in raw_mailboxes:
if mailbox['addresses'] == []:
address_data = {
@ -155,6 +167,11 @@ class Orchestra(object):
return addresses
def retrieve_mailbox_list(self):
# TODO(@slamora) encapsulate as a Service class
raw_mailboxes = self.retrieve_service_list('mailbox')
return raw_mailboxes
def retrieve_domain(self, pk):
path = API_PATHS.get('domain-detail').format_map({'pk': pk})

View file

@ -1,5 +1,7 @@
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError
from . import api
@ -20,3 +22,23 @@ class LoginForm(AuthenticationForm):
self.user = orchestra.retrieve_profile()
return self.cleaned_data
class MailForm(forms.Form):
name = forms.CharField()
domain = forms.ChoiceField()
mailboxes = forms.MultipleChoiceField(required=False)
forward = forms.EmailField(required=False)
def __init__(self, *args, **kwargs):
domains = kwargs.pop('domains')
mailboxes = kwargs.pop('mailboxes')
super().__init__(*args, **kwargs)
self.fields['domain'].choices = [(d.url, d.name) for d in domains]
self.fields['mailboxes'].choices = [(m['url'], m['name']) for m in mailboxes]
def clean(self):
cleaned_data = super().clean()
if not cleaned_data.get('mailboxes') and not cleaned_data.get('forward'):
raise ValidationError("A mailbox or forward address should be provided.")
return cleaned_data

View file

@ -161,7 +161,7 @@ class DatabaseService(OrchestraModel):
return super().new_from_json(data=data, users=users, usage=usage)
@classmethod
def get_usage(self, data):
def get_usage(cls, data):
try:
resources = data['resources']
resource_disk = {}
@ -201,6 +201,7 @@ class Domain(OrchestraModel):
"mails": [],
"usage": {},
"websites": [],
"url": None,
}
@classmethod

View file

@ -41,4 +41,5 @@
</tbody>
{% include "musician/components/table_paginator.html" %}
</table>
<a class="btn btn-primary mt-4 mb-4" href="{% url 'musician:mail-create' %}">{% trans "New mail address" %}</a>
{% endblock %}

View file

@ -0,0 +1,10 @@
{% extends "musician/base.html" %}
{% load i18n %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">OK</button>
</form>
{% endblock %}

View file

@ -20,6 +20,7 @@ urlpatterns = [
path('bills/<int:pk>/download/', views.BillDownloadView.as_view(), name='bill-download'),
path('profile/', views.ProfileView.as_view(), name='profile'),
path('mails/', views.MailView.as_view(), name='mails'),
path('mails/new/', views.MailCreateView.as_view(), name='mail-create'),
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
path('databases/', views.DatabasesView.as_view(), name='databases'),
path('software-as-a-service/', views.SaasView.as_view(), name='saas'),

View file

@ -11,11 +11,12 @@ from django.views.generic.base import RedirectView, TemplateView
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormView
from django.views.generic.list import ListView
from requests.exceptions import HTTPError
from . import api, get_version
from .auth import login as auth_login
from .auth import logout as auth_logout
from .forms import LoginForm
from .forms import LoginForm, MailForm
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
UserTokenRequiredMixin)
from .models import (Bill, DatabaseService, MailinglistService, MailService,
@ -201,6 +202,29 @@ class MailView(ServiceListView):
return context
class MailCreateView(CustomContextMixin, UserTokenRequiredMixin, FormView):
service_class = MailService
template_name = "musician/mail_form.html"
form_class = MailForm
success_url = reverse_lazy("musician:mails")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['domains'] = self.orchestra.retrieve_domain_list()
kwargs['mailboxes'] = self.orchestra.retrieve_mailbox_list()
return kwargs
def form_valid(self, form):
# handle request errors e.g. 400 validation
try:
self.orchestra.create_mail_address(form.cleaned_data)
except HTTPError as e:
form.add_error(field='__all__', error=e)
return self.form_invalid(form)
return super().form_valid(form)
class MailingListsView(ServiceListView):
service_class = MailinglistService
template_name = "musician/mailinglists.html"