hobo/hobo/environment/forms.py

213 lines
6.6 KiB
Python

# hobo - portal to configure and deploy applications
# Copyright (C) 2015-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms
from django.conf import settings
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.template.defaultfilters import slugify
from django.utils.translation import gettext_lazy as _
from .models import Authentic, BiJoe, Chrono, Combo, Fargo, Hobo, Lingo, Passerelle, Variable, Wcs, Welco
from .utils import get_variable
from .validators import validate_service_url
EXCLUDED_FIELDS = (
'last_operational_check_timestamp',
'last_operational_success_timestamp',
'legacy_urls',
'secret_key',
'secondary',
)
class BaseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
choices = self.get_template_choices()
super().__init__(*args, **kwargs)
if len(choices) < 2 or self.instance.id:
del self.fields['template_name']
else:
self.fields['template_name'].choices = choices
self.fields['template_name'].widget = forms.Select(choices=choices)
# the template name cannot change once the object exists, display the
# choice that was selected as an additional, disabled, <select> widget.
if self.instance.id and len(choices) > 1:
self.fields['template_name_readonly'] = forms.fields.CharField(
label=_('Template'), required=False, initial=self.instance.template_name
)
self.fields['template_name_readonly'].widget = forms.Select(choices=choices)
self.fields['template_name_readonly'].widget.attrs['disabled'] = 'disabled'
if self.instance.id:
del self.fields['slug']
del self.fields['base_url']
def get_template_choices(self):
if not settings.SERVICE_TEMPLATES:
return []
service_id = self.Meta.model.Extra.service_id
return settings.SERVICE_TEMPLATES.get(service_id, [])
def clean_base_url(self):
url = self.cleaned_data['base_url']
validate_service_url(url)
return url
def save(self, commit=True):
if not self.instance.slug:
base_slug = slugify(self.instance.title)
slug = base_slug
i = 1
while True:
try:
self.Meta.model.objects.get(slug=slug)
except self.Meta.model.DoesNotExist:
break
i += 1
slug = '%s-%s' % (base_slug, i)
self.instance.slug = slug
choices = self.get_template_choices()
if not self.instance.id and len(choices) == 1:
self.instance.template_name = choices[0][0]
return super().save(commit=commit)
class AuthenticForm(BaseForm):
class Meta:
model = Authentic
exclude = EXCLUDED_FIELDS
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.instance.is_operational() and not self.initial.get('use_as_idp_for_self'):
del self.fields['use_as_idp_for_self']
def save(self, commit=True):
if not self.instance.use_as_idp_for_self:
if self.cleaned_data.get('use_as_idp_for_self'):
# this idp was just marked as the idp to use, unmark all others
Authentic.objects.update(use_as_idp_for_self=False)
return super().save(commit=commit)
class WcsForm(BaseForm):
class Meta:
model = Wcs
exclude = EXCLUDED_FIELDS
class PasserelleForm(BaseForm):
class Meta:
model = Passerelle
exclude = EXCLUDED_FIELDS
class ComboForm(BaseForm):
class Meta:
model = Combo
exclude = EXCLUDED_FIELDS
class FargoForm(BaseForm):
class Meta:
model = Fargo
exclude = EXCLUDED_FIELDS
class WelcoForm(BaseForm):
class Meta:
model = Welco
exclude = EXCLUDED_FIELDS
class ChronoForm(BaseForm):
class Meta:
model = Chrono
exclude = EXCLUDED_FIELDS
class LingoForm(BaseForm):
class Meta:
model = Lingo
exclude = EXCLUDED_FIELDS
class BiJoeForm(BaseForm):
class Meta:
model = BiJoe
exclude = EXCLUDED_FIELDS
class HoboForm(BaseForm):
class Meta:
model = Hobo
exclude = EXCLUDED_FIELDS
class VariableForm(forms.ModelForm):
class Meta:
model = Variable
exclude = ('service_type', 'service_pk', 'auto')
def __init__(self, service=None, **kwargs):
self.service = service
super().__init__(**kwargs)
def save(self, commit=True):
if self.service:
self.instance.service = self.service
return super().save(commit=commit)
class VariablesFormMixin:
form_class = None
success_message = None
variables = []
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
form_data = self.request.POST
else:
form_data = None
initial_data = {}
for variable_name in self.variables:
initial_data[variable_name] = get_variable(variable_name).value
context['form'] = self.form_class(form_data, initial=initial_data)
return context
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if not form.is_valid():
return self.get(request, *args, **kwargs)
changed = False
for variable_name in self.variables:
variable = get_variable(variable_name)
if variable.value != form.cleaned_data[variable_name]:
variable.value = form.cleaned_data[variable_name]
variable.save()
changed = True
if changed and self.success_message:
messages.info(self.request, self.success_message)
return HttpResponseRedirect('.')
class ImportForm(forms.Form):
parameters_json = forms.FileField(label=_('Parameters Export File'))