Skip to content

Commit 81ae499

Browse files
authored
Merge pull request #124 from deploymenttheory/dev
Moved cookiejar to it's own specific package
2 parents 9f424e1 + 5ec2bae commit 81ae499

File tree

6 files changed

+142
-11
lines changed

6 files changed

+142
-11
lines changed

authenticationhandler/auth_bearer_token.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// authenticationhandler/auth_bearer_token.go
22
/* The http_client_auth package focuses on authentication mechanisms for an HTTP client.
3-
It provides structures and methods for handling both basic and bearer token based authentication
4-
*/
3+
It provides structures and methods for handling both basic and bearer token based authentication */
54

65
package authenticationhandler
76

cookiejar/cookiejar.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// cookiejar/cookiejar.go
2+
3+
/* The cookiejar package provides utility functions for managing cookies within an HTTP client
4+
context in Go. This package aims to enhance HTTP client functionalities by offering cookie
5+
handling capabilities, including initialization of a cookie jar, redaction of sensitive cookies,
6+
and parsing of cookies from HTTP headers. Below is an explanation of the core functionalities
7+
provided by this package*/
8+
9+
package cookiejar
10+
11+
import (
12+
"fmt"
13+
"net/http"
14+
"net/http/cookiejar"
15+
"strings"
16+
17+
"github.com/deploymenttheory/go-api-http-client/logger"
18+
"go.uber.org/zap"
19+
)
20+
21+
// SetupCookieJar initializes the HTTP client with a cookie jar if enabled in the configuration.
22+
func SetupCookieJar(client *http.Client, enableCookieJar bool, log logger.Logger) error {
23+
if enableCookieJar {
24+
jar, err := cookiejar.New(nil) // nil options use default options
25+
if err != nil {
26+
log.Error("Failed to create cookie jar", zap.Error(err))
27+
return fmt.Errorf("setupCookieJar failed: %w", err) // Wrap and return the error
28+
}
29+
client.Jar = jar
30+
}
31+
return nil
32+
}
33+
34+
// RedactSensitiveCookies redacts sensitive information from cookies.
35+
// It takes a slice of *http.Cookie and returns a redacted slice of *http.Cookie.
36+
func RedactSensitiveCookies(cookies []*http.Cookie) []*http.Cookie {
37+
// Define sensitive cookie names that should be redacted.
38+
sensitiveCookieNames := map[string]bool{
39+
"SessionID": true, // Example sensitive cookie name
40+
// More sensitive cookie names will be added as needed.
41+
}
42+
43+
// Iterate over the cookies and redact sensitive ones.
44+
for _, cookie := range cookies {
45+
if _, found := sensitiveCookieNames[cookie.Name]; found {
46+
cookie.Value = "REDACTED"
47+
}
48+
}
49+
50+
return cookies
51+
}
52+
53+
// Utility function to convert cookies from http.Header to []*http.Cookie.
54+
// This can be useful if cookies are stored in http.Header (e.g., from a response).
55+
func CookiesFromHeader(header http.Header) []*http.Cookie {
56+
cookies := []*http.Cookie{}
57+
for _, cookieHeader := range header["Set-Cookie"] {
58+
if cookie := ParseCookieHeader(cookieHeader); cookie != nil {
59+
cookies = append(cookies, cookie)
60+
}
61+
}
62+
return cookies
63+
}
64+
65+
// ParseCookieHeader parses a single Set-Cookie header and returns an *http.Cookie.
66+
func ParseCookieHeader(header string) *http.Cookie {
67+
headerParts := strings.Split(header, ";")
68+
if len(headerParts) > 0 {
69+
cookieParts := strings.SplitN(headerParts[0], "=", 2)
70+
if len(cookieParts) == 2 {
71+
return &http.Cookie{Name: cookieParts[0], Value: cookieParts[1]}
72+
}
73+
}
74+
return nil
75+
}

