New lint rules

This commit is contained in:
Jamie Curnow 2024-11-21 19:07:36 +10:00
parent 4e6d65645f
commit 152b7666d8
No known key found for this signature in database
GPG Key ID: FFBB624C43388E9E
85 changed files with 385 additions and 259 deletions

View File

@ -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'

View File

@ -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"
)

View File

@ -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)

View File

@ -2,6 +2,7 @@ package handler
import (
"net/http"
h "npm/internal/api/http"
"npm/internal/config"
)

View File

@ -2,6 +2,7 @@ package handler
import (
"net/http"
"npm/internal/acme"
h "npm/internal/api/http"
"npm/internal/config"

View File

@ -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)

View File

@ -3,9 +3,10 @@ package handler
import (
"net/http"
"net/http/httptest"
"npm/internal/model"
"testing"
"npm/internal/model"
"github.com/stretchr/testify/assert"
)

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
})

View File

@ -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)
}

View File

@ -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)
})

View File

@ -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"))
})

View File

@ -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)
}))

View File

@ -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)
})

View File

@ -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",

View File

@ -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)
}))

View File

@ -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)

View File

@ -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),

View File

@ -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 {

View File

@ -3,9 +3,10 @@ package schema
import (
"bytes"
"encoding/json"
"npm/internal/entity/certificate"
"testing"
"npm/internal/entity/certificate"
"github.com/stretchr/testify/assert"
)

View File

@ -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 `
{

View File

@ -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)
}
}

View File

@ -2,6 +2,7 @@ package config
import (
"fmt"
"npm/internal/logger"
)

View File

@ -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)

View File

@ -2,8 +2,9 @@ package database
import (
"fmt"
"npm/internal/config"
"strings"
"npm/internal/config"
)
const (

View File

@ -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"

View File

@ -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
}

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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"`

View File

@ -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() {

View File

@ -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()

View File

@ -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"`

View File

@ -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

View File

@ -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",

View File

@ -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"`

View File

@ -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,
},
}

View File

@ -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"`

View File

@ -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,
},
}

View File

@ -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
}

View File

@ -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

View File

@ -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(),

View File

@ -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"`

View File

@ -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 {

View File

@ -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"`

View File

@ -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()

View File

@ -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"`

View File

@ -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"`

View File

@ -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"`

View File

@ -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"`

View File

@ -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"},

View File

@ -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

View File

@ -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

View File

@ -2,6 +2,7 @@ package jobqueue
import (
"fmt"
"npm/internal/logger"
)

View File

@ -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)

View File

@ -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,
},
}

View File

@ -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

View File

@ -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...)
}

View File

@ -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"`

View File

@ -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) {

View File

@ -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,
},
},

View File

@ -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)
})
}
}

View File

@ -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
},
})

View File

@ -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)

View File

@ -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)
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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:

View File

@ -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

View File

@ -50,7 +50,7 @@ func TestNullableDBUint_Scan(t *testing.T) {
tests := []struct {
name string
input interface{}
input any
wantUint uint
wantErr bool
}{

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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,
}

View File

@ -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]
}

View File

@ -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 {

View File

@ -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"