Skip to content

Commit

Permalink
Add new endpoint to validate password reset token.
Browse files Browse the repository at this point in the history
Added a new endpoint to validate password reset token for
logistration MFE.

VAN-61
  • Loading branch information
waheedahmed committed Sep 30, 2020
1 parent a9380e2 commit af958ad
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
2 changes: 2 additions & 0 deletions openedx/core/djangoapps/user_authn/urls_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
name='password_reset_confirm',
),
url(r'^account/password$', password_reset.password_change_request_handler, name='password_change_request'),
url(r'^user_api/v1/account/password_reset/token/validate/$', password_reset.password_reset_token_validate,
name="user_api_password_reset_token_validate"),

]

Expand Down
23 changes: 23 additions & 0 deletions openedx/core/djangoapps/user_authn/views/password_reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,3 +598,26 @@ def password_change_request_handler(request):
return HttpResponse(status=200)
else:
return HttpResponseBadRequest(_("No email address provided."))


@require_POST
@ensure_csrf_cookie
def password_reset_token_validate(request):
"""HTTP end-point to validate password reset token. """
is_valid = False
token = request.POST.get('token')
try:
token = token.split('-', 1)
uid_int = base36_to_int(token[0])
if request.user.is_authenticated and request.user.id != uid_int:
return JsonResponse({'is_valid': is_valid})

user = User.objects.get(id=uid_int)
is_valid = default_token_generator.check_token(user, token[1])
if is_valid and not user.is_active:
user.is_active = True
user.save()
except Exception: # pylint: disable=broad-except
AUDIT_LOG.exception("Invalid password reset confirm token")

return JsonResponse({'is_valid': is_valid})
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
SETTING_CHANGE_INITIATED, password_reset,
PasswordResetConfirmWrapper)
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from student.tests.factories import UserFactory
from student.tests.factories import TEST_PASSWORD, UserFactory
from student.tests.test_configuration_overrides import fake_get_value
from student.tests.test_email import mock_render_to_string

Expand Down Expand Up @@ -629,3 +629,52 @@ def test_password_reset_form(self):
"supplementalLink": "",
}
])


@skip_unless_lms
class PasswordResetTokenValidateViewTest(UserAPITestCase):
"""Tests of the user API's password reset endpoint. """

def setUp(self):
super(PasswordResetTokenValidateViewTest, self).setUp()
self.user = UserFactory.create()
self.user.is_active = False
self.user.save()
self.token = '{uidb36}-{token}'.format(
uidb36=int_to_base36(self.user.id),
token=default_token_generator.make_token(self.user)
)
self.url = reverse("user_api_password_reset_token_validate")

def test_reset_password_valid_token(self):
"""
Verify that API valid token response and activate user if not active.
"""
response = self.client.post(self.url, data={'token': self.token})
json_response = json.loads(response.content.decode('utf-8'))
self.assertTrue(json_response.get('is_valid'))

self.user = User.objects.get(pk=self.user.pk)
self.assertTrue(self.user.is_active)

def test_reset_password_invalid_token(self):
"""
Verify that API invalid token response if token is invalid.
"""
response = self.client.post(self.url, data={'token': 'invalid-token'})
json_response = json.loads(response.content.decode('utf-8'))
self.assertFalse(json_response.get('is_valid'))

def test_reset_password_token_with_other_user(self):
"""
Verify that API returns invalid token response if the user different.
"""
different_user = UserFactory.create(password=TEST_PASSWORD)
self.client.login(username=different_user.username, password=TEST_PASSWORD)

response = self.client.post(self.url, {'token': self.token})
json_response = json.loads(response.content.decode('utf-8'))
self.assertFalse(json_response.get('is_valid'))

self.user = User.objects.get(pk=self.user.pk)
self.assertFalse(self.user.is_active)

0 comments on commit af958ad

Please sign in to comment.