diff --git a/cliv2/internal/analytics/analytics.go b/cliv2/internal/analytics/analytics.go index 4f649e1e1e..d363dd0624 100644 --- a/cliv2/internal/analytics/analytics.go +++ b/cliv2/internal/analytics/analytics.go @@ -9,8 +9,10 @@ import ( "net/http" "net/url" "os" + "os/user" "regexp" "runtime" + "strings" "time" "github.com/hashicorp/go-uuid" @@ -196,6 +198,15 @@ func (a *Analytics) GetRequest() (*http.Request, error) { return nil, err } + user, err := user.Current() + if err != nil { + return nil, err + } + outputJson, err = SanitizeUsername(user.Username, sanitize_replacement_string, outputJson) + if err != nil { + return nil, err + } + analyticsUrl, _ := url.Parse(a.apiUrl + api_endpoint) if len(a.org) > 0 { query := url.Values{} @@ -247,3 +258,26 @@ func SanitizeValuesByKey(keysToFilter []string, replacementValue string, content } return content, nil } + +func SanitizeUsername(rawUserName string, replacementValue string, content []byte) ([]byte, error) { + contentStr := string(content) + contentStr = strings.ReplaceAll(contentStr, rawUserName, replacementValue) + + if strings.Contains(rawUserName, "\\") { + segments := strings.Split(rawUserName, "\\") + segmentsLen := len(segments) + if segmentsLen < 2 { + // this should never happen because we already checked for the existence of a backslash + return nil, fmt.Errorf("could not sanitize username") + } else if segmentsLen == 2 { + simpleUsername := segments[1] + contentStr = strings.ReplaceAll(contentStr, simpleUsername, replacementValue) + } else { + // don't recognize this format + fmt.Println(segments) + return nil, fmt.Errorf("could not sanitize username - unrecognized format") + } + } + + return []byte(contentStr), nil +} diff --git a/cliv2/internal/analytics/analytics_test.go b/cliv2/internal/analytics/analytics_test.go index a746cf3c83..705d6bef66 100644 --- a/cliv2/internal/analytics/analytics_test.go +++ b/cliv2/internal/analytics/analytics_test.go @@ -113,3 +113,74 @@ func Test_SanitizeValuesByKey(t *testing.T) { assert.Equal(t, expectedNumberOfRedacted, secretsCountBefore) assert.Equal(t, 0, secretsCountAfter) } + +func Test_SanitizeUsername(t *testing.T) { + type sanTest struct { + ErrorLog string + Other string + } + + rawUserName := "someuser" + simpleUsername := "someuser" + replacement := "REDACTED" + + inputStruct := sanTest{ + ErrorLog: "/Users/" + rawUserName + "/some/path", + Other: fmt.Sprintf("some other value where %s is contained", rawUserName), + } + + input, _ := json.Marshal(inputStruct) + fmt.Println("Before: " + string(input)) + + // invoke method under test + output, err := SanitizeUsername(rawUserName, replacement, input) + + fmt.Println("After: " + string(output)) + assert.Nil(t, err, "Failed to santize static values!") + + numRedacted := strings.Count(string(output), replacement) + assert.Equal(t, 2, numRedacted) + + numUsernameInstances := strings.Count(string(output), rawUserName) + assert.Equal(t, 0, numUsernameInstances) + + numSimpleUsernameInstances := strings.Count(string(output), simpleUsername) + assert.Equal(t, 0, numSimpleUsernameInstances) + + var outputStruct sanTest + json.Unmarshal(output, &outputStruct) + assert.Equal(t, "/Users/REDACTED/some/path", outputStruct.ErrorLog) + assert.Equal(t, "some other value where REDACTED is contained", outputStruct.Other) + + // Check with Windows style domain\username + rawUserName = "somedomain\\someuser" + simpleUsername = "someuser" + replacement = "REDACTED" + + inputStruct = sanTest{ + ErrorLog: fmt.Sprintf("C:\\Users\\%s\\some\\path", simpleUsername), + Other: fmt.Sprintf("some other value where %s is contained", rawUserName), + } + + input, _ = json.Marshal(inputStruct) + fmt.Println("Before: " + string(input)) + + // invoke method under test + output, err = SanitizeUsername(rawUserName, replacement, input) + + fmt.Println("After: " + string(output)) + assert.Nil(t, err, "Failed to santize static values!") + + numRedacted = strings.Count(string(output), replacement) + assert.Equal(t, 2, numRedacted) + + numUsernameInstances = strings.Count(string(output), rawUserName) + assert.Equal(t, 0, numUsernameInstances) + + numSimpleUsernameInstances = strings.Count(string(output), simpleUsername) + assert.Equal(t, 0, numSimpleUsernameInstances) + + json.Unmarshal(output, &outputStruct) + assert.Equal(t, "C:\\Users\\REDACTED\\some\\path", outputStruct.ErrorLog) + assert.Equal(t, "some other value where somedomain\\REDACTED is contained", outputStruct.Other) +}