Skip to content
Snippets Groups Projects
Unverified Commit 700a4d8e authored by Diana Huang's avatar Diana Huang Committed by GitHub
Browse files

Merge pull request #17915 from edx/diana/new-auth-endpoint

LEARNER-4882: Create new auth endpoint for checking user password.
parents b613494a 8056d89f
No related merge requests found
......@@ -638,3 +638,55 @@ class LoginOAuthTokenTestFacebook(LoginOAuthTokenMixin, ThirdPartyOAuthTestMixin
class LoginOAuthTokenTestGoogle(LoginOAuthTokenMixin, ThirdPartyOAuthTestMixinGoogle, TestCase):
"""Tests login_oauth_token with the Google backend"""
pass
class TestPasswordVerificationView(CacheIsolationTestCase):
"""
Test the password verification endpoint.
"""
def setUp(self):
super(TestPasswordVerificationView, self).setUp()
self.user = UserFactory.build(username='test_user', is_active=True)
self.password = 'test_password'
self.user.set_password(self.password)
self.user.save()
# Create a registration for the user
RegistrationFactory(user=self.user)
# Create a profile for the user
UserProfileFactory(user=self.user)
# Create the test client
self.client = Client()
cache.clear()
self.url = reverse('verify_password')
def test_password_logged_in_valid(self):
success = self.client.login(username=self.user.username, password=self.password)
assert success
response = self.client.post(self.url, {'password': self.password})
assert response.status_code == 200
def test_password_logged_in_invalid(self):
success = self.client.login(username=self.user.username, password=self.password)
assert success
response = self.client.post(self.url, {'password': 'wrong_password'})
assert response.status_code == 403
def test_password_logged_out(self):
response = self.client.post(self.url, {'username': self.user.username, 'password': self.password})
assert response.status_code == 302
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True})
@override_settings(MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS=6000)
def test_locked_out(self):
success = self.client.login(username=self.user.username, password=self.password)
assert success
# Attempt a password check greater than the number of allowed times.
for _ in xrange(settings.MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED + 1):
self.client.post(self.url, {'password': 'wrong_password'})
response = self.client.post(self.url, {'password': self.password})
assert response.status_code == 403
assert response.content == ('This account has been temporarily locked due '
'to excessive login failures. Try again later.')
......@@ -37,10 +37,12 @@ urlpatterns = [
views.password_reset_confirm_wrapper,
name='password_reset_confirm',
),
url(r'accounts/verify_password', views.verify_user_password, name='verify_password'),
url(r'^course_run/{}/refund_status$'.format(settings.COURSE_ID_PATTERN),
views.course_run_refund_status,
name="course_run_refund_status"),
]
# enable automatic login
......
......@@ -15,6 +15,7 @@ import edx_oauth2_provider
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate, load_backend, login as django_login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import AnonymousUser, User
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.core.urlresolvers import NoReverseMatch, reverse, reverse_lazy
......@@ -386,6 +387,32 @@ def send_reactivation_email_for_user(user):
return JsonResponse({"success": True})
@login_required
@ensure_csrf_cookie
def verify_user_password(request):
"""
If the user is logged in and we want to verify that they have submitted the correct password
for a major account change (for example, retiring this user's account).
Args:
request (HttpRequest): A request object where the password should be included in the POST fields.
"""
try:
_check_excessive_login_attempts(request.user)
user = authenticate(username=request.user.username, password=request.POST['password'], request=request)
if user:
if LoginFailures.is_feature_enabled():
LoginFailures.clear_lockout_counter(user)
return JsonResponse({'success': True})
else:
_handle_failed_authentication(request.user)
except AuthFailedError as err:
return HttpResponse(err.value, content_type="text/plain", status=403)
except Exception: # pylint: disable=broad-except
log.exception("Could not verify user password")
return HttpResponseBadRequest()
@ensure_csrf_cookie
def login_user(request):
"""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment