Skip to content
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# v25.1.1

## Features
- Add `UseForEnrollment`, `ForceSave`, and certificate cleanup fields (`AllowedEnrollmentTypes`, `StandaloneCA`, `MonitorThresholds`, `FullScanIntervalMinutes`, `IncrementalScanIntervalMinutes`) to CA request/response models in `v25/api/keyfactor/v1`

## Fixes
- Restore `AccessToken`, `Audience`, `Scopes` fields to `buildHttpClientV2` OAuth config (fields were silently dropped in prior refactor)
- Skip appending port 443 to request URL to avoid duplicate port in HTTPS connections

## Tests
- Add OAuth `access_token`/`audience`/`scopes` field propagation regression tests for v1 and v2 clients
- Add CA model regression tests covering cleanup and enrollment fields

# v24.1.1

## Features
- Add `UseForEnrollment`, `ForceSave`, and certificate cleanup fields (`AllowedEnrollmentTypes`, `StandaloneCA`, `MonitorThresholds`, `FullScanIntervalMinutes`, `IncrementalScanIntervalMinutes`) to CA request/response models in `v24/api/keyfactor/v1`

## Fixes
- Restore `AccessToken`, `Audience`, `Scopes` fields to `buildHttpClientV2` OAuth config (fields were silently dropped in prior refactor)
- Skip appending port 443 to request URL to avoid duplicate port in HTTPS connections

## Tests
- Add OAuth `access_token`/`audience`/`scopes` field propagation regression tests for v1 and v2 clients
- Add CA model regression tests covering cleanup and enrollment fields

# v25.0.1

## Chores
Expand All @@ -12,6 +38,14 @@
- Support for Keyfactor Command REST API endpoints up to 25.1.1. [API Change Log](https://software.keyfactor.com/Core-OnPrem/Current/Content/WebAPI/ChangeLogs/25_1_1-APIChangeLog.htm)
- Add [helper methods](https://github.com/Keyfactor/keyfactor-go-client-sdk/blob/feat/AB%2372090/sdk-version-25/v25/helpers.go) to support some common lookup patterns.

# v24.0.1
## Chores
- Bump github.com/Keyfactor/keyfactor-auth-client-go dependency from v1.1.0-rc.8 to 1.3.0.

## Fixes
- fix: Fix issue with the OAuth token flow with explicit access token provided to config runs into an error
- fix: Skip appending port 443 to request URL to avoid duplicate port in HTTPS connections

# v24.0.0

## Features
Expand Down
5 changes: 4 additions & 1 deletion v24/api/keyfactor/v1/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions v24/api/keyfactor/v1/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package v1

import (
"reflect"
"testing"

"github.com/Keyfactor/keyfactor-auth-client-go/auth_providers"
)

// TestCommandConfigOauth_AccessTokenFieldPropagation is a compilation + correctness
// regression test for the v2.8.0 bug where AccessToken, Audience, and Scopes were
// silently dropped when constructing CommandConfigOauth from auth_providers.Server
// in buildHttpClientV2. If any of those three fields are ever removed from either
// struct, this test fails to compile.
func TestCommandConfigOauth_AccessTokenFieldPropagation(t *testing.T) {
srv := &auth_providers.Server{
Host: "test.example.com",
AccessToken: "mytoken-abc123",
Audience: "https://my.audience.example.com",
Scopes: []string{"read", "write", "admin"},
}

// Step 1: Verify Server struct holds the fields correctly
if srv.AccessToken != "mytoken-abc123" {
t.Errorf("Server.AccessToken = %q, want %q", srv.AccessToken, "mytoken-abc123")
}
if srv.Audience != "https://my.audience.example.com" {
t.Errorf("Server.Audience = %q, want %q", srv.Audience, "https://my.audience.example.com")
}
if !reflect.DeepEqual(srv.Scopes, []string{"read", "write", "admin"}) {
t.Errorf("Server.Scopes = %v, want %v", srv.Scopes, []string{"read", "write", "admin"})
}

// Step 2: Construct CommandConfigOauth the same way buildHttpClientV2 does
// (minus the Authenticate() call which requires network). This mirrors lines
// 344-351 of client.go exactly.
baseConfig := auth_providers.CommandAuthConfig{
CommandHostName: srv.Host,
CommandPort: srv.Port,
CommandAPIPath: srv.APIPath,
CommandCACert: srv.CACertPath,
SkipVerify: srv.SkipTLSVerify,
}
oauthCfg := auth_providers.CommandConfigOauth{
CommandAuthConfig: baseConfig,
ClientID: srv.ClientID,
ClientSecret: srv.ClientSecret,
TokenURL: srv.OAuthTokenUrl,
AccessToken: srv.AccessToken,
Audience: srv.Audience,
Scopes: srv.Scopes,
}

// Step 3: Verify the three fields that were missing in the v2.8.0 regression
if oauthCfg.AccessToken != "mytoken-abc123" {
t.Errorf("CommandConfigOauth.AccessToken = %q, want %q", oauthCfg.AccessToken, "mytoken-abc123")
}
if oauthCfg.Audience != "https://my.audience.example.com" {
t.Errorf("CommandConfigOauth.Audience = %q, want %q", oauthCfg.Audience, "https://my.audience.example.com")
}
if !reflect.DeepEqual(oauthCfg.Scopes, []string{"read", "write", "admin"}) {
t.Errorf("CommandConfigOauth.Scopes = %v, want %v", oauthCfg.Scopes, []string{"read", "write", "admin"})
}

// Step 4: Verify GetAuthType returns "oauth" for access_token-only config
authType := srv.GetAuthType()
if authType != "oauth" {
t.Errorf("Server.GetAuthType() = %q, want %q (access_token-only should be oauth)", authType, "oauth")
}
}

// TestCommandConfigOauth_AccessTokenOnlyNoClientCreds verifies that a Server
// configured with only Host + AccessToken (no ClientID/ClientSecret/TokenURL)
// is classified as "oauth" auth type and the token propagates correctly.
func TestCommandConfigOauth_AccessTokenOnlyNoClientCreds(t *testing.T) {
srv := &auth_providers.Server{
Host: "command.example.com",
AccessToken: "pre-fetched-bearer-token",
// Deliberately omitting ClientID, ClientSecret, OAuthTokenUrl
}

if got := srv.GetAuthType(); got != "oauth" {
t.Fatalf("GetAuthType() = %q, want %q for access_token-only", got, "oauth")
}

oauthCfg := auth_providers.CommandConfigOauth{
AccessToken: srv.AccessToken,
}

if oauthCfg.AccessToken != "pre-fetched-bearer-token" {
t.Errorf("AccessToken = %q, want %q", oauthCfg.AccessToken, "pre-fetched-bearer-token")
}
if oauthCfg.ClientID != "" {
t.Errorf("ClientID = %q, want empty", oauthCfg.ClientID)
}
if oauthCfg.ClientSecret != "" {
t.Errorf("ClientSecret = %q, want empty", oauthCfg.ClientSecret)
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading