diff --git a/orchestra/contrib/musician/forms.py b/orchestra/contrib/musician/forms.py
index fa7f4503..6fb90f7e 100644
--- a/orchestra/contrib/musician/forms.py
+++ b/orchestra/contrib/musician/forms.py
@@ -2,12 +2,14 @@ from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
+from django.forms.widgets import HiddenInput
from django.contrib.auth.hashers import make_password
from orchestra.contrib.domains.models import Domain, Record
from orchestra.contrib.mailboxes.models import Address, Mailbox
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
+from orchestra.contrib.saas.models import SaaS
from orchestra.contrib.musician.validators import ValidateZoneMixin
from . import api
@@ -202,3 +204,22 @@ class SystemUsersChangePasswordForm(ChangePasswordForm):
fields = ("password",)
model = SystemUser
+
+class SaasUpdateForm(forms.ModelForm):
+ class Meta:
+ model = SaaS
+ fields = ("is_active", "service", "name", "data", "custom_url")
+
+ def __init__(self, *args, **kwargs):
+ self.user = kwargs.pop('user')
+ super().__init__(*args, **kwargs)
+ self.fields['name'].widget.attrs['readonly'] = True
+ self.fields['service'].widget.attrs['disabled'] = 'disabled'
+ self.fields['data'].widget = HiddenInput()
+ self.fields["custom_url"].widget = HiddenInput()
+
+class NextcloudChangePasswordForm(ChangePasswordForm):
+
+ class Meta:
+ fields = ("password",)
+ model = SaaS
\ No newline at end of file
diff --git a/orchestra/contrib/musician/templates/musician/nextcloud_change_password.html b/orchestra/contrib/musician/templates/musician/nextcloud_change_password.html
new file mode 100644
index 00000000..515ccbab
--- /dev/null
+++ b/orchestra/contrib/musician/templates/musician/nextcloud_change_password.html
@@ -0,0 +1,15 @@
+{% extends "musician/base.html" %}
+{% load bootstrap4 i18n %}
+
+{% block content %}
+
{% trans "Change password" %}: {{ object.name }}
+
+
+{% endblock %}
diff --git a/orchestra/contrib/musician/templates/musician/saas_check_delete.html b/orchestra/contrib/musician/templates/musician/saas_check_delete.html
new file mode 100644
index 00000000..07e4f292
--- /dev/null
+++ b/orchestra/contrib/musician/templates/musician/saas_check_delete.html
@@ -0,0 +1,12 @@
+{% extends "musician/base.html" %}
+{% load i18n %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/orchestra/contrib/musician/templates/musician/saas_form.html b/orchestra/contrib/musician/templates/musician/saas_form.html
new file mode 100644
index 00000000..64d00c14
--- /dev/null
+++ b/orchestra/contrib/musician/templates/musician/saas_form.html
@@ -0,0 +1,41 @@
+{% extends "musician/base.html" %}
+{% load bootstrap4 i18n %}
+
+
+{% block content %}
+
+
+
+{% trans "Go back" %}
+
+
+ {% if form.instance.pk %}
+ {% trans "Update SaaS" %} {{ saas.name }}
+ {% else %}
+ {% trans "Create SaaS" %}
+ {% endif %}
+
+
+
+{% endblock %}
+
diff --git a/orchestra/contrib/musician/templates/musician/saas_list.html b/orchestra/contrib/musician/templates/musician/saas_list.html
index 7a62d6d1..dc262071 100644
--- a/orchestra/contrib/musician/templates/musician/saas_list.html
+++ b/orchestra/contrib/musician/templates/musician/saas_list.html
@@ -20,6 +20,7 @@
{% trans "Status" %} |
{% trans "Service" %} |
{% trans "Service info" %} |
+ |
@@ -43,6 +44,12 @@
{{ value }}
{% endfor %}
+
+
+
+
+
+ |
{% empty %}
@@ -59,4 +66,5 @@
{% include "musician/components/table_paginator.html" %}
+{% trans "New SaaS" %}
{% endblock %}
diff --git a/orchestra/contrib/musician/urls.py b/orchestra/contrib/musician/urls.py
index 42fe9e18..14748806 100644
--- a/orchestra/contrib/musician/urls.py
+++ b/orchestra/contrib/musician/urls.py
@@ -51,6 +51,9 @@ urlpatterns = [
path('databases/', views.DatabaseListView.as_view(), name='database-list'),
path('saas/', views.SaasListView.as_view(), name='saas-list'),
+ path('saas//', views.SaasUpdateView.as_view(), name='saas-update'),
+ path('saas//delete/', views.SaasDeleteView.as_view(), name='saas-delete'),
+ path('saas//nextcloud-change-password/', views.NextcloudChangePasswordView.as_view(), name='nextcloud-password'),
path('webappusers/', views.WebappUserListView.as_view(), name='webappuser-list'),
path('webappuser//change-password/', views.WebappUserChangePasswordView.as_view(), name='webappuser-password'),
diff --git a/orchestra/contrib/musician/views.py b/orchestra/contrib/musician/views.py
index 4034ff58..f3a85314 100644
--- a/orchestra/contrib/musician/views.py
+++ b/orchestra/contrib/musician/views.py
@@ -42,7 +42,7 @@ from .auth import logout as auth_logout
from .forms import (LoginForm, MailboxChangePasswordForm, MailboxCreateForm,
MailboxSearchForm, MailboxUpdateForm, MailForm,
RecordCreateForm, RecordUpdateForm, WebappUsersChangePasswordForm,
- SystemUsersChangePasswordForm)
+ SystemUsersChangePasswordForm, SaasUpdateForm, NextcloudChangePasswordForm)
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
UserTokenRequiredMixin)
from .models import Address as AddressService
@@ -623,6 +623,40 @@ class SaasListView(ServiceListView):
'title': _('Software as a Service'),
}
+class SaasUpdateView(CustomContextMixin, UserTokenRequiredMixin, UpdateView):
+ model = SaaS
+ form_class = SaasUpdateForm
+ template_name = "musician/saas_form.html"
+
+ def get_queryset(self):
+ qs = SaaS.objects.filter(account=self.request.user)
+ return qs
+
+ def get_success_url(self):
+ return reverse_lazy("musician:saas-list")
+
+ def get_form_kwargs(self):
+ kwargs = super().get_form_kwargs()
+ kwargs["user"] = self.request.user
+ return kwargs
+
+class NextcloudChangePasswordView(CustomContextMixin, UserTokenRequiredMixin, UpdateView):
+ template_name = "musician/nextcloud_change_password.html"
+ model = SaaS
+ form_class = NextcloudChangePasswordForm
+ success_url = reverse_lazy("musician:saas-list")
+
+ def get_queryset(self):
+ return self.model.objects.filter(account=self.request.user)
+
+class SaasDeleteView(CustomContextMixin, UserTokenRequiredMixin, DeleteView):
+ template_name = "musician/saas_check_delete.html"
+ model = SaaS
+ success_url = reverse_lazy("musician:saas-list")
+
+ def get_queryset(self):
+ return self.model.objects.filter(account=self.request.user)
+
class DomainDetailView(CustomContextMixin, UserTokenRequiredMixin, DetailView):
template_name = "musician/domain_detail.html"