"""Tests for the PP shadow authorization (CDAM-4044).""" from unittest.mock import MagicMock import pytest from pytest_mock import MockerFixture from assets.api import authorization_backend from assets.exceptions import AssetUploadNotFound from assets.logic import pdp_auth from assets.models import asset_upload, ows_product ACTION = pdp_auth.ACTION_UPDATE @pytest.fixture(autouse=True) def mock_request(mocker: MockerFixture) -> MagicMock: """Patch flask.request; default has no referrer.""" request = mocker.patch.object(pdp_auth, "request", MagicMock()) request.referrer = None return request def test_tenant_from_product_prefers_subaccount(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid", "subaccountUUID": "subaccount-uuid"}, ) assert pdp_auth.tenant_from_product(123) == ("subaccount", "subaccount-uuid") def test_tenant_from_product_falls_back_to_vendor(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid", "subaccountUUID": None}, ) assert pdp_auth.tenant_from_product(123) == ("account", "vendor-uuid") def test_tenant_from_product_none_when_no_owner(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": None, "subaccountUUID": None}, ) assert pdp_auth.tenant_from_product(123) is None def test_tenant_from_filename_resolves_via_product(mocker: MockerFixture) -> None: mocker.patch.object( asset_upload, "get_asset_upload", return_value={"product_id": 123} ) mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid"} ) assert pdp_auth.tenant_from_filename("file.wav") == ("account", "vendor-uuid") def test_tenant_from_filename_none_when_no_product(mocker: MockerFixture) -> None: mocker.patch.object( asset_upload, "get_asset_upload", return_value={"product_id": 0} ) assert pdp_auth.tenant_from_filename("file.wav") is None def test_tenant_from_filename_none_when_upload_not_found( mocker: MockerFixture, ) -> None: mocker.patch.object( asset_upload, "get_asset_upload", side_effect=AssetUploadNotFound("not found"), ) assert pdp_auth.tenant_from_filename("file.wav") is None def test_shadow_calls_backend_with_resolved_tenant(mocker: MockerFixture) -> None: """The single pdp call carries the resolved action + tenant. MigrationAuthorizationBackend forwards action/resource_type/etc. to the inner backend positionally, but `tenant` (part of `**kwargs`) stays a keyword arg. """ mocker.patch.object( ows_product, "get_product_by_id", return_value={"subaccountUUID": "subaccount-uuid"}, ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = None is_authorized = mocker.patch.object( authorization_backend, "is_authorized", return_value=True ) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) is_authorized.assert_called_once() args = is_authorized.call_args.args assert args[0] == ACTION assert args[2] == "product" assert is_authorized.call_args.kwargs["tenant"] == { "tenant_type": "subaccount", "tenant_uuid": "subaccount-uuid", } def test_shadow_skips_when_no_tenant(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": None, "subaccountUUID": None}, ) mocker.patch.object(pdp_auth, "g", MagicMock()) is_authorized = mocker.patch.object(authorization_backend, "is_authorized") pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) is_authorized.assert_not_called() def test_shadow_runs_for_workstation_referrer( mocker: MockerFixture, mock_request: MagicMock ) -> None: """A workstation.* referrer runs the shadow like any other caller.""" mock_request.referrer = "https://workstation.theorchard.com/releases/1/assets" mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid"} ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = None is_authorized = mocker.patch.object( authorization_backend, "is_authorized", return_value=True ) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) is_authorized.assert_called_once() def test_shadow_logs_identity_when_pp_would_deny(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid"} ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = "id-abc" mocker.patch.object(authorization_backend, "is_authorized", return_value=False) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) logged = mock_g.log.info.call_args[0][0] assert "pp_would_deny" in logged assert "identity=id-abc" in logged assert f"action={ACTION}" in logged assert "tenant_uuid=vendor-uuid" in logged def test_shadow_no_log_when_pp_allows(mocker: MockerFixture) -> None: mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid"} ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = "id-abc" mocker.patch.object(authorization_backend, "is_authorized", return_value=True) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) mock_g.log.info.assert_not_called() def test_shadow_calls_backend_but_skips_log_without_jwt_identity( mocker: MockerFixture, ) -> None: """The metric path runs for every request; only the would-deny log needs an identity.""" mocker.patch.object( ows_product, "get_product_by_id", return_value={"vendorUUID": "vendor-uuid"} ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = None is_authorized = mocker.patch.object( authorization_backend, "is_authorized", return_value=False ) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) is_authorized.assert_called_once() mock_g.log.info.assert_not_called() def test_shadow_swallows_errors(mocker: MockerFixture) -> None: """A failure resolving the tenant must never propagate to the request.""" mocker.patch.object( ows_product, "get_product_by_id", side_effect=RuntimeError("ows-product down") ) mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) pdp_auth.shadow_authorization(ACTION, pdp_auth.tenant_from_product, 123) mock_g.log.exception.assert_called_once() def test_principal_shadow_calls_backend_without_tenant(mocker: MockerFixture) -> None: """Machine endpoints check the principal policy — no tenant is passed.""" mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = None is_authorized = mocker.patch.object( authorization_backend, "is_authorized", return_value=True ) pdp_auth.shadow_authorization(pdp_auth.ACTION_UPDATE_AI_DETECTION) args = is_authorized.call_args.args assert args[0] == pdp_auth.ACTION_UPDATE_AI_DETECTION assert args[2] == "product" assert "tenant" not in is_authorized.call_args.kwargs def test_principal_shadow_logs_identity_when_pp_would_deny( mocker: MockerFixture, ) -> None: mock_g = mocker.patch.object(pdp_auth, "g", MagicMock()) mock_g.request_context.jwt_identity_id = "hive-uuid" mocker.patch.object(authorization_backend, "is_authorized", return_value=False) pdp_auth.shadow_authorization(pdp_auth.ACTION_UPDATE_AI_DETECTION) logged = mock_g.log.info.call_args[0][0] assert "pp_would_deny" in logged assert "identity=hive-uuid" in logged assert "tenant=none" in logged def test_request_tags_extracts_referrer_hostname(mock_request: MagicMock) -> None: mock_request.method = "POST" mock_request.url_rule = "/v2/assets/upload" mock_request.headers = { "Authorization": "Bearer x", "Orchard-Profile-Type": "Label", } mock_request.referrer = "https://workstation.theorchard.com/releases/1/assets" tags = pdp_auth.request_tags() assert "method:POST" in tags assert "endpoint:/v2/assets/upload" in tags assert "has_authorization_header:true" in tags assert "profile_type:label" in tags assert "referrer:workstation.theorchard.com" in tags def test_request_tags_referrer_unknown_without_referrer( mock_request: MagicMock, ) -> None: mock_request.method = "GET" mock_request.url_rule = "/health" mock_request.headers = {} mock_request.referrer = None tags = pdp_auth.request_tags() assert "has_authorization_header:false" in tags assert "profile_type:none" in tags assert "referrer:unknown" in tags