cookiejar/cookiejar_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// cookiejar/cookiejar_test.go
2+
package cookiejar
3+
4+
import (
5+
"net/http"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
// TestRedactSensitiveCookies tests the RedactSensitiveCookies function to ensure it correctly redacts sensitive cookies.
12+
func TestRedactSensitiveCookies(t *testing.T) {
13+
cookies := []*http.Cookie{
14+
{Name: "SessionID", Value: "sensitive-value-1"},
15+
{Name: "NonSensitiveCookie", Value: "non-sensitive-value"},
16+
{Name: "AnotherSensitiveCookie", Value: "sensitive-value-2"},
17+
}
18+
19+
redactedCookies := RedactSensitiveCookies(cookies)
20+
21+
// Define expected outcomes for each cookie.
22+
expectedValues := map[string]string{
23+
"SessionID": "REDACTED",
24+
"NonSensitiveCookie": "non-sensitive-value",
25+
"AnotherSensitiveCookie": "sensitive-value-2", // Assuming this is not in the sensitive list.
26+
}
27+
28+
for _, cookie := range redactedCookies {
29+
assert.Equal(t, expectedValues[cookie.Name], cookie.Value, "Cookie value should match expected redaction outcome")
30+
}
31+
}
32+
33+
// TestCookiesFromHeader tests the CookiesFromHeader function to ensure it can correctly parse cookies from HTTP headers.
34+
func TestCookiesFromHeader(t *testing.T) {
35+
header := http.Header{
36+
"Set-Cookie": []string{
37+
"SessionID=sensitive-value; Path=/; HttpOnly",
38+
"NonSensitiveCookie=non-sensitive-value; Path=/",
39+
},
40+
}
41+
42+
cookies := CookiesFromHeader(header)
43+
44+
// Define expected outcomes for each cookie.
45+
expectedCookies := []*http.Cookie{
46+
{Name: "SessionID", Value: "sensitive-value"},
47+
{Name: "NonSensitiveCookie", Value: "non-sensitive-value"},
48+
}
49+
50+
assert.Equal(t, len(expectedCookies), len(cookies), "Number of parsed cookies should match expected")
51+
52+
for i, expectedCookie := range expectedCookies {
53+
assert.Equal(t, expectedCookie.Name, cookies[i].Name, "Cookie names should match")
54+
assert.Equal(t, expectedCookie.Value, cookies[i].Value, "Cookie values should match")
55+
}
56+
}

httpclient/httpclient_client.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/deploymenttheory/go-api-http-client/apiintegrations/apihandler"
1616
"github.com/deploymenttheory/go-api-http-client/authenticationhandler"
17+
"github.com/deploymenttheory/go-api-http-client/cookiejar"
1718
"github.com/deploymenttheory/go-api-http-client/logger"
1819
"github.com/deploymenttheory/go-api-http-client/redirecthandler"
1920
"go.uber.org/zap"
@@ -27,13 +28,13 @@ type Client struct {
2728
OverrideBaseDomain string // Base domain override used when the default in the api handler isn't suitable
2829
Expiry time.Time // Expiry time set for the auth token
2930
httpClient *http.Client
30-
tokenLock sync.Mutex
31-
clientConfig ClientConfig
32-
Logger logger.Logger
33-
ConcurrencyMgr *ConcurrencyManager
34-
PerfMetrics PerformanceMetrics
35-
APIHandler apihandler.APIHandler // APIHandler interface used to define which API handler to use
36-
AuthTokenHandler *authenticationhandler.AuthTokenHandler
31+
//tokenLock sync.Mutex
32+
clientConfig ClientConfig
33+
Logger logger.Logger
34+
ConcurrencyMgr *ConcurrencyManager
35+
PerfMetrics PerformanceMetrics
36+
APIHandler apihandler.APIHandler // APIHandler interface used to define which API handler to use
37+
AuthTokenHandler *authenticationhandler.AuthTokenHandler
3738
}
3839

3940
// Config holds configuration options for the HTTP Client.
@@ -136,7 +137,7 @@ func BuildClient(config ClientConfig) (*Client, error) {
136137
}
137138

138139
// Conditionally setup cookie jar
139-
if err := setupCookieJar(httpClient, config.ClientOptions.EnableCookieJar, log); err != nil {
140+
if err := cookiejar.SetupCookieJar(httpClient, config.ClientOptions.EnableCookieJar, log); err != nil {
140141
log.Error("Error setting up cookie jar", zap.Error(err))
141142
return nil, err
142143
}

httpclient/httpclient_cookies.go renamed to httpclient/httpclient_cookies.go.BACK

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// httpclient_cookies.go
1+
// cookiejar/cookiejar_test.go
22
package httpclient
33

44
import (

0 commit comments

Comments
 (0)