(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) 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"] assert verb in ["HEAD", "GET", "POST", "PATCH", "PUT", "DELETE"]
if resource is not None: if resource is not None:
url = self.build_absolute_uri(resource) url = self.build_absolute_uri(resource)
@ -73,8 +73,11 @@ class Orchestra(object):
url = "{}?{}".format(url, querystring) url = "{}?{}".format(url, querystring)
verb = getattr(self.session, verb.lower()) verb = getattr(self.session, verb.lower())
response = verb(url, headers={"Authorization": "Token {}".format( headers = {
self.auth_token)}, allow_redirects=False) "Authorization": "Token {}".format(self.auth_token),
"Content-Type": "application/json",
}
response = verb(url, json=data, headers=headers, allow_redirects=False)
if raise_exception: if raise_exception:
response.raise_for_status() response.raise_for_status()
@ -109,6 +112,15 @@ class Orchestra(object):
raise Http404(_("No domain found matching the query")) raise Http404(_("No domain found matching the query"))
return bill_pdf 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 retrieve_mail_address_list(self, querystring=None):
def get_mailbox_id(value): def get_mailbox_id(value):
mailboxes = value.get('mailboxes') mailboxes = value.get('mailboxes')
@ -139,7 +151,7 @@ class Orchestra(object):
# PATCH to include Pangea addresses not shown by orchestra # PATCH to include Pangea addresses not shown by orchestra
# described on issue #4 # described on issue #4
raw_mailboxes = self.retrieve_service_list('mailbox') raw_mailboxes = self.retrieve_mailbox_list()
for mailbox in raw_mailboxes: for mailbox in raw_mailboxes:
if mailbox['addresses'] == []: if mailbox['addresses'] == []:
address_data = { address_data = {
@ -155,6 +167,11 @@ class Orchestra(object):
return addresses 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): def retrieve_domain(self, pk):
path = API_PATHS.get('domain-detail').format_map({'pk': 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.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError
from . import api from . import api
@ -20,3 +22,23 @@ class LoginForm(AuthenticationForm):
self.user = orchestra.retrieve_profile() self.user = orchestra.retrieve_profile()
return self.cleaned_data 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) return super().new_from_json(data=data, users=users, usage=usage)
@classmethod @classmethod
def get_usage(self, data): def get_usage(cls, data):
try: try:
resources = data['resources'] resources = data['resources']
resource_disk = {} resource_disk = {}
@ -201,6 +201,7 @@ class Domain(OrchestraModel):
"mails": [], "mails": [],
"usage": {}, "usage": {},
"websites": [], "websites": [],
"url": None,
} }
@classmethod @classmethod

View file

@ -41,4 +41,5 @@
</tbody> </tbody>
{% include "musician/components/table_paginator.html" %} {% include "musician/components/table_paginator.html" %}
</table> </table>
<a class="btn btn-primary mt-4 mb-4" href="{% url 'musician:mail-create' %}">{% trans "New mail address" %}</a>
{% endblock %} {% 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('bills/<int:pk>/download/', views.BillDownloadView.as_view(), name='bill-download'),
path('profile/', views.ProfileView.as_view(), name='profile'), path('profile/', views.ProfileView.as_view(), name='profile'),
path('mails/', views.MailView.as_view(), name='mails'), 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('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
path('databases/', views.DatabasesView.as_view(), name='databases'), path('databases/', views.DatabasesView.as_view(), name='databases'),
path('software-as-a-service/', views.SaasView.as_view(), name='saas'), 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.detail import DetailView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.views.generic.list import ListView from django.views.generic.list import ListView
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 from .forms import LoginForm, MailForm
from .mixins import (CustomContextMixin, ExtendedPaginationMixin, from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
UserTokenRequiredMixin) UserTokenRequiredMixin)
from .models import (Bill, DatabaseService, MailinglistService, MailService, from .models import (Bill, DatabaseService, MailinglistService, MailService,
@ -201,6 +202,29 @@ class MailView(ServiceListView):
return context 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): class MailingListsView(ServiceListView):
service_class = MailinglistService service_class = MailinglistService
template_name = "musician/mailinglists.html" template_name = "musician/mailinglists.html"