mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	New lint rules
This commit is contained in:
		| @@ -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' | ||||
|   | ||||
| @@ -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" | ||||
| ) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package handler | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	h "npm/internal/api/http" | ||||
| 	"npm/internal/config" | ||||
| ) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package handler | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	"npm/internal/acme" | ||||
| 	h "npm/internal/api/http" | ||||
| 	"npm/internal/config" | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -3,9 +3,10 @@ package handler | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"npm/internal/model" | ||||
| 	"testing" | ||||
|  | ||||
| 	"npm/internal/model" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
| 	}) | ||||
|   | ||||
| @@ -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")) | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| 			})) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| 		}) | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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) | ||||
| 			})) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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), | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -3,9 +3,10 @@ package schema | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"npm/internal/entity/certificate" | ||||
| 	"testing" | ||||
|  | ||||
| 	"npm/internal/entity/certificate" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -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 ` | ||||
| 		{ | ||||
|   | ||||
| @@ -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) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package config | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"npm/internal/logger" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -2,8 +2,9 @@ package database | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"npm/internal/config" | ||||
| 	"strings" | ||||
|  | ||||
| 	"npm/internal/config" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(), | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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"}, | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package jobqueue | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"npm/internal/logger" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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...) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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"` | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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, | ||||
| 				}, | ||||
| 			}, | ||||
|   | ||||
| @@ -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) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| 			}, | ||||
| 		}) | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -50,7 +50,7 @@ func TestNullableDBUint_Scan(t *testing.T) { | ||||
|  | ||||
| 	tests := []struct { | ||||
| 		name     string | ||||
| 		input    interface{} | ||||
| 		input    any | ||||
| 		wantUint uint | ||||
| 		wantErr  bool | ||||
| 	}{ | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|   | ||||
| @@ -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, | ||||
| 	} | ||||
|   | ||||
| @@ -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] | ||||
| 	} | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user