diff --git a/sdk/identity/azure-identity-broker/tests/conftest.py b/sdk/identity/azure-identity-broker/tests/conftest.py index e69de29bb2d1..1193772c7784 100644 --- a/sdk/identity/azure-identity-broker/tests/conftest.py +++ b/sdk/identity/azure-identity-broker/tests/conftest.py @@ -0,0 +1,21 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +import pytest + + +def pytest_addoption(parser): + parser.addoption("--manual", action="store_true", default=False, help="include manual tests in test run") + + +def pytest_configure(config): + config.addinivalue_line("markers", "manual: mark test as requiring manual interaction") + + +def pytest_collection_modifyitems(config, items): + run_manual_tests = config.getoption("--manual") + skip_manual = pytest.mark.skip(reason="run pytest with '--manual' to run manual tests") + for test in items: + if not run_manual_tests and "manual" in test.keywords: + test.add_marker(skip_manual) diff --git a/sdk/identity/azure-identity-broker/tests/test_broker.py b/sdk/identity/azure-identity-broker/tests/test_broker.py index 77151ce52e5b..be55d1fe73d6 100644 --- a/sdk/identity/azure-identity-broker/tests/test_broker.py +++ b/sdk/identity/azure-identity-broker/tests/test_broker.py @@ -3,11 +3,15 @@ # Licensed under the MIT License. # ------------------------------------ import pytest +import re import sys from unittest.mock import patch, Mock +from azure.core import PipelineClient from azure.core.exceptions import ClientAuthenticationError -from azure.identity.broker import InteractiveBrowserBrokerCredential +from azure.core.rest import HttpRequest, HttpResponse +from azure.identity.broker import InteractiveBrowserBrokerCredential, PopTokenRequestOptions +import msal @pytest.mark.skipif(not sys.platform.startswith("win"), reason="tests Windows-specific behavior") @@ -55,3 +59,42 @@ def test_enable_support_logging_enabled(): assert mock_client_application.call_count == 1, "credential didn't create an msal application" _, kwargs = mock_client_application.call_args assert kwargs["enable_pii_log"] + + +@pytest.mark.manual +@pytest.mark.skipif(not sys.platform.startswith("win"), reason="tests Windows-specific behavior") +def test_broker_pop_authentication_flow(): + """The credential should be be able to access a resource with a PoP token.""" + + endpoint = "https://graph.microsoft.com/beta/me" + client = PipelineClient(base_url=endpoint) + + request = HttpRequest("GET", endpoint) + response: HttpResponse = client.send_request(request) + + assert response.status_code == 401 + + www_authenticate = response.headers["WWW-Authenticate"] + found = re.search(r'nonce="(.+?)"', www_authenticate) + + assert found, "server didn't return a nonce" + nonce = found.group(1) + + request_options = PopTokenRequestOptions( + { + "pop": { + "nonce": nonce, + "resource_request_url": endpoint, + "resource_request_method": "GET", + } + } + ) + + cred = InteractiveBrowserBrokerCredential(parent_window_handle=msal.PublicClientApplication.CONSOLE_WINDOW_HANDLE) + pop_token = cred.get_token_info("https://graph.microsoft.com/.default", options=request_options) + assert pop_token.token_type == "pop" + + request = HttpRequest("GET", endpoint, headers={"Authorization": f"{pop_token.token_type} {pop_token.token}"}) + response = client.send_request(request) + + assert response.status_code == 200