diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 6116cd0b36..d0d725c2f8 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -124,21 +124,31 @@ class EditUserForm(HelperForm): class SetPasswordForm(HelperForm): """Form for setting user password.""" - enter_password = forms.CharField(max_length=100, - min_length=8, - required=True, - initial='', - widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), - label=_('Enter password'), - help_text=_('Enter new password')) + enter_password = forms.CharField( + max_length=100, + min_length=8, + required=True, + initial='', + widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), + label=_('Enter password'), + help_text=_('Enter new password') + ) - confirm_password = forms.CharField(max_length=100, - min_length=8, - required=True, - initial='', - widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), - label=_('Confirm password'), - help_text=_('Confirm new password')) + confirm_password = forms.CharField( + max_length=100, + min_length=8, + required=True, + initial='', + widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), + label=_('Confirm password'), + help_text=_('Confirm new password') + ) + + old_password = forms.CharField( + label=_("Old password"), + strip=False, + widget=forms.PasswordInput(attrs={'autocomplete': 'current-password', 'autofocus': True}), + ) class Meta: """Metaclass options.""" @@ -146,7 +156,8 @@ class SetPasswordForm(HelperForm): model = User fields = [ 'enter_password', - 'confirm_password' + 'confirm_password', + 'old_password', ] diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 5a0c24e373..26f7f5ecf5 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -8,8 +8,10 @@ import json import os from django.conf import settings +from django.contrib.auth import password_validation from django.contrib.auth.mixins import (LoginRequiredMixin, PermissionRequiredMixin) +from django.core.exceptions import ValidationError from django.http import HttpResponse, HttpResponseRedirect, JsonResponse from django.shortcuts import redirect from django.template.loader import render_to_string @@ -540,6 +542,8 @@ class SetPasswordView(AjaxUpdateView): p1 = request.POST.get('enter_password', '') p2 = request.POST.get('confirm_password', '') + old_password = request.POST.get('old_password', '') + user = self.request.user if valid: # Passwords must match @@ -548,20 +552,28 @@ class SetPasswordView(AjaxUpdateView): error = _('Password fields must match') form.add_error('enter_password', error) form.add_error('confirm_password', error) - valid = False - data = { - 'form_valid': valid - } + if valid: + # Old password must be correct + + if not user.check_password(old_password): + form.add_error('old_password', _('Wrong password provided')) + valid = False if valid: - user = self.request.user + try: + # Validate password + password_validation.validate_password(p1, user) - user.set_password(p1) - user.save() + # Update the user + user.set_password(p1) + user.save() + except ValidationError as error: + form.add_error('confirm_password', str(error)) + valid = False - return self.renderJsonResponse(request, form, data=data) + return self.renderJsonResponse(request, form, data={'form_valid': valid}) class IndexView(TemplateView):