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

Feature/inquirer #156

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ flake8>=5.0.0
flake8-black
flake8-docstrings
flake8-import-order
moto
moto<5.0.0
pep8-naming
pexpect
pydocstyle
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
license=about["__license__"],
zip_safe=False,
install_requires=[required],
extras_require={
'inquirer': ['inquirer'],
},
entry_points={
"console_scripts": ["tokendito=tokendito.__main__:main"],
},
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,9 @@ def test_mfa_option_info(factor_type, output):

def test_select_preferred_mfa_index(mocker, sample_json_response):
"""Test whether the function returns index entered by user."""
# Don't enable inquirer for these tests
mocker.patch('tokendito.user.INQUIRER_AVAILABLE', False)

from tokendito.user import select_preferred_mfa_index

primary_auth = sample_json_response
Expand All @@ -569,6 +572,20 @@ def test_select_preferred_mfa_index(mocker, sample_json_response):
assert select_preferred_mfa_index(mfa_options) == output


def test_select_preferred_mfa_index_inquirer(mocker, sample_json_response):
"""Test whether the function returns index entered by user."""
from tokendito.user import select_preferred_mfa_index
from tokendito.user import INQUIRER_AVAILABLE

if not INQUIRER_AVAILABLE:
pytest.skip("No items found")
else:
primary_auth = sample_json_response
mfa_options = primary_auth["okta_response_mfa"]["_embedded"]["factors"]
for output in mfa_options:
mocker.patch("tokendito.user.inquirer.prompt", return_value={"mfa_selection": output})
assert select_preferred_mfa_index(mfa_options) == output

@pytest.mark.parametrize(
"email",
[
Expand All @@ -577,6 +594,9 @@ def test_select_preferred_mfa_index(mocker, sample_json_response):
)
def test_select_preferred_mfa_index_output(email, capsys, mocker, sample_json_response):
"""Test whether the function gives correct output."""

# Don't enable inquirer for these tests
mocker.patch('tokendito.user.INQUIRER_AVAILABLE', False)
from tokendito.config import config
from tokendito.user import select_preferred_mfa_index

Expand Down
47 changes: 43 additions & 4 deletions tokendito/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
except ModuleNotFoundError:
pass

INQUIRER_AVAILABLE = False
try:
import inquirer

INQUIRER_AVAILABLE = True
except ModuleNotFoundError:
pass

logger = logging.getLogger(__name__)

mask_items = []
Expand Down Expand Up @@ -447,25 +455,41 @@ def select_preferred_mfa_index(mfa_options, factor_key="provider", subfactor_key
"""
logger.debug("Show all the MFA options to the users.")
logger.debug(json.dumps(mfa_options))
print("\nSelect your preferred MFA method and press Enter:")


longest_index = len(str(len(mfa_options)))
longest_factor_name = max([len(d[factor_key]) for d in mfa_options])
longest_subfactor_name = max([len(d[subfactor_key]) for d in mfa_options])
factor_info_indent = max([len(mfa_option_info(d)) for d in mfa_options])

mfa_list = []
for i, mfa_option in enumerate(mfa_options):
factor_id = mfa_option.get("id", "Not presented")
factor_info = mfa_option_info(mfa_option)
mfa = mfa_option.get(subfactor_key, "Not presented")
provider = mfa_option.get(factor_key, "Not presented")
print(
mfa_item = (
f"[{i: >{longest_index}}] "
f"{provider: <{longest_factor_name}} "
f"{mfa: <{longest_subfactor_name}} "
f"{factor_info: <{factor_info_indent}} "
f"Id: {factor_id}"
)
mfa_list.append((mfa_item, i))

if INQUIRER_AVAILABLE:
questions = [
inquirer.List('mfa_selection',
message="Select your preferred MFA method and press Enter:",
choices=mfa_list,
),
]
answers = inquirer.prompt(questions)
return answers['mfa_selection']

print("\nSelect your preferred MFA method and press Enter:")
for text, i in mfa_list:
print(text)

user_input = collect_integer(len(mfa_options))

Expand All @@ -492,22 +516,37 @@ def prompt_role_choices(aut_tiles):
aliases_mapping.append((tile["label"], role.split(":")[4], role, url))

logger.debug("Ask user to select role")
print("\nPlease select one of the following:")

longest_alias = max(len(i[1]) for i in aliases_mapping)
longest_index = len(str(len(aliases_mapping)))
aliases_mapping = sorted(aliases_mapping)
print_label = ""

role_list = []
for i, data in enumerate(aliases_mapping):
label, alias, role, _ = data
padding_index = longest_index - len(str(i))
if print_label != label:
print_label = label
print(f"\n{label}:")

print(f"[{i}] {padding_index * ' '}" f"{alias: <{longest_alias}} {role}")
role_item = f"[{i}] {padding_index * ' '}" f"{alias: <{longest_alias}} {role}"
role_list.append((role_item, (aliases_mapping[i][2], aliases_mapping[i][3])))

if INQUIRER_AVAILABLE:
questions = [
inquirer.List('role_selection',
message="Please select one of the following:",
choices=role_list,
),
]
answers = inquirer.prompt(questions)
logger.debug(f"Selected role [{answers.get('role_selection')}]")
return answers['role_selection']

print("\nPlease select one of the following:")
for role_item, i in role_list:
print(role_item)
user_input = collect_integer(len(aliases_mapping))
selected_role = (aliases_mapping[user_input][2], aliases_mapping[user_input][3])
logger.debug(f"Selected role [{user_input}]")
Expand Down