diff --git a/pkg/auth/auth_client.go b/pkg/auth/auth_client.go index 2e1e5a1..c1c26d0 100644 --- a/pkg/auth/auth_client.go +++ b/pkg/auth/auth_client.go @@ -31,19 +31,19 @@ const tokenRefreshMargin = 10 * time.Second type KeycloakConfig struct { ClientID string Username string - Password string + Password string //nolint:gosec AuthURL string KeycloakRealm string } type tokenInfo struct { - AccessToken string + AccessToken string //nolint:gosec ExpiresAt time.Time } type authResponse struct { - AccessToken string `json:"access_token"` - ExpiresIn int `json:"expires_in"` // in seconds + AccessToken string `json:"access_token"` //nolint:gosec + ExpiresIn int `json:"expires_in"` // in seconds } // KeycloakClient can be used to authenticate against a Keycloak server. @@ -121,7 +121,7 @@ func (c *KeycloakClient) requestToken(ctx context.Context) (*authResponse, error } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - resp, err := c.httpClient.Do(req) + resp, err := c.httpClient.Do(req) //nolint:gosec if err != nil { return nil, fmt.Errorf("failed to execute authentication request: %w", err) } diff --git a/pkg/auth/auth_client_test.go b/pkg/auth/auth_client_test.go index 64ad24b..2eb1d22 100644 --- a/pkg/auth/auth_client_test.go +++ b/pkg/auth/auth_client_test.go @@ -39,7 +39,9 @@ func TestKeycloakClient_GetToken(t *testing.T) { for name, tt := range tests { t.Run(name, func(t *testing.T) { var serverCallCount atomic.Int32 - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mockServer := httptest.NewServer(http.HandlerFunc(func( + w http.ResponseWriter, r *http.Request, + ) { serverCallCount.Add(1) w.WriteHeader(tt.responseCode) _, err := w.Write([]byte(tt.responseBody)) @@ -108,7 +110,9 @@ func TestKeycloakClient_GetToken_Refresh(t *testing.T) { fakeClock := NewFakeClock(time.Now()) var serverCallCount atomic.Int32 - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mockServer := httptest.NewServer(http.HandlerFunc(func( + w http.ResponseWriter, r *http.Request, + ) { serverCallCount.Add(1) w.WriteHeader(200) _, err := w.Write(kcMockResponse) diff --git a/pkg/dbcrypt/dbcipher.go b/pkg/dbcrypt/dbcipher.go index 130f36b..c9a49f8 100644 --- a/pkg/dbcrypt/dbcipher.go +++ b/pkg/dbcrypt/dbcipher.go @@ -25,7 +25,7 @@ type Config struct { Version string // Contains the password used to derive encryption key - Password string + Password string //nolint:gosec // Contains the salt for increasing password entropy PasswordSalt string diff --git a/pkg/httpassert/response.go b/pkg/httpassert/response.go index 9066bce..44dee26 100644 --- a/pkg/httpassert/response.go +++ b/pkg/httpassert/response.go @@ -6,7 +6,6 @@ package httpassert import ( "encoding/json" - "fmt" "os" "strings" @@ -63,7 +62,11 @@ func (r *responseImpl) Header(name string, value any) Response { } func (r *responseImpl) StatusCode(expected int) Response { - require.Equal(r.t, expected, r.response.Code) + if assert.Equal(r.t, expected, r.response.Code) { + return r + } + r.Log() + r.t.FailNow() return r } @@ -210,9 +213,15 @@ func (r *responseImpl) GetJsonBodyObject(target any) Response { } func (r *responseImpl) Log() Response { - fmt.Printf("Response: %d\nHeaders: %v\nBody: %s\n", + r.t.Logf("Request\nMethod: %s\nURL: %s\nContent-Type: %s\nHeaders: %v\nBody: %s\n", + r.request.method, + r.request.url, + r.request.contentType, + r.request.headers, + r.request.body) + r.t.Logf("Response\nCode: %d\nHeaders: %v\nBody: %s\n", r.response.Code, r.response.Header(), - r.response.Body.String()) + r.response.Body) return r } diff --git a/pkg/notifications/notification.go b/pkg/notifications/notification.go index c53e125..1491a50 100644 --- a/pkg/notifications/notification.go +++ b/pkg/notifications/notification.go @@ -121,7 +121,7 @@ func (c *Client) RegisterOrigins(ctx context.Context, serviceID string, origins req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Content-Type", "application/json") - response, err := c.httpClient.Do(req) + response, err := c.httpClient.Do(req) //nolint:gosec if err != nil { return fmt.Errorf("failed to execute request: %w", err) } diff --git a/pkg/notifications/notification_test.go b/pkg/notifications/notification_test.go index a3e093f..dbe6937 100644 --- a/pkg/notifications/notification_test.go +++ b/pkg/notifications/notification_test.go @@ -113,7 +113,8 @@ func TestClient_CreateNotification(t *testing.T) { mockAuthServer := setupMockAuthServer(t, tt.serverErrors.authenticationFail) defer mockAuthServer.Close() - mockNotificationServer := setupMockNotificationServer(t, &serverCallCount, tt.wantNotificationSent, tt.serverErrors) + mockNotificationServer := setupMockNotificationServer(t, &serverCallCount, + tt.wantNotificationSent, tt.serverErrors) defer mockNotificationServer.Close() config := Config{ @@ -158,7 +159,9 @@ func setupMockAuthServer(t *testing.T, failAuth bool) *httptest.Server { })) } -func setupMockNotificationServer(t *testing.T, serverCallCount *atomic.Int32, wantNotification notificationModel, errors serverErrors) *httptest.Server { +func setupMockNotificationServer(t *testing.T, serverCallCount *atomic.Int32, + wantNotification notificationModel, errors serverErrors, +) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { serverCallCount.Add(1) diff --git a/pkg/openSearch/openSearchQuery/sort_test.go b/pkg/openSearch/openSearchQuery/sort_test.go index a4acb4e..0437d0f 100644 --- a/pkg/openSearch/openSearchQuery/sort_test.go +++ b/pkg/openSearch/openSearchQuery/sort_test.go @@ -70,7 +70,8 @@ func TestSorting(t *testing.T) { } termsAggregation := esquery.TermsAgg("vulnerabilityWithAssetCountAgg", "vulnerabilityTest.oid.keyword"). Aggs(subAggs...) - termsAggregation, err = AddOrder(termsAggregation, testCases[name].SortingRequest, sortFieldMapping) + termsAggregation, err = AddOrder(termsAggregation, + testCases[name].SortingRequest, sortFieldMapping) resultingJson, queryErr := esquery.Search().Query(q.Build()).Aggs(termsAggregation).Size(0).MarshalJSON() assert.Nil(t, queryErr) assert.JSONEq(t, testCases[name].ExpectedQueryJson, string(resultingJson)) diff --git a/pkg/openSearch/osquery/boolQueryBuilder.go b/pkg/openSearch/osquery/boolQueryBuilder.go index a704a19..bc72141 100644 --- a/pkg/openSearch/osquery/boolQueryBuilder.go +++ b/pkg/openSearch/osquery/boolQueryBuilder.go @@ -151,7 +151,8 @@ func (q *BoolQueryBuilder) AddFilterRequest(request *filter.Request) error { if handler, ok := operatorMapping[field.Operator]; ok { value := field.Value - if field.Operator == filter.CompareOperatorExists || field.Operator == filter.CompareOperatorDoesNotExist { + if field.Operator == filter.CompareOperatorExists || + field.Operator == filter.CompareOperatorDoesNotExist { value = "" // exists operator does not need a value, but for more consistent handling just pass a dummy value } if value == nil { diff --git a/pkg/openSearch/osquery/boolQueryBuilder_test.go b/pkg/openSearch/osquery/boolQueryBuilder_test.go index 701a61e..662d100 100644 --- a/pkg/openSearch/osquery/boolQueryBuilder_test.go +++ b/pkg/openSearch/osquery/boolQueryBuilder_test.go @@ -703,7 +703,8 @@ func TestBoolQueryBuilder_AddFilterRequest(t *testing.T) { t.Logf("sending search request to OpenSearch: %s", string(requestBody)) gotDocuments, totalResults, err := client.ListDocuments(alias, requestBody) require.NoError(t, err, "listing documents failed") - require.Len(t, gotDocuments, int(totalResults), "test requires results to be returned on a single page") // catch paging misconfiguration + require.Len(t, gotDocuments, int(totalResults), + "test requires results to be returned on a single page") // catch paging misconfiguration assert.ElementsMatch(t, tt.wantDocuments, gotDocuments) } @@ -751,7 +752,9 @@ func TestBoolQueryBuilder_AddTermFilter(t *testing.T) { // index setup needed only once, as test cases are only reading data _, alias := tester.NewTestTypeIndexAlias(t, "arbitrary") - tester.CreateDocuments(t, alias, ostesting.ToAnySlice(allDocs), []string{"id0", "id1", "id2", "id3", "id4"}) + tester.CreateDocuments(t, alias, ostesting.ToAnySlice(allDocs), []string{ + "id0", "id1", "id2", "id3", "id4", + }) client, err := newTestOSClient(tester.OSClient()) require.NoError(t, err) @@ -939,7 +942,8 @@ func TestBoolQueryBuilder_AddTermFilter(t *testing.T) { t.Logf("sending search request to OpenSearch: %s", string(requestBody)) gotDocuments, totalResults, err := client.ListDocuments(alias, requestBody) require.NoError(t, err, "listing documents failed") - require.Len(t, gotDocuments, int(totalResults), "test requires results to be returned on a single page") // catch paging misconfiguration + require.Len(t, gotDocuments, int(totalResults), + "test requires results to be returned on a single page") // catch paging misconfiguration assert.ElementsMatch(t, tt.wantDocuments, gotDocuments) }) diff --git a/pkg/openSearch/ostesting/test_type.go b/pkg/openSearch/ostesting/test_type.go index 2b54106..1c58df2 100644 --- a/pkg/openSearch/ostesting/test_type.go +++ b/pkg/openSearch/ostesting/test_type.go @@ -20,9 +20,8 @@ type TestType struct { KeywordOmitEmpty string `json:"keywordOmitEmpty,omitempty"` } -var ( - // testTypeMapping is an index mapping for testType - testTypeMapping string = `{ +// testTypeMapping is an index mapping for testType +var testTypeMapping string = `{ "mappings": { "properties": { "id": { @@ -64,4 +63,3 @@ var ( } } }` -) diff --git a/pkg/openSearch/ostesting/tester.go b/pkg/openSearch/ostesting/tester.go index 5fae79d..ab890c2 100644 --- a/pkg/openSearch/ostesting/tester.go +++ b/pkg/openSearch/ostesting/tester.go @@ -33,7 +33,7 @@ const KeepFailedEnv = "TEST_KEEP_FAILED" type ClientConfig struct { Address string User string - Password string + Password string //nolint:gosec } const ( @@ -43,15 +43,13 @@ const ( defaultTestUser = "admin" ) -var ( - // defaultOSConf is the default configuration used for testing OpenSearch to connect - // to the test OpenSearch instance running in docker - defaultOSConf = ClientConfig{ - Address: defaultTestAddress, - User: defaultTestUser, - Password: defaultTestPassword, - } -) +// defaultOSConf is the default configuration used for testing OpenSearch to connect +// to the test OpenSearch instance running in docker +var defaultOSConf = ClientConfig{ + Address: defaultTestAddress, + User: defaultTestUser, + Password: defaultTestPassword, +} // Tester manages connecting with testing OpenSearch instance and implements // helper methods @@ -109,7 +107,8 @@ func NewTester(t *testing.T, opts ...TesterOption) *Tester { Addresses: []string{tst.conf.Address}, Username: tst.conf.User, Password: tst.conf.Password, - }}) + }, + }) if err != nil { t.Fatalf("error while initializing opensearchapi.Client for testing: %v", err) } @@ -177,7 +176,7 @@ func (tst Tester) NewIndex(t *testing.T, prefix string, mapping *string) string if createResponse != nil { resp = createResponse.Inspect().Response } - defer func() { //close response body + defer func() { // close response body if resp != nil { if err := resp.Body.Close(); err != nil { t.Errorf("failed to close response body: %v", err) diff --git a/pkg/postgres/query/builder.go b/pkg/postgres/query/builder.go index 161d137..de937f7 100644 --- a/pkg/postgres/query/builder.go +++ b/pkg/postgres/query/builder.go @@ -81,7 +81,7 @@ func (qb *Builder) addFilters(request *filter.Request) (args []any, err error) { } if index > 0 { - qb.query.WriteString(fmt.Sprintf(" %s ", logicOperator)) + fmt.Fprintf(&qb.query, " %s ", logicOperator) } qb.query.WriteString(conditionTemplate) } @@ -163,11 +163,11 @@ func (qb *Builder) addPaging(paging paging.Request) error { if paging.PageIndex > 0 { offset := paging.PageIndex * paging.PageSize - qb.query.WriteString(fmt.Sprintf(" OFFSET %d", offset)) + fmt.Fprintf(&qb.query, " OFFSET %d", offset) } if paging.PageSize > 0 { - qb.query.WriteString(fmt.Sprintf(" LIMIT %d", paging.PageSize)) + fmt.Fprintf(&qb.query, " LIMIT %d", paging.PageSize) } return nil } diff --git a/pkg/postgres/query/builder_test.go b/pkg/postgres/query/builder_test.go index a2fea0a..8df005d 100644 --- a/pkg/postgres/query/builder_test.go +++ b/pkg/postgres/query/builder_test.go @@ -549,10 +549,12 @@ func Test_PostgresQueryBuilder_Build(t *testing.T) { value := doc1.String require.Greater(t, len(value), 1, "test requires value to be longer than 1 character for `contains` operator") firstPart := value[:len(value)/2] - require.NotEqual(t, firstPart, strings.ToLower(firstPart), "test requires mixed case, to verify case insensitivity") + require.NotEqual(t, firstPart, strings.ToLower(firstPart), + "test requires mixed case, to verify case insensitivity") firstPart = strings.ToLower(firstPart) secondPart := value[len(value)/2:] - require.NotEqual(t, secondPart, strings.ToLower(secondPart), "test requires mixed case, to verify case insensitivity") + require.NotEqual(t, secondPart, strings.ToLower(secondPart), + "test requires mixed case, to verify case insensitivity") secondPart = strings.ToLower(secondPart) addTest("operator Contains: single value", testCase{ @@ -652,10 +654,12 @@ func Test_PostgresQueryBuilder_Build(t *testing.T) { for _, value := range values { require.Greater(t, len(value), 1, "test requires value to be longer than 1 character for `contains` operator") firstPart := value[:len(value)/2] - require.NotEqual(t, firstPart, strings.ToLower(firstPart), "test requires mixed case, to verify case insensitivity") + require.NotEqual(t, firstPart, strings.ToLower(firstPart), + "test requires mixed case, to verify case insensitivity") firstParts = append(firstParts, strings.ToLower(firstPart)) secondPart := value[len(value)/2:] - require.NotEqual(t, secondPart, strings.ToLower(secondPart), "test requires mixed case, to verify case insensitivity") + require.NotEqual(t, secondPart, strings.ToLower(secondPart), + "test requires mixed case, to verify case insensitivity") secondParts = append(secondParts, strings.ToLower(secondPart)) } @@ -726,7 +730,10 @@ func Test_PostgresQueryBuilder_Build(t *testing.T) { // date specific filters, multiple values dateValues := map[string][]any{ - "date as string": {doc1.DateTime.Format(time.RFC3339Nano), doc2.DateTime.Format(time.RFC3339Nano)}, + "date as string": { + doc1.DateTime.Format(time.RFC3339Nano), + doc2.DateTime.Format(time.RFC3339Nano), + }, "date as time.Time": {doc1.DateTime, doc2.DateTime}, } for valueType, values := range dateValues { diff --git a/pkg/postgres/query/compose.go b/pkg/postgres/query/compose.go index 168845e..2cd0bb5 100644 --- a/pkg/postgres/query/compose.go +++ b/pkg/postgres/query/compose.go @@ -25,7 +25,8 @@ func composeQuery( dbColumnName, ok := fieldMapping[field.Name] if !ok { return "", filter.NewInvalidFilterFieldError( - "invalid filter field '%s', available fields: ", slices.Collect(maps.Keys(fieldMapping))) + "invalid filter field '%s', available fields: ", + slices.Collect(maps.Keys(fieldMapping))) } quotedName, err := getQuotedName(dbColumnName) if err != nil { diff --git a/pkg/postgres/query/query.go b/pkg/postgres/query/query.go index 55b02fb..c43f71a 100644 --- a/pkg/postgres/query/query.go +++ b/pkg/postgres/query/query.go @@ -107,7 +107,8 @@ func sanitizeFilterValue(value any) (sanitizedValue any, err error) { sanitizedValue = value - if reflect.TypeOf(value).Kind() == reflect.Slice || reflect.TypeOf(value).Kind() == reflect.Array { + if reflect.TypeOf(value).Kind() == reflect.Slice || + reflect.TypeOf(value).Kind() == reflect.Array { slice := reflect.ValueOf(value) if slice.Len() == 0 { // disallow empty list values, as the there is no clear way to interpret this kind of filter diff --git a/pkg/query/filter/request_test.go b/pkg/query/filter/request_test.go index bf97713..660a74e 100644 --- a/pkg/query/filter/request_test.go +++ b/pkg/query/filter/request_test.go @@ -74,14 +74,22 @@ func TestReadableValues(t *testing.T) { want: []filter.ReadableValue[filter.ControlType]{}, }, { - name: "already-sorted", - given: []filter.ReadableValue[filter.ControlType]{{Label: "aaa", Value: filter.ControlTypeBool}, {Label: "bbb", Value: filter.ControlTypeEnum}}, - want: []filter.ReadableValue[filter.ControlType]{{Label: "aaa", Value: filter.ControlTypeBool}, {Label: "bbb", Value: filter.ControlTypeEnum}}, + name: "already-sorted", + given: []filter.ReadableValue[filter.ControlType]{{ + Label: "aaa", Value: filter.ControlTypeBool, + }, {Label: "bbb", Value: filter.ControlTypeEnum}}, + want: []filter.ReadableValue[filter.ControlType]{{ + Label: "aaa", Value: filter.ControlTypeBool, + }, {Label: "bbb", Value: filter.ControlTypeEnum}}, }, { - name: "reordered", - given: []filter.ReadableValue[filter.ControlType]{{Label: "aaa", Value: filter.ControlTypeEnum}, {Label: "bbb", Value: filter.ControlTypeBool}}, - want: []filter.ReadableValue[filter.ControlType]{{Label: "bbb", Value: filter.ControlTypeBool}, {Label: "aaa", Value: filter.ControlTypeEnum}}, + name: "reordered", + given: []filter.ReadableValue[filter.ControlType]{{ + Label: "aaa", Value: filter.ControlTypeEnum, + }, {Label: "bbb", Value: filter.ControlTypeBool}}, + want: []filter.ReadableValue[filter.ControlType]{{ + Label: "bbb", Value: filter.ControlTypeBool, + }, {Label: "aaa", Value: filter.ControlTypeEnum}}, }, } for _, test := range tests { diff --git a/pkg/retryableRequest/retryableRequest.go b/pkg/retryableRequest/retryableRequest.go index e2e2157..b962fe6 100644 --- a/pkg/retryableRequest/retryableRequest.go +++ b/pkg/retryableRequest/retryableRequest.go @@ -20,7 +20,8 @@ import ( // ExecuteRequestWithRetry executes the given request via the passed http client and retries on failures. // An error is only returned if there was a non retryable error or the maximum number of retries was reached. // It uses the retry policy of [retryablehttp.ErrorPropagatedRetryPolicy] and exponential backoff from [retryablehttp.DefaultBackoff]. -func ExecuteRequestWithRetry(ctx context.Context, client *http.Client, request *http.Request, +func ExecuteRequestWithRetry( + ctx context.Context, client *http.Client, request *http.Request, maxRetries int, retryWaitMin, retryWaitMax time.Duration, ) (*http.Response, error) { var errList []error @@ -30,7 +31,7 @@ func ExecuteRequestWithRetry(ctx context.Context, client *http.Client, request * return nil, fmt.Errorf("failed to copy request for repeated use: %w", err) } - response, err := client.Do(requestCopy.WithContext(ctx)) + response, err := client.Do(requestCopy.WithContext(ctx)) //nolint:gosec if err == nil && IsOk(response.StatusCode) { return response, nil diff --git a/pkg/secretfiles/secret_files.go b/pkg/secretfiles/secret_files.go index 0584437..804a5b8 100644 --- a/pkg/secretfiles/secret_files.go +++ b/pkg/secretfiles/secret_files.go @@ -24,7 +24,7 @@ func ReadSecret(envVar string, target *string) error { } path := os.Getenv(envVar) if path != "" { - content, err := os.ReadFile(path) + content, err := os.ReadFile(path) //nolint:gosec if err != nil { return fmt.Errorf("failed to read secret from file: %w", err) }