Skip to content

Commit 794adbd

Browse files
committed
feat: support custom token endpoint from service account credentials
- Extended `KeyFlowConfig` with a `GetCredentialsTokenEndpoint` helper to safely extract custom token URLs from service account credentials. - Updated `KeyFlow.Init` to use the new helper, allowing the flow to fallback to the default `tokenAPI` gracefully if no custom endpoint is provided. - Added standard Go doc comments for KeyFlow methods. - Expanded `TestKeyFlowInit` to assert the resolved TokenUrl and added a new test scenario to verify the custom endpoint logic.
1 parent 48f3f79 commit 794adbd

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

core/clients/key_flow.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@ type ServiceAccountKeyResponse struct {
7878
}
7979

8080
type ServiceAccountKeyCredentials struct {
81-
Aud string `json:"aud"`
82-
Iss string `json:"iss"`
83-
Kid string `json:"kid"`
84-
PrivateKey *string `json:"privateKey,omitempty"`
85-
Sub uuid.UUID `json:"sub"`
81+
Aud string `json:"aud"`
82+
Iss string `json:"iss"`
83+
Kid string `json:"kid"`
84+
PrivateKey *string `json:"privateKey,omitempty"`
85+
Sub uuid.UUID `json:"sub"`
86+
TokenEndpoint string `json:"tokenEndpoint"`
8687
}
8788

8889
// GetConfig returns the flow configuration
@@ -117,13 +118,26 @@ func (c *KeyFlow) GetToken() TokenResponseBody {
117118
return *c.token
118119
}
119120

121+
// GetCredentialsTokenEndpoint returns the token endpoint from credentials or a default fallback
122+
func (cfg *KeyFlowConfig) GetCredentialsTokenEndpoint() string {
123+
if cfg.ServiceAccountKey == nil || cfg.ServiceAccountKey.Credentials == nil {
124+
return tokenAPI
125+
}
126+
127+
if cfg.ServiceAccountKey.Credentials.TokenEndpoint == "" {
128+
return tokenAPI
129+
}
130+
131+
return cfg.ServiceAccountKey.Credentials.TokenEndpoint
132+
}
133+
120134
func (c *KeyFlow) Init(cfg *KeyFlowConfig) error {
121135
// No concurrency at this point, so no mutex check needed
122136
c.token = &TokenResponseBody{}
123137
c.config = cfg
124138

125139
if c.config.TokenUrl == "" {
126-
c.config.TokenUrl = tokenAPI
140+
c.config.TokenUrl = c.config.GetCredentialsTokenEndpoint()
127141
}
128142

129143
c.tokenExpirationLeeway = defaultTokenExpirationLeeway

core/clients/key_flow_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ func TestKeyFlowInit(t *testing.T) {
7676
genPrivateKey bool
7777
invalidPrivateKey bool
7878
wantErr bool
79+
wantTokenUrl string
7980
}{
8081
{
8182
name: "ok-provided-private-key",
8283
serviceAccountKey: fixtureServiceAccountKey(),
8384
genPrivateKey: true,
8485
wantErr: false,
86+
wantTokenUrl: tokenAPI,
8587
},
8688
{
8789
name: "missing_private_key",
@@ -102,6 +104,15 @@ func TestKeyFlowInit(t *testing.T) {
102104
invalidPrivateKey: true,
103105
wantErr: true,
104106
},
107+
{
108+
name: "ok-custom-token-endpoint",
109+
serviceAccountKey: fixtureServiceAccountKey(func(s *ServiceAccountKeyResponse) {
110+
s.Credentials.TokenEndpoint = "https://custom.stackit.cloud/token"
111+
}),
112+
genPrivateKey: true,
113+
wantErr: false,
114+
wantTokenUrl: "https://custom.stackit.cloud/token",
115+
},
105116
}
106117
for _, tt := range tests {
107118
t.Run(tt.name, func(t *testing.T) {
@@ -126,6 +137,12 @@ func TestKeyFlowInit(t *testing.T) {
126137
if keyFlow.config == nil {
127138
t.Error("config is nil")
128139
}
140+
141+
if !tt.wantErr && tt.wantTokenUrl != "" {
142+
if keyFlow.config.TokenUrl != tt.wantTokenUrl {
143+
t.Errorf("KeyFlow.Init() TokenUrl = %v, wantTokenUrl %v", keyFlow.config.TokenUrl, tt.wantTokenUrl)
144+
}
145+
}
129146
})
130147
}
131148
}

0 commit comments

Comments
 (0)