mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2026-04-28 03:30:10 +00:00
97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
"""Tests for skyvern.services.otp_service — MFA key detection and TOTP extraction."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from skyvern.services.otp_service import _is_mfa_like_parameter_key, extract_totp_from_navigation_inputs
|
|
|
|
|
|
class TestIsMfaLikeParameterKey:
|
|
"""_is_mfa_like_parameter_key should match OTP *code* keys but reject metadata keys."""
|
|
|
|
@pytest.mark.parametrize(
|
|
"key",
|
|
[
|
|
"otp_code",
|
|
"mfa_code",
|
|
"verification_code",
|
|
"otp",
|
|
"mfa",
|
|
"verification",
|
|
"OTP_CODE",
|
|
"MFA_Code",
|
|
],
|
|
)
|
|
def test_matches_actual_otp_code_keys(self, key: str) -> None:
|
|
assert _is_mfa_like_parameter_key(key) is True
|
|
|
|
@pytest.mark.parametrize(
|
|
"key",
|
|
[
|
|
# The root-cause bug: totp_identifier contains "otp" but is metadata
|
|
"totp_identifier",
|
|
"totp_url",
|
|
"totp_secret",
|
|
"totp_seed",
|
|
"otp_identifier",
|
|
"mfa_secret_key",
|
|
"verification_url",
|
|
# Unrelated keys
|
|
"username",
|
|
"password",
|
|
"email",
|
|
"url",
|
|
],
|
|
)
|
|
def test_rejects_metadata_and_unrelated_keys(self, key: str) -> None:
|
|
assert _is_mfa_like_parameter_key(key) is False
|
|
|
|
|
|
class TestExtractTotpFromNavigationInputs:
|
|
"""extract_totp_from_navigation_inputs should only return actual OTP codes."""
|
|
|
|
def test_returns_none_for_none_payload(self) -> None:
|
|
assert extract_totp_from_navigation_inputs(None) is None
|
|
|
|
def test_returns_none_for_empty_dict(self) -> None:
|
|
assert extract_totp_from_navigation_inputs({}) is None
|
|
|
|
def test_extracts_otp_code_from_payload(self) -> None:
|
|
payload = {"otp_code": "123456"}
|
|
result = extract_totp_from_navigation_inputs(payload)
|
|
assert result is not None
|
|
assert result.value == "123456"
|
|
|
|
def test_ignores_totp_identifier_key(self) -> None:
|
|
"""The core bug: totp_identifier value must NOT be returned as OTP code."""
|
|
payload = {
|
|
"totp_identifier": "2fa.00000000-0000-0000-0000-000000000000.wpid_000000000000000000",
|
|
"totp_url": "https://example.com/totp",
|
|
}
|
|
result = extract_totp_from_navigation_inputs(payload)
|
|
assert result is None
|
|
|
|
def test_extracts_code_even_with_metadata_keys_present(self) -> None:
|
|
"""When both metadata and code keys exist, only the code value is returned."""
|
|
payload = {
|
|
"totp_identifier": "2fa.ab4a9cf0-xxx",
|
|
"otp_code": "654321",
|
|
}
|
|
result = extract_totp_from_navigation_inputs(payload)
|
|
assert result is not None
|
|
assert result.value == "654321"
|
|
|
|
def test_extracts_mfa_code_from_nested_dict(self) -> None:
|
|
payload = {"data": {"mfa_code": "789012"}}
|
|
result = extract_totp_from_navigation_inputs(payload)
|
|
assert result is not None
|
|
assert result.value == "789012"
|
|
|
|
def test_returns_none_for_only_metadata_keys(self) -> None:
|
|
payload = {
|
|
"totp_identifier": "user@example.com",
|
|
"totp_secret": "JBSWY3DPEHPK3PXP",
|
|
}
|
|
result = extract_totp_from_navigation_inputs(payload)
|
|
assert result is None
|