Use a 403 status to indicate that the user does not have a linked

account for third party auth.
This commit is contained in:
Will Daly
2014-10-23 14:19:25 -04:00
parent b14a129132
commit cc07afb967
7 changed files with 27 additions and 22 deletions

View File

@@ -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

View File

@@ -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"))

View File

@@ -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: