gitlab.com/gitlab-org/labkit@v1.21.0/errortracking/capture_request_test.go (about)

     1  package errortracking
     2  
     3  import (
     4  	"fmt"
     5  	"net/http/httptest"
     6  	"net/url"
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  	"gitlab.com/gitlab-org/labkit/mask"
    12  )
    13  
    14  func TestCleanHeaders(t *testing.T) {
    15  	tests := []struct {
    16  		name        string
    17  		url         string
    18  		headers     map[string]string
    19  		wantHeaders map[string]string
    20  		wantQuery   string
    21  	}{
    22  		{
    23  			name:        "trivial",
    24  			url:         "/api/projects",
    25  			headers:     map[string]string{},
    26  			wantHeaders: map[string]string{},
    27  			wantQuery:   "",
    28  		},
    29  		{
    30  			name: "no_secrets",
    31  			url:  "/api/projects?app=gitlab",
    32  			headers: map[string]string{
    33  				"User-Agent": "golang",
    34  			},
    35  			wantHeaders: map[string]string{
    36  				"User-Agent": "golang",
    37  			},
    38  			wantQuery: "app=gitlab",
    39  		},
    40  		{
    41  			name: "authorization_secret",
    42  			url:  "/api/projects?authorization=secret1",
    43  			headers: map[string]string{
    44  				"User-Agent":    "golang",
    45  				"Authorization": "secret2",
    46  			},
    47  			wantHeaders: map[string]string{
    48  				"User-Agent":    "golang",
    49  				"Authorization": mask.RedactionString,
    50  			},
    51  			wantQuery: fmt.Sprintf("authorization=%s", url.QueryEscape(mask.RedactionString)),
    52  		},
    53  		{
    54  			name: "private_token_secret",
    55  			url:  "/api/projects?private-token=secret1",
    56  			headers: map[string]string{
    57  				"User-Agent":    "golang",
    58  				"Private-Token": "secret2",
    59  			},
    60  			wantHeaders: map[string]string{
    61  				"User-Agent":    "golang",
    62  				"Private-Token": mask.RedactionString,
    63  			},
    64  			wantQuery: fmt.Sprintf("private-token=%s", url.QueryEscape(mask.RedactionString)),
    65  		},
    66  		{
    67  			name: "ending_with_token_secret",
    68  			url:  "/api/projects?Sometoken=abc",
    69  			headers: map[string]string{
    70  				"User-Agent": "golang",
    71  				"Sometoken":  "token",
    72  			},
    73  			wantHeaders: map[string]string{
    74  				"User-Agent": "golang",
    75  				"Sometoken":  mask.RedactionString,
    76  			},
    77  			wantQuery: fmt.Sprintf("Sometoken=%s", url.QueryEscape(mask.RedactionString)),
    78  		},
    79  		{
    80  			name: "containing_password_secret",
    81  			url:  "/api/projects?my_password_secret=pa55word",
    82  			headers: map[string]string{
    83  				"User-Agent":                 "golang",
    84  				"X-Personal-Password-Secret": "password",
    85  			},
    86  			wantHeaders: map[string]string{
    87  				"User-Agent":                 "golang",
    88  				"X-Personal-Password-Secret": mask.RedactionString,
    89  			},
    90  			wantQuery: fmt.Sprintf("my_password_secret=%s", url.QueryEscape(mask.RedactionString)),
    91  		},
    92  		{
    93  			name: "ending_key_secret",
    94  			url:  "/api/projects?my_key=1212",
    95  			headers: map[string]string{
    96  				"User-Agent":       "golang",
    97  				"Personalvaultkey": "Key",
    98  			},
    99  			wantHeaders: map[string]string{
   100  				"User-Agent":       "golang",
   101  				"Personalvaultkey": mask.RedactionString,
   102  			},
   103  			wantQuery: fmt.Sprintf("my_key=%s", url.QueryEscape(mask.RedactionString)),
   104  		},
   105  		{
   106  			name: "containing_key",
   107  			url:  "/api/projects",
   108  			headers: map[string]string{
   109  				"User-Agent":  "golang",
   110  				"Keypassuser": "Not-Secret-String",
   111  			},
   112  			wantHeaders: map[string]string{
   113  				"User-Agent":  "golang",
   114  				"Keypassuser": "Not-Secret-String",
   115  			},
   116  		},
   117  		{
   118  			name: "multiple_secrets",
   119  			url:  "/api/projects?token=123&token=456",
   120  			headers: map[string]string{
   121  				"User-Agent":    "golang",
   122  				"Authorization": "secret1",
   123  				"Private-Token": "secret2",
   124  			},
   125  			wantHeaders: map[string]string{
   126  				"User-Agent":    "golang",
   127  				"Authorization": mask.RedactionString,
   128  				"Private-Token": mask.RedactionString,
   129  			},
   130  			wantQuery: fmt.Sprintf("token=%s&token=%s", url.QueryEscape(mask.RedactionString), url.QueryEscape(mask.RedactionString)),
   131  		},
   132  	}
   133  	for _, tt := range tests {
   134  		t.Run(tt.name, func(t *testing.T) {
   135  			req := httptest.NewRequest("GET", tt.url, nil)
   136  			for k, v := range tt.headers {
   137  				req.Header.Set(k, v)
   138  			}
   139  
   140  			result := redactRequestInfo(req)
   141  			processedRequestHeaders := result.Headers
   142  
   143  			require.True(t, reflect.DeepEqual(tt.wantHeaders, processedRequestHeaders), "Expected %+v, got %+v", tt.wantHeaders, processedRequestHeaders)
   144  			require.Equal(t, tt.wantQuery, result.QueryString, "Expected query %+v, got %+v", tt.wantQuery, result.QueryString)
   145  		})
   146  	}
   147  }