diff --git a/tests/unit/test_okta.py b/tests/unit/test_okta.py index b422313..bcb7826 100644 --- a/tests/unit/test_okta.py +++ b/tests/unit/test_okta.py @@ -73,6 +73,7 @@ def test_bad_session_token(mocker, sample_json_response, sample_headers): {"_embedded": {"factor": {"factorType": "push"}}}, 345, ), # Changed expected value to 2 + ("OKTA", 321, {"_embedded": {"factor": {"factorType": "question"}}}, 321), ("GOOGLE", 456, {"_embedded": {"factor": {"factorType": "sms"}}}, 456), ], ) diff --git a/tests/unit/test_user.py b/tests/unit/test_user.py index 0cb823a..b689663 100644 --- a/tests/unit/test_user.py +++ b/tests/unit/test_user.py @@ -60,13 +60,13 @@ def test_get_username(mocker): assert val == "pytest_patched" -def test_get_password(mocker): +def test_get_secret_input(mocker): """Test whether data sent is the same as data returned.""" from tokendito import user mocker.patch("tokendito.user.tty_assertion", return_value=True) mocker.patch("tokendito.user.getpass", return_value="pytest_patched") - val = user.get_password() + val = user.get_secret_input() assert val == "pytest_patched" diff --git a/tokendito/okta.py b/tokendito/okta.py index 79a2c95..55e4b3a 100644 --- a/tokendito/okta.py +++ b/tokendito/okta.py @@ -1037,7 +1037,9 @@ def mfa_provider_type( elif mfa_provider == "OKTA" and factor_type == "push": mfa_verify = push_approval(mfa_challenge_url, payload) - elif mfa_provider in ["OKTA", "GOOGLE"] and factor_type in ["token:software:totp", "sms"]: + elif (mfa_provider in ["OKTA", "GOOGLE"] and factor_type in ["token:software:totp", "sms"]) or ( + mfa_provider == "OKTA" and factor_type == "question" + ): mfa_verify = totp_approval( config, selected_mfa_option, headers, mfa_challenge_url, payload, primary_auth ) @@ -1153,7 +1155,12 @@ def totp_approval(config, selected_mfa_option, headers, mfa_challenge_url, paylo logger.debug(f"User MFA options selected: [{selected_mfa_option['factorType']}]") if config.okta["mfa_response"] is None: logger.debug("Getting verification code from user.") - config.okta["mfa_response"] = user.get_input("Enter your verification code: ") + if selected_mfa_option["factorType"] == "question": + config.okta["mfa_response"] = user.get_secret_input( + selected_mfa_option["profile"]["questionText"] + ) + else: + config.okta["mfa_response"] = user.get_input("Enter your verification code: ") user.add_sensitive_value_to_be_masked(config.okta["mfa_response"]) # time to verify the mfa diff --git a/tokendito/user.py b/tokendito/user.py index b0d957a..be88f39 100644 --- a/tokendito/user.py +++ b/tokendito/user.py @@ -807,7 +807,7 @@ def process_interactive_input(config, skip_password=False): if ("password" not in config.okta or config.okta["password"] == "") and not skip_password: logger.debug("No password set, will try to get one interactively") - res["okta"]["password"] = get_password() + res["okta"]["password"] = get_secret_input() add_sensitive_value_to_be_masked(res["okta"]["password"]) config_int = Config(**res) @@ -920,22 +920,24 @@ def get_username(): return res -def get_password(): - """Set okta password interactively. - - :param args: command line arguments - :return: okta_password +def get_secret_input(message=None): + """Get secret value interactively. + :param args: message to display user. + :return: secret """ - res = "" - logger.debug("Set password.") + secret = "" + logger.debug("get_secret_value") tty_assertion() - while res == "": - password = getpass() - res = password - logger.debug("password set interactively") - return res + while secret == "": + if message is None: + password = getpass() + else: + password = getpass(message) + secret = password + logger.debug("secret value set interactively") + return secret def get_interactive_profile_name(default):