Use a 403 status to indicate that the user does not have a linked
account for third party auth.
This commit is contained in:
@@ -372,13 +372,20 @@ def shim_student_view(view_func, check_logged_in=False):
|
||||
and request.user.is_authenticated()
|
||||
)
|
||||
if check_logged_in and not is_authenticated:
|
||||
# Preserve the 401 status code so the client knows
|
||||
# that the user successfully authenticated with third-party auth
|
||||
# but does not have a linked account.
|
||||
# Otherwise, send a 403 to indicate that the login failed.
|
||||
if response.status_code != 401:
|
||||
# If we get a 403 status code from the student view
|
||||
# this means we've successfully authenticated with a
|
||||
# third party provider, but we don't have a linked
|
||||
# EdX account. Send a helpful error code so the client
|
||||
# knows this occurred.
|
||||
if response.status_code == 403:
|
||||
response.content = "third-party-auth"
|
||||
|
||||
# Otherwise, it's a general authentication failure.
|
||||
# Ensure that the status code is a 403 and pass
|
||||
# along the message from the view.
|
||||
else:
|
||||
response.status_code = 403
|
||||
response.content = msg
|
||||
response.content = msg
|
||||
|
||||
# If the view wants to redirect us, send a status 302
|
||||
elif redirect_url is not None:
|
||||
@@ -397,9 +404,6 @@ def shim_student_view(view_func, check_logged_in=False):
|
||||
# If the response is successful, then return the content
|
||||
# of the response directly rather than including it
|
||||
# in a JSON-serialized dictionary.
|
||||
# This will also preserve error status codes such as a 401
|
||||
# (if the user is trying to log in using a third-party provider
|
||||
# but hasn't yet linked his or her account.)
|
||||
else:
|
||||
response.content = msg
|
||||
|
||||
|
||||
@@ -144,14 +144,14 @@ class StudentViewShimTest(TestCase):
|
||||
self.assertNotIn("enrollment_action", self.captured_request.POST)
|
||||
self.assertNotIn("course_id", self.captured_request.POST)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_preserve_401_status(self, check_logged_in):
|
||||
def test_third_party_auth_login_failure(self):
|
||||
view = self._shimmed_view(
|
||||
HttpResponse(status=401),
|
||||
check_logged_in=check_logged_in
|
||||
HttpResponse(status=403),
|
||||
check_logged_in=True
|
||||
)
|
||||
response = view(HttpRequest())
|
||||
self.assertEqual(response.status_code, 401)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.content, "third-party-auth")
|
||||
|
||||
def test_non_json_response(self):
|
||||
view = self._shimmed_view(HttpResponse(content="Not a JSON dict"))
|
||||
|
||||
@@ -117,9 +117,10 @@ class LoginSessionView(APIView):
|
||||
Returns:
|
||||
HttpResponse: 200 on success
|
||||
HttpResponse: 400 if the request is not valid.
|
||||
HttpResponse: 401 if the user successfully authenticated with a third-party
|
||||
provider but does not have a linked account.
|
||||
HttpResponse: 403 if authentication failed.
|
||||
403 with content "third-party-auth" if the user
|
||||
has successfully authenticated with a third party provider
|
||||
but does not have a linked account.
|
||||
HttpResponse: 302 if redirecting to another page.
|
||||
|
||||
Example Usage:
|
||||
|
||||
Reference in New Issue
Block a user