1- // Copyright 2024 Keyfactor
1+ // Copyright 2026 Keyfactor
22//
33// Licensed under the Apache License, Version 2.0 (the "License");
44// you may not use this file except in compliance with the License.
@@ -16,13 +16,16 @@ package auth_providers_test
1616
1717import (
1818 "crypto/tls"
19+ "encoding/json"
1920 "encoding/pem"
2021 "fmt"
2122 "net/http"
23+ "net/http/httptest"
2224 "net/url"
2325 "os"
2426 "path/filepath"
2527 "strings"
28+ "sync/atomic"
2629 "testing"
2730
2831 "github.com/Keyfactor/keyfactor-auth-client-go/auth_providers"
@@ -568,3 +571,49 @@ func DownloadCertificate(input string, outputPath string) error {
568571 fmt .Printf ("Certificate chain saved to: %s\n " , outputFile )
569572 return nil
570573}
574+
575+ func TestCommandConfigOauth_TokenSourceIsReused (t * testing.T ) {
576+ var tokenRequestCount atomic.Int32
577+
578+ // Fake IdP token endpoint
579+ tokenServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
580+ tokenRequestCount .Add (1 )
581+ w .Header ().Set ("Content-Type" , "application/json" )
582+ json .NewEncoder (w ).Encode (map [string ]interface {}{
583+ "access_token" : "shared-test-token" ,
584+ "token_type" : "Bearer" ,
585+ "expires_in" : 3600 ,
586+ })
587+ }))
588+ defer tokenServer .Close ()
589+
590+ // Fake API endpoint (just needs to accept requests)
591+ apiServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
592+ w .WriteHeader (http .StatusOK )
593+ }))
594+ defer apiServer .Close ()
595+
596+ config := & auth_providers.CommandConfigOauth {
597+ ClientID : "test-client-id" ,
598+ ClientSecret : "test-client-secret" ,
599+ TokenURL : tokenServer .URL + "/token" ,
600+ }
601+
602+ // Get multiple clients from the same config
603+ const numClients = 3
604+ for i := 0 ; i < numClients ; i ++ {
605+ client , err := config .GetHttpClient ()
606+ if err != nil {
607+ t .Fatalf ("GetHttpClient() call %d failed: %v" , i + 1 , err )
608+ }
609+ resp , err := client .Get (apiServer .URL )
610+ if err != nil {
611+ t .Fatalf ("request %d failed: %v" , i + 1 , err )
612+ }
613+ resp .Body .Close ()
614+ }
615+
616+ if tokenRequestCount .Load () != 1 {
617+ t .Errorf ("expected token endpoint to be called once, got %d — token source is not being reused across GetHttpClient() calls" , tokenRequestCount .Load ())
618+ }
619+ }
0 commit comments