From 6cb6877301bc7399eb783ad2563dfffb1577e7c9 Mon Sep 17 00:00:00 2001 From: Taksh Date: Wed, 24 Jun 2026 21:25:29 +0530 Subject: [PATCH] fix: include user email in inactive account login error Return the inactive user's email address in the login API response so the activation reminder on the login page shows the correct address. Fixes #37406 Co-authored-by: Cursor --- openedx/core/djangoapps/user_authn/views/login.py | 12 ++++++++---- .../djangoapps/user_authn/views/tests/test_login.py | 13 +++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/openedx/core/djangoapps/user_authn/views/login.py b/openedx/core/djangoapps/user_authn/views/login.py index 6a012d8d212d..e9391f884029 100644 --- a/openedx/core/djangoapps/user_authn/views/login.py +++ b/openedx/core/djangoapps/user_authn/views/login.py @@ -564,6 +564,7 @@ def login_user(request, api_version="v1"): # pylint: disable=too-many-statement "Third party authentication is required to login. Username and password were received instead." ) possibly_authenticated_user = None + user = None try: if third_party_auth_requested and not first_party_auth_requested: # The user has already authenticated via third-party auth and has not @@ -681,10 +682,13 @@ def login_user(request, api_version="v1"): # pylint: disable=too-many-statement error_code = response_content.get("error_code") if error_code: set_custom_attribute("login_error_code", error_code) - email_or_username_key = "email" if api_version == API_V1 else "email_or_username" - email_or_username = request.POST.get(email_or_username_key, None) - email_or_username = possibly_authenticated_user.email if possibly_authenticated_user else email_or_username - response_content["email"] = email_or_username + if error_code == "inactive-user" and user: + response_content["email"] = user.email + else: + email_or_username = request.POST.get("email") or request.POST.get("email_or_username") + if possibly_authenticated_user: + email_or_username = possibly_authenticated_user.email + response_content["email"] = email_or_username except VulnerablePasswordError as error: response_content = error.get_response() log.exception(response_content) diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py index 4e4d0a9e8894..677e2b93609d 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py @@ -441,6 +441,19 @@ def test_login_not_activated_with_correct_credentials(self): self._assert_response(response, success=False, error_code="inactive-user") self._assert_audit_log(mock_audit_log, 'warning', ['Login failed', 'Account not active for user']) + def test_login_not_activated_includes_user_email(self): + self.user.is_active = False + self.user.save() + + response, _mock_audit_log = self._login_response( + self.user_email, + self.password, + ) + response_dict = json.loads(response.content.decode('utf-8')) + + self._assert_response(response, success=False, error_code="inactive-user") + assert response_dict['email'] == self.user_email + @patch('openedx.core.djangoapps.user_authn.views.login._log_and_raise_inactive_user_auth_error') def test_login_inactivated_user_with_incorrect_credentials(self, mock_inactive_user_email_and_error): """