Skip to content

Commit 7f79631

Browse files
juanjuxemmettbutlermajorgreysmabdinur
authored
fix: dont raise a ValueError on set_user when no span [backport #5548 to 1.12] (#5568)
Backport of #5548 to 1.12 Don't raise a ValueError if there is a call to `set_user` or any of the other event SDK functions that require a span, without a span, just log + regression test. Fixes #5485 ## Checklist - [X] Change(s) are motivated and described in the PR description. - [X] Testing strategy is described if automated tests are not included in the PR. - [X] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [X] Change is maintainable (easy to change, telemetry, documentation). - [X] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [X] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [X] PR description includes explicit acknowledgement/acceptance of the performance implications of this PR as reported in the benchmarks PR comment. ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. Co-authored-by: Emmett Butler <[email protected]> Co-authored-by: Tahir H. Butt <[email protected]> Co-authored-by: Munir Abdinur <[email protected]>
1 parent 12f9d97 commit 7f79631

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

ddtrace/appsec/trace_utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ def should_block_user(tracer, userid): # type: (Tracer, str) -> bool
146146

147147
# Early check to avoid calling the WAF if the request is already blocked
148148
span = tracer.current_root_span()
149+
if not span:
150+
log.warning(
151+
"No root span in the current execution. should_block_user returning False"
152+
"See https://docs.datadoghq.com/security_platform/application_security"
153+
"/setup_and_configure/"
154+
"?tab=set_user&code-lang=python for more information.",
155+
)
156+
return False
157+
149158
if _context.get_item(WAF_CONTEXT_NAMES.BLOCKED, span=span):
150159
return True
151160

ddtrace/contrib/trace_utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -631,14 +631,14 @@ def set_user(tracer, user_id, name=None, email=None, scope=None, role=None, sess
631631
span.set_tag_str(user.ROLE, role)
632632
if session_id:
633633
span.set_tag_str(user.SESSION_ID, session_id)
634+
635+
if config._appsec_enabled:
636+
from ddtrace.appsec.trace_utils import block_request_if_user_blocked
637+
638+
block_request_if_user_blocked(tracer, user_id)
634639
else:
635640
log.warning(
636641
"No root span in the current execution. Skipping set_user tags. "
637642
"See https://docs.datadoghq.com/security_platform/application_security/setup_and_configure/"
638643
"?tab=set_user&code-lang=python for more information.",
639644
)
640-
641-
if config._appsec_enabled:
642-
from ddtrace.appsec.trace_utils import block_request_if_user_blocked
643-
644-
block_request_if_user_blocked(tracer, user_id)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
ASM: fix calling `set_user` without a created span raising a `ValueError`.

tests/appsec/test_appsec_trace_utils.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import logging
2+
13
import pytest
24

35
from ddtrace import constants
46
from ddtrace.appsec._constants import APPSEC
7+
from ddtrace.appsec.trace_utils import block_request_if_user_blocked
8+
from ddtrace.appsec.trace_utils import should_block_user
59
from ddtrace.appsec.trace_utils import track_custom_event
610
from ddtrace.appsec.trace_utils import track_user_login_failure_event
711
from ddtrace.appsec.trace_utils import track_user_login_success_event
@@ -19,7 +23,8 @@ class EventsSDKTestCase(TracerTestCase):
1923
_BLOCKED_USER = "123456"
2024

2125
@pytest.fixture(autouse=True)
22-
def inject_fixtures(self, tracer_appsec): # noqa: F811
26+
def inject_fixtures(self, tracer_appsec, caplog): # noqa: F811
27+
self._caplog = caplog
2328
self._tracer_appsec = tracer_appsec
2429

2530
def test_track_user_login_event_success_without_metadata(self):
@@ -137,3 +142,20 @@ def test_set_user_blocked(self):
137142
assert span.get_tag(user.SCOPE)
138143
assert span.get_tag(user.SESSION_ID)
139144
assert _context.get_item("http.request.blocked", span=span)
145+
146+
def test_no_span_doesnt_raise(self):
147+
from ddtrace import tracer
148+
149+
with self._caplog.at_level(logging.DEBUG):
150+
try:
151+
should_block_user(tracer, "111")
152+
block_request_if_user_blocked(tracer, "111")
153+
track_custom_event(tracer, "testevent", {})
154+
track_user_login_success_event(tracer, "111", {})
155+
track_user_login_failure_event(tracer, "111", {})
156+
set_user(tracer, "111")
157+
except Exception as e:
158+
pytest.fail("Should not raise but raised %s" % str(e))
159+
160+
assert any("No root span" in record.message for record in self._caplog.records)
161+
assert any(record.levelno == logging.WARNING for record in self._caplog.records)

0 commit comments

Comments
 (0)