From a354a7bc482d98bf469a5af0707a04354359b815 Mon Sep 17 00:00:00 2001 From: VladislavOstapov Date: Fri, 19 Jan 2024 16:07:47 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BC=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=B0?= =?UTF-8?q?=D1=80=D0=BE=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/account/change-password-done.html | 12 ++++ templates/account/change-password.html | 28 ++++++-- users/models.py | 1 - users/views.py | 80 +++++++++++++++------ 4 files changed, 96 insertions(+), 25 deletions(-) create mode 100644 templates/account/change-password-done.html diff --git a/templates/account/change-password-done.html b/templates/account/change-password-done.html new file mode 100644 index 0000000..8304c33 --- /dev/null +++ b/templates/account/change-password-done.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} +{% load static %} + +{% block title %} Пароль изменен {% endblock %} + +{% block header-title %} +

Пароль аккаунта {{ target_user.login }} изменен!

+{% endblock %} + +{% block content %} +

Вернуться на главную

+{% endblock %} diff --git a/templates/account/change-password.html b/templates/account/change-password.html index 8c04edf..47289e4 100644 --- a/templates/account/change-password.html +++ b/templates/account/change-password.html @@ -10,12 +10,32 @@
{% csrf_token %} - {% for field in form %} + {% if old_password_required %} +
+ + + {% if old_password_wrong %} +

Проверьте правильность ввода пароля

+ {% endif %} +
+ {% endif %} +
- {{ field.label_tag }} {{ field }} - {{ field.errors }} + + + {% for err in new_password_errors %} +

{{ err }}

+ {% endfor %} +
+ +
+ + + {% if not new_password_equals %} +

Пароли не совпадают

+ {% endif %}
- {% endfor %}
diff --git a/users/models.py b/users/models.py index ece6e68..125e2c9 100644 --- a/users/models.py +++ b/users/models.py @@ -8,7 +8,6 @@ from .managers import CustomUserManager class User(AbstractBaseUser): login = models.CharField(max_length=16, validators=[MinLengthValidator(3)], verbose_name="Логин", unique=True) - password = models.CharField(verbose_name="Пароль", max_length=128) last_login = models.DateTimeField(verbose_name="Последний вход", blank=True, null=True) is_superuser = models.BooleanField(default=False, verbose_name="Администратор") registered = models.DateTimeField(default=timezone.now, editable=False, verbose_name="Время регистрации") diff --git a/users/views.py b/users/views.py index 85d4050..0ae4377 100644 --- a/users/views.py +++ b/users/views.py @@ -1,10 +1,10 @@ -import os - -from django.contrib.auth.forms import PasswordChangeForm -from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest, Http404 +from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest, Http404, HttpResponseForbidden from django.shortcuts import render # from django.db.models import Manager from django.contrib.auth import authenticate, login, logout, update_session_auth_hash +from django.contrib.auth.hashers import check_password +from django.contrib.auth.password_validation import validate_password, password_changed +from django.core.exceptions import ValidationError from django.contrib.auth.decorators import login_required, permission_required from .models import User from .forms import UserRegisterForm @@ -34,8 +34,11 @@ def view_login(request): 'message': None } if request.method == "POST": - username = request.POST["username"] - password = request.POST["password"] + try: + username = request.POST["username"] + password = request.POST["password"] + except KeyError: + return HttpResponseBadRequest() user = authenticate(request, username=username, password=password) if user is not None: login(request, user) @@ -82,24 +85,61 @@ def view_register(request): @login_required def view_change_password(request): - user = request.user + target_user = request.user + old_password_required = True if 'username' in request.GET: - if request.user.has_perm('users.change_user'): - try: - user = User.objects.get_by_natural_key(request.GET['username']) - except: - return Http404() - else: - raise PermissionError() + if request.GET['username'] != target_user.login: + if request.user.has_perm('users.change_user'): + old_password_required = False + try: + target_user = User.objects.get_by_natural_key(request.GET['username']) + except: + return Http404() + else: + return HttpResponseForbidden() + + render_context = { + 'target_user': target_user, + 'old_password_required': old_password_required, + 'old_password_wrong': False, + 'new_password_errors': None, + 'new_password_equals': True + } - form = PasswordChangeForm(user=user, data=(request.POST or None)) if request.method == "POST": - if form.is_valid(): - form.save() - update_session_auth_hash(request, form.user) - return HttpResponseRedirect('account') + # для начала проверка того, что старый пароль + form_valid = True + try: + post_curr_pass = request.POST['current_password'] if old_password_required else None + post_pass1 = request.POST['password1'] + post_pass2 = request.POST['password2'] + except KeyError: + return HttpResponseBadRequest() - return render(request, 'account/change-password.html', {'form': form, 'target_user': user}) + if old_password_required: + if not check_password(post_curr_pass, target_user.password): + render_context['old_password_wrong'] = False + form_valid = False + + # теперь проверим то, что пароли одинаковые + if post_pass1 != post_pass2: + render_context['new_password_equals'] = False + form_valid = False + + # теперь проверим, что пароль ввели нормальный + try: + validate_password(post_pass1, target_user) + except ValidationError as ve: + render_context['new_password_errors'] = ve.messages + form_valid = False + + if form_valid: + password_changed(post_pass1, target_user) + target_user.save() + update_session_auth_hash(request, target_user) + return render(request, 'account/change-password-done.html', {'target_user': target_user}) + + return render(request, 'account/change-password.html', render_context) @login_required