diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 14c252283..254c6524a 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -37,7 +37,7 @@ from ietf.ietfauth.htpasswd import update_htpasswd_file from ietf.mailinglists.models import Subscribed from ietf.meeting.factories import MeetingFactory from ietf.nomcom.factories import NomComFactory -from ietf.person.factories import PersonFactory, EmailFactory +from ietf.person.factories import PersonFactory, EmailFactory, UserFactory from ietf.person.models import Person, Email, PersonalApiKey from ietf.review.factories import ReviewRequestFactory, ReviewAssignmentFactory from ietf.review.models import ReviewWish, UnavailablePeriod @@ -433,10 +433,20 @@ class IetfAuthTests(TestCase): self.assertEqual(r.status_code, 200) self.assertEqual(len(outbox), 1) - # go to change password page + # goto change password page, logged in as someone else confirm_url = self.extract_confirm_url(outbox[-1]) + other_user = UserFactory() + self.client.login(username=other_user.username, password=other_user.username + '+password') + r = self.client.get(confirm_url) + self.assertEqual(r.status_code, 403) + + # sign out and go back to change password page + self.client.logout() r = self.client.get(confirm_url) self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertNotIn(user.username, q('.nav').text(), + 'user should not appear signed in while resetting password') # password mismatch r = self.client.post(confirm_url, { 'password': 'secret', 'password_confirmation': 'nosecret' }) diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index 2660edcc9..8cf21f52c 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -55,7 +55,7 @@ from django.contrib.sites.models import Site from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.urls import reverse as urlreverse from django.utils.safestring import mark_safe -from django.http import Http404, HttpResponseRedirect #, HttpResponse, +from django.http import Http404, HttpResponseRedirect, HttpResponseForbidden from django.shortcuts import render, redirect, get_object_or_404 from django.utils.encoding import force_bytes @@ -303,7 +303,6 @@ def profile(request): person_form = get_person_form(instance=person) return render(request, 'registration/edit_profile.html', { - 'user': request.user, 'person': person, 'person_form': person_form, 'roles': roles, @@ -462,7 +461,11 @@ def confirm_password_reset(request, auth): raise Http404("Invalid or expired auth") user = get_object_or_404(User, username=username, password__endswith=password, last_login=last_login) - + if request.user.is_authenticated and request.user != user: + return HttpResponseForbidden( + f'This password reset link is not for the signed-in user. ' + f'Please sign out and try again.' + ) success = False if request.method == 'POST': form = PasswordForm(request.POST) @@ -483,7 +486,7 @@ def confirm_password_reset(request, auth): hasher = getattr(hlib, hashername) return render(request, 'registration/change_password.html', { 'form': form, - 'user': user, + 'update_user': user, 'success': success, 'hasher': hasher, }) @@ -647,7 +650,6 @@ def change_password(request): hasher = getattr(hlib, hashername) return render(request, 'registration/change_password.html', { 'form': form, - 'user': user, 'success': success, 'hasher': hasher, }) @@ -685,10 +687,7 @@ def change_username(request): else: form = ChangeUsernameForm(request.user) - return render(request, 'registration/change_username.html', { - 'form': form, - 'user': user, - }) + return render(request, 'registration/change_username.html', {'form': form}) diff --git a/ietf/templates/registration/change_password.html b/ietf/templates/registration/change_password.html index e1de22e66..1df189031 100644 --- a/ietf/templates/registration/change_password.html +++ b/ietf/templates/registration/change_password.html @@ -24,6 +24,11 @@ {% endif %} {% else %}