diff --git a/backend/.golangci.yml b/backend/.golangci.yml index e6faeb4b..7f0d0857 100644 --- a/backend/.golangci.yml +++ b/backend/.golangci.yml @@ -1,63 +1,166 @@ +--- linters: - enable: - - bodyclose - - errcheck - - gosimple - - govet - - gosec - - goconst - - gocritic - - gocyclo - - gofmt - - goimports - - ineffassign - - misspell - - nakedret - - prealloc - #- revive - - staticcheck - - typecheck - - unused - - unconvert - - unparam + enable: + # Prevents against memory leaks in production caused by not closing + # file handle + - bodyclose + # Detects cloned code. DRY is good programming practice. Can cause issues + # with testing code where simplicity is preferred over duplication. + # Disabled for test code. + # - dupl + # Detects unchecked errors in go programs. These unchecked errors can be + # critical bugs in some cases. + - errcheck + # Simplifies go code. + - gosimple + # Controls Go package import order and makes it always deterministic. + - gci + # Reports suspicious constructs, maintained by goteam. e.g. Printf unused + # params not caught at compile time. + - govet + # Detect security issues with gocode. Use of secrets in code or obsolete + # security algorithms. It's imaged heuristic methods are used in finding + # problems. If issues with rules are found particular rules can be disabled + # as required. Could possibility cause issues with testing. + # Disabled for test code. + - gosec + # Detect repeated strings that could be replaced by a constant + - goconst + # Misc linters missing from other projects. Grouped into 3 categories + # diagnostics, style and performance + - gocritic + # Limits code cyclomatic complexity + - gocyclo + # Detects if code needs to be gofmt'd + - gofmt + # Detects unused go package imports + - goimports + # Detects style mistakes not correctness. Golint is meant to carry out the + # stylistic conventions put forth in Effective Go and CodeReviewComments. + # golint has false positives and false negatives and can be tweaked. + - revive + # Detects ineffectual assignments in code + - ineffassign + # Reports long lines + # - lll + # Detect commonly misspelled english words in comments + - misspell + # Detect naked returns on non-trivial functions, and conform with + # Go CodeReviewComments + - nakedret + # Detect slice allocations that can be preallocated + - prealloc + # Misc collection of static analysis tools + - staticcheck + # Detects unused struct fields + # - structcheck + # Parses and typechecks the code like the go compiler + - typecheck + # Detects unused constants, variables, functions and types + - unused + # Remove unnecessary type conversions + - unconvert + # Remove unnecessary(unused) function parameters + - unparam linters-settings: - gosec: - excludes: - - G115 - errcheck: - exclude-functions: - - fmt.Fprint - - fmt.Fprintf - goconst: - # minimal length of string constant - # default: 3 - min-len: 2 - # minimum number of occurrences of string constant - # default: 3 - min-occurences: 2 - misspell: - locale: UK - ignore-words: - - color + errcheck: + exclude-functions: + - fmt.Fprint + - fmt.Fprintf + gci: + sections: + - standard # Standard section: captures all standard packages. + - localmodule # Local module section: contains all local packages. + # - prefix(gogs.jc21.com) # Prefixed gerrit.lan packages (jumgo). + - default # Everything else (github.com, golang.org, etc). + - blank # Blank section: contains all blank imports. + custom-order: true + goconst: + # minimal length of string constant + # default: 3 + min-len: 2 + # minimum number of occurrences of string constant + # default: 3 + min-occurences: 2 + revive: + enable-all-rules: true + rules: + - name: unchecked-type-assertion + disabled: true + # handled by goconst + - name: add-constant + disabled: true + # cant limit this arbitrarily + - name: argument-limit + disabled: true + # handled by gocyclo + - name: cognitive-complexity + disabled: true + # false positive for Exported vs non-exported functions of the same name + - name: confusing-naming + disabled: true + # false positives for "" - which is the nil value of a string (also 0) + - name: confusing-results + disabled: true + # handled by gocyclo + - name: cyclomatic + disabled: true + # have comments on exported functions but not on vars/types/constants + - name: exported + arguments: + - "disableChecksOnConstants" + - "disableChecksOnTypes" + - "disableChecksOnVariables" + # false positives on bool params + - name: flag-parameter + disabled: true + # extreme verticalization can happen + - name: function-length + disabled: true + # can false positive for non-getters + - name: get-return + disabled: true + # only allows lowercase names + - name: import-alias-naming + disabled: true + # handled by lll + - name: line-length-limit + disabled: true + # don't want to arbitrarily limit this + # many places have specific model.go files to contain all structs + - name: max-public-structs + disabled: true + # disable package-comments + - name: package-comments + disabled: true + # this is handled by errcheck + - name: unhandled-error + disabled: true + - name: function-result-limit + disabled: true issues: - # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. - # We have chosen an arbitrary value that works based on practical usage. - max-same: 20 - # See cmdline flag documentation for more info about default excludes --exclude-use-default - # Nothing is excluded by default - exclude-use-default: false - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - # Exclude some linters from running on tests files. # TODO: Add examples why this is good - - - path: _test\.go - linters: - # Tests should be simple? Add example why this is good? - - gocyclo - # Error checking adds verbosity and complexity for minimal value - - errcheck - # Table test encourage duplication in defining the table tests. - - dupl - # Hard coded example tokens, SQL injection and other bad practices may - # want to be tested - - gosec + # Maximum count of issues with the same text. Set to 0 to disable. Default + # is 3. We have chosen an arbitrary value that works based on practical usage. + max-same: 20 + # See cmdline flag documentation for more info about default excludes + # --exclude-use-default. Nothing is excluded by default + exclude-use-default: false + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + # Exclude some linters from running on tests files. + # TODO: Add examples why this is good + - path: _test\.go + linters: + # Tests should be simple? Add example why this is good? + - gocyclo + # Error checking adds verbosity and complexity for minimal value + - errcheck + # Table test encourage duplication in defining the table tests. + - dupl + # Hard coded example tokens, SQL injection and other bad practices may + # want to be tested + - gosec + # Test data can long + # - lll +run: + go: '1.23' diff --git a/backend/internal/api/handler/auth.go b/backend/internal/api/handler/auth.go index f4f2799c..54f428c2 100644 --- a/backend/internal/api/handler/auth.go +++ b/backend/internal/api/handler/auth.go @@ -3,17 +3,17 @@ package handler import ( "encoding/json" "net/http" - h "npm/internal/api/http" - "npm/internal/errors" - "npm/internal/logger" "slices" "time" c "npm/internal/api/context" + h "npm/internal/api/http" "npm/internal/entity/auth" "npm/internal/entity/setting" "npm/internal/entity/user" + "npm/internal/errors" njwt "npm/internal/jwt" + "npm/internal/logger" "gorm.io/gorm" ) diff --git a/backend/internal/api/handler/certificates.go b/backend/internal/api/handler/certificates.go index 8b156141..618d6d4f 100644 --- a/backend/internal/api/handler/certificates.go +++ b/backend/internal/api/handler/certificates.go @@ -151,7 +151,7 @@ func getCertificateFromRequest(w http.ResponseWriter, r *http.Request) *certific // fillObjectFromBody has some reusable code for all endpoints that // have a certificate id in the url. it will write errors to the output. -func fillObjectFromBody(w http.ResponseWriter, r *http.Request, validationSchema string, o interface{}) bool { +func fillObjectFromBody(w http.ResponseWriter, r *http.Request, validationSchema string, o any) bool { bodyBytes, _ := r.Context().Value(c.BodyCtxKey).([]byte) if validationSchema != "" { @@ -176,10 +176,10 @@ func fillObjectFromBody(w http.ResponseWriter, r *http.Request, validationSchema return true } -func configureCertificate(c certificate.Model) { +func configureCertificate(cert certificate.Model) { err := jobqueue.AddJob(jobqueue.Job{ Name: "RequestCertificate", - Action: c.Request, + Action: cert.Request, }) if err != nil { logger.Error("ConfigureCertificateError", err) diff --git a/backend/internal/api/handler/config.go b/backend/internal/api/handler/config.go index 811d7580..3f6bc954 100644 --- a/backend/internal/api/handler/config.go +++ b/backend/internal/api/handler/config.go @@ -2,6 +2,7 @@ package handler import ( "net/http" + h "npm/internal/api/http" "npm/internal/config" ) diff --git a/backend/internal/api/handler/health.go b/backend/internal/api/handler/health.go index 82040144..6f0ac313 100644 --- a/backend/internal/api/handler/health.go +++ b/backend/internal/api/handler/health.go @@ -2,6 +2,7 @@ package handler import ( "net/http" + "npm/internal/acme" h "npm/internal/api/http" "npm/internal/config" diff --git a/backend/internal/api/handler/helpers.go b/backend/internal/api/handler/helpers.go index e4a36253..f04b4225 100644 --- a/backend/internal/api/handler/helpers.go +++ b/backend/internal/api/handler/helpers.go @@ -56,7 +56,7 @@ func getQueryVarInt(r *http.Request, varName string, required bool, defaultValue } func getURLParamInt(r *http.Request, varName string) (uint, error) { - var defaultValue uint = 0 + var defaultValue uint required := true paramStr := chi.URLParam(r, varName) diff --git a/backend/internal/api/handler/helpers_test.go b/backend/internal/api/handler/helpers_test.go index e0f93f68..c8c1fd6c 100644 --- a/backend/internal/api/handler/helpers_test.go +++ b/backend/internal/api/handler/helpers_test.go @@ -3,9 +3,10 @@ package handler import ( "net/http" "net/http/httptest" - "npm/internal/model" "testing" + "npm/internal/model" + "github.com/stretchr/testify/assert" ) diff --git a/backend/internal/api/handler/hosts.go b/backend/internal/api/handler/hosts.go index 19b95a5a..c902b57d 100644 --- a/backend/internal/api/handler/hosts.go +++ b/backend/internal/api/handler/hosts.go @@ -192,7 +192,7 @@ func GetHostNginxConfig(format string) func(http.ResponseWriter, *http.Request) return } if format == "text" { - h.ResultResponseText(w, r, http.StatusOK, content) + h.ResultResponseText(w, http.StatusOK, content) return } h.ResultResponseJSON(w, r, http.StatusOK, content) @@ -202,11 +202,11 @@ func GetHostNginxConfig(format string) func(http.ResponseWriter, *http.Request) } } -func configureHost(h host.Model) { +func configureHost(hst host.Model) { err := jobqueue.AddJob(jobqueue.Job{ Name: "NginxConfigureHost", Action: func() error { - return nginx.ConfigureHost(h) + return nginx.ConfigureHost(hst) }, }) if err != nil { diff --git a/backend/internal/api/handler/schema.go b/backend/internal/api/handler/schema.go index 2ae795fd..d7a3f0cf 100644 --- a/backend/internal/api/handler/schema.go +++ b/backend/internal/api/handler/schema.go @@ -12,7 +12,7 @@ import ( "npm/internal/config" "npm/internal/logger" - jsref "github.com/jc21/jsref" + "github.com/jc21/jsref" "github.com/jc21/jsref/provider" ) @@ -24,7 +24,7 @@ var ( // Schema simply reads the swagger schema from disk and returns is raw // Route: GET /schema func Schema() func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(getSchema())) @@ -42,8 +42,8 @@ func getSchema() []byte { swaggerSchema = []byte(strings.ReplaceAll(string(swaggerSchema), "{{VERSION}}", config.Version)) // Dereference the JSON Schema: - var schema interface{} - if err := json.Unmarshal(swaggerSchema, &schema); err != nil { + var sch any + if err := json.Unmarshal(swaggerSchema, &sch); err != nil { logger.Error("SwaggerUnmarshalError", err) return nil } @@ -55,7 +55,7 @@ func getSchema() []byte { logger.Error("SchemaProviderError", err) } - result, err := resolver.Resolve(schema, "", []jsref.Option{jsref.WithRecursiveResolution(true)}...) + result, err := resolver.Resolve(sch, "", []jsref.Option{jsref.WithRecursiveResolution(true)}...) if err != nil { logger.Error("SwaggerResolveError", err) } else { diff --git a/backend/internal/api/handler/upstreams.go b/backend/internal/api/handler/upstreams.go index 41b7b59f..4b1a4e78 100644 --- a/backend/internal/api/handler/upstreams.go +++ b/backend/internal/api/handler/upstreams.go @@ -95,7 +95,7 @@ func CreateUpstream() func(http.ResponseWriter, *http.Request) { } } -// UpdateHost updates a host +// UpdateUpstream updates a stream // Route: PUT /upstreams/{upstreamID} func UpdateUpstream() func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { @@ -167,7 +167,7 @@ func DeleteUpstream() func(http.ResponseWriter, *http.Request) { } } -// GetHostNginxConfig will return a Host's nginx config from disk +// GetUpstreamNginxConfig will return a Host's nginx config from disk // Route: GET /upstreams/{upstreamID}/nginx-config // Route: GET /upstreams/{upstreamID}/nginx-config.txt func GetUpstreamNginxConfig(format string) func(http.ResponseWriter, *http.Request) { @@ -191,7 +191,7 @@ func GetUpstreamNginxConfig(format string) func(http.ResponseWriter, *http.Reque return } if format == "text" { - h.ResultResponseText(w, r, http.StatusOK, content) + h.ResultResponseText(w, http.StatusOK, content) return } h.ResultResponseJSON(w, r, http.StatusOK, content) diff --git a/backend/internal/api/http/responses.go b/backend/internal/api/http/responses.go index 1bf42124..f0aa25c3 100644 --- a/backend/internal/api/http/responses.go +++ b/backend/internal/api/http/responses.go @@ -21,19 +21,19 @@ var ( // Response interface for standard API results type Response struct { - Result interface{} `json:"result"` - Error interface{} `json:"error,omitempty"` + Result any `json:"result"` + Error any `json:"error,omitempty"` } // ErrorResponse interface for errors returned via the API type ErrorResponse struct { - Code interface{} `json:"code"` - Message interface{} `json:"message"` - Invalid interface{} `json:"invalid,omitempty"` + Code any `json:"code"` + Message any `json:"message"` + Invalid any `json:"invalid,omitempty"` } // ResultResponseJSON will write the result as json to the http output -func ResultResponseJSON(w http.ResponseWriter, r *http.Request, status int, result interface{}) { +func ResultResponseJSON(w http.ResponseWriter, r *http.Request, status int, result any) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(status) @@ -77,7 +77,7 @@ func ResultSchemaErrorJSON(w http.ResponseWriter, r *http.Request, errs []jsonsc } // ResultErrorJSON will format the result as a standard error object and send it for output -func ResultErrorJSON(w http.ResponseWriter, r *http.Request, status int, message string, extended interface{}) { +func ResultErrorJSON(w http.ResponseWriter, r *http.Request, status int, message string, extended any) { errorResponse := ErrorResponse{ Code: status, Message: message, @@ -98,7 +98,7 @@ func NotFound(w http.ResponseWriter, r *http.Request) { } // ResultResponseText will write the result as text to the http output -func ResultResponseText(w http.ResponseWriter, r *http.Request, status int, content string) { +func ResultResponseText(w http.ResponseWriter, status int, content string) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(status) fmt.Fprint(w, content) diff --git a/backend/internal/api/http/responses_test.go b/backend/internal/api/http/responses_test.go index f59f20f6..afcaa4ff 100644 --- a/backend/internal/api/http/responses_test.go +++ b/backend/internal/api/http/responses_test.go @@ -21,7 +21,7 @@ func TestResultResponseJSON(t *testing.T) { tests := []struct { name string status int - given interface{} + given any want string }{ { @@ -34,9 +34,9 @@ func TestResultResponseJSON(t *testing.T) { name: "detailed response", status: http.StatusBadRequest, given: user.Model{ - ModelBase: model.ModelBase{ID: 10}, - Email: "me@example.com", - Name: "John Doe", + Base: model.Base{ID: 10}, + Email: "me@example.com", + Name: "John Doe", }, want: "{\"result\":{\"id\":10,\"created_at\":0,\"updated_at\":0,\"name\":\"John Doe\",\"email\":\"me@example.com\",\"is_disabled\":false,\"gravatar_url\":\"\"}}", }, @@ -118,7 +118,7 @@ func TestResultErrorJSON(t *testing.T) { name string status int message string - extended interface{} + extended any want string }{ { @@ -180,9 +180,8 @@ func TestResultResponseText(t *testing.T) { defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) t.Run("basic test", func(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/anything", nil) w := httptest.NewRecorder() - ResultResponseText(w, r, http.StatusOK, "omg this works") + ResultResponseText(w, http.StatusOK, "omg this works") res := w.Result() defer res.Body.Close() body, err := io.ReadAll(res.Body) diff --git a/backend/internal/api/middleware/access_control_test.go b/backend/internal/api/middleware/access_control_test.go index 3a84f8e2..6f9b0993 100644 --- a/backend/internal/api/middleware/access_control_test.go +++ b/backend/internal/api/middleware/access_control_test.go @@ -15,7 +15,7 @@ func TestAccessControl(t *testing.T) { // goleak is used to detect goroutine leaks defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }) diff --git a/backend/internal/api/middleware/auth_cache.go b/backend/internal/api/middleware/auth_cache.go index 66becfe7..e0ba5a1e 100644 --- a/backend/internal/api/middleware/auth_cache.go +++ b/backend/internal/api/middleware/auth_cache.go @@ -18,6 +18,6 @@ func AuthCacheInit() { } // AuthCacheSet will store the item in memory for the expiration time -func AuthCacheSet(k string, x interface{}) { +func AuthCacheSet(k string, x any) { AuthCache.Set(k, x, cache.DefaultExpiration) } diff --git a/backend/internal/api/middleware/body_context_test.go b/backend/internal/api/middleware/body_context_test.go index da0ad70e..603b0a56 100644 --- a/backend/internal/api/middleware/body_context_test.go +++ b/backend/internal/api/middleware/body_context_test.go @@ -26,7 +26,7 @@ func TestBodyContext(t *testing.T) { rr := httptest.NewRecorder() // Create a test handler that checks the context for the body data - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { bodyData := r.Context().Value(c.BodyCtxKey).([]byte) assert.Equal(t, body, bodyData) }) diff --git a/backend/internal/api/middleware/cors_test.go b/backend/internal/api/middleware/cors_test.go index ffa1802c..da51638c 100644 --- a/backend/internal/api/middleware/cors_test.go +++ b/backend/internal/api/middleware/cors_test.go @@ -15,7 +15,7 @@ func TestCors(t *testing.T) { r := chi.NewRouter() r.Use(middleware.Cors(r)) - r.Get("/test", func(w http.ResponseWriter, r *http.Request) { + r.Get("/test", func(w http.ResponseWriter, _ *http.Request) { w.Write([]byte("test")) }) @@ -48,7 +48,7 @@ func TestOptions(t *testing.T) { r := chi.NewRouter() r.Use(middleware.Options(r)) - r.Get("/test", func(w http.ResponseWriter, r *http.Request) { + r.Get("/test", func(w http.ResponseWriter, _ *http.Request) { w.Write([]byte("test")) }) diff --git a/backend/internal/api/middleware/enforce_setup_test.go b/backend/internal/api/middleware/enforce_setup_test.go index 38ec7560..dba7cf1f 100644 --- a/backend/internal/api/middleware/enforce_setup_test.go +++ b/backend/internal/api/middleware/enforce_setup_test.go @@ -5,11 +5,11 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" - "go.uber.org/goleak" - "npm/internal/api/middleware" "npm/internal/config" + + "github.com/stretchr/testify/assert" + "go.uber.org/goleak" ) func TestEnforceSetup(t *testing.T) { @@ -37,7 +37,7 @@ func TestEnforceSetup(t *testing.T) { t.Run(tt.name, func(t *testing.T) { config.IsSetup = tt.isSetup - handler := middleware.EnforceSetup()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := middleware.EnforceSetup()(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) diff --git a/backend/internal/api/middleware/expansion_test.go b/backend/internal/api/middleware/expansion_test.go index 4d4b324c..47904d5c 100644 --- a/backend/internal/api/middleware/expansion_test.go +++ b/backend/internal/api/middleware/expansion_test.go @@ -23,7 +23,7 @@ func TestExpansion(t *testing.T) { rr := httptest.NewRecorder() - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { expand := middleware.GetExpandFromContext(r) assert.Equal(t, []string{"item1", "item2"}, expand) }) @@ -39,7 +39,7 @@ func TestExpansion(t *testing.T) { rr := httptest.NewRecorder() - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { expand := middleware.GetExpandFromContext(r) assert.Nil(t, expand) }) diff --git a/backend/internal/api/middleware/list_query.go b/backend/internal/api/middleware/list_query.go index b597f588..9660f70b 100644 --- a/backend/internal/api/middleware/list_query.go +++ b/backend/internal/api/middleware/list_query.go @@ -21,7 +21,7 @@ import ( // and the sort parameter is valid as well. // After we have determined what the Filters are to be, they are saved on the Context // to be used later in other endpoints. -func ListQuery(obj interface{}) func(http.Handler) http.Handler { +func ListQuery(obj any) func(http.Handler) http.Handler { schemaData := tags.GetFilterSchema(obj) filterMap := tags.GetFilterMap(obj, "") @@ -29,13 +29,13 @@ func ListQuery(obj interface{}) func(http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx, statusCode, errMsg, errors := listQueryFilters(r, ctx, schemaData) + ctx, statusCode, errMsg, errors := listQueryFilters(ctx, r, schemaData) if statusCode > 0 { h.ResultErrorJSON(w, r, statusCode, errMsg, errors) return } - ctx, statusCode, errMsg = listQuerySort(r, filterMap, ctx) + ctx, statusCode, errMsg = listQuerySort(ctx, r, filterMap) if statusCode > 0 { h.ResultErrorJSON(w, r, statusCode, errMsg, nil) return @@ -47,9 +47,9 @@ func ListQuery(obj interface{}) func(http.Handler) http.Handler { } func listQuerySort( + ctx context.Context, r *http.Request, filterMap map[string]model.FilterMapValue, - ctx context.Context, ) (context.Context, int, string) { var sortFields []model.Sort @@ -99,10 +99,10 @@ func listQuerySort( } func listQueryFilters( - r *http.Request, ctx context.Context, + r *http.Request, schemaData string, -) (context.Context, int, string, interface{}) { +) (context.Context, int, string, any) { reservedFilterKeys := []string{ "limit", "offset", diff --git a/backend/internal/api/middleware/list_query_test.go b/backend/internal/api/middleware/list_query_test.go index d05c4483..3563c1fe 100644 --- a/backend/internal/api/middleware/list_query_test.go +++ b/backend/internal/api/middleware/list_query_test.go @@ -53,7 +53,7 @@ func TestListQuery(t *testing.T) { ctx = context.WithValue(ctx, c.FiltersCtxKey, tags.GetFilterSchema(testObj)) rr := httptest.NewRecorder() - handler := middleware.ListQuery(testObj)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := middleware.ListQuery(testObj)(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) diff --git a/backend/internal/api/middleware/schema.go b/backend/internal/api/middleware/schema.go index a0352dc7..8f09e580 100644 --- a/backend/internal/api/middleware/schema.go +++ b/backend/internal/api/middleware/schema.go @@ -33,7 +33,6 @@ func CheckRequestSchema(ctx context.Context, schemaData string, payload []byte) func EnforceRequestSchema(schemaData string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Get content from context bodyBytes, _ := r.Context().Value(c.BodyCtxKey).([]byte) diff --git a/backend/internal/api/router.go b/backend/internal/api/router.go index 570dd9be..8928d59d 100644 --- a/backend/internal/api/router.go +++ b/backend/internal/api/router.go @@ -29,7 +29,7 @@ import ( // NewRouter returns a new router object func NewRouter() http.Handler { // Cors - cors := cors.New(cors.Options{ + corss := cors.New(cors.Options{ AllowedOrigins: []string{"*"}, AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-Requested-With"}, @@ -42,7 +42,7 @@ func NewRouter() http.Handler { middleware.AccessControl, middleware.Cors(r), middleware.Options(r), - cors.Handler, + corss.Handler, chiMiddleware.RealIP, chiMiddleware.Recoverer, chiMiddleware.Throttle(5), diff --git a/backend/internal/api/schema/create_dns_provider.go b/backend/internal/api/schema/create_dns_provider.go index fea8f80d..d51f2dcc 100644 --- a/backend/internal/api/schema/create_dns_provider.go +++ b/backend/internal/api/schema/create_dns_provider.go @@ -18,7 +18,7 @@ func CreateDNSProvider() string { allSchemasWrapped := make([]string, 0) for providerName, provider := range allProviders { - schema, err := provider.GetJsonSchema() + schema, err := provider.GetJSONSchema() if err != nil { logger.Error("ProviderSchemaError", eris.Wrapf(err, "Invalid Provider Schema for %s: %v", provider.Title, err)) } else { diff --git a/backend/internal/api/schema/schema_test.go b/backend/internal/api/schema/schema_test.go index 67bd93f8..4b69b390 100644 --- a/backend/internal/api/schema/schema_test.go +++ b/backend/internal/api/schema/schema_test.go @@ -3,9 +3,10 @@ package schema import ( "bytes" "encoding/json" - "npm/internal/entity/certificate" "testing" + "npm/internal/entity/certificate" + "github.com/stretchr/testify/assert" ) diff --git a/backend/internal/api/schema/update_nginx_template.go b/backend/internal/api/schema/update_nginx_template.go index 4ba59cd9..8f8e1459 100644 --- a/backend/internal/api/schema/update_nginx_template.go +++ b/backend/internal/api/schema/update_nginx_template.go @@ -1,6 +1,6 @@ package schema -// UpdateHostTemplate is the schema for incoming data validation +// UpdateNginxTemplate is the schema for incoming data validation func UpdateNginxTemplate() string { return ` { diff --git a/backend/internal/config/args.go b/backend/internal/config/args.go index 6bade68d..dffb3131 100644 --- a/backend/internal/config/args.go +++ b/backend/internal/config/args.go @@ -23,6 +23,7 @@ func InitArgs(version, commit *string) { if appArguments.Version { fmt.Printf("v%s (%s)\n", *version, *commit) + // nolint: revive os.Exit(0) } } diff --git a/backend/internal/config/vars.go b/backend/internal/config/vars.go index d95fdd33..8d243ecb 100644 --- a/backend/internal/config/vars.go +++ b/backend/internal/config/vars.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "npm/internal/logger" ) diff --git a/backend/internal/database/db.go b/backend/internal/database/db.go index f613051b..7f4d429a 100644 --- a/backend/internal/database/db.go +++ b/backend/internal/database/db.go @@ -46,8 +46,8 @@ func SetDB(db *gorm.DB) { func connect() (*gorm.DB, error) { var d gorm.Dialector dsn := config.Configuration.DB.GetGormConnectURL() - switch strings.ToLower(config.Configuration.DB.Driver) { + switch strings.ToLower(config.Configuration.DB.Driver) { case config.DatabaseSqlite: // autocreate(dsn) d = sqlite.Open(dsn) diff --git a/backend/internal/database/helpers.go b/backend/internal/database/helpers.go index c07ad217..c34208bd 100644 --- a/backend/internal/database/helpers.go +++ b/backend/internal/database/helpers.go @@ -2,8 +2,9 @@ package database import ( "fmt" - "npm/internal/config" "strings" + + "npm/internal/config" ) const ( diff --git a/backend/internal/database/migrator.go b/backend/internal/database/migrator.go index 0622d187..5d5555be 100644 --- a/backend/internal/database/migrator.go +++ b/backend/internal/database/migrator.go @@ -9,6 +9,8 @@ import ( "npm/internal/logger" "github.com/amacneil/dbmate/v2/pkg/dbmate" + + // Drivers: _ "github.com/amacneil/dbmate/v2/pkg/driver/mysql" _ "github.com/amacneil/dbmate/v2/pkg/driver/postgres" _ "github.com/amacneil/dbmate/v2/pkg/driver/sqlite" diff --git a/backend/internal/dnsproviders/common.go b/backend/internal/dnsproviders/common.go index b552ff87..fef52e16 100644 --- a/backend/internal/dnsproviders/common.go +++ b/backend/internal/dnsproviders/common.go @@ -2,6 +2,7 @@ package dnsproviders import ( "encoding/json" + "npm/internal/errors" ) @@ -31,8 +32,8 @@ type Provider struct { Properties map[string]providerField `json:"properties"` } -// GetJsonSchema encodes this object as JSON string -func (p *Provider) GetJsonSchema() (string, error) { +// GetJSONSchema encodes this object as JSON string +func (p *Provider) GetJSONSchema() (string, error) { b, err := json.Marshal(p) return string(b), err } diff --git a/backend/internal/dnsproviders/dns_acmedns_test.go b/backend/internal/dnsproviders/dns_acmedns_test.go index 8e60c05a..6c5f25db 100644 --- a/backend/internal/dnsproviders/dns_acmedns_test.go +++ b/backend/internal/dnsproviders/dns_acmedns_test.go @@ -1,9 +1,10 @@ package dnsproviders import ( - "npm/internal/util" "testing" + "npm/internal/util" + "github.com/stretchr/testify/assert" "go.uber.org/goleak" ) @@ -13,7 +14,7 @@ func TestAcmeDNSProvider(t *testing.T) { defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) provider := getDNSAcmeDNS() - json, err := provider.GetJsonSchema() + json, err := provider.GetJSONSchema() assert.Nil(t, err) assert.Equal(t, `{ "title": "dns_acmedns", diff --git a/backend/internal/dnsproviders/dns_ad_test.go b/backend/internal/dnsproviders/dns_ad_test.go index 4034a4ca..4bf3b471 100644 --- a/backend/internal/dnsproviders/dns_ad_test.go +++ b/backend/internal/dnsproviders/dns_ad_test.go @@ -1,9 +1,10 @@ package dnsproviders import ( - "npm/internal/util" "testing" + "npm/internal/util" + "github.com/stretchr/testify/assert" "go.uber.org/goleak" ) @@ -14,7 +15,7 @@ func TestAdProvider(t *testing.T) { provider := getDNSAd() provider.ConvertToUpdatable() - json, err := provider.GetJsonSchema() + json, err := provider.GetJSONSchema() assert.Nil(t, err) assert.Equal(t, `{ "title": "dns_ad", diff --git a/backend/internal/dnsproviders/dns_ali_test.go b/backend/internal/dnsproviders/dns_ali_test.go index e09a2616..85783739 100644 --- a/backend/internal/dnsproviders/dns_ali_test.go +++ b/backend/internal/dnsproviders/dns_ali_test.go @@ -1,9 +1,10 @@ package dnsproviders import ( - "npm/internal/util" "testing" + "npm/internal/util" + "github.com/stretchr/testify/assert" "go.uber.org/goleak" ) @@ -13,7 +14,7 @@ func TestAliProvider(t *testing.T) { defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) provider := getDNSAli() - json, err := provider.GetJsonSchema() + json, err := provider.GetJSONSchema() assert.Nil(t, err) assert.Equal(t, `{ "title": "dns_ali", diff --git a/backend/internal/entity/accesslist/model.go b/backend/internal/entity/accesslist/model.go index 5b55b36b..64e0a058 100644 --- a/backend/internal/entity/accesslist/model.go +++ b/backend/internal/entity/accesslist/model.go @@ -11,7 +11,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Name string `json:"name" gorm:"column:name" filter:"name,string"` Meta types.JSONB `json:"meta" gorm:"column:meta"` diff --git a/backend/internal/entity/auth/entity_test.go b/backend/internal/entity/auth/entity_test.go index 8cf612a1..b4b6f8d4 100644 --- a/backend/internal/entity/auth/entity_test.go +++ b/backend/internal/entity/auth/entity_test.go @@ -139,13 +139,11 @@ func (s *testsuite) TestSave() { func (s *testsuite) TestSetPassword() { // goleak is used to detect goroutine leaks defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) - m := Model{UserID: 100} err := m.SetPassword("abc123") require.NoError(s.T(), err) assert.Equal(s.T(), TypeLocal, m.Type) assert.Greater(s.T(), len(m.Secret), 15) - } func (s *testsuite) TestValidateSecret() { diff --git a/backend/internal/entity/auth/methods.go b/backend/internal/entity/auth/methods.go index 37afd0d9..8cce3f33 100644 --- a/backend/internal/entity/auth/methods.go +++ b/backend/internal/entity/auth/methods.go @@ -22,7 +22,7 @@ func GetByUserIDType(userID uint, authType string) (Model, error) { return auth, result.Error } -// GetByUserIDType finds a user by id and type +// GetByIdenityType finds a user by identity and type func GetByIdenityType(identity string, authType string) (Model, error) { var auth Model db := database.GetDB() diff --git a/backend/internal/entity/auth/model.go b/backend/internal/entity/auth/model.go index bab6082b..38a55627 100644 --- a/backend/internal/entity/auth/model.go +++ b/backend/internal/entity/auth/model.go @@ -17,7 +17,7 @@ const ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id"` Type string `json:"type" gorm:"column:type;default:local"` Identity string `json:"identity,omitempty" gorm:"column:identity"` diff --git a/backend/internal/entity/auth/oauth.go b/backend/internal/entity/auth/oauth.go index 0866a732..438eb87e 100644 --- a/backend/internal/entity/auth/oauth.go +++ b/backend/internal/entity/auth/oauth.go @@ -32,9 +32,9 @@ func OAuthCacheInit() { // OAuthUser is the OAuth User type OAuthUser struct { - Identifier string `json:"identifier"` - Token string `json:"token"` - Resource map[string]interface{} `json:"resource"` + Identifier string `json:"identifier"` + Token string `json:"token"` + Resource map[string]any `json:"resource"` } // GetResourceField will attempt to get a field from the resource diff --git a/backend/internal/entity/auth/oauth_test.go b/backend/internal/entity/auth/oauth_test.go index 6b9729c0..46efaea8 100644 --- a/backend/internal/entity/auth/oauth_test.go +++ b/backend/internal/entity/auth/oauth_test.go @@ -105,7 +105,7 @@ func TestGetEmail(t *testing.T) { { name: "Email in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "email": "user@example.com", }, }, @@ -128,7 +128,7 @@ func TestGetEmail(t *testing.T) { { name: "No email or identifier", oauthUser: OAuthUser{ - Resource: map[string]interface{}{}, + Resource: map[string]any{}, }, expected: "", }, @@ -151,7 +151,7 @@ func TestGetName(t *testing.T) { { name: "Nickname in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "nickname": "user_nick", }, }, @@ -160,7 +160,7 @@ func TestGetName(t *testing.T) { { name: "Given name in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "given_name": "User Given", }, }, @@ -169,7 +169,7 @@ func TestGetName(t *testing.T) { { name: "Name in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "name": "User Name", }, }, @@ -178,7 +178,7 @@ func TestGetName(t *testing.T) { { name: "Preferred username in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "preferred_username": "preferred_user", }, }, @@ -187,7 +187,7 @@ func TestGetName(t *testing.T) { { name: "Username in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "username": "user123", }, }, @@ -197,14 +197,14 @@ func TestGetName(t *testing.T) { name: "No name fields in resource, fallback to identifier", oauthUser: OAuthUser{ Identifier: "fallback_identifier", - Resource: map[string]interface{}{}, + Resource: map[string]any{}, }, expected: "fallback_identifier", }, { name: "No name fields and no identifier", oauthUser: OAuthUser{ - Resource: map[string]interface{}{}, + Resource: map[string]any{}, }, expected: "", }, @@ -212,7 +212,7 @@ func TestGetName(t *testing.T) { name: "All fields", oauthUser: OAuthUser{ Identifier: "fallback_identifier", - Resource: map[string]interface{}{ + Resource: map[string]any{ "nickname": "user_nick", "given_name": "User Given", "name": "User Name", @@ -248,7 +248,7 @@ func TestGetID(t *testing.T) { { name: "UID in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "uid": "uid123", }, }, @@ -257,7 +257,7 @@ func TestGetID(t *testing.T) { { name: "User ID in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "user_id": "user_id123", }, }, @@ -266,7 +266,7 @@ func TestGetID(t *testing.T) { { name: "Username in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "username": "username123", }, }, @@ -275,7 +275,7 @@ func TestGetID(t *testing.T) { { name: "Preferred username in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "preferred_username": "preferred_user", }, }, @@ -284,7 +284,7 @@ func TestGetID(t *testing.T) { { name: "Email in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "email": "user@example.com", }, }, @@ -293,7 +293,7 @@ func TestGetID(t *testing.T) { { name: "Mail in resource", oauthUser: OAuthUser{ - Resource: map[string]interface{}{ + Resource: map[string]any{ "mail": "mail@example.com", }, }, @@ -302,7 +302,7 @@ func TestGetID(t *testing.T) { { name: "No identifier or resource fields", oauthUser: OAuthUser{ - Resource: map[string]interface{}{}, + Resource: map[string]any{}, }, expected: "", }, @@ -310,7 +310,7 @@ func TestGetID(t *testing.T) { name: "All fields", oauthUser: OAuthUser{ Identifier: "user123", - Resource: map[string]interface{}{ + Resource: map[string]any{ "uid": "uid123", "user_id": "user_id123", "username": "username123", diff --git a/backend/internal/entity/certificate/model.go b/backend/internal/entity/certificate/model.go index df37911f..589814fa 100644 --- a/backend/internal/entity/certificate/model.go +++ b/backend/internal/entity/certificate/model.go @@ -44,7 +44,7 @@ const ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Type string `json:"type" gorm:"column:type" filter:"type,string"` CertificateAuthorityID types.NullableDBUint `json:"certificate_authority_id" gorm:"column:certificate_authority_id" filter:"certificate_authority_id,integer"` diff --git a/backend/internal/entity/certificateauthority/entity_test.go b/backend/internal/entity/certificateauthority/entity_test.go index c13dc356..3aa52f03 100644 --- a/backend/internal/entity/certificateauthority/entity_test.go +++ b/backend/internal/entity/certificateauthority/entity_test.go @@ -210,7 +210,7 @@ func (s *testsuite) TestDelete() { assert.Equal(s.T(), "Unable to delete a new object", err.Error()) m2 := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, } diff --git a/backend/internal/entity/certificateauthority/model.go b/backend/internal/entity/certificateauthority/model.go index a1a88f01..a370a59a 100644 --- a/backend/internal/entity/certificateauthority/model.go +++ b/backend/internal/entity/certificateauthority/model.go @@ -13,7 +13,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base Name string `json:"name" gorm:"column:name" filter:"name,string"` AcmeshServer string `json:"acmesh_server" gorm:"column:acmesh_server" filter:"acmesh_server,string"` CABundle string `json:"ca_bundle" gorm:"column:ca_bundle" filter:"ca_bundle,string"` diff --git a/backend/internal/entity/dnsprovider/entity_test.go b/backend/internal/entity/dnsprovider/entity_test.go index f1ab0f11..40c34eab 100644 --- a/backend/internal/entity/dnsprovider/entity_test.go +++ b/backend/internal/entity/dnsprovider/entity_test.go @@ -296,7 +296,7 @@ func (s *testsuite) TestDelete() { assert.Equal(s.T(), "Unable to delete a new object", err.Error()) m2 := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, } diff --git a/backend/internal/entity/dnsprovider/model.go b/backend/internal/entity/dnsprovider/model.go index 945fc6da..e128922b 100644 --- a/backend/internal/entity/dnsprovider/model.go +++ b/backend/internal/entity/dnsprovider/model.go @@ -14,7 +14,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Name string `json:"name" gorm:"column:name" filter:"name,string"` AcmeshName string `json:"acmesh_name" gorm:"column:acmesh_name" filter:"acmesh_name,string"` @@ -70,8 +70,8 @@ func (m *Model) GetAcmeShEnvVars() ([]string, error) { return envs, nil } -func getEnvsFromMeta(meta interface{}) []string { - if rec, ok := meta.(map[string]interface{}); ok { +func getEnvsFromMeta(meta any) []string { + if rec, ok := meta.(map[string]any); ok { envs := make([]string, 0) for key, val := range rec { if f, ok := val.(string); ok { @@ -81,8 +81,8 @@ func getEnvsFromMeta(meta interface{}) []string { } } return envs - } else { - logger.Debug("getEnvsFromMeta: meta is not an map of strings") - return nil } + + logger.Debug("getEnvsFromMeta: meta is not an map of strings") + return nil } diff --git a/backend/internal/entity/filters.go b/backend/internal/entity/filters.go index 16617660..906a25e5 100644 --- a/backend/internal/entity/filters.go +++ b/backend/internal/entity/filters.go @@ -6,12 +6,13 @@ import ( ) // GetFilterMap returns the filter map -func GetFilterMap(m interface{}, includeBaseEntity bool) map[string]model.FilterMapValue { +// _ was called `includeBaseEntity` +func GetFilterMap(m any, _ bool) map[string]model.FilterMapValue { filterMap := tags.GetFilterMap(m, "") // TODO: this is done in GetFilterMap isn't it? // if includeBaseEntity { - // return mergeFilterMaps(tags.GetFilterMap(model.ModelBase{}, ""), filterMap) + // return mergeFilterMaps(tags.GetFilterMap(model.Base{}, ""), filterMap) // } return filterMap diff --git a/backend/internal/entity/host/entity_test.go b/backend/internal/entity/host/entity_test.go index 20229a87..031ec860 100644 --- a/backend/internal/entity/host/entity_test.go +++ b/backend/internal/entity/host/entity_test.go @@ -189,7 +189,7 @@ func (s *testsuite) TestDelete() { assert.Equal(s.T(), "Unable to delete a new object", err.Error()) m2 := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, } @@ -203,7 +203,7 @@ func (s *testsuite) TestGetTemplate() { defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) m := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, CreatedAt: time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC).UnixMilli(), UpdatedAt: time.Date(2018, 8, 12, 7, 30, 24, 16, time.UTC).UnixMilli(), diff --git a/backend/internal/entity/host/model.go b/backend/internal/entity/host/model.go index c517219f..8907eda2 100644 --- a/backend/internal/entity/host/model.go +++ b/backend/internal/entity/host/model.go @@ -27,7 +27,7 @@ const ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Type string `json:"type" gorm:"column:type" filter:"type,string"` NginxTemplateID uint `json:"nginx_template_id" gorm:"column:nginx_template_id" filter:"nginx_template_id,integer"` diff --git a/backend/internal/entity/lists.go b/backend/internal/entity/lists.go index 0ce5faed..186253b7 100644 --- a/backend/internal/entity/lists.go +++ b/backend/internal/entity/lists.go @@ -14,12 +14,12 @@ type ListResponse struct { Limit int `json:"limit"` Sort []model.Sort `json:"sort"` Filter []model.Filter `json:"filter,omitempty"` - Items interface{} `json:"items,omitempty"` + Items any `json:"items,omitempty"` } // ListQueryBuilder is used to setup queries for lists func ListQueryBuilder( - pageInfo *model.PageInfo, + _ *model.PageInfo, filters []model.Filter, filterMap map[string]model.FilterMapValue, ) *gorm.DB { diff --git a/backend/internal/entity/nginxtemplate/model.go b/backend/internal/entity/nginxtemplate/model.go index 68a215f8..1d04a06a 100644 --- a/backend/internal/entity/nginxtemplate/model.go +++ b/backend/internal/entity/nginxtemplate/model.go @@ -9,7 +9,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Name string `json:"name" gorm:"column:name" filter:"name,string"` Type string `json:"type" gorm:"column:type" filter:"type,string"` diff --git a/backend/internal/entity/scopes.go b/backend/internal/entity/scopes.go index 7406eb4d..4c1922ef 100644 --- a/backend/internal/entity/scopes.go +++ b/backend/internal/entity/scopes.go @@ -10,6 +10,7 @@ import ( "gorm.io/gorm" ) +// ScopeOffsetLimit ... func ScopeOffsetLimit(pageInfo *model.PageInfo) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { if pageInfo.Offset > 0 || pageInfo.Limit > 0 { @@ -19,6 +20,7 @@ func ScopeOffsetLimit(pageInfo *model.PageInfo) func(db *gorm.DB) *gorm.DB { } } +// ScopeOrderBy ... func ScopeOrderBy(sort []model.Sort, defaultSort model.Sort) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { if sort != nil { @@ -36,6 +38,7 @@ func ScopeOrderBy(sort []model.Sort, defaultSort model.Sort) func(db *gorm.DB) * } } +// ScopeFilters ... func ScopeFilters(filters []model.Filter, filterMap map[string]model.FilterMapValue) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { like := database.GetCaseInsensitiveLike() diff --git a/backend/internal/entity/setting/model.go b/backend/internal/entity/setting/model.go index 9f06f6b4..7cf24618 100644 --- a/backend/internal/entity/setting/model.go +++ b/backend/internal/entity/setting/model.go @@ -11,7 +11,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base Name string `json:"name" gorm:"column:name" filter:"name,string"` Description string `json:"description" gorm:"column:description" filter:"description,string"` Value datatypes.JSON `json:"value" gorm:"column:value"` diff --git a/backend/internal/entity/stream/model.go b/backend/internal/entity/stream/model.go index 518ec3e3..206b91ea 100644 --- a/backend/internal/entity/stream/model.go +++ b/backend/internal/entity/stream/model.go @@ -10,7 +10,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base ExpiresOn types.DBDate `json:"expires_on" gorm:"column:expires_on" filter:"expires_on,integer"` UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Provider string `json:"provider" gorm:"column:provider" filter:"provider,string"` diff --git a/backend/internal/entity/upstream/model.go b/backend/internal/entity/upstream/model.go index b9d21a27..c817d272 100644 --- a/backend/internal/entity/upstream/model.go +++ b/backend/internal/entity/upstream/model.go @@ -17,7 +17,7 @@ import ( // Model is the model // See: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream type Model struct { - model.ModelBase + model.Base UserID uint `json:"user_id" gorm:"column:user_id" filter:"user_id,integer"` Name string `json:"name" gorm:"column:name" filter:"name,string"` NginxTemplateID uint `json:"nginx_template_id" gorm:"column:nginx_template_id" filter:"nginx_template_id,integer"` diff --git a/backend/internal/entity/upstreamserver/model.go b/backend/internal/entity/upstreamserver/model.go index 0fe177da..d572bdc7 100644 --- a/backend/internal/entity/upstreamserver/model.go +++ b/backend/internal/entity/upstreamserver/model.go @@ -7,7 +7,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base UpstreamID uint `json:"upstream_id" gorm:"column:upstream_id" filter:"upstream_id,integer"` Server string `json:"server" gorm:"column:server" filter:"server,string"` Weight int `json:"weight" gorm:"column:weight" filter:"weight,integer"` diff --git a/backend/internal/entity/user/entity_test.go b/backend/internal/entity/user/entity_test.go index 7b907997..7045b4d0 100644 --- a/backend/internal/entity/user/entity_test.go +++ b/backend/internal/entity/user/entity_test.go @@ -226,7 +226,7 @@ func (s *testsuite) TestDelete() { assert.Equal(s.T(), "Unable to delete a new object", err.Error()) m2 := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, Name: "John Doe", @@ -442,7 +442,7 @@ func (s *testsuite) TestSaveCapabilitiesInvalid() { // Empty model returns error m := Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, Capabilities: []string{"doesnotexist", "hosts.manage"}, diff --git a/backend/internal/entity/user/methods.go b/backend/internal/entity/user/methods.go index 459b96db..1002d185 100644 --- a/backend/internal/entity/user/methods.go +++ b/backend/internal/entity/user/methods.go @@ -108,7 +108,7 @@ func DeleteAll() error { // GetCapabilities gets capabilities for a user func GetCapabilities(userID uint) ([]string, error) { capabilities := make([]string, 0) - var hasCapabilities []UserHasCapabilityModel + var hasCapabilities []HasCapabilityModel db := database.GetDB() if result := db.Where("user_id = ?", userID).Find(&hasCapabilities); result.Error != nil { return nil, result.Error diff --git a/backend/internal/entity/user/model.go b/backend/internal/entity/user/model.go index 6d71ab6e..cb49457d 100644 --- a/backend/internal/entity/user/model.go +++ b/backend/internal/entity/user/model.go @@ -16,7 +16,7 @@ import ( // Model is the model type Model struct { - model.ModelBase + model.Base Name string `json:"name" gorm:"column:name" filter:"name,string"` Email string `json:"email" gorm:"column:email" filter:"email,email"` IsDisabled bool `json:"is_disabled" gorm:"column:is_disabled" filter:"is_disabled,boolean"` @@ -33,14 +33,14 @@ func (Model) TableName() string { return "user" } -// UserHasCapabilityModel is the model -type UserHasCapabilityModel struct { +// HasCapabilityModel is the model +type HasCapabilityModel struct { UserID uint `json:"user_id" gorm:"column:user_id"` CapabilityName string `json:"name" gorm:"column:capability_name"` } // TableName overrides the table name used by gorm -func (UserHasCapabilityModel) TableName() string { +func (HasCapabilityModel) TableName() string { return "user_has_capability" } @@ -99,15 +99,15 @@ func (m *Model) SetPermissions(permissions []string) error { db := database.GetDB() // Wipe out previous permissions - if result := db.Where("user_id = ?", m.ID).Delete(&UserHasCapabilityModel{}); result.Error != nil { + if result := db.Where("user_id = ?", m.ID).Delete(&HasCapabilityModel{}); result.Error != nil { return result.Error } if len(permissions) > 0 { // Add new permissions - objs := []*UserHasCapabilityModel{} + objs := []*HasCapabilityModel{} for _, permission := range permissions { - objs = append(objs, &UserHasCapabilityModel{UserID: m.ID, CapabilityName: permission}) + objs = append(objs, &HasCapabilityModel{UserID: m.ID, CapabilityName: permission}) } if result := db.Create(objs); result.Error != nil { return result.Error diff --git a/backend/internal/jobqueue/worker.go b/backend/internal/jobqueue/worker.go index c021fbec..f431b82a 100644 --- a/backend/internal/jobqueue/worker.go +++ b/backend/internal/jobqueue/worker.go @@ -2,6 +2,7 @@ package jobqueue import ( "fmt" + "npm/internal/logger" ) diff --git a/backend/internal/jwt/keys_db.go b/backend/internal/jwt/keys_db.go index 7ab2647c..e3ecd55d 100644 --- a/backend/internal/jwt/keys_db.go +++ b/backend/internal/jwt/keys_db.go @@ -9,7 +9,7 @@ var currentKeys KeysModel // KeysModel is the model type KeysModel struct { - model.ModelBase + model.Base PublicKey string `gorm:"column:public_key"` PrivateKey string `gorm:"column:private_key"` } @@ -19,7 +19,7 @@ func (KeysModel) TableName() string { return "jwt_keys" } -// LoadByID will load from an ID +// LoadLatest will load the latest keys func (m *KeysModel) LoadLatest() error { db := database.GetDB() result := db.Order("created_at DESC").First(&m) diff --git a/backend/internal/jwt/suite_test.go b/backend/internal/jwt/suite_test.go index 672d4577..b17f5d67 100644 --- a/backend/internal/jwt/suite_test.go +++ b/backend/internal/jwt/suite_test.go @@ -183,7 +183,7 @@ func (s *testsuite) TestGetPrivateKey() { // Set currentKeys and try again currentKeys = KeysModel{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, PrivateKey: s.privateKeyString, @@ -210,7 +210,7 @@ func (s *testsuite) TestGetPublicKey() { // Set currentKeys and try again currentKeys = KeysModel{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, PrivateKey: s.privateKeyString, @@ -228,7 +228,7 @@ func (s *testsuite) TestGenerate() { defer goleak.VerifyNone(s.T(), goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) currentKeys = KeysModel{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, PrivateKey: s.privateKeyString, @@ -236,7 +236,7 @@ func (s *testsuite) TestGenerate() { } usr := user.Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, } diff --git a/backend/internal/logger/config.go b/backend/internal/logger/config.go index 9e641115..abbfbf7a 100644 --- a/backend/internal/logger/config.go +++ b/backend/internal/logger/config.go @@ -24,11 +24,11 @@ type Config struct { // Interface for a logger type Interface interface { GetLogLevel() Level - Debug(format string, args ...interface{}) - Info(format string, args ...interface{}) - Warn(format string, args ...interface{}) - Error(errorClass string, err error, args ...interface{}) - Errorf(errorClass, format string, err error, args ...interface{}) + Debug(format string, args ...any) + Info(format string, args ...any) + Warn(format string, args ...any) + Error(errorClass string, err error, args ...any) + Errorf(errorClass, format string, err error, args ...any) } // ConfigurableLogger is an interface for a logger that can be configured diff --git a/backend/internal/logger/logger.go b/backend/internal/logger/logger.go index 4ded1810..56be4b71 100644 --- a/backend/internal/logger/logger.go +++ b/backend/internal/logger/logger.go @@ -71,17 +71,17 @@ func GetLogLevel() Level { } // Debug logs if the log level is set to DebugLevel or below. Arguments are handled in the manner of fmt.Printf. -func Debug(format string, args ...interface{}) { +func Debug(format string, args ...any) { logger.Debug(format, args...) } // Info logs if the log level is set to InfoLevel or below. Arguments are handled in the manner of fmt.Printf. -func Info(format string, args ...interface{}) { +func Info(format string, args ...any) { logger.Info(format, args...) } // Warn logs if the log level is set to WarnLevel or below. Arguments are handled in the manner of fmt.Printf. -func Warn(format string, args ...interface{}) { +func Warn(format string, args ...any) { logger.Warn(format, args...) } @@ -134,7 +134,7 @@ var logLevels = map[Level]string{ ErrorLevel: "ERROR", } -func (l *Logger) logLevel(logLevel Level, format string, args ...interface{}) { +func (l *Logger) logLevel(logLevel Level, format string, args ...any) { if logLevel < l.LogThreshold { return } @@ -146,7 +146,7 @@ func (l *Logger) logLevel(logLevel Level, format string, args ...interface{}) { if len(args) > 1 { args = args[1:] } else { - args = []interface{}{} + args = []any{} } } @@ -202,17 +202,17 @@ func (l *Logger) GetLogLevel() Level { } // Debug logs if the log level is set to DebugLevel or below. Arguments are handled in the manner of fmt.Printf. -func (l *Logger) Debug(format string, args ...interface{}) { +func (l *Logger) Debug(format string, args ...any) { l.logLevel(DebugLevel, format, args...) } // Info logs if the log level is set to InfoLevel or below. Arguments are handled in the manner of fmt.Printf. -func (l *Logger) Info(format string, args ...interface{}) { +func (l *Logger) Info(format string, args ...any) { l.logLevel(InfoLevel, format, args...) } // Warn logs if the log level is set to WarnLevel or below. Arguments are handled in the manner of fmt.Printf. -func (l *Logger) Warn(format string, args ...interface{}) { +func (l *Logger) Warn(format string, args ...any) { l.logLevel(WarnLevel, format, args...) } diff --git a/backend/internal/model/model_base.go b/backend/internal/model/model_base.go index f59d5cda..8465f95e 100644 --- a/backend/internal/model/model_base.go +++ b/backend/internal/model/model_base.go @@ -4,8 +4,8 @@ import ( "gorm.io/plugin/soft_delete" ) -// ModelBase include common fields for db control -type ModelBase struct { +// Base include common fields for db control +type Base struct { ID uint `json:"id" gorm:"column:id;primaryKey" filter:"id,integer"` CreatedAt int64 `json:"created_at" gorm:"<-:create;autoCreateTime:milli;column:created_at" filter:"created_at,date"` UpdatedAt int64 `json:"updated_at" gorm:"<-;autoUpdateTime:milli;column:updated_at" filter:"updated_at,date"` diff --git a/backend/internal/nginx/control.go b/backend/internal/nginx/control.go index e2f39dad..91cc948f 100644 --- a/backend/internal/nginx/control.go +++ b/backend/internal/nginx/control.go @@ -151,14 +151,14 @@ func ConfigureUpstream(u upstream.Model) error { return u.Save(true) } -func getHostFilename(h host.Model, append string) string { +func getHostFilename(h host.Model, appends string) string { confDir := fmt.Sprintf("%s/nginx/hosts", config.Configuration.DataFolder) - return fmt.Sprintf("%s/host_%d.conf%s", confDir, h.ID, append) + return fmt.Sprintf("%s/host_%d.conf%s", confDir, h.ID, appends) } -func getUpstreamFilename(u upstream.Model, append string) string { +func getUpstreamFilename(u upstream.Model, appends string) string { confDir := fmt.Sprintf("%s/nginx/upstreams", config.Configuration.DataFolder) - return fmt.Sprintf("%s/upstream_%d.conf%s", confDir, u.ID, append) + return fmt.Sprintf("%s/upstream_%d.conf%s", confDir, u.ID, appends) } func removeHostFiles(h host.Model) { diff --git a/backend/internal/nginx/control_test.go b/backend/internal/nginx/control_test.go index 53072985..dfbd19c6 100644 --- a/backend/internal/nginx/control_test.go +++ b/backend/internal/nginx/control_test.go @@ -1,10 +1,11 @@ package nginx import ( + "testing" + "npm/internal/entity/host" "npm/internal/model" "npm/internal/test" - "testing" "github.com/stretchr/testify/assert" "go.uber.org/goleak" @@ -24,7 +25,7 @@ func TestGetHostFilename(t *testing.T) { { "test1", host.Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, }, @@ -34,7 +35,7 @@ func TestGetHostFilename(t *testing.T) { { "test2", host.Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 10, }, }, diff --git a/backend/internal/nginx/template_test.go b/backend/internal/nginx/template_test.go index b85013fa..f61c6193 100644 --- a/backend/internal/nginx/template_test.go +++ b/backend/internal/nginx/template_test.go @@ -54,7 +54,7 @@ server { IsDisabled: false, }, cert: certificate.Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 77, }, Status: certificate.StatusProvided, @@ -79,7 +79,7 @@ server { IsDisabled: false, }, cert: certificate.Model{ - ModelBase: model.ModelBase{ + Base: model.Base{ ID: 66, }, Status: certificate.StatusProvided, @@ -108,18 +108,18 @@ server { }, } - for _, test := range tests { - t.Run(test.name, func(st *testing.T) { + for _, tst := range tests { + t.Run(tst.name, func(st *testing.T) { templateData := TemplateData{ ConfDir: "/etc/nginx/conf.d", DataDir: "/data", - Host: test.host.GetTemplate(), - Certificate: test.cert.GetTemplate(), + Host: tst.host.GetTemplate(), + Certificate: tst.cert.GetTemplate(), } output, err := renderTemplate(template, templateData) - assert.Equal(t, test.want.err, err) - assert.Equal(t, test.want.output, output) + assert.Equal(st, tst.want.err, err) + assert.Equal(st, tst.want.output, output) }) } } diff --git a/backend/internal/serverevents/sse.go b/backend/internal/serverevents/sse.go index cc18bf61..636e91aa 100644 --- a/backend/internal/serverevents/sse.go +++ b/backend/internal/serverevents/sse.go @@ -26,7 +26,7 @@ func Get() *sse.Server { if instance == nil { instance = sse.NewServer(&sse.Options{ Logger: logger.Get(), - ChannelNameFunc: func(request *http.Request) string { + ChannelNameFunc: func(_ *http.Request) string { return defaultChannel // This is the channel for all updates regardless of visibility }, }) diff --git a/backend/internal/tags/filters.go b/backend/internal/tags/filters.go index d8982e78..bce6319e 100644 --- a/backend/internal/tags/filters.go +++ b/backend/internal/tags/filters.go @@ -14,7 +14,8 @@ import ( "github.com/rotisserie/eris" ) -func GetFilterMap(m interface{}, globalTablePrefix string) map[string]model.FilterMapValue { +// GetFilterMap ... +func GetFilterMap(m any, globalTablePrefix string) map[string]model.FilterMapValue { name := getName(m) filterMap := make(map[string]model.FilterMapValue) @@ -39,8 +40,8 @@ func GetFilterMap(m interface{}, globalTablePrefix string) map[string]model.Filt // If this is an entity model (and it probably is) // then include the base model as well - if strings.Contains(name, ".Model") && !strings.Contains(name, "ModelBase") { - filterMap = GetFilterMap(model.ModelBase{}, globalTablePrefix) + if strings.Contains(name, ".Model") && !strings.Contains(name, "Base") { + filterMap = GetFilterMap(model.Base{}, globalTablePrefix) } if t.Kind() != reflect.Struct { @@ -128,7 +129,7 @@ func getFilterTagSchema(filterTag string) string { // GetFilterSchema creates a jsonschema for validating filters, based on the model // object given and by reading the struct "filter" tags. -func GetFilterSchema(m interface{}) string { +func GetFilterSchema(m any) string { filterMap := GetFilterMap(m, "") schemas := make([]string, 0) diff --git a/backend/internal/tags/reflect.go b/backend/internal/tags/reflect.go index 2f1f8b2a..0dbadbee 100644 --- a/backend/internal/tags/reflect.go +++ b/backend/internal/tags/reflect.go @@ -10,7 +10,7 @@ import ( var tagCache map[string]map[string]model.FilterMapValue // getName returns the name of the type given -func getName(m interface{}) string { +func getName(m any) string { fc := reflect.TypeOf(m) return fmt.Sprint(fc) } diff --git a/backend/internal/test/suite.go b/backend/internal/test/suite.go index ecf9b098..8d9fec23 100644 --- a/backend/internal/test/suite.go +++ b/backend/internal/test/suite.go @@ -12,6 +12,7 @@ import ( "gorm.io/gorm" ) +// Setup ... func Setup() (sqlmock.Sqlmock, error) { db, mock, err := sqlmock.New() if err != nil { @@ -26,6 +27,7 @@ func Setup() (sqlmock.Sqlmock, error) { return mock, err } +// InitConfig ... func InitConfig(t *testing.T, envs ...string) { if len(envs) > 0 { for _, env := range envs { diff --git a/backend/internal/types/db_date.go b/backend/internal/types/db_date.go index 9339868e..27e212df 100644 --- a/backend/internal/types/db_date.go +++ b/backend/internal/types/db_date.go @@ -18,7 +18,7 @@ func (d DBDate) Value() (driver.Value, error) { } // Scan takes data from the database and modifies it for Go Types -func (d *DBDate) Scan(src interface{}) error { +func (d *DBDate) Scan(src any) error { d.Time = time.Unix(src.(int64), 0) return nil } diff --git a/backend/internal/types/db_nullable_int.go b/backend/internal/types/db_nullable_int.go index 4283a07b..0ece3f5d 100644 --- a/backend/internal/types/db_nullable_int.go +++ b/backend/internal/types/db_nullable_int.go @@ -22,7 +22,7 @@ func (d NullableDBInt) Value() (driver.Value, error) { } // Scan takes data from the database and modifies it for Go Types -func (d *NullableDBInt) Scan(src interface{}) error { +func (d *NullableDBInt) Scan(src any) error { var i int switch v := src.(type) { case int: diff --git a/backend/internal/types/db_nullable_uint.go b/backend/internal/types/db_nullable_uint.go index 8ac49ab1..e268621d 100644 --- a/backend/internal/types/db_nullable_uint.go +++ b/backend/internal/types/db_nullable_uint.go @@ -18,16 +18,19 @@ func (d NullableDBUint) Value() (driver.Value, error) { } // According to current database/sql docs, the sql has four builtin functions that // returns driver.Value, and the underlying types are `int64`, `float64`, `string` and `bool` + // nolint: gosec return driver.Value(int64(d.Uint)), nil } // Scan takes data from the database and modifies it for Go Types -func (d *NullableDBUint) Scan(src interface{}) error { +func (d *NullableDBUint) Scan(src any) error { var i uint switch v := src.(type) { case int: + // nolint: gosec i = uint(v) case int64: + // nolint: gosec i = uint(v) case float32: i = uint(v) @@ -35,6 +38,7 @@ func (d *NullableDBUint) Scan(src interface{}) error { i = uint(v) case string: a, _ := strconv.Atoi(v) + // nolint: gosec i = uint(a) } d.Uint = i diff --git a/backend/internal/types/db_nullable_uint_test.go b/backend/internal/types/db_nullable_uint_test.go index 755b111b..129f91a7 100644 --- a/backend/internal/types/db_nullable_uint_test.go +++ b/backend/internal/types/db_nullable_uint_test.go @@ -50,7 +50,7 @@ func TestNullableDBUint_Scan(t *testing.T) { tests := []struct { name string - input interface{} + input any wantUint uint wantErr bool }{ diff --git a/backend/internal/types/jsonb.go b/backend/internal/types/jsonb.go index b3755222..1cd8b3b7 100644 --- a/backend/internal/types/jsonb.go +++ b/backend/internal/types/jsonb.go @@ -9,18 +9,18 @@ import ( // JSONB can be anything type JSONB struct { - Encoded string `json:"decoded"` - Decoded interface{} `json:"encoded"` + Encoded string `json:"decoded"` + Decoded any `json:"encoded"` } // Value encodes the type ready for the database func (j JSONB) Value() (driver.Value, error) { - json, err := json.Marshal(j.Decoded) - return driver.Value(string(json)), err + jsn, err := json.Marshal(j.Decoded) + return driver.Value(string(jsn)), err } // Scan takes data from the database and modifies it for Go Types -func (j *JSONB) Scan(src interface{}) error { +func (j *JSONB) Scan(src any) error { var jsonb JSONB var srcString string switch v := src.(type) { diff --git a/backend/internal/types/jsonb_test.go b/backend/internal/types/jsonb_test.go index c4702ca3..0ec7e55c 100644 --- a/backend/internal/types/jsonb_test.go +++ b/backend/internal/types/jsonb_test.go @@ -8,7 +8,7 @@ import ( // TestJSONBValue tests the Value method of the JSONB type func TestJSONBValue(t *testing.T) { j := JSONB{ - Decoded: map[string]interface{}{ + Decoded: map[string]any{ "name": "John", "age": 30, }, @@ -35,7 +35,7 @@ func TestJSONBScan(t *testing.T) { t.Errorf("Unexpected error: %v", err) } - expectedDecoded := map[string]interface{}{ + expectedDecoded := map[string]any{ "name": "John", "age": 30, } @@ -59,7 +59,7 @@ func TestJSONBUnmarshalJSON(t *testing.T) { t.Errorf("Unexpected error: %v", err) } - expectedDecoded := map[string]interface{}{ + expectedDecoded := map[string]any{ "name": "John", "age": 30, } @@ -76,7 +76,7 @@ func TestJSONBUnmarshalJSON(t *testing.T) { // TestJSONBMarshalJSON tests the MarshalJSON method of the JSONB type func TestJSONBMarshalJSON(t *testing.T) { j := JSONB{ - Decoded: map[string]interface{}{ + Decoded: map[string]any{ "name": "John", "age": 30, }, @@ -113,7 +113,7 @@ func TestJSONBAsStringArray(t *testing.T) { } // Helper function to compare JSON objects -func jsonEqual(a, b interface{}) bool { +func jsonEqual(a, b any) bool { aJSON, _ := json.Marshal(a) bJSON, _ := json.Marshal(b) return string(aJSON) == string(bJSON) diff --git a/backend/internal/types/nullable_db_date.go b/backend/internal/types/nullable_db_date.go index 528599db..f6532ee9 100644 --- a/backend/internal/types/nullable_db_date.go +++ b/backend/internal/types/nullable_db_date.go @@ -23,7 +23,7 @@ func (d NullableDBDate) Value() (driver.Value, error) { } // Scan takes data from the database and modifies it for Go Types -func (d *NullableDBDate) Scan(src interface{}) error { +func (d *NullableDBDate) Scan(src any) error { var tme time.Time if src != nil { tme = time.Unix(src.(int64), 0) diff --git a/backend/internal/util/interfaces.go b/backend/internal/util/interfaces.go index ebb6ffa3..d647dcb6 100644 --- a/backend/internal/util/interfaces.go +++ b/backend/internal/util/interfaces.go @@ -1,9 +1,9 @@ package util // FindItemInInterface Find key in interface (recursively) and return value as interface -func FindItemInInterface(key string, obj interface{}) (interface{}, bool) { +func FindItemInInterface(key string, obj any) (any, bool) { // if the argument is not a map, ignore it - mobj, ok := obj.(map[string]interface{}) + mobj, ok := obj.(map[string]any) if !ok { return nil, false } @@ -15,14 +15,14 @@ func FindItemInInterface(key string, obj interface{}) (interface{}, bool) { } // if the value is a map, search recursively - if m, ok := v.(map[string]interface{}); ok { + if m, ok := v.(map[string]any); ok { if res, ok := FindItemInInterface(key, m); ok { return res, true } } // if the value is an array, search recursively // from each element - if va, ok := v.([]interface{}); ok { + if va, ok := v.([]any); ok { for _, a := range va { if res, ok := FindItemInInterface(key, a); ok { return res, true diff --git a/backend/internal/util/interfaces_test.go b/backend/internal/util/interfaces_test.go index 135edf4a..c2b48023 100644 --- a/backend/internal/util/interfaces_test.go +++ b/backend/internal/util/interfaces_test.go @@ -11,13 +11,13 @@ func TestFindItemInInterface(t *testing.T) { // goleak is used to detect goroutine leaks defer goleak.VerifyNone(t, goleak.IgnoreAnyFunction("database/sql.(*DB).connectionOpener")) - obj := map[string]interface{}{ + obj := map[string]any{ "key1": "value1", "key2": 10, - "key3": map[string]interface{}{ + "key3": map[string]any{ "nestedKey": "nestedValue", }, - "key4": []interface{}{"item1", "item2"}, + "key4": []any{"item1", "item2"}, } // Test case 1: Key exists at the top level diff --git a/backend/internal/util/maps.go b/backend/internal/util/maps.go index 1ff211ec..a2cd2788 100644 --- a/backend/internal/util/maps.go +++ b/backend/internal/util/maps.go @@ -1,7 +1,7 @@ package util // MapContainsKey is fairly self explanatory -func MapContainsKey(dict map[string]interface{}, key string) bool { +func MapContainsKey(dict map[string]any, key string) bool { if _, ok := dict[key]; ok { return true } diff --git a/backend/internal/util/maps_test.go b/backend/internal/util/maps_test.go index e4f6ac7d..0d1bc621 100644 --- a/backend/internal/util/maps_test.go +++ b/backend/internal/util/maps_test.go @@ -19,7 +19,7 @@ func TestMapContainsKey(t *testing.T) { var r rect r.width = 5 r.height = 5 - m := map[string]interface{}{ + m := map[string]any{ "rect_width": r.width, "rect_height": r.height, } diff --git a/backend/internal/util/slices.go b/backend/internal/util/slices.go index 9dfdcb8d..b02cd346 100644 --- a/backend/internal/util/slices.go +++ b/backend/internal/util/slices.go @@ -35,8 +35,8 @@ func ConvertIntSliceToString(slice []int) string { } // ConvertStringSliceToInterface is required in some special cases -func ConvertStringSliceToInterface(slice []string) []interface{} { - res := make([]interface{}, len(slice)) +func ConvertStringSliceToInterface(slice []string) []any { + res := make([]any, len(slice)) for i := range slice { res[i] = slice[i] } diff --git a/backend/internal/util/slices_test.go b/backend/internal/util/slices_test.go index 0653b29c..4afee77f 100644 --- a/backend/internal/util/slices_test.go +++ b/backend/internal/util/slices_test.go @@ -99,11 +99,11 @@ func TestConvertIntSliceToString(t *testing.T) { func TestConvertStringSliceToInterface(t *testing.T) { testCases := []struct { input []string - expected []interface{} + expected []any }{ - {[]string{"hello", "world"}, []interface{}{"hello", "world"}}, - {[]string{"apple", "banana", "cherry"}, []interface{}{"apple", "banana", "cherry"}}, - {[]string{}, []interface{}{}}, // Empty slice should return an empty slice + {[]string{"hello", "world"}, []any{"hello", "world"}}, + {[]string{"apple", "banana", "cherry"}, []any{"apple", "banana", "cherry"}}, + {[]string{}, []any{}}, // Empty slice should return an empty slice } for _, tc := range testCases { diff --git a/backend/internal/validator/upstreams_test.go b/backend/internal/validator/upstreams_test.go index 051828ed..e9b29a93 100644 --- a/backend/internal/validator/upstreams_test.go +++ b/backend/internal/validator/upstreams_test.go @@ -1,10 +1,11 @@ package validator import ( + "testing" + "npm/internal/entity/nginxtemplate" "npm/internal/entity/upstream" "npm/internal/entity/upstreamserver" - "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"