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

Add interactive prompt for AWS profile name #111

Merged
merged 9 commits into from
Feb 21, 2023
43 changes: 37 additions & 6 deletions tests/unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,24 +1172,55 @@ def test_process_interactive_input(mocker):
assert user.process_interactive_input({"pytest": "pytest"}) == error


@pytest.mark.parametrize(
"default,submit,expected",
[
("", "", ""),
("", "different_name", "different_name"),
("role_name", "", "role_name"),
("role_name", "different_name", "different_name"),
("role_name", "role_name", "role_name"),
],
)
def test_get_interactive_profile_name(mocker, default, submit, expected):
"""Test getting the AWS profile name form user input."""
from tokendito import user

mocker.patch("tokendito.user.input", return_value=submit)
assert user.get_interactive_profile_name(default) == expected


def test_get_interactive_profile_name_invalid_input(monkeypatch):
"""Test reprompting the AWS profile name form user on invalid input."""
from tokendito import user

# provided inputs
inputs = iter(["_this_is_invalid", "str with space", "1StartsWithNum", "valid"])

# using lambda statement for mocking
monkeypatch.setattr("builtins.input", lambda name: next(inputs))

assert user.get_interactive_profile_name("role_name") == "valid"


@pytest.mark.parametrize(
"value,submit,expected",
[
("pytest", None, "pytest"),
("pytest", "deadbeef", "pytest"),
("pytest", 0xDEADBEEF, "pytest"),
(None, None, "default"),
(None, "", "default"),
(None, 0xDEADBEEF, str(0xDEADBEEF)),
(None, "user_input", "user_input"),
],
)
def test_set_role_name(value, submit, expected):
"""Test setting the AWS Role (profile) name."""
def test_set_profile_name(mocker, value, submit, expected):
"""Test setting the AWS Profile name."""
from tokendito import user, Config

pytest_config = Config(aws=dict(profile=value))

ret = user.set_role_name(pytest_config, submit)
mocker.patch("tokendito.user.get_interactive_profile_name", return_value=submit)

ret = user.set_profile_name(pytest_config, "role_name")
assert ret.aws["profile"] == expected


Expand Down
2 changes: 1 addition & 1 deletion tokendito/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def cli(args):
)
sys.exit(1)

user.set_role_name(config, role_name)
user.set_profile_name(config, role_name)

user.set_local_credentials(
response=role_response,
Expand Down
32 changes: 26 additions & 6 deletions tokendito/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,17 +864,37 @@ def get_password():
return res


def set_role_name(config_obj, name):
def get_interactive_profile_name(default):
"""Get AWS profile name from user.

:return: string with sanitized value, or the default string.
"""
message = f"Enter a profile name or leave blank to use '{default}': "
res = ""

while res == "":
user_data = get_input(prompt=message)
user_data = user_data.strip()
if user_data == "":
res = default
break
if re.fullmatch("[a-zA-Z][a-zA-Z0-9_-]*", user_data):
res = user_data
else:
print("Invalid input, try again.")
logger.debug(f"Profile name is: {res}")
return res


def set_profile_name(config_obj, role_name):
"""Set AWS Role alias name based on user preferences.

:param config: Config object.
:param name: Role name. Defaults to the string "default"
:param role_name: Role name.
:return: Config object.
"""
if name is None or name == "":
name = "default"
if config_obj.aws["profile"] is None:
config_obj.aws["profile"] = str(name)
if config_obj.aws["profile"] is None or config_obj.aws["profile"] == "":
config_obj.aws["profile"] = get_interactive_profile_name(role_name)

return config_obj

Expand Down