11import { expect } from 'chai' ;
22import sinon from 'sinon' ;
3- import nock from 'nock' ;
43import FederationProvider from '../../../../../lib/connection/auth/tokenProvider/FederationProvider' ;
54import ITokenProvider from '../../../../../lib/connection/auth/tokenProvider/ITokenProvider' ;
65import Token from '../../../../../lib/connection/auth/tokenProvider/Token' ;
@@ -28,10 +27,6 @@ class MockTokenProvider implements ITokenProvider {
2827}
2928
3029describe ( 'FederationProvider' , ( ) => {
31- afterEach ( ( ) => {
32- nock . cleanAll ( ) ;
33- } ) ;
34-
3530 describe ( 'getToken' , ( ) => {
3631 it ( 'should pass through token if issuer matches Databricks host' , async ( ) => {
3732 const jwt = createJWT ( { iss : 'https://my-workspace.cloud.databricks.com' } ) ;
@@ -52,129 +47,24 @@ describe('FederationProvider', () => {
5247 expect ( token . accessToken ) . to . equal ( 'not-a-jwt-token' ) ;
5348 } ) ;
5449
55- it ( 'should exchange token when issuer differs from Databricks host' , async ( ) => {
56- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
57- const exchangedToken = 'exchanged-databricks-token' ;
58- const baseProvider = new MockTokenProvider ( externalJwt ) ;
59-
60- nock ( 'https://my-workspace.cloud.databricks.com' )
61- . post ( '/oidc/v1/token' )
62- . reply ( 200 , {
63- access_token : exchangedToken ,
64- token_type : 'Bearer' ,
65- expires_in : 3600 ,
66- } ) ;
67-
68- const federationProvider = new FederationProvider ( baseProvider , 'https://my-workspace.cloud.databricks.com' ) ;
69-
70- const token = await federationProvider . getToken ( ) ;
71-
72- expect ( token . accessToken ) . to . equal ( exchangedToken ) ;
73- expect ( token . tokenType ) . to . equal ( 'Bearer' ) ;
74- } ) ;
75-
76- it ( 'should include client_id in exchange request when provided' , async ( ) => {
77- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
78- const baseProvider = new MockTokenProvider ( externalJwt ) ;
79-
80- let requestBody : string | undefined ;
81- nock ( 'https://my-workspace.cloud.databricks.com' )
82- . post ( '/oidc/v1/token' , ( body ) => {
83- requestBody = body ;
84- return true ;
85- } )
86- . reply ( 200 , {
87- access_token : 'exchanged-token' ,
88- token_type : 'Bearer' ,
89- } ) ;
90-
91- const federationProvider = new FederationProvider ( baseProvider , 'https://my-workspace.cloud.databricks.com' , {
92- clientId : 'my-client-id' ,
93- } ) ;
94-
95- await federationProvider . getToken ( ) ;
96-
97- expect ( requestBody ) . to . include ( 'client_id=my-client-id' ) ;
98- } ) ;
99-
100- it ( 'should fall back to original token on exchange failure by default' , async ( ) => {
101- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
102- const baseProvider = new MockTokenProvider ( externalJwt ) ;
103-
104- nock ( 'https://my-workspace.cloud.databricks.com' )
105- . post ( '/oidc/v1/token' )
106- . reply ( 401 , { error : 'unauthorized' } ) ;
107-
108- const federationProvider = new FederationProvider ( baseProvider , 'https://my-workspace.cloud.databricks.com' ) ;
50+ it ( 'should pass through token when issuer matches (case insensitive)' , async ( ) => {
51+ const jwt = createJWT ( { iss : 'https://MY-WORKSPACE.CLOUD.DATABRICKS.COM' } ) ;
52+ const baseProvider = new MockTokenProvider ( jwt ) ;
53+ const federationProvider = new FederationProvider ( baseProvider , 'my-workspace.cloud.databricks.com' ) ;
10954
11055 const token = await federationProvider . getToken ( ) ;
11156
112- expect ( token . accessToken ) . to . equal ( externalJwt ) ;
113- } ) ;
114-
115- it ( 'should throw error on exchange failure when fallback is disabled' , async ( ) => {
116- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
117- const baseProvider = new MockTokenProvider ( externalJwt ) ;
118-
119- nock ( 'https://my-workspace.cloud.databricks.com' )
120- . post ( '/oidc/v1/token' )
121- . reply ( 401 , { error : 'unauthorized' } ) ;
122-
123- const federationProvider = new FederationProvider ( baseProvider , 'https://my-workspace.cloud.databricks.com' , {
124- returnOriginalTokenOnFailure : false ,
125- } ) ;
126-
127- try {
128- await federationProvider . getToken ( ) ;
129- expect . fail ( 'Should have thrown an error' ) ;
130- } catch ( error : any ) {
131- expect ( error . message ) . to . include ( 'Token exchange failed' ) ;
132- }
57+ expect ( token . accessToken ) . to . equal ( jwt ) ;
13358 } ) ;
13459
135- it ( 'should handle host without protocol' , async ( ) => {
136- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
137- const baseProvider = new MockTokenProvider ( externalJwt ) ;
138-
139- nock ( 'https://my-workspace.cloud.databricks.com' )
140- . post ( '/oidc/v1/token' )
141- . reply ( 200 , {
142- access_token : 'exchanged-token' ,
143- token_type : 'Bearer' ,
144- } ) ;
145-
146- const federationProvider = new FederationProvider (
147- baseProvider ,
148- 'my-workspace.cloud.databricks.com' , // No protocol
149- ) ;
60+ it ( 'should pass through token when issuer matches (ignoring port)' , async ( ) => {
61+ const jwt = createJWT ( { iss : 'https://my-workspace.cloud.databricks.com:443' } ) ;
62+ const baseProvider = new MockTokenProvider ( jwt ) ;
63+ const federationProvider = new FederationProvider ( baseProvider , 'my-workspace.cloud.databricks.com' ) ;
15064
15165 const token = await federationProvider . getToken ( ) ;
15266
153- expect ( token . accessToken ) . to . equal ( 'exchanged-token' ) ;
154- } ) ;
155-
156- it ( 'should send correct token exchange parameters' , async ( ) => {
157- const externalJwt = createJWT ( { iss : 'https://external-idp.com' } ) ;
158- const baseProvider = new MockTokenProvider ( externalJwt ) ;
159-
160- let requestBody : string | undefined ;
161- nock ( 'https://my-workspace.cloud.databricks.com' )
162- . post ( '/oidc/v1/token' , ( body ) => {
163- requestBody = body ;
164- return true ;
165- } )
166- . reply ( 200 , {
167- access_token : 'exchanged-token' ,
168- } ) ;
169-
170- const federationProvider = new FederationProvider ( baseProvider , 'https://my-workspace.cloud.databricks.com' ) ;
171-
172- await federationProvider . getToken ( ) ;
173-
174- expect ( requestBody ) . to . include ( 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange' ) ;
175- expect ( requestBody ) . to . include ( 'subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt' ) ;
176- expect ( requestBody ) . to . include ( `subject_token=${ encodeURIComponent ( externalJwt ) } ` ) ;
177- expect ( requestBody ) . to . include ( 'scope=sql' ) ;
67+ expect ( token . accessToken ) . to . equal ( jwt ) ;
17868 } ) ;
17969 } ) ;
18070
0 commit comments