2023-11-21 11:48:39 +00:00
|
|
|
|
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 _
|
2024-10-30 12:29:34 +00:00
|
|
|
|
from orchestra.utils.python import random_ascii
|
2024-10-29 18:14:43 +00:00
|
|
|
|
from django.forms.widgets import HiddenInput
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
2024-04-16 18:49:11 +00:00
|
|
|
|
from django.contrib.auth.hashers import make_password
|
|
|
|
|
|
2023-11-29 11:16:17 +00:00
|
|
|
|
from orchestra.contrib.domains.models import Domain, Record
|
2023-11-23 11:50:55 +00:00
|
|
|
|
from orchestra.contrib.mailboxes.models import Address, Mailbox
|
2024-04-16 18:49:11 +00:00
|
|
|
|
from orchestra.contrib.systemusers.models import WebappUsers, SystemUser
|
2024-10-29 18:14:43 +00:00
|
|
|
|
from orchestra.contrib.saas.models import SaaS
|
2023-11-29 14:03:12 +00:00
|
|
|
|
from orchestra.contrib.musician.validators import ValidateZoneMixin
|
2023-11-23 11:50:55 +00:00
|
|
|
|
|
2023-11-21 11:48:39 +00:00
|
|
|
|
from . import api
|
|
|
|
|
|
2023-11-21 12:56:09 +00:00
|
|
|
|
|
2023-11-21 11:48:39 +00:00
|
|
|
|
class LoginForm(AuthenticationForm):
|
|
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
username = self.cleaned_data.get('username')
|
|
|
|
|
password = self.cleaned_data.get('password')
|
|
|
|
|
|
|
|
|
|
if username is not None and password:
|
2023-11-21 12:56:09 +00:00
|
|
|
|
orchestra = api.Orchestra(self.request, username=username, password=password)
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
2023-11-21 12:56:09 +00:00
|
|
|
|
if orchestra.user is None:
|
2023-11-21 11:48:39 +00:00
|
|
|
|
raise self.get_invalid_login_error()
|
|
|
|
|
else:
|
|
|
|
|
self.username = username
|
2023-11-21 12:56:09 +00:00
|
|
|
|
self.user = orchestra.user
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
2024-04-16 18:49:11 +00:00
|
|
|
|
class ChangePasswordForm(forms.ModelForm):
|
|
|
|
|
error_messages = {
|
|
|
|
|
'password_mismatch': _('The two password fields didn’t match.'),
|
|
|
|
|
}
|
|
|
|
|
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."),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("password",)
|
|
|
|
|
model = WebappUsers
|
|
|
|
|
|
|
|
|
|
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 clean(self):
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
password = cleaned_data.get("password")
|
|
|
|
|
cleaned_data['password'] = make_password(password)
|
|
|
|
|
return cleaned_data
|
|
|
|
|
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
class MailForm(forms.ModelForm):
|
|
|
|
|
class Meta:
|
|
|
|
|
model = Address
|
|
|
|
|
fields = ("name", "domain", "mailboxes", "forward")
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
2023-11-23 11:50:55 +00:00
|
|
|
|
self.user = kwargs.pop('user')
|
2023-11-21 11:48:39 +00:00
|
|
|
|
super().__init__(*args, **kwargs)
|
2023-11-23 11:50:55 +00:00
|
|
|
|
self.fields['domain'].queryset = Domain.objects.filter(account=self.user)
|
|
|
|
|
self.fields['mailboxes'].queryset = Mailbox.objects.filter(account=self.user)
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
def save(self, commit=True):
|
|
|
|
|
instance = super().save(commit=False)
|
|
|
|
|
instance.account = self.user
|
|
|
|
|
if commit:
|
|
|
|
|
super().save(commit=True)
|
|
|
|
|
return instance
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
|
2024-04-16 18:49:11 +00:00
|
|
|
|
class MailboxChangePasswordForm(ChangePasswordForm):
|
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("password",)
|
|
|
|
|
model = Mailbox
|
|
|
|
|
|
2024-04-16 18:49:11 +00:00
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
class MailboxCreateForm(forms.ModelForm):
|
2023-11-21 11:48:39 +00:00
|
|
|
|
error_messages = {
|
|
|
|
|
'password_mismatch': _('The two password fields didn’t 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."),
|
|
|
|
|
)
|
2023-11-23 11:50:55 +00:00
|
|
|
|
addresses = forms.ModelMultipleChoiceField(queryset=Address.objects.none(), required=False)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("name", "password", "password2", "addresses")
|
|
|
|
|
model = Mailbox
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
2023-11-23 11:50:55 +00:00
|
|
|
|
user = kwargs.pop('user')
|
2023-11-21 11:48:39 +00:00
|
|
|
|
super().__init__(*args, **kwargs)
|
2023-11-23 11:50:55 +00:00
|
|
|
|
self.fields['addresses'].queryset = Address.objects.filter(account=user)
|
|
|
|
|
self.user = user
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
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',
|
|
|
|
|
)
|
2024-04-16 18:49:11 +00:00
|
|
|
|
return password
|
2024-04-18 14:58:37 +00:00
|
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
cleaned_data = super().clean()
|
|
|
|
|
password = cleaned_data.get("password")
|
|
|
|
|
cleaned_data['password'] = make_password(password)
|
|
|
|
|
return cleaned_data
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
def save(self, commit=True):
|
|
|
|
|
instance = super().save(commit=False)
|
|
|
|
|
instance.account = self.user
|
|
|
|
|
if commit:
|
|
|
|
|
super().save(commit=True)
|
|
|
|
|
return instance
|
2023-11-21 11:48:39 +00:00
|
|
|
|
|
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
class MailboxUpdateForm(forms.ModelForm):
|
2023-11-21 11:48:39 +00:00
|
|
|
|
addresses = forms.MultipleChoiceField(required=False)
|
2023-11-29 11:16:17 +00:00
|
|
|
|
|
2023-11-23 11:50:55 +00:00
|
|
|
|
class Meta:
|
|
|
|
|
fields = ('addresses',)
|
|
|
|
|
model = Mailbox
|
2023-11-29 11:16:17 +00:00
|
|
|
|
|
|
|
|
|
|
2024-01-30 10:31:24 +00:00
|
|
|
|
class MailboxSearchForm(forms.Form):
|
|
|
|
|
name = forms.CharField(required=False)
|
|
|
|
|
address = forms.CharField(required=False)
|
|
|
|
|
|
2023-11-29 14:03:12 +00:00
|
|
|
|
class RecordCreateForm(ValidateZoneMixin, forms.ModelForm):
|
2023-11-29 11:16:17 +00:00
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = Record
|
|
|
|
|
fields = ("ttl", "type", "value")
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
self.domain = kwargs.pop('domain')
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def save(self, commit=True):
|
|
|
|
|
instance = super().save(commit=False)
|
|
|
|
|
instance.domain = self.domain
|
|
|
|
|
if commit:
|
|
|
|
|
super().save(commit=True)
|
|
|
|
|
return instance
|
2023-11-29 11:42:54 +00:00
|
|
|
|
|
|
|
|
|
|
2023-11-29 14:03:12 +00:00
|
|
|
|
class RecordUpdateForm(ValidateZoneMixin, forms.ModelForm):
|
2023-11-29 11:42:54 +00:00
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = Record
|
|
|
|
|
fields = ("ttl", "type", "value")
|
2023-11-29 14:03:12 +00:00
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
self.domain = self.instance.domain
|
2024-04-16 18:49:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WebappUsersChangePasswordForm(ChangePasswordForm):
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("password",)
|
|
|
|
|
model = WebappUsers
|
|
|
|
|
|
|
|
|
|
class SystemUsersChangePasswordForm(ChangePasswordForm):
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("password",)
|
|
|
|
|
model = SystemUser
|
2024-04-23 19:06:48 +00:00
|
|
|
|
|
2024-10-30 12:29:34 +00:00
|
|
|
|
from orchestra.forms.widgets import SpanWidget
|
|
|
|
|
from orchestra.forms import widgets
|
|
|
|
|
from django.utils.safestring import mark_safe
|
|
|
|
|
from rest_framework import serializers
|
2024-10-29 18:14:43 +00:00
|
|
|
|
class SaasUpdateForm(forms.ModelForm):
|
2024-10-30 12:29:34 +00:00
|
|
|
|
site_url = forms.CharField(label=_("Site URL"), widget=SpanWidget(), required=False)
|
|
|
|
|
|
|
|
|
|
# dos campos para wordpress
|
|
|
|
|
blog_id = forms.IntegerField(label=("Blog ID"), widget=widgets.SpanWidget, required=False,
|
|
|
|
|
help_text=_("ID of this blog used by WordPress, the only attribute that doesn't change."))
|
|
|
|
|
email = forms.EmailField(label=_("Email"),
|
|
|
|
|
help_text=_("A new user will be created if the above email address is not in the database.<br>"
|
|
|
|
|
"The username and password will be mailed to this email address."))
|
|
|
|
|
|
2024-10-29 18:14:43 +00:00
|
|
|
|
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
|
2024-10-30 12:29:34 +00:00
|
|
|
|
self.fields['site_url'].widget.attrs['readonly'] = True
|
|
|
|
|
self.fields['email'].widget.attrs['readonly'] = True
|
|
|
|
|
self.fields['blog_id'].widget.attrs['readonly'] = True
|
|
|
|
|
self.fields['service'].widget = HiddenInput()
|
2024-10-29 18:14:43 +00:00
|
|
|
|
self.fields['data'].widget = HiddenInput()
|
|
|
|
|
self.fields["custom_url"].widget = HiddenInput()
|
2024-10-30 12:29:34 +00:00
|
|
|
|
|
|
|
|
|
# asignar valor al field site_url
|
|
|
|
|
site_domain = self.instance.get_site_domain()
|
|
|
|
|
context = {
|
|
|
|
|
'site_name': '<site_name>',
|
|
|
|
|
'name': '<site_name>',
|
|
|
|
|
}
|
|
|
|
|
site_domain = site_domain % context
|
|
|
|
|
if '<site_name>' in site_domain:
|
|
|
|
|
site_link = site_domain
|
|
|
|
|
else:
|
|
|
|
|
site_link = '<a href="http://%s">%s</a>' % (site_domain, site_domain)
|
|
|
|
|
self.fields['site_url'].widget.display = site_link
|
|
|
|
|
|
|
|
|
|
if self.instance:
|
|
|
|
|
if self.instance.pk:
|
|
|
|
|
self.fields['data'].required = False
|
|
|
|
|
|
|
|
|
|
if self.instance.service == 'nextcloud':
|
|
|
|
|
self.fields["email"].widget = HiddenInput()
|
|
|
|
|
self.fields["blog_id"].widget = HiddenInput()
|
|
|
|
|
self.fields["email"].required = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.instance.service == 'wordpress':
|
|
|
|
|
admin_url = 'http://%s/wp-admin/' % self.instance.get_site_domain()
|
|
|
|
|
help_text = 'Admin URL: <a href="{0}">{0}</a>'.format(admin_url)
|
|
|
|
|
self.fields['site_url'].help_text = mark_safe(help_text)
|
|
|
|
|
|
|
|
|
|
if self.instance:
|
|
|
|
|
for field in self.declared_fields:
|
|
|
|
|
initial = self.fields[field].initial
|
|
|
|
|
self.fields[field].initial = self.instance.data.get(field, initial)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
super().clean()
|
|
|
|
|
data = {}
|
|
|
|
|
# Update data fields
|
|
|
|
|
for field in self.declared_fields:
|
|
|
|
|
try:
|
|
|
|
|
data[field] = self.cleaned_data[field]
|
|
|
|
|
except KeyError:
|
|
|
|
|
data[field] = self.data[field]
|
|
|
|
|
# Keep old data fields
|
|
|
|
|
for field, value in self.instance.data.items():
|
|
|
|
|
if field not in data:
|
|
|
|
|
try:
|
|
|
|
|
data[field] = self.cleaned_data[field]
|
|
|
|
|
except KeyError:
|
|
|
|
|
data[field] = value
|
|
|
|
|
self.cleaned_data['data'] = data
|
|
|
|
|
|
2024-10-29 18:14:43 +00:00
|
|
|
|
|
|
|
|
|
class NextcloudChangePasswordForm(ChangePasswordForm):
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ("password",)
|
2024-10-30 12:29:34 +00:00
|
|
|
|
model = SaaS
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super(NextcloudChangePasswordForm, self).__init__(*args, **kwargs)
|
|
|
|
|
self.fields['password'].help_text = _("Suggestion: %s") % random_ascii(20)
|
|
|
|
|
|
|
|
|
|
def clean_password(self):
|
|
|
|
|
password = self.cleaned_data.get("password")
|
|
|
|
|
self.fields['password'] = password
|
|
|
|
|
self.instance.set_password(password)
|