Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@
- **Feature:** Add configuration option that, for the key flow, enables a goroutine to be spawned that will refresh the access token when it's close to expiring
- **Deprecation:** Mark method `config.WithCaptureHTTPResponse` as deprecated, to avoid confusion due to it not being a configuration option. Use `runtime.WithCaptureHTTPResponse` instead.
- **Deprecation:** Mark method `config.WithJWKSEndpoint` and field `config.Configuration.JWKSCustomUrl` as deprecated. Validation using JWKS was removed, for being redundant with token validation done in the APIs. These have no effect.
- **Breaking Change:** Remove method `KeyFlow.Clone`, that was no longer being used.
- **Deprecation:**
- Methods:
- `config.WithMaxRetries`
- `config.WithWaitBetweenCalls`
- `config.WithRetryTimeout`
- `clients.NewRetryConfig`
- Fields:
- `clients.KeyFlowConfig.ClientRetry`
- `clients.TokenFlowConfig.ClientRetry`
- `clients.NoAuthFlowConfig.ClientRetry`
- `clients.RetryConfig`
- Retry options were removed to reduce complexity of the clients. If this functionality is needed, you can provide your own custom HTTP client.
- **Breaking Change:** Remove method `clients.KeyFlow.Clone`, `clients.TokenFlow.Clone`, `clients.NoAuthFlow.Clone` and `clients.Do`, that are no longer being used.
- **Breaking Change:** Removed fields `clients.DefaultRetryMaxRetries`, `clients.DefaultRetryWaitBetweenCalls`and `clients.DefaultRetryTimeout`. Removed constants `clients.ClientTimeoutErr`,`clients.ClientContextDeadlineErr`, `clients.ClientConnectionRefusedErr`, `clients.ClientEOFError`. These are no longer being used.
- **Breaking Change:** Change signature of `auth.NoAuth`, which no longer takes `clients.RetryConfig` as argument.

## Release (2024-02-07)

Expand Down
15 changes: 8 additions & 7 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
- `config.WithMaxRetries`
- `config.WithWaitBetweenCalls`
- `config.WithRetryTimeout`
- `client.NewRetryConfig()`
- `clients.NewRetryConfig`
- Fields:
- `client.KeyFlowConfig.ClientRetry`
- `client.TokenFlowConfig.ClientRetry`
- `client.NoAuthFlowConfig.ClientRetry`
- `client.RetryConfig`
- Retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client. An option to add HTTP middleware will be introduced soon.
- **Breaking Change:** Remove methods `client.TokenFlow.Clone` and `client.NoAuthFlow.Clone`. Removed fields `client.DefaultRetryMaxRetries`, `client.DefaultRetryWaitBetweenCalls` and `client.DefaultRetryTimeout`. These are no longer being used.
- `clients.KeyFlowConfig.ClientRetry`
- `clients.TokenFlowConfig.ClientRetry`
- `clients.NoAuthFlowConfig.ClientRetry`
- `clients.RetryConfig`
- Retry options were removed to reduce complexity of the clients. If this functionality is needed, you can provide your own custom HTTP client.
- **Breaking Change:** Remove methods `clients.TokenFlow.Clone`, `clients.NoAuthFlow.Clone`, `clients.Do`. Removed fields `clients.DefaultRetryMaxRetries`, `clients.DefaultRetryWaitBetweenCalls`and`clients.DefaultRetryTimeout`. Removed constants `clients.ClientTimeoutErr`,`clients.ClientContextDeadlineErr`, `clients.ClientConnectionRefusedErr`, `clients.ClientEOFError`. These are no longer being used.
- **Breaking Change:** Change signature of `auth.NoAuth`, which no longer takes `clients.RetryConfig` as argument

## v0.9.0 (2024-02-19)

Expand Down
4 changes: 2 additions & 2 deletions core/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func SetupAuth(cfg *config.Configuration) (rt http.RoundTripper, err error) {
if cfg.CustomAuth != nil {
return cfg.CustomAuth, nil
} else if cfg.NoAuth {
noAuthRoundTripper, err := NoAuth(cfg.RetryOptions) //nolint:staticcheck //will be removed in a later update
noAuthRoundTripper, err := NoAuth()
if err != nil {
return nil, fmt.Errorf("configuring no auth client: %w", err)
}
Expand Down Expand Up @@ -93,7 +93,7 @@ func DefaultAuth(cfg *config.Configuration) (rt http.RoundTripper, err error) {

// NoAuth configures a flow without authentication and returns an http.RoundTripper
// that can be used to make unauthenticated requests
func NoAuth(_ *clients.RetryConfig) (rt http.RoundTripper, err error) { //nolint:staticcheck //will be removed in a later update
func NoAuth() (rt http.RoundTripper, err error) {
noAuthConfig := clients.NoAuthFlowConfig{}
noAuthRoundTripper := &clients.NoAuthFlow{}
if err := noAuthRoundTripper.Init(noAuthConfig); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ func TestNoAuth(t *testing.T) {
} {
t.Run(test.desc, func(t *testing.T) {
// Get the default authentication client and ensure that it's not nil
authClient, err := NoAuth(nil)
authClient, err := NoAuth()
if err != nil {
t.Fatalf("Test returned error on valid test case: %v", err)
}
Expand Down
21 changes: 2 additions & 19 deletions core/clients/clients.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package clients

import (
"net/http"
"time"
)

Expand All @@ -10,35 +9,19 @@ const (
Environment = "STACKIT_ENV"
)

const (
// Known error messages
ClientTimeoutErr = "Client.Timeout exceeded while awaiting headers"
ClientContextDeadlineErr = "context deadline exceeded"
ClientConnectionRefusedErr = "connection refused"
ClientEOFError = "unexpected EOF"
)

const (
DefaultClientTimeout = time.Minute
)

// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client. An option to add HTTP middleware will be introduced soon
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client.
type RetryConfig struct {
MaxRetries int // Max retries
WaitBetweenCalls time.Duration // Time to wait between requests
RetryTimeout time.Duration // Max time to re-try
ClientTimeout time.Duration // HTTP Client timeout
}

// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client. An option to add HTTP middleware will be introduced soon
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client.
func NewRetryConfig() *RetryConfig {
return &RetryConfig{}
}

// Do performs the request
func Do(client *http.Client, req *http.Request) (resp *http.Response, err error) {
if client == nil {
client = http.DefaultClient
}
return client.Do(req)
}
112 changes: 0 additions & 112 deletions core/clients/clients_test.go

This file was deleted.

18 changes: 13 additions & 5 deletions core/clients/key_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const (
type KeyFlow struct {
client *http.Client
config *KeyFlowConfig
doer func(client *http.Client, req *http.Request) (resp *http.Response, err error)
doer func(req *http.Request) (resp *http.Response, err error)
key *ServiceAccountKeyResponse
privateKey *rsa.PrivateKey
privateKeyPEM []byte
Expand All @@ -49,7 +49,7 @@ type KeyFlow struct {
type KeyFlowConfig struct {
ServiceAccountKey *ServiceAccountKeyResponse
PrivateKey string
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client. An option to add HTTP middleware will be introduced soon
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client.
ClientRetry *RetryConfig
TokenUrl string
BackgroundTokenRefreshContext context.Context // Functionality is enabled if this isn't nil
Expand Down Expand Up @@ -120,7 +120,6 @@ func (c *KeyFlow) Init(cfg *KeyFlowConfig) error {
// No concurrency at this point, so no mutex check needed
c.token = &TokenResponseBody{}
c.config = cfg
c.doer = Do

if c.config.TokenUrl == "" {
c.config.TokenUrl = tokenAPI
Expand Down Expand Up @@ -173,11 +172,15 @@ func (c *KeyFlow) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, err
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
return c.doer(c.client, req)
return c.doer(req)
}

// GetAccessToken returns a short-lived access token and saves the access and refresh tokens in the token field
func (c *KeyFlow) GetAccessToken() (string, error) {
if c.client == nil {
return "", fmt.Errorf("nil http client, please run Init()")
}

c.tokenMutex.RLock()
accessToken := c.token.AccessToken
c.tokenMutex.RUnlock()
Expand All @@ -200,6 +203,7 @@ func (c *KeyFlow) configureHTTPClient() {
client := &http.Client{}
client.Timeout = DefaultClientTimeout
c.client = client
c.doer = c.client.Do
}

// validate the client is configured well
Expand Down Expand Up @@ -270,6 +274,10 @@ func (c *KeyFlow) createAccessToken() (err error) {
// createAccessTokenWithRefreshToken creates an access token using
// an existing pre-validated refresh token
func (c *KeyFlow) createAccessTokenWithRefreshToken() (err error) {
if c.client == nil {
return fmt.Errorf("nil http client, please run Init()")
}

c.tokenMutex.RLock()
refreshToken := c.token.RefreshToken
c.tokenMutex.RUnlock()
Expand Down Expand Up @@ -317,7 +325,7 @@ func (c *KeyFlow) requestToken(grant, assertion string) (*http.Response, error)
return nil, err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
return c.doer(&http.Client{}, req)
return c.doer(req)
}

// parseTokenResponse parses the response from the server
Expand Down
7 changes: 4 additions & 3 deletions core/clients/key_flow_continuous_refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func TestContinuousRefreshToken(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
numberDoCalls := 0
mockDo := func(client *http.Client, req *http.Request) (resp *http.Response, err error) {
mockDo := func(req *http.Request) (resp *http.Response, err error) {
numberDoCalls++

if tt.doError != nil {
Expand Down Expand Up @@ -129,7 +129,8 @@ func TestContinuousRefreshToken(t *testing.T) {
config: &KeyFlowConfig{
BackgroundTokenRefreshContext: ctx,
},
doer: mockDo,
client: &http.Client{},
doer: mockDo,
token: &TokenResponseBody{
AccessToken: accessToken,
},
Expand Down Expand Up @@ -211,7 +212,7 @@ func TestContinuousRefreshTokenConcurrency(t *testing.T) {
doTestPhase1RequestDone := false
doTestPhase2RequestDone := false
doTestPhase4RequestDone := false
mockDo := func(client *http.Client, req *http.Request) (resp *http.Response, err error) {
mockDo := func(req *http.Request) (resp *http.Response, err error) {
switch currentTestPhase {
default:
t.Fatalf("Do call: unexpected request during test phase %d", currentTestPhase)
Expand Down
2 changes: 1 addition & 1 deletion core/clients/key_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func TestRequestToken(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
mockDo := func(client *http.Client, req *http.Request) (resp *http.Response, err error) {
mockDo := func(req *http.Request) (resp *http.Response, err error) {
return tt.mockResponse, tt.mockError
}

Expand Down
4 changes: 2 additions & 2 deletions core/clients/no_auth_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type NoAuthFlow struct {

// NoAuthFlowConfig holds the configuration for the unauthenticated flow
type NoAuthFlowConfig struct {
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client. An option to add HTTP middleware will be introduced soon
// Deprecated: retry options were removed to reduce complexity of the client. If this functionality is needed, you can provide your own custom HTTP client.
ClientRetry *RetryConfig
}

Expand All @@ -37,5 +37,5 @@ func (c *NoAuthFlow) RoundTrip(req *http.Request) (*http.Response, error) {
if c.client == nil {
return nil, fmt.Errorf("please run Init()")
}
return Do(c.client, req)
return c.client.Do(req)
}
8 changes: 1 addition & 7 deletions core/clients/no_auth_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,13 @@ func TestNoAuthFlow_Init(t *testing.T) {
if err := c.Init(tt.args.cfg); (err != nil) != tt.wantErr {
t.Errorf("NoAuthFlow.Init() error = %v, wantErr %v", err, tt.wantErr)
}
if c.config == nil {
t.Error("config is nil")
}
})
}
}

func TestNoAuthFlow_Do(t *testing.T) {
type fields struct {
client *http.Client
config *NoAuthFlowConfig
}
type args struct{}
tests := []struct {
Expand All @@ -50,7 +46,7 @@ func TestNoAuthFlow_Do(t *testing.T) {
}{
{
name: "fail",
fields: fields{nil, nil},
fields: fields{nil},
args: args{},
want: 0,
wantErr: true,
Expand All @@ -59,7 +55,6 @@ func TestNoAuthFlow_Do(t *testing.T) {
name: "success",
fields: fields{
&http.Client{},
&NoAuthFlowConfig{},
},
args: args{},
want: http.StatusOK,
Expand All @@ -70,7 +65,6 @@ func TestNoAuthFlow_Do(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
c := &NoAuthFlow{
client: tt.fields.client,
config: tt.fields.config,
}
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
Expand Down
Loading