Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve EOF error messaging during CLI login flows #1093

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Changed
~~~~~~~

- Improved error messaging around EOF errors when prompting for code during a command
line login flow (:pr:`NUMBER`)
3 changes: 3 additions & 0 deletions docs/authorization/login_flows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ Example Code:
:member-order: bysource
:show-inheritance:


.. autoexception:: CommandLineLoginFlowEOFError

Local Server
------------

Expand Down
6 changes: 5 additions & 1 deletion src/globus_sdk/login_flows/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from .command_line_login_flow_manager import CommandLineLoginFlowManager
from .command_line_login_flow_manager import (
CommandLineLoginFlowEOFError,
CommandLineLoginFlowManager,
)
from .local_server_login_flow_manager import (
LocalServerEnvironmentalLoginError,
LocalServerLoginError,
Expand All @@ -8,6 +11,7 @@

__all__ = (
"CommandLineLoginFlowManager",
"CommandLineLoginFlowEOFError",
"LocalServerLoginError",
"LocalServerEnvironmentalLoginError",
"LocalServerLoginFlowManager",
Expand Down
23 changes: 22 additions & 1 deletion src/globus_sdk/login_flows/command_line_login_flow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import textwrap
import typing as t
from contextlib import contextmanager
sirosen marked this conversation as resolved.
Show resolved Hide resolved

import globus_sdk
from globus_sdk.exc.base import GlobusError
from globus_sdk.gare import GlobusAuthorizationParameters
from globus_sdk.utils import get_nice_hostname

Expand All @@ -13,6 +15,13 @@
from globus_sdk.globus_app import GlobusAppConfig


class CommandLineLoginFlowEOFError(GlobusError, EOFError):
"""
An error raised when a CommandLineLoginFlowManager reads an EOF when prompting for
a code.
"""


class CommandLineLoginFlowManager(LoginFlowManager):
"""
A login flow manager which drives authorization-code token grants through the
Expand Down Expand Up @@ -128,4 +137,16 @@ def prompt_for_code(self) -> str:
:returns: The authorization code entered by the user.
"""
code_prompt = "Enter the resulting Authorization Code here: "
return input(code_prompt).strip()
with self._handle_input_errors():
return input(code_prompt).strip()

@contextmanager
def _handle_input_errors(self) -> t.Iterator[None]:
try:
yield
except EOFError as e:
msg = (
"An EOF was read when an authorization code was expected."
" (Are you running this in an interactive terminal?)"
)
raise CommandLineLoginFlowEOFError(msg) from e
27 changes: 27 additions & 0 deletions tests/functional/login_flows/test_login_flow_manager.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from unittest.mock import Mock, patch

import pytest

from globus_sdk import ConfidentialAppAuthClient, NativeAppAuthClient
from globus_sdk._testing import load_response
from globus_sdk.gare import GlobusAuthorizationParameters
from globus_sdk.login_flows import (
CommandLineLoginFlowManager,
LocalServerLoginFlowManager,
)
from globus_sdk.login_flows.command_line_login_flow_manager import (
CommandLineLoginFlowEOFError,
)


def _mock_input(s):
Expand Down Expand Up @@ -96,6 +101,28 @@ def test_command_line_login_flower_manager_confidential(monkeypatch, capsys):
assert "&session_required_single_domain=org.edu" in captured_output


def test_command_line_login_flow_manager_eof_error(monkeypatch, capsys):
"""
test CommandLineLoginFlowManager with a NativeAppAuthClient
"""
login_client = NativeAppAuthClient("mock_client_id")
load_response(login_client.oauth2_exchange_code_for_tokens)

def broken_input(_s):
raise EOFError()

monkeypatch.setattr("builtins.input", broken_input)

login_flow_manager = CommandLineLoginFlowManager(login_client)
auth_params = GlobusAuthorizationParameters(
required_scopes=["urn:globus:auth:scope:transfer.api.globus.org:all"],
session_required_identities=["user@org.edu"],
)

with pytest.raises(CommandLineLoginFlowEOFError):
login_flow_manager.run_login_flow(auth_params)


class MockRedirectServer:
def __init__(self, *args, **kwargs):
self.socket = Mock()
Expand Down