diff --git a/firebase_admin/_auth_client.py b/firebase_admin/_auth_client.py index 2f6713d41..a58dbef74 100644 --- a/firebase_admin/_auth_client.py +++ b/firebase_admin/_auth_client.py @@ -181,7 +181,7 @@ def get_user_by_email(self, email): Raises: ValueError: If the email is None, empty or malformed. - UserNotFoundError: If no user exists by the specified email address. + UserNotFoundError: If no user exists for the specified email address. FirebaseError: If an error occurs while retrieving the user. """ response = self._user_manager.get_user(email=email) @@ -198,7 +198,7 @@ def get_user_by_phone_number(self, phone_number): Raises: ValueError: If the phone number is ``None``, empty or malformed. - UserNotFoundError: If no user exists by the specified phone number. + UserNotFoundError: If no user exists for the specified phone number. FirebaseError: If an error occurs while retrieving the user. """ response = self._user_manager.get_user(phone_number=phone_number) @@ -444,6 +444,7 @@ def generate_password_reset_link(self, email, action_code_settings=None): Raises: ValueError: If the provided arguments are invalid + EmailNotFoundError: If no user exists for the specified email address. FirebaseError: If an error occurs while generating the link """ return self._user_manager.generate_email_action_link( @@ -464,6 +465,7 @@ def generate_email_verification_link(self, email, action_code_settings=None): Raises: ValueError: If the provided arguments are invalid + UserNotFoundError: If no user exists for the specified email address. FirebaseError: If an error occurs while generating the link """ return self._user_manager.generate_email_action_link( diff --git a/firebase_admin/_auth_utils.py b/firebase_admin/_auth_utils.py index d8e49b1a1..50c52812e 100644 --- a/firebase_admin/_auth_utils.py +++ b/firebase_admin/_auth_utils.py @@ -351,6 +351,15 @@ def __init__(self, message, cause=None, http_response=None): exceptions.NotFoundError.__init__(self, message, cause, http_response) +class EmailNotFoundError(exceptions.NotFoundError): + """No user record found for the specified email.""" + + default_message = 'No user record found for the given email' + + def __init__(self, message, cause=None, http_response=None): + exceptions.NotFoundError.__init__(self, message, cause, http_response) + + class TenantNotFoundError(exceptions.NotFoundError): """No tenant found for the specified identifier.""" @@ -381,6 +390,7 @@ def __init__(self, message, cause=None, http_response=None): 'DUPLICATE_EMAIL': EmailAlreadyExistsError, 'DUPLICATE_LOCAL_ID': UidAlreadyExistsError, 'EMAIL_EXISTS': EmailAlreadyExistsError, + 'EMAIL_NOT_FOUND': EmailNotFoundError, 'INSUFFICIENT_PERMISSION': InsufficientPermissionError, 'INVALID_DYNAMIC_LINK_DOMAIN': InvalidDynamicLinkDomainError, 'INVALID_ID_TOKEN': InvalidIdTokenError, diff --git a/firebase_admin/auth.py b/firebase_admin/auth.py index 5154bb495..ed9829aca 100644 --- a/firebase_admin/auth.py +++ b/firebase_admin/auth.py @@ -39,6 +39,7 @@ 'ConfigurationNotFoundError', 'DELETE_ATTRIBUTE', 'EmailAlreadyExistsError', + 'EmailNotFoundError', 'ErrorInfo', 'ExpiredIdTokenError', 'ExpiredSessionCookieError', @@ -112,6 +113,7 @@ DELETE_ATTRIBUTE = _user_mgt.DELETE_ATTRIBUTE DeleteUsersResult = _user_mgt.DeleteUsersResult EmailAlreadyExistsError = _auth_utils.EmailAlreadyExistsError +EmailNotFoundError = _auth_utils.EmailNotFoundError ErrorInfo = _user_import.ErrorInfo ExpiredIdTokenError = _token_gen.ExpiredIdTokenError ExpiredSessionCookieError = _token_gen.ExpiredSessionCookieError diff --git a/tests/test_user_mgt.py b/tests/test_user_mgt.py index ac80a92a6..10dfe698f 100644 --- a/tests/test_user_mgt.py +++ b/tests/test_user_mgt.py @@ -1446,6 +1446,17 @@ def test_api_call_failure(self, user_mgt_app, func): assert excinfo.value.http_response is not None assert excinfo.value.cause is not None + def test_password_reset_non_existing(self, user_mgt_app): + _instrument_user_manager(user_mgt_app, 400, '{"error":{"message": "EMAIL_NOT_FOUND"}}') + with pytest.raises(auth.EmailNotFoundError) as excinfo: + auth.generate_password_reset_link( + 'nonexistent@user', MOCK_ACTION_CODE_SETTINGS, app=user_mgt_app) + error_msg = 'No user record found for the given email (EMAIL_NOT_FOUND).' + assert excinfo.value.code == exceptions.NOT_FOUND + assert str(excinfo.value) == error_msg + assert excinfo.value.http_response is not None + assert excinfo.value.cause is not None + @pytest.mark.parametrize('func', [ auth.generate_sign_in_with_email_link, auth.generate_email_verification_link,