diff --git a/kolibri/core/assets/src/constants.js b/kolibri/core/assets/src/constants.js index f6796739d4e..47f2f3c6d21 100644 --- a/kolibri/core/assets/src/constants.js +++ b/kolibri/core/assets/src/constants.js @@ -150,6 +150,7 @@ export const ERROR_CONSTANTS = { ALREADY_REGISTERED_FOR_COMMUNITY: 'ALREADY_REGISTERED_FOR_COMMUNITY', // 401 error constants INVALID_CREDENTIALS: 'INVALID_CREDENTIALS', + INVALID_USERNAME: 'INVALID_USERNAME', // 404 error constants NOT_FOUND: 'NOT_FOUND', INVALID_KDP_REGISTRATION_TOKEN: 'INVALID_KDP_REGISTRATION_TOKEN', diff --git a/kolibri/core/auth/tasks.py b/kolibri/core/auth/tasks.py index b1a1e166ca7..8065cda5426 100644 --- a/kolibri/core/auth/tasks.py +++ b/kolibri/core/auth/tasks.py @@ -7,6 +7,7 @@ from django.core.management import call_command from django.utils import timezone from rest_framework import serializers +from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import ValidationError from kolibri.core.auth.constants.demographics import NOT_SPECIFIED @@ -532,7 +533,12 @@ def validate(self, data): facility_id = data["facility"] username = data["username"] password = data["password"] - facility_info = get_remote_users_info(baseurl, facility_id, username, password) + try: + facility_info = get_remote_users_info( + baseurl, facility_id, username, password + ) + except AuthenticationFailed as e: + raise ValidationError(detail=str(e.detail), code=e.detail.code) user_info = facility_info["user"] # syncing using an admin account (username & password belong to the admin): diff --git a/kolibri/core/auth/utils/users.py b/kolibri/core/auth/utils/users.py index a03e6a5f2bc..97c51a8116d 100644 --- a/kolibri/core/auth/utils/users.py +++ b/kolibri/core/auth/utils/users.py @@ -49,9 +49,23 @@ def get_remote_users_info(baseurl, facility_id, username, password): response.raise_for_status() except (CommandError, HTTPError, ConnectionError) as e: if password == NOT_SPECIFIED or not password: - raise AuthenticationFailed( - detail="Password is required", code=error_constants.MISSING_PASSWORD + facility_info_url = reverse_remote( + baseurl, + "kolibri:core:publicfacility-detail", + args=[ + facility_id, + ], ) + response = requests.get(facility_info_url) + if response.json()["learner_can_login_with_no_password"]: + raise AuthenticationFailed( + detail="The username can not be found", + code=error_constants.INVALID_USERNAME, + ) + else: + raise AuthenticationFailed( + detail="Password is required", code=error_constants.MISSING_PASSWORD + ) else: raise AuthenticationFailed( detail=str(e), code=error_constants.AUTHENTICATION_FAILED diff --git a/kolibri/core/error_constants.py b/kolibri/core/error_constants.py index 1b2af8846a0..f5c668eb9d8 100644 --- a/kolibri/core/error_constants.py +++ b/kolibri/core/error_constants.py @@ -15,6 +15,7 @@ PASSWORD_NOT_SPECIFIED = "PASSWORD_NOT_SPECIFIED" # 401 error constants INVALID_CREDENTIALS = "INVALID_CREDENTIALS" +INVALID_USERNAME = "INVALID_USERNAME" # 404 error constants NOT_FOUND = "NOT_FOUND" FACILITY_DOES_NOT_EXIST = "FACILITY_DOES_NOT_EXIST" diff --git a/kolibri/plugins/setup_wizard/assets/src/views/ImportIndividualUserForm.vue b/kolibri/plugins/setup_wizard/assets/src/views/ImportIndividualUserForm.vue index 386126ca59a..e8d4619c9bf 100644 --- a/kolibri/plugins/setup_wizard/assets/src/views/ImportIndividualUserForm.vue +++ b/kolibri/plugins/setup_wizard/assets/src/views/ImportIndividualUserForm.vue @@ -284,6 +284,7 @@ ERROR_CONSTANTS.MISSING_PASSWORD, ERROR_CONSTANTS.PASSWORD_NOT_SPECIFIED, ERROR_CONSTANTS.AUTHENTICATION_FAILED, + ERROR_CONSTANTS.INVALID_USERNAME, ]); const errorData = error.response.data;