diff --git a/sentry_sdk/integrations/quart.py b/sentry_sdk/integrations/quart.py index 1343867fc3..344c42d36f 100644 --- a/sentry_sdk/integrations/quart.py +++ b/sentry_sdk/integrations/quart.py @@ -10,14 +10,12 @@ from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations._wsgi_common import _filter_headers from sentry_sdk.integrations.asgi import SentryAsgiMiddleware -from sentry_sdk.scope import should_send_default_pii from sentry_sdk.traces import SOURCE_FOR_STYLE as SEGMENT_SOURCE_FOR_STYLE from sentry_sdk.traces import Span, get_current_span from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, event_from_exception, - has_data_collection_enabled, parse_url, ) @@ -196,56 +194,27 @@ async def _request_websocket_started(app: "Quart", **kwargs: "Any") -> None: client_options = sentry_sdk.get_client().options filtered_query_string = None - if has_data_collection_enabled(client_options): - query_string = request_websocket.query_string.decode( - "utf-8", errors="replace" - ) - if query_string: - filtered_query_string = ( - _apply_data_collection_filtering_to_query_string( - query_string=query_string, - behaviour=client_options["data_collection"]["url_query_params"], - ) - ) - if filtered_query_string: - segment.set_attribute( - "url.query", - filtered_query_string, - ) - - parsed_url = parse_url(request_websocket.url) - segment.set_attribute( - "url.full", - f"{parsed_url.url}?{filtered_query_string}" - if filtered_query_string - else parsed_url.url, - ) - - if client_options["data_collection"]["user_info"]: - user_properties = {} - - if len(request_websocket.access_route) >= 1: - segment.set_attribute( - "client.address", request_websocket.access_route[0] - ) - user_properties["ip_address"] = request_websocket.access_route[0] - current_user_id = _get_current_user_id_from_quart() - if current_user_id: - user_properties["id"] = current_user_id - - if user_properties: - existing_user_properties = scope._user or {} - scope.set_user({**existing_user_properties, **user_properties}) - - elif should_send_default_pii(): - segment.set_attribute("url.full", request_websocket.url) - segment.set_attribute( - "url.query", - request_websocket.query_string.decode("utf-8", errors="replace"), + query_string = request_websocket.query_string.decode("utf-8", errors="replace") + if query_string: + filtered_query_string = _apply_data_collection_filtering_to_query_string( + query_string=query_string, + behaviour=client_options["data_collection"]["url_query_params"], ) + if filtered_query_string: + segment.set_attribute("url.query", filtered_query_string) + + parsed_url = parse_url(request_websocket.url) + segment.set_attribute( + "url.full", + f"{parsed_url.url}?{filtered_query_string}" + if filtered_query_string + else parsed_url.url, + ) + if client_options["data_collection"]["user_info"]: user_properties = {} + if len(request_websocket.access_route) >= 1: segment.set_attribute( "client.address", request_websocket.access_route[0] @@ -285,17 +254,7 @@ def inner(event: "Event", hint: "dict[str, Any]") -> "Event": request_info["headers"] = _filter_headers(dict(request.headers)) client_options = sentry_sdk.get_client().options - if has_data_collection_enabled(client_options): - if client_options["data_collection"]["user_info"]: - if len(request.access_route) >= 1: - request_info["env"] = {"REMOTE_ADDR": request.access_route[0]} - - current_user_id = _get_current_user_id_from_quart() - if current_user_id: - user_info = event.setdefault("user", {}) - user_info["id"] = current_user_id - - elif should_send_default_pii(): + if client_options["data_collection"]["user_info"]: if len(request.access_route) >= 1: request_info["env"] = {"REMOTE_ADDR": request.access_route[0]} diff --git a/tests/integrations/quart/test_quart.py b/tests/integrations/quart/test_quart.py index e2653b25d3..b5039e3dde 100644 --- a/tests/integrations/quart/test_quart.py +++ b/tests/integrations/quart/test_quart.py @@ -11,10 +11,10 @@ capture_message, set_tag, ) -from sentry_sdk._types import SENSITIVE_DATA_SUBSTITUTE from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.utils import parse_version +from tests.integrations.utils import DATA_COLLECTION_USER_INFO_CASES try: from importlib.metadata import version @@ -73,6 +73,12 @@ async def _thread_ids_async(): return app +QUART_USER_INFO_CASES = [ + pytest.param({}, True, id="data_collection_default"), + *DATA_COLLECTION_USER_INFO_CASES, +] + + @pytest.fixture(params=("manual",)) def integration_enabled_params(request): if request.param == "manual": @@ -107,6 +113,7 @@ async def test_quart_flask_patch(sentry_init, capture_events, reset_integrations app = quart_app_factory() sentry_init( integrations=[quart_sentry.QuartIntegration()], + data_collection={}, ) @app.route("/") @@ -127,7 +134,7 @@ async def index(): @pytest.mark.asyncio async def test_has_context(sentry_init, capture_events): - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() events = capture_events() @@ -149,6 +156,7 @@ async def test_http_route( sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, + data_collection={}, ) app = quart_app_factory() @@ -170,7 +178,7 @@ async def test_errors( capture_events, integration_enabled_params, ): - sentry_init(**integration_enabled_params) + sentry_init(data_collection={}, **integration_enabled_params) app = quart_app_factory() @app.route("/") @@ -197,7 +205,7 @@ async def index(): async def test_quart_auth_not_installed( sentry_init, capture_events, monkeypatch, integration_enabled_params ): - sentry_init(**integration_enabled_params) + sentry_init(data_collection={}, **integration_enabled_params) app = quart_app_factory() monkeypatch.setattr(quart_sentry, "quart_auth", None) @@ -212,43 +220,11 @@ async def test_quart_auth_not_installed( @pytest.mark.asyncio -async def test_quart_auth_not_configured( - sentry_init, capture_events, monkeypatch, integration_enabled_params -): - sentry_init(**integration_enabled_params) - app = quart_app_factory() - - assert quart_sentry.quart_auth - - events = capture_events() - client = app.test_client() - await client.get("/message") - - (event,) = events - assert event.get("user", {}).get("id") is None - - -@pytest.mark.asyncio -async def test_quart_auth_partially_configured( - sentry_init, capture_events, monkeypatch, integration_enabled_params -): - sentry_init(**integration_enabled_params) - app = quart_app_factory() - - events = capture_events() - - client = app.test_client() - await client.get("/message") - - (event,) = events - assert event.get("user", {}).get("id") is None - - -@pytest.mark.asyncio -@pytest.mark.parametrize("send_default_pii", [True, False]) -@pytest.mark.parametrize("user_id", [None, "42", "3"]) +@pytest.mark.parametrize("data_collection, expect_user_info", QUART_USER_INFO_CASES) +@pytest.mark.parametrize("user_id", [None, "42"]) async def test_quart_auth_configured( - send_default_pii, + data_collection, + expect_user_info, sentry_init, user_id, capture_events, @@ -257,7 +233,7 @@ async def test_quart_auth_configured( ): from quart_auth import AuthUser, login_user - sentry_init(send_default_pii=send_default_pii, **integration_enabled_params) + sentry_init(data_collection=data_collection, **integration_enabled_params) app = quart_app_factory() @app.route("/login") @@ -275,10 +251,15 @@ async def login(): assert (await client.get("/message")).status_code == 200 (event,) = events - if user_id is None or not send_default_pii: + if expect_user_info and user_id is not None: + assert event["user"]["id"] == user_id + else: assert event.get("user", {}).get("id") is None + + if expect_user_info: + assert "REMOTE_ADDR" in event["request"]["env"] else: - assert event["user"]["id"] == str(user_id) + assert "env" not in event["request"] @pytest.mark.asyncio @@ -290,7 +271,7 @@ async def login(): ], ) async def test_errors_not_reported_twice(sentry_init, integrations, capture_events): - sentry_init(integrations=integrations) + sentry_init(integrations=integrations, data_collection={}) app = quart_app_factory() @app.route("/") @@ -317,7 +298,8 @@ async def test_logging(sentry_init, capture_events): integrations=[ quart_sentry.QuartIntegration(), LoggingIntegration(event_level="ERROR"), - ] + ], + data_collection={}, ) app = quart_app_factory() @@ -337,7 +319,7 @@ async def index(): @pytest.mark.asyncio async def test_no_errors_without_request(sentry_init): - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() async with app.app_context(): @@ -364,7 +346,7 @@ def foo(): @pytest.mark.asyncio async def test_500(sentry_init): - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() @app.route("/") @@ -383,7 +365,7 @@ async def error_handler(err): @pytest.mark.asyncio async def test_error_in_errorhandler(sentry_init, capture_events): - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() @app.route("/") @@ -447,7 +429,7 @@ async def error_handler(err): async def test_bad_request_not_captured(sentry_init, capture_events): from quart import abort - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() events = capture_events() @@ -466,7 +448,7 @@ async def index(): async def test_does_not_leak_scope(sentry_init, capture_events): from quart import Response, stream_with_context - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() events = capture_events() @@ -495,7 +477,7 @@ async def generate(): @pytest.mark.asyncio async def test_scoped_test_client(sentry_init): - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() @app.route("/") @@ -515,7 +497,7 @@ async def test_errorhandler_for_exception_swallows_exception( # In contrast to error handlers for a status code, error # handlers for exceptions can swallow the exception (this is # just how the Quart signal works) - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() events = capture_events() @@ -539,6 +521,7 @@ async def test_tracing_success(sentry_init, capture_items): sentry_init( traces_sample_rate=1.0, integrations=[quart_sentry.QuartIntegration()], + data_collection={}, ) app = quart_app_factory() @@ -575,6 +558,7 @@ async def test_tracing_error(sentry_init, capture_items): sentry_init( traces_sample_rate=1.0, integrations=[quart_sentry.QuartIntegration()], + data_collection={}, ) app = quart_app_factory() @@ -603,7 +587,7 @@ async def error(): async def test_class_based_views(sentry_init, capture_events): from quart.views import View - sentry_init(integrations=[quart_sentry.QuartIntegration()]) + sentry_init(integrations=[quart_sentry.QuartIntegration()], data_collection={}) app = quart_app_factory() events = capture_events() @@ -632,6 +616,7 @@ async def test_span_origin(sentry_init, capture_items): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, + data_collection={}, ) app = quart_app_factory() items = capture_items("span") @@ -651,6 +636,7 @@ async def test_basic(sentry_init, capture_items): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, + data_collection={}, ) items = capture_items("span") @@ -697,6 +683,7 @@ async def test_transaction_style( quart_sentry.QuartIntegration(transaction_style=transaction_style) ], traces_sample_rate=1.0, + data_collection={}, ) items = capture_items("span") @@ -721,6 +708,7 @@ async def test_with_error(sentry_init, capture_items): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, + data_collection={}, ) items = capture_items("event", "span") @@ -759,41 +747,14 @@ async def error(): @pytest.mark.asyncio -async def test_request_attributes_no_pii(sentry_init, capture_items): - sentry_init( - integrations=[quart_sentry.QuartIntegration()], - traces_sample_rate=1.0, - send_default_pii=False, - ) - items = capture_items("span") - - app = quart_app_factory() - client = app.test_client() - response = await client.get("/message?foo=bar") - assert response.status_code == 200 - - sentry_sdk.flush() - - spans = [item.payload for item in items] - assert len(spans) == 1 - - segment = spans[0] - assert segment["attributes"]["http.request.method"] == "GET" - assert "http.request.header.host" in segment["attributes"] - - assert "url.full" not in segment["attributes"] - assert "url.path" not in segment["attributes"] - assert "url.query" not in segment["attributes"] - assert "client.address" not in segment["attributes"] - assert "user.ip_address" not in segment["attributes"] - - -@pytest.mark.asyncio -async def test_request_attributes_with_pii(sentry_init, capture_items): +@pytest.mark.parametrize("data_collection, expect_user_info", QUART_USER_INFO_CASES) +async def test_request_attributes( + sentry_init, capture_items, data_collection, expect_user_info +): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, - send_default_pii=True, + data_collection=data_collection, ) items = capture_items("span") @@ -816,50 +777,34 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): ) assert segment["attributes"]["url.path"] == "/message" assert segment["attributes"]["url.query"] == "foo=bar&baz=qux" - assert "client.address" in segment["attributes"] - assert "user.ip_address" in segment["attributes"] + + if expect_user_info: + assert "client.address" in segment["attributes"] + assert "user.ip_address" in segment["attributes"] + else: + assert "client.address" not in segment["attributes"] + assert "user.ip_address" not in segment["attributes"] @pytest.mark.parametrize( - "options,expected", + "data_collection,expected", [ pytest.param( - { - "send_default_pii": True, - "data_collection": {}, - }, + {}, { "authorization": "[Filtered]", "custom": "passthrough", "cookie": "[Filtered]", }, - id="enabled_send_default_pii_redacts_auth_header_due_to_data_collection_default_settings", + id="data_collection_default_redacts_auth_header", ), pytest.param( - { - "send_default_pii": False, - "data_collection": {}, - }, - { - "authorization": "[Filtered]", - "custom": "passthrough", - "cookie": "[Filtered]", - }, - id="disabled_send_default_pii_redacts_auth_header_due_to_data_collection_default_settings", - ), - pytest.param( - { - "send_default_pii": False, - "data_collection": {"http_headers": {"request": {"mode": "off"}}}, - }, + {"http_headers": {"request": {"mode": "off"}}}, None, id="data_collection_off_does_not_add_headers", ), pytest.param( - { - "send_default_pii": False, - "data_collection": {"http_headers": {"request": {"mode": "allowlist"}}}, - }, + {"http_headers": {"request": {"mode": "allowlist"}}}, { "authorization": "[Filtered]", "custom": "[Filtered]", @@ -869,12 +814,9 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): ), pytest.param( { - "send_default_pii": False, - "data_collection": { - "http_headers": { - "request": {"mode": "allowlist", "terms": ["Authorization"]} - } - }, + "http_headers": { + "request": {"mode": "allowlist", "terms": ["Authorization"]} + } }, { "authorization": "[Filtered]", @@ -884,14 +826,7 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): id="data_collection_allow_list_redacts_sensitive_terms_even_when_provided_by_user", ), pytest.param( - { - "send_default_pii": False, - "data_collection": { - "http_headers": { - "request": {"mode": "allowlist", "terms": ["custom"]} - } - }, - }, + {"http_headers": {"request": {"mode": "allowlist", "terms": ["custom"]}}}, { "authorization": "[Filtered]", "custom": "passthrough", @@ -900,14 +835,7 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): id="data_collection_allow_list_does_not_redact_provided_term", ), pytest.param( - { - "send_default_pii": False, - "data_collection": { - "http_headers": { - "request": {"mode": "denylist", "terms": ["custom"]} - } - }, - }, + {"http_headers": {"request": {"mode": "denylist", "terms": ["custom"]}}}, { "authorization": "[Filtered]", "custom": "[Filtered]", @@ -916,14 +844,7 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): id="data_collection_deny_list_redacts_sensitive_terms_when_provided_by_user", ), pytest.param( - { - "send_default_pii": False, - "data_collection": { - "http_headers": { - "request": {"mode": "allowlist", "terms": ["cookie"]} - } - }, - }, + {"http_headers": {"request": {"mode": "allowlist", "terms": ["cookie"]}}}, { "authorization": "[Filtered]", "custom": "[Filtered]", @@ -935,13 +856,12 @@ async def test_request_attributes_with_pii(sentry_init, capture_items): ) @pytest.mark.asyncio async def test_sensitive_header_scrubbing( - sentry_init, capture_items, options, expected, request + sentry_init, capture_items, data_collection, expected ): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, - send_default_pii=options["send_default_pii"], - data_collection=options["data_collection"], + data_collection=data_collection, ) items = capture_items("span") @@ -979,43 +899,11 @@ async def test_sensitive_header_scrubbing( @pytest.mark.asyncio -async def test_sensitive_header_without_data_collection(sentry_init, capture_items): - sentry_init( - integrations=[quart_sentry.QuartIntegration()], - traces_sample_rate=1.0, - send_default_pii=False, - ) - items = capture_items("span") - - app = quart_app_factory() - client = app.test_client() - response = await client.get( - "/message", - headers={ - "Authorization": "Bearer secret-token", - "X-Custom-Header": "passthrough", - }, - ) - assert response.status_code == 200 - - sentry_sdk.flush() - - spans = [item.payload for item in items] - assert len(spans) == 1 - - segment = spans[0] - assert ( - segment["attributes"]["http.request.header.authorization"] - == SENSITIVE_DATA_SUBSTITUTE - ) - assert segment["attributes"]["http.request.header.x-custom-header"] == "passthrough" - - -@pytest.mark.asyncio -@pytest.mark.parametrize("send_default_pii", [True, False]) +@pytest.mark.parametrize("data_collection, expect_user_info", QUART_USER_INFO_CASES) @pytest.mark.parametrize("user_id", [None, "42"]) async def test_quart_auth_user_id( - send_default_pii, + data_collection, + expect_user_info, sentry_init, user_id, capture_items, @@ -1025,7 +913,7 @@ async def test_quart_auth_user_id( sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, - send_default_pii=send_default_pii, + data_collection=data_collection, ) items = capture_items("span") @@ -1047,254 +935,50 @@ async def login(): assert len(spans) == 2 segment = next(s for s in spans if s["name"] == "hi") - if send_default_pii and user_id is not None: + if expect_user_info and user_id is not None: assert segment["attributes"]["user.id"] == user_id else: assert "user.id" not in segment.get("attributes", {}) -QUART_USER_INFO_CASES = [ - pytest.param( - {"data_collection": {}}, - True, - id="dc_default_user_info", - ), - pytest.param( - {"data_collection": {"user_info": True}}, - True, - id="dc_user_info_true", - ), - pytest.param( - {"data_collection": {"user_info": False}}, - False, - id="dc_user_info_false", - ), - pytest.param( - { - "send_default_pii": True, - "data_collection": {"user_info": False}, - }, - False, - id="dc_wins_over_pii", - ), -] - - -@pytest.mark.asyncio -@pytest.mark.parametrize("init_kwargs, expect_user_info", QUART_USER_INFO_CASES) -async def test_quart_auth_user_info_data_collection( - sentry_init, - capture_events, - init_kwargs, - expect_user_info, -): - from quart_auth import AuthUser, login_user - - kwargs = dict(init_kwargs) - sentry_init(integrations=[quart_sentry.QuartIntegration()], **kwargs) - app = quart_app_factory() - - @app.route("/login") - async def login(): - login_user(AuthUser("42")) - return "ok" - - events = capture_events() - - client = app.test_client() - assert (await client.get("/login")).status_code == 200 - assert not events - - assert (await client.get("/message")).status_code == 200 - - (event,) = events - if expect_user_info: - assert event["user"]["id"] == "42" - assert "REMOTE_ADDR" in event["request"]["env"] - else: - assert event.get("user", {}).get("id") is None - assert "env" not in event["request"] - - -@pytest.mark.asyncio -@pytest.mark.parametrize("init_kwargs, expect_user_info", QUART_USER_INFO_CASES) -async def test_quart_auth_user_id_data_collection( - sentry_init, - capture_items, - init_kwargs, - expect_user_info, -): - from quart_auth import AuthUser, login_user - - sentry_init( - integrations=[quart_sentry.QuartIntegration()], - traces_sample_rate=1.0, - **init_kwargs, - ) - items = capture_items("span") - - app = quart_app_factory() - - @app.route("/login") - async def login(): - login_user(AuthUser("42")) - return "ok" - - client = app.test_client() - assert (await client.get("/login")).status_code == 200 - assert (await client.get("/message")).status_code == 200 - - sentry_sdk.flush() - - spans = [item.payload for item in items] - assert len(spans) == 2 - - (segment,) = ( - span for span in spans if span["attributes"]["url.path"] == "/message" - ) - if expect_user_info: - assert segment["attributes"]["user.id"] == "42" - else: - assert "user.id" not in segment.get("attributes", {}) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("init_kwargs, expect_user_info", QUART_USER_INFO_CASES) -async def test_request_attributes_data_collection( - sentry_init, capture_items, init_kwargs, expect_user_info -): - sentry_init( - integrations=[quart_sentry.QuartIntegration()], - traces_sample_rate=1.0, - **init_kwargs, - ) - items = capture_items("span") - - app = quart_app_factory() - client = app.test_client() - response = await client.get("/message") - assert response.status_code == 200 - - sentry_sdk.flush() - - spans = [item.payload for item in items] - assert len(spans) == 1 - - segment = spans[0] - if expect_user_info: - assert "client.address" in segment["attributes"] - assert "user.ip_address" in segment["attributes"] - else: - assert "client.address" not in segment["attributes"] - assert "user.ip_address" not in segment["attributes"] - - -@pytest.mark.asyncio -async def test_sensitive_header_passthrough_with_pii_and_no_data_collection( - sentry_init, capture_items -): - sentry_init( - integrations=[quart_sentry.QuartIntegration()], - traces_sample_rate=1.0, - send_default_pii=True, - ) - items = capture_items("span") - - app = quart_app_factory() - client = app.test_client() - response = await client.get( - "/message", - headers={"Authorization": "Bearer secret-token"}, - ) - assert response.status_code == 200 - - sentry_sdk.flush() - - spans = [item.payload for item in items] - assert len(spans) == 1 - - segment = spans[0] - assert ( - segment["attributes"]["http.request.header.authorization"] - == "Bearer secret-token" - ) - - _QUERY_PARAM_DATA_COLLECTION_CASES = [ - pytest.param( - {"send_default_pii": True}, - "toy=tennisball&color=red&auth=secret", - id="send_default_pii_true", - ), - pytest.param( - {"send_default_pii": False}, - None, - id="send_default_pii_false", - ), pytest.param( {}, - None, - id="defaults", - ), - pytest.param( - {"data_collection": {}}, "toy=tennisball&color=red&auth=%5BFiltered%5D", id="data_collection_denylist_default", ), pytest.param( - { - "data_collection": { - "url_query_params": {"mode": "denylist", "terms": ["toy"]} - } - }, + {"url_query_params": {"mode": "denylist", "terms": ["toy"]}}, "toy=%5BFiltered%5D&color=red&auth=%5BFiltered%5D", id="data_collection_denylist_custom_terms", ), pytest.param( - { - "data_collection": { - "url_query_params": {"mode": "allowlist", "terms": ["toy"]} - } - }, + {"url_query_params": {"mode": "allowlist", "terms": ["toy"]}}, "toy=tennisball&color=%5BFiltered%5D&auth=%5BFiltered%5D", id="data_collection_allowlist", ), pytest.param( - { - "data_collection": { - "url_query_params": {"mode": "allowlist", "terms": ["auth"]} - } - }, + {"url_query_params": {"mode": "allowlist", "terms": ["auth"]}}, "toy=%5BFiltered%5D&color=%5BFiltered%5D&auth=%5BFiltered%5D", id="data_collection_allowlist_sensitive_term", ), pytest.param( - {"data_collection": {"url_query_params": {"mode": "off"}}}, + {"url_query_params": {"mode": "off"}}, None, id="data_collection_off", ), - pytest.param( - { - "send_default_pii": True, - "data_collection": {"url_query_params": {"mode": "off"}}, - }, - None, - id="data_collection_wins_over_send_default_pii", - ), ] @pytest.mark.asyncio @pytest.mark.parametrize( - "init_kwargs, expected_query", _QUERY_PARAM_DATA_COLLECTION_CASES + "data_collection, expected_query", _QUERY_PARAM_DATA_COLLECTION_CASES ) -async def test_url_query_data_collection( - sentry_init, capture_items, init_kwargs, expected_query -): +async def test_url_query(sentry_init, capture_items, data_collection, expected_query): sentry_init( integrations=[quart_sentry.QuartIntegration()], traces_sample_rate=1.0, - **init_kwargs, + data_collection=data_collection, ) items = capture_items("span") @@ -1310,19 +994,11 @@ async def test_url_query_data_collection( segment = spans[0] - data_collection_enabled = "data_collection" in init_kwargs - url_attrs_expected = data_collection_enabled or init_kwargs.get( - "send_default_pii", False - ) - if expected_query is None: assert "url.query" not in segment["attributes"] - if url_attrs_expected: - # When the filtered query string is empty, url.full carries the - # base URL only (no query). - assert segment["attributes"]["url.full"] == "http://localhost/message" - else: - assert "url.full" not in segment["attributes"] + # When the filtered query string is empty, url.full carries the + # base URL only (no query). + assert segment["attributes"]["url.full"] == "http://localhost/message" else: assert segment["attributes"]["url.query"] == expected_query assert segment["attributes"]["url.full"] == (