From a4289b79edde7c171f64e8512bb5ab8a8101334e Mon Sep 17 00:00:00 2001 From: ShocOne <62835948+ShocOne@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:45:08 +0000 Subject: [PATCH] Update ClientOptions struct and add helper function for redacting sensitive data in logs --- httpclient/httpclient_client.go | 26 ++++++++++--------- httpclient/httpclient_helpers.go | 43 ++++++++++++++++++++++---------- httpclient/httpclient_oauth.go | 5 +++- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/httpclient/httpclient_client.go b/httpclient/httpclient_client.go index 10ea5fe..c207eef 100644 --- a/httpclient/httpclient_client.go +++ b/httpclient/httpclient_client.go @@ -59,9 +59,10 @@ type AuthConfig struct { // ClientOptions holds optional configuration options for the HTTP Client. type ClientOptions struct { LogLevel logger.LogLevel // Field for defining tiered logging level. + HideSensitiveData bool // Field for defining whether sensitive fields should be hidden in logs. MaxRetryAttempts int // Config item defines the max number of retry request attempts for retryable HTTP methods. - EnableDynamicRateLimiting bool - MaxConcurrentRequests int // Field for defining the maximum number of concurrent requests allowed in the semaphore + EnableDynamicRateLimiting bool // Field for defining whether dynamic rate limiting should be enabled. + MaxConcurrentRequests int // Field for defining the maximum number of concurrent requests allowed in the semaphore TokenRefreshBufferPeriod time.Duration TotalRetryDuration time.Duration CustomTimeout time.Duration @@ -160,17 +161,18 @@ func BuildClient(config ClientConfig) (*Client, error) { // Log the client's configuration. log.Info("New API client initialized", - zap.String("API Service", config.Environment.APIType), + zap.String("API Type", config.Environment.APIType), zap.String("Instance Name", client.InstanceName), - zap.String("OverrideBaseDomain", config.Environment.OverrideBaseDomain), - zap.String("AuthMethod", authMethod), - zap.Int("MaxRetryAttempts", config.ClientOptions.MaxRetryAttempts), - zap.Int("MaxConcurrentRequests", config.ClientOptions.MaxConcurrentRequests), - zap.Bool("EnableDynamicRateLimiting", config.ClientOptions.EnableDynamicRateLimiting), - zap.Duration("TokenRefreshBufferPeriod", config.ClientOptions.TokenRefreshBufferPeriod), - zap.Duration("TotalRetryDuration", config.ClientOptions.TotalRetryDuration), - zap.Duration("CustomTimeout", config.ClientOptions.CustomTimeout), - zap.String("LogLevel", config.ClientOptions.LogLevel.String()), + zap.String("Override Base Domain", config.Environment.OverrideBaseDomain), + zap.String("Authentication Method", authMethod), + zap.String("Logging Level", config.ClientOptions.LogLevel.String()), + zap.Bool("Hide Sensitive Data In Logs", config.ClientOptions.HideSensitiveData), + zap.Int("Max Retry Attempts", config.ClientOptions.MaxRetryAttempts), + zap.Int("Max Concurrent Requests", config.ClientOptions.MaxConcurrentRequests), + zap.Bool("Enable Dynamic Rate Limiting", config.ClientOptions.EnableDynamicRateLimiting), + zap.Duration("Token Refresh Buffer Period", config.ClientOptions.TokenRefreshBufferPeriod), + zap.Duration("Total Retry Duration", config.ClientOptions.TotalRetryDuration), + zap.Duration("Custom Timeout", config.ClientOptions.CustomTimeout), ) return client, nil diff --git a/httpclient/httpclient_helpers.go b/httpclient/httpclient_helpers.go index 4f02afb..14af191 100644 --- a/httpclient/httpclient_helpers.go +++ b/httpclient/httpclient_helpers.go @@ -2,11 +2,7 @@ package httpclient import ( - "encoding/json" - "fmt" "net/http" - "os" - "strings" "time" "github.com/deploymenttheory/go-api-http-client/logger" @@ -18,14 +14,6 @@ func ParseISO8601Date(dateStr string) (time.Time, error) { return time.Parse(time.RFC3339, dateStr) } -// EnsureHTTPScheme prefixes a URL with "http://" it defaults to "https://" doesn't already have an "https://". -func EnsureHTTPScheme(url string) string { - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { - return fmt.Sprintf("https://%s", url) - } - return url -} - // CheckDeprecationHeader checks the response headers for the Deprecation header and logs a warning if present. func CheckDeprecationHeader(resp *http.Response, log logger.Logger) { deprecationHeader := resp.Header.Get("Deprecation") @@ -38,6 +26,33 @@ func CheckDeprecationHeader(resp *http.Response, log logger.Logger) { } } +// RedactSensitiveData redacts sensitive data if the HideSensitiveData flag is set to true. +func RedactSensitiveData(client *Client, key string, value string) string { + if client.clientConfig.ClientOptions.HideSensitiveData { + // Define sensitive data keys that should be redacted. + sensitiveKeys := map[string]bool{ + "AccessToken": true, + // Add more sensitive keys as necessary. + } + + if _, found := sensitiveKeys[key]; found { + return "REDACTED" + } + } + return value +} + +/* +// EnsureHTTPScheme prefixes a URL with "http://" it defaults to "https://" doesn't already have an "https://". +func EnsureHTTPScheme(url string) string { + if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { + return fmt.Sprintf("https://%s", url) + } + return url +} +*/ + +/* // SetAuthenticationCredentials interprets and sets the credentials for the Client. func (c *Client) SetAuthenticationCredentials(creds map[string]string) { // Check for OAuth credentials @@ -76,7 +91,8 @@ func (c *Client) GetOAuthCredentials() OAuthCredentials { func (c *Client) GetBearerAuthCredentials() BearerTokenAuthCredentials { return c.BearerTokenAuthCredentials } - +*/ +/* // LoadAuthConfig reads a JSON configuration file and decodes it into a ClientAuthConfig struct. // It is used to retrieve authentication details like BaseURL, Username, and Password for the client. func LoadAuthConfig(filename string) (*AuthConfig, error) { @@ -95,3 +111,4 @@ func LoadAuthConfig(filename string) (*AuthConfig, error) { return config, nil } +*/ diff --git a/httpclient/httpclient_oauth.go b/httpclient/httpclient_oauth.go index 6c4fd0b..861c9ce 100644 --- a/httpclient/httpclient_oauth.go +++ b/httpclient/httpclient_oauth.go @@ -99,7 +99,10 @@ func (c *Client) ObtainOAuthToken(credentials AuthConfig, log logger.Logger) err expiresIn := time.Duration(oauthResp.ExpiresIn) * time.Second expirationTime := time.Now().Add(expiresIn) - log.Info("OAuth token obtained successfully", zap.String("AccessToken", oauthResp.AccessToken), zap.Duration("ExpiresIn", expiresIn), zap.Time("ExpirationTime", expirationTime)) + + // Modified log call using the helper function + redactedAccessToken := RedactSensitiveData(c, "AccessToken", oauthResp.AccessToken) + log.Info("OAuth token obtained successfully", zap.String("AccessToken", redactedAccessToken), zap.Duration("ExpiresIn", expiresIn), zap.Time("ExpirationTime", expirationTime)) c.Token = oauthResp.AccessToken c.Expiry = expirationTime