Skip to content

Commit be93f11

Browse files
committed
Telemetry: report wrapped provider's auth mech/flow under TokenFederation
TokenFederationProvider wraps an underlying auth provider (PAT, OAuth, M2M) and only adds a token-exchange step. The telemetry helpers previously fell through to AuthMech.OTHER with no flow, hiding the actual auth method. Unwrap and recurse on external_provider so federated PAT reports PAT, federated M2M reports CLIENT_CREDENTIALS, etc. Co-authored-by: Isaac
1 parent ee63b81 commit be93f11

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/databricks/sql/telemetry/telemetry_client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
DatabricksOAuthProvider,
3535
ExternalAuthProvider,
3636
)
37+
from databricks.sql.auth.token_federation import TokenFederationProvider
3738
import sys
3839
import platform
3940
import uuid
@@ -90,6 +91,8 @@ def get_auth_mechanism(auth_provider):
9091

9192
if not auth_provider:
9293
return None
94+
if isinstance(auth_provider, TokenFederationProvider):
95+
return TelemetryHelper.get_auth_mechanism(auth_provider.external_provider)
9396
if isinstance(auth_provider, AccessTokenAuthProvider):
9497
return AuthMech.PAT
9598
elif isinstance(auth_provider, DatabricksOAuthProvider):
@@ -105,6 +108,8 @@ def get_auth_flow(auth_provider):
105108

106109
if not auth_provider:
107110
return None
111+
if isinstance(auth_provider, TokenFederationProvider):
112+
return TelemetryHelper.get_auth_flow(auth_provider.external_provider)
108113
if isinstance(auth_provider, DatabricksOAuthProvider):
109114
if auth_provider._access_token and auth_provider._refresh_token:
110115
return AuthFlow.TOKEN_PASSTHROUGH

tests/unit/test_telemetry.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
DatabricksOAuthProvider,
3030
ExternalAuthProvider,
3131
)
32+
from databricks.sql.auth.token_federation import TokenFederationProvider
3233
from databricks import sql
3334

3435

@@ -211,6 +212,37 @@ def test_auth_flow_detection(self):
211212
# Test None auth provider
212213
assert TelemetryHelper.get_auth_flow(None) is None
213214

215+
def test_token_federation_unwraps_to_inner_provider(self):
216+
"""Token federation should report the wrapped provider's mech and flow."""
217+
218+
def make_federation(inner):
219+
fed = MagicMock(spec=TokenFederationProvider)
220+
fed.external_provider = inner
221+
return fed
222+
223+
# PAT wrapped by federation
224+
pat_inner = AccessTokenAuthProvider("test-token")
225+
fed_pat = make_federation(pat_inner)
226+
assert TelemetryHelper.get_auth_mechanism(fed_pat) == AuthMech.PAT
227+
assert TelemetryHelper.get_auth_flow(fed_pat) is None
228+
229+
# M2M (ExternalAuthProvider) wrapped by federation
230+
m2m_inner = MagicMock(spec=ExternalAuthProvider)
231+
fed_m2m = make_federation(m2m_inner)
232+
assert TelemetryHelper.get_auth_mechanism(fed_m2m) == AuthMech.OTHER
233+
assert TelemetryHelper.get_auth_flow(fed_m2m) == AuthFlow.CLIENT_CREDENTIALS
234+
235+
# OAuth (browser) wrapped by federation
236+
oauth_inner = MagicMock(spec=DatabricksOAuthProvider)
237+
oauth_inner._access_token = None
238+
oauth_inner._refresh_token = None
239+
fed_oauth = make_federation(oauth_inner)
240+
assert TelemetryHelper.get_auth_mechanism(fed_oauth) == AuthMech.OAUTH
241+
assert (
242+
TelemetryHelper.get_auth_flow(fed_oauth)
243+
== AuthFlow.BROWSER_BASED_AUTHENTICATION
244+
)
245+
214246

215247
class TestTelemetryFactory:
216248
"""Tests for TelemetryClientFactory lifecycle and management."""

0 commit comments

Comments
 (0)