@@ -170,77 +170,6 @@ impl ClientCredentialsProvider {
170170 scopes,
171171 } )
172172 }
173-
174- /// Exchanges client credentials for an access token.
175- ///
176- /// This method performs the OAuth 2.0 client credentials grant:
177- /// ```text
178- /// POST {token_endpoint}
179- /// Authorization: Basic base64(client_id:client_secret)
180- /// Content-Type: application/x-www-form-urlencoded
181- ///
182- /// grant_type=client_credentials&scope=all-apis
183- /// ```
184- ///
185- /// Uses the DatabricksHttpClient's inner reqwest::Client to execute the request.
186- /// The oauth2 crate adds Basic authentication header automatically.
187- ///
188- /// Note: This method is currently unused but kept for potential future use
189- /// (e.g., direct testing or alternative refresh strategies).
190- #[ allow( dead_code) ]
191- async fn fetch_token ( & self ) -> Result < OAuthToken > {
192- // Build the OAuth client
193- let oauth_client = BasicClient :: new ( ClientId :: new ( self . client_id . clone ( ) ) )
194- . set_client_secret ( ClientSecret :: new ( self . client_secret . clone ( ) ) )
195- . set_auth_uri ( AuthUrl :: new ( self . auth_endpoint . clone ( ) ) . map_err ( |e| {
196- DatabricksErrorHelper :: invalid_argument ( )
197- . message ( format ! ( "Invalid authorization endpoint URL: {}" , e) )
198- } ) ?)
199- . set_token_uri ( TokenUrl :: new ( self . token_endpoint . clone ( ) ) . map_err ( |e| {
200- DatabricksErrorHelper :: invalid_argument ( )
201- . message ( format ! ( "Invalid token endpoint URL: {}" , e) )
202- } ) ?) ;
203-
204- // Build the token request with scopes
205- let mut token_request = oauth_client. exchange_client_credentials ( ) ;
206-
207- for scope in & self . scopes {
208- token_request = token_request. add_scope ( Scope :: new ( scope. clone ( ) ) ) ;
209- }
210-
211- // Execute the token exchange using the inner reqwest client
212- // The oauth2 crate's reqwest::Client implements AsyncHttpClient
213- let token_response = token_request
214- . request_async ( self . http_client . inner ( ) )
215- . await
216- . map_err ( |e| {
217- DatabricksErrorHelper :: io ( )
218- . message ( format ! ( "M2M token exchange failed: {}" , e) )
219- . context ( "client credentials grant" )
220- } ) ?;
221-
222- // Convert oauth2 token response to our OAuthToken
223- let access_token = token_response. access_token ( ) . secret ( ) . to_string ( ) ;
224- let token_type = token_response. token_type ( ) . as_ref ( ) . to_string ( ) ;
225- let expires_in = token_response
226- . expires_in ( )
227- . map ( |d| d. as_secs ( ) as i64 )
228- . unwrap_or ( 3600 ) ; // Default to 1 hour if not specified
229-
230- let scopes = token_response
231- . scopes ( )
232- . map ( |s| s. iter ( ) . map ( |scope| scope. to_string ( ) ) . collect ( ) )
233- . unwrap_or_else ( || self . scopes . clone ( ) ) ;
234-
235- // M2M tokens have no refresh_token
236- Ok ( OAuthToken :: new (
237- access_token,
238- token_type,
239- expires_in,
240- None , // No refresh token for M2M
241- scopes,
242- ) )
243- }
244173}
245174
246175impl AuthProvider for ClientCredentialsProvider {
@@ -367,20 +296,18 @@ mod tests {
367296 // Mock OIDC discovery
368297 Mock :: given ( method ( "GET" ) )
369298 . and ( path ( "/oidc/.well-known/oauth-authorization-server" ) )
370- . respond_with (
371- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
372- "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
373- "token_endpoint" : token_endpoint,
374- } ) ) ,
375- )
299+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
300+ "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
301+ "token_endpoint" : token_endpoint,
302+ } ) ) )
376303 . mount ( & mock_server)
377304 . await ;
378305
379306 // Mock token endpoint - verify grant_type and Basic auth
380307 Mock :: given ( method ( "POST" ) )
381308 . and ( path ( "/oidc/v1/token" ) )
382309 . and ( header ( "content-type" , "application/x-www-form-urlencoded" ) )
383- . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( & mock_token_response_body ( ) ) )
310+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( mock_token_response_body ( ) ) )
384311 . expect ( 1 )
385312 . mount ( & mock_server)
386313 . await ;
@@ -416,12 +343,10 @@ mod tests {
416343 // Mock OIDC discovery
417344 Mock :: given ( method ( "GET" ) )
418345 . and ( path ( "/oidc/.well-known/oauth-authorization-server" ) )
419- . respond_with (
420- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
421- "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
422- "token_endpoint" : token_endpoint,
423- } ) ) ,
424- )
346+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
347+ "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
348+ "token_endpoint" : token_endpoint,
349+ } ) ) )
425350 . mount ( & mock_server)
426351 . await ;
427352
@@ -436,15 +361,15 @@ mod tests {
436361 let count = call_count_clone. fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
437362 if count == 0 {
438363 // First call - return short-lived token
439- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
364+ ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
440365 "access_token" : "initial-token" ,
441366 "token_type" : "Bearer" ,
442367 "expires_in" : 1 , // Very short expiry to trigger refresh
443368 "scope" : "all-apis"
444369 } ) )
445370 } else {
446371 // Subsequent calls - return long-lived token
447- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
372+ ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
448373 "access_token" : "refreshed-token" ,
449374 "token_type" : "Bearer" ,
450375 "expires_in" : 3600 ,
@@ -493,19 +418,17 @@ mod tests {
493418 // Mock OIDC discovery with specific endpoints
494419 Mock :: given ( method ( "GET" ) )
495420 . and ( path ( "/oidc/.well-known/oauth-authorization-server" ) )
496- . respond_with (
497- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
498- "authorization_endpoint" : "https://custom.example.com/auth" ,
499- "token_endpoint" : "https://custom.example.com/token" ,
500- } ) ) ,
501- )
421+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
422+ "authorization_endpoint" : "https://custom.example.com/auth" ,
423+ "token_endpoint" : "https://custom.example.com/token" ,
424+ } ) ) )
502425 . mount ( & mock_server)
503426 . await ;
504427
505428 // Mock token endpoint
506429 Mock :: given ( method ( "POST" ) )
507430 . and ( path ( "/token" ) )
508- . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( & mock_token_response_body ( ) ) )
431+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( mock_token_response_body ( ) ) )
509432 . mount ( & mock_server)
510433 . await ;
511434
@@ -572,19 +495,17 @@ mod tests {
572495 // Mock OIDC discovery
573496 Mock :: given ( method ( "GET" ) )
574497 . and ( path ( "/oidc/.well-known/oauth-authorization-server" ) )
575- . respond_with (
576- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
577- "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
578- "token_endpoint" : token_endpoint,
579- } ) ) ,
580- )
498+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
499+ "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
500+ "token_endpoint" : token_endpoint,
501+ } ) ) )
581502 . mount ( & mock_server)
582503 . await ;
583504
584505 // Mock token endpoint - should only be called once despite concurrent requests
585506 Mock :: given ( method ( "POST" ) )
586507 . and ( path ( "/oidc/v1/token" ) )
587- . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( & mock_token_response_body ( ) ) )
508+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( mock_token_response_body ( ) ) )
588509 . expect ( 1 ) // Verify only one token fetch occurs
589510 . mount ( & mock_server)
590511 . await ;
@@ -640,26 +561,22 @@ mod tests {
640561 // Mock OIDC discovery
641562 Mock :: given ( method ( "GET" ) )
642563 . and ( path ( "/oidc/.well-known/oauth-authorization-server" ) )
643- . respond_with (
644- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
645- "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
646- "token_endpoint" : token_endpoint,
647- } ) ) ,
648- )
564+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
565+ "authorization_endpoint" : format!( "{}/oidc/v1/authorize" , mock_server. uri( ) ) ,
566+ "token_endpoint" : token_endpoint,
567+ } ) ) )
649568 . mount ( & mock_server)
650569 . await ;
651570
652571 // Mock token endpoint
653572 Mock :: given ( method ( "POST" ) )
654573 . and ( path ( "/oidc/v1/token" ) )
655- . respond_with (
656- ResponseTemplate :: new ( 200 ) . set_body_json ( & serde_json:: json!( {
657- "access_token" : "test-token-custom-scopes" ,
658- "token_type" : "Bearer" ,
659- "expires_in" : 3600 ,
660- "scope" : "custom-scope-1 custom-scope-2"
661- } ) ) ,
662- )
574+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
575+ "access_token" : "test-token-custom-scopes" ,
576+ "token_type" : "Bearer" ,
577+ "expires_in" : 3600 ,
578+ "scope" : "custom-scope-1 custom-scope-2"
579+ } ) ) )
663580 . mount ( & mock_server)
664581 . await ;
665582
0 commit comments