|
| 1 | +from io import StringIO |
| 2 | + |
1 | 3 | import py42.sdk |
2 | 4 | import py42.settings.debug as debug |
3 | 5 | import pytest |
| 6 | +from py42.exceptions import Py42MFARequiredError |
4 | 7 | from py42.exceptions import Py42UnauthorizedError |
5 | 8 | from requests import Response |
6 | 9 | from requests.exceptions import ConnectionError |
| 10 | +from requests.exceptions import HTTPError |
7 | 11 | from requests.exceptions import RequestException |
8 | 12 |
|
9 | 13 | from .conftest import create_mock_profile |
10 | 14 | from code42cli.errors import Code42CLIError |
11 | 15 | from code42cli.errors import LoggedCLIError |
| 16 | +from code42cli.main import cli |
| 17 | +from code42cli.options import CLIState |
12 | 18 | from code42cli.sdk_client import create_sdk |
13 | 19 | from code42cli.sdk_client import validate_connection |
14 | 20 |
|
@@ -114,5 +120,46 @@ def mock_get_password(): |
114 | 120 |
|
115 | 121 |
|
116 | 122 | def test_validate_connection_uses_given_credentials(mock_sdk_factory): |
117 | | - assert validate_connection("Authority", "Test", "Password") |
118 | | - mock_sdk_factory.assert_called_once_with("Authority", "Test", "Password") |
| 123 | + assert validate_connection("Authority", "Test", "Password", None) |
| 124 | + mock_sdk_factory.assert_called_once_with("Authority", "Test", "Password", totp=None) |
| 125 | + |
| 126 | + |
| 127 | +def test_validate_connection_when_mfa_required_exception_raised_prompts_for_totp( |
| 128 | + mocker, monkeypatch, mock_sdk_factory, capsys |
| 129 | +): |
| 130 | + monkeypatch.setattr("sys.stdin", StringIO("101010")) |
| 131 | + response = mocker.MagicMock(spec=Response) |
| 132 | + mock_sdk_factory.side_effect = [ |
| 133 | + Py42MFARequiredError(HTTPError(response=response)), |
| 134 | + None, |
| 135 | + ] |
| 136 | + validate_connection("Authority", "Test", "Password", None) |
| 137 | + output = capsys.readouterr() |
| 138 | + assert "Multi-factor authentication required. Enter TOTP:" in output.out |
| 139 | + |
| 140 | + |
| 141 | +def test_validate_connection_when_mfa_token_invalid_raises_expected_cli_error( |
| 142 | + mocker, mock_sdk_factory |
| 143 | +): |
| 144 | + response = mocker.MagicMock(spec=Response) |
| 145 | + response.text = '{"data":null,"error":[{"primaryErrorKey":"INVALID_TIME_BASED_ONE_TIME_PASSWORD","otherErrors":null}],"warnings":null}' |
| 146 | + mock_sdk_factory.side_effect = Py42UnauthorizedError(HTTPError(response=response)) |
| 147 | + with pytest.raises(Code42CLIError) as err: |
| 148 | + validate_connection("Authority", "Test", "Password", "1234") |
| 149 | + assert str(err.value) == "Invalid TOTP token for user Test." |
| 150 | + |
| 151 | + |
| 152 | +def test_totp_option_when_passed_is_passed_to_sdk_initialization( |
| 153 | + mocker, profile, runner |
| 154 | +): |
| 155 | + mock_py42 = mocker.patch("code42cli.sdk_client.py42.sdk.from_local_account") |
| 156 | + cli_state = CLIState() |
| 157 | + totp = "1234" |
| 158 | + profile.authority_url = "example.com" |
| 159 | + profile.username = "user" |
| 160 | + profile.get_password.return_value = "password" |
| 161 | + cli_state._profile = profile |
| 162 | + runner.invoke(cli, ["users", "list", "--totp", totp], obj=cli_state) |
| 163 | + mock_py42.assert_called_once_with( |
| 164 | + profile.authority_url, profile.username, "password", totp=totp |
| 165 | + ) |
0 commit comments