diff --git a/forms.py b/forms.py index 8c45568..181e2d1 100644 --- a/forms.py +++ b/forms.py @@ -1,7 +1,9 @@ from django import forms from django.contrib.auth.models import User -from django.contrib.auth.forms import UserCreationForm, UserChangeForm -from .models import UserProfile +from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm +from django.utils.translation import gettext as _ +from .models import UserProfile, get_userprofile +from users import emails class UserRegistrationForm(UserCreationForm): @@ -24,6 +26,72 @@ class UserProfileFormLanguageOnly(forms.ModelForm): fields = ['language_code'] +class UserPasswordChangeForm(PasswordChangeForm): + email = forms.EmailField() + first_name = forms.CharField(max_length=150) + last_name = forms.CharField(max_length=150) + field_order = ["email", "first_name", "last_name", "old_password", "new_password1", "new_password2"] + + def __init__(self, request): + self.request = request + # + data = request.POST or {'email': request.user.email, 'first_name': request.user.first_name, 'last_name': request.user.last_name} + # + super().__init__(request.user, data) + self.fields['old_password'].widget.attrs.update({'autofocus': False}) + self.fields['old_password'].required = False + + def clean_old_password(self): + """ + Validation of old_password field only, if set. + """ + old_password = self.cleaned_data["old_password"] + if old_password and not self.user.check_password(old_password): + raise forms.ValidationError( + self.error_messages["password_incorrect"], + code="password_incorrect", + ) + return old_password + + def clean(self): + """ + Validation of new_passwords only if old_password field is set. + """ + clean_data = forms.Form.clean(self) + old_password = clean_data.get('old_password') + # + if old_password: + self.validate_passwords("new_password1", "new_password2") + self.validate_password_for_user(self.user, "new_password2") + return forms.Form.clean(self) + + def save(self, commit=True): + changed = False + for key in self.fields: + new = self.data.get(key) + try: + old = getattr(self.user, key) + except AttributeError: + pass # Is a password field + else: + if new != old: + if key == 'email': + emails.send_validation_mail(self.user, self.request) + up = get_userprofile(self.user) + up.mail_pending = new + up.save() + else: + changed = True + setattr(self.user, key, new) + if self.data.get('new_password1'): + changed = True + self.user.set_password(self.data.get('new_password1')) + # + if changed: + self.user.save() + return changed + + class UserActivationForm(UserChangeForm): password = None diff --git a/migrations/0004_userprofile_mail_pending.py b/migrations/0004_userprofile_mail_pending.py new file mode 100644 index 0000000..f83fcc9 --- /dev/null +++ b/migrations/0004_userprofile_mail_pending.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.2 on 2024-10-27 17:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_userprofile_mail_validated'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='mail_pending', + field=models.EmailField(max_length=254, null=True), + ), + ] diff --git a/models.py b/models.py index 0ddcaf0..0d17d45 100644 --- a/models.py +++ b/models.py @@ -30,6 +30,7 @@ class UserProfile(models.Model): timezone = models.CharField(max_length=150, default='UTC', choices=[(t, t) for t in pytz.common_timezones]) language_code = models.CharField(max_length=150, default='en', choices=settings.LANGUAGES) mail_validated = models.BooleanField(default=False) + mail_pending = models.EmailField(null=True) def export_key(self): return self.user.username diff --git a/templates/users/profile.html b/templates/users/profile.html index b4cd62b..f91cb87 100644 --- a/templates/users/profile.html +++ b/templates/users/profile.html @@ -4,7 +4,14 @@ {% block content %}
diff --git a/templates/users/profile_formdata.html b/templates/users/profile_formdata.html deleted file mode 100644 index 3dd2aab..0000000 --- a/templates/users/profile_formdata.html +++ /dev/null @@ -1,6 +0,0 @@ -{% load i18n %} - -{% get_current_language as LANGUAGE_CODE %} -