Catch HttpError thrown by Python Social Auth.
This patch enables catching HttpError exception raised by PSA because of any issue caused at client/server. Further it redirects user to login page with a message about the error. LEARNER-4344
This commit is contained in:
@@ -1,7 +1,16 @@
|
|||||||
"""Middleware classes for third_party_auth."""
|
"""Middleware classes for third_party_auth."""
|
||||||
|
|
||||||
|
import urlparse
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from requests import HTTPError
|
||||||
from social_django.middleware import SocialAuthExceptionMiddleware
|
from social_django.middleware import SocialAuthExceptionMiddleware
|
||||||
|
|
||||||
|
from student.helpers import get_next_url_for_login_page
|
||||||
|
|
||||||
from . import pipeline
|
from . import pipeline
|
||||||
|
|
||||||
|
|
||||||
@@ -23,3 +32,19 @@ class ExceptionMiddleware(SocialAuthExceptionMiddleware):
|
|||||||
redirect_uri = pipeline.AUTH_DISPATCH_URLS[auth_entry]
|
redirect_uri = pipeline.AUTH_DISPATCH_URLS[auth_entry]
|
||||||
|
|
||||||
return redirect_uri
|
return redirect_uri
|
||||||
|
|
||||||
|
def process_exception(self, request, exception):
|
||||||
|
"""Handles specific exception raised by Python Social Auth eg HTTPError."""
|
||||||
|
|
||||||
|
referer_url = request.META.get('HTTP_REFERER', '')
|
||||||
|
if (referer_url and isinstance(exception, HTTPError) and
|
||||||
|
exception.response.status_code == 502):
|
||||||
|
referer_url = urlparse.urlparse(referer_url).path
|
||||||
|
if referer_url == reverse('signin_user'):
|
||||||
|
messages.error(request, _('Unable to connect with the external provider, please try again'),
|
||||||
|
extra_tags='social-auth')
|
||||||
|
|
||||||
|
redirect_url = get_next_url_for_login_page(request)
|
||||||
|
return redirect('/login?next=' + redirect_url)
|
||||||
|
|
||||||
|
return super(ExceptionMiddleware, self).process_exception(request, exception)
|
||||||
|
|||||||
42
common/djangoapps/third_party_auth/tests/test_middleware.py
Normal file
42
common/djangoapps/third_party_auth/tests/test_middleware.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
"""
|
||||||
|
Tests for third party auth middleware
|
||||||
|
"""
|
||||||
|
import mock
|
||||||
|
from django.contrib.messages.middleware import MessageMiddleware
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.test.client import RequestFactory
|
||||||
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
|
from openedx.core.djangolib.testing.utils import skip_unless_lms
|
||||||
|
from third_party_auth.middleware import ExceptionMiddleware
|
||||||
|
from third_party_auth.tests.testutil import TestCase
|
||||||
|
from student.helpers import get_next_url_for_login_page
|
||||||
|
|
||||||
|
|
||||||
|
class ThirdPartyAuthMiddlewareTestCase(TestCase):
|
||||||
|
"""Tests that ExceptionMiddleware is correctly redirected"""
|
||||||
|
|
||||||
|
@skip_unless_lms
|
||||||
|
@mock.patch('django.conf.settings.MESSAGE_STORAGE', 'django.contrib.messages.storage.cookie.CookieStorage')
|
||||||
|
def test_http_exception_redirection(self):
|
||||||
|
"""
|
||||||
|
Test ExceptionMiddleware is correctly redirected to login page
|
||||||
|
when PSA raises HttpError exception.
|
||||||
|
"""
|
||||||
|
|
||||||
|
request = RequestFactory().get("dummy_url")
|
||||||
|
next_url = get_next_url_for_login_page(request)
|
||||||
|
login_url = '/login?next=' + next_url
|
||||||
|
request.META['HTTP_REFERER'] = 'http://example.com:8000/login'
|
||||||
|
exception = HTTPError()
|
||||||
|
exception.response = HttpResponse(status=502)
|
||||||
|
|
||||||
|
# Add error message for error in auth pipeline
|
||||||
|
MessageMiddleware().process_request(request)
|
||||||
|
response = ExceptionMiddleware().process_exception(
|
||||||
|
request, exception
|
||||||
|
)
|
||||||
|
target_url = response.url
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertTrue(target_url.endswith(login_url))
|
||||||
Reference in New Issue
Block a user