mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Added a settings change view for users in the frontend
This commit is contained in:
93
src/pretix/base/forms/__init__.py
Normal file
93
src/pretix/base/forms/__init__.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import copy
|
||||
from django.db import models
|
||||
from django.forms.models import ModelFormMetaclass, BaseModelForm
|
||||
from django import forms
|
||||
from django.utils import six
|
||||
from pretix.base.i18n import I18nFormField
|
||||
from versions.models import Versionable
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class BaseI18nModelForm(BaseModelForm):
|
||||
"""
|
||||
This is a helperclass to construct I18nModelForm
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
event = kwargs.pop('event', None)
|
||||
super().__init__(*args, **kwargs)
|
||||
if event:
|
||||
for k, field in self.fields.items():
|
||||
if isinstance(field, I18nFormField):
|
||||
field.widget.enabled_langcodes = event.settings.get('locales')
|
||||
|
||||
|
||||
class VersionedBaseModelForm(BaseI18nModelForm):
|
||||
"""
|
||||
This is a helperclass to construct VersionedModelForm
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
instance = kwargs.get('instance', None)
|
||||
self.original_instance = copy.copy(instance) if instance else None
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def save(self, commit=True):
|
||||
if self.instance.pk is not None and isinstance(self.instance, Versionable):
|
||||
if self.has_changed() and self.original_instance:
|
||||
new = self.instance
|
||||
old = self.original_instance
|
||||
clone = old.clone()
|
||||
for f in type(self.instance)._meta.get_fields():
|
||||
if f.name not in (
|
||||
'id', 'identity', 'version_start_date', 'version_end_date',
|
||||
'version_birth_date'
|
||||
) and not isinstance(f, (
|
||||
models.ManyToOneRel, models.ManyToManyRel, models.ManyToManyField
|
||||
)):
|
||||
setattr(clone, f.name, getattr(new, f.name))
|
||||
self.instance = clone
|
||||
return super().save(commit)
|
||||
|
||||
|
||||
class VersionedModelForm(six.with_metaclass(ModelFormMetaclass, VersionedBaseModelForm)):
|
||||
"""
|
||||
This is a modified version of I18nModelForm which differs from I18nModelForm in
|
||||
only one way: It executes the .clone() method of an object before saving it back to
|
||||
the database, if the model is a sub-class of versions.models.Versionable. You can
|
||||
safely use this as a base class for all your model forms, it will work out correctly
|
||||
with both versioned and non-versioned models.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class I18nModelForm(six.with_metaclass(ModelFormMetaclass, BaseI18nModelForm)):
|
||||
"""
|
||||
This is a modified version of Django's ModelForm which differs from ModelForm in
|
||||
only one way: The constructor takes one additional optional argument ``event``
|
||||
which may be given an :pyclass:`pretix.base.models.Event` instance. If given, this
|
||||
instance is used to select the visible languages in all I18nFormFields of the form. If
|
||||
not given, all languages will be displayed.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SettingsForm(forms.Form):
|
||||
"""
|
||||
This form is meant to be used for modifying Event- or OrganizerSettings
|
||||
"""
|
||||
BOOL_CHOICES = (
|
||||
('False', _('disabled')),
|
||||
('True', _('enabled')),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.obj = kwargs.pop('obj')
|
||||
kwargs['initial'] = self.obj.settings
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def save(self):
|
||||
for name, field in self.fields.items():
|
||||
value = self.cleaned_data[name]
|
||||
if value is None:
|
||||
del self.obj.settings[name]
|
||||
elif self.obj.settings.get(name, as_type=type(value)) != value:
|
||||
self.obj.settings.set(name, value)
|
||||
94
src/pretix/base/forms/user.py
Normal file
94
src/pretix/base/forms/user.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.hashers import check_password
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from pytz import common_timezones
|
||||
|
||||
from pretix.base.models import User
|
||||
|
||||
|
||||
class UserSettingsForm(forms.ModelForm):
|
||||
error_messages = {
|
||||
'duplicate_identifier': _("There already is an account associated with this e-mail address. "
|
||||
"Please choose a different one."),
|
||||
'pw_current': _("Please enter your current password if you want to change your e-mail "
|
||||
"address or password."),
|
||||
'pw_current_wrong': _("The current password you entered was not correct."),
|
||||
'pw_mismatch': _("Please enter the same password twice"),
|
||||
}
|
||||
|
||||
old_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Your current password"),
|
||||
widget=forms.PasswordInput())
|
||||
new_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("New password"),
|
||||
widget=forms.PasswordInput())
|
||||
new_pw_repeat = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Repeat new password"),
|
||||
widget=forms.PasswordInput())
|
||||
# timezone = forms.ChoiceField(
|
||||
# choices=((a, a) for a in common_timezones),
|
||||
# label=_("Default timezone"),
|
||||
# )
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
'givenname',
|
||||
'familyname',
|
||||
'locale',
|
||||
# 'timezone',
|
||||
'email'
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop('user')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean_old_pw(self):
|
||||
old_pw = self.cleaned_data.get('old_pw')
|
||||
if old_pw and not check_password(old_pw, self.user.password):
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['pw_current_wrong'],
|
||||
code='pw_current_wrong',
|
||||
)
|
||||
|
||||
return old_pw
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data['email']
|
||||
if User.objects.filter(Q(identifier=email) & ~Q(pk=self.instance.pk)).exists():
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['duplicate_identifier'],
|
||||
code='duplicate_identifier',
|
||||
)
|
||||
return email
|
||||
|
||||
def clean_new_pw_repeat(self):
|
||||
password1 = self.cleaned_data.get('new_pw')
|
||||
password2 = self.cleaned_data.get('new_pw_repeat')
|
||||
if password1 and password1 != password2:
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['pw_mismatch'],
|
||||
code='pw_mismatch'
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
password1 = self.cleaned_data.get('new_pw')
|
||||
email = self.cleaned_data.get('email')
|
||||
old_pw = self.cleaned_data.get('old_pw')
|
||||
|
||||
if (password1 or email != self.user.email) and not old_pw:
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['pw_current'],
|
||||
code='pw_current'
|
||||
)
|
||||
|
||||
if password1:
|
||||
self.instance.set_password(password1)
|
||||
self.instance.identifier = email
|
||||
|
||||
return self.cleaned_data
|
||||
Reference in New Issue
Block a user