core/ci: update linting (#4844)

* core/ci: update linting

* re-add exportloopref

* re-add gocheckcompilerdirectives

* re-add stylecheck

* re-add usestdlibvars

* upgrade lint

---------

Co-authored-by: Denis Mishin <dmishin@pomerium.com>
This commit is contained in:
Caleb Doxsey 2023-12-14 10:07:54 -07:00 committed by GitHub
parent b66634d1e6
commit a2fd95aae6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 132 additions and 214 deletions

View file

@ -22,5 +22,5 @@ jobs:
- uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc - uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc
with: with:
version: v1.52 version: v1.55
args: --timeout=10m args: --timeout=10m

View file

@ -2,68 +2,31 @@ run:
deadline: 20m deadline: 20m
linters-settings: linters-settings:
dupl:
threshold: 100
funlen:
lines: 100
statements: 50
gci: gci:
local-prefixes: github.com/pomerium custom-order: true
goconst: sections:
min-len: 2 - standard
min-occurrences: 2 - default
gocritic: - prefix(github.com/pomerium)
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 15
goimports:
local-prefixes: github.com/pomerium
govet:
check-shadowing: false
lll:
line-length: 160
maligned:
suggest-new: true
misspell:
locale: US
nolintlint:
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
linters: linters:
disable-all: true disable-all: true
enable: enable:
- asasalint - asasalint
- bodyclose - bodyclose
- depguard
- dogsled - dogsled
- errcheck - errcheck
- errorlint - errorlint
- exportloopref - exportloopref
- gci - gci
- gocheckcompilerdirectives - gocheckcompilerdirectives
- gofmt - gofumpt
- goimports - goimports
- goprintffuncname - goprintffuncname
- gosec - gosec
- gosimple - gosimple
- govet - govet
- ineffassign - ineffassign
- lll
- loggercheck
- misspell - misspell
- nakedret - nakedret
- nolintlint - nolintlint
@ -71,13 +34,11 @@ linters:
- staticcheck - staticcheck
- stylecheck - stylecheck
- tenv - tenv
- typecheck
- unconvert - unconvert
- unused - unused
- usestdlibvars - usestdlibvars
issues: issues:
exclude-use-default: false
# List of regexps of issue texts to exclude, empty list by default. # List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns, # But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all # it can be disabled by `exclude-use-default: false`. To list all
@ -86,51 +47,13 @@ issues:
## Defaults we want from golangci-lint ## Defaults we want from golangci-lint
# errcheck: Almost all programs ignore errors on these functions and in most cases it's ok # errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
- Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked - Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
# golint: False positive when tests are defined in package 'test'
- func name will be used as test\.Test.* by other packages, and that stutters; consider calling this
# govet: Common false positives
- (possible misuse of unsafe.Pointer|should have signature)
# staticcheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore
- ineffective break statement. Did you mean to break out of the outer loop
# gosec: Too many false-positives on 'unsafe' usage
- Use of unsafe calls should be audited
# gosec: Too many false-positives for parametrized shell calls
- Subprocess launch(ed with variable|ing should be audited)
# gosec: Duplicated errcheck checks
- G104
# gosec: unsafe close on file errors
- G307
# gosec: Too many issues in popular repos
- (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)
# gosec: False positive is triggered by 'src, err := os.ReadFile(filename)'
- Potential file inclusion via variable
- empty-block - empty-block
##
## Custom
##
# Mostly harmless buffer writes where we skip error checking
# https://golang.org/pkg/bytes/#Buffer.Write
- "Error return value of `w.Write` is not checked"
- "Error return value of `io.WriteString` is not checked"
- "Error return value of `viper.BindEnv` is not checked"
- "Error return value of `h.Write` is not checked"
- "ExecuteTemplate` is not checked"
# go sec : we want to allow skipping tls auth # go sec : we want to allow skipping tls auth
- "TLS InsecureSkipVerify set true." - "TLS InsecureSkipVerify set true."
- "goroutine calls T.Fatalf, which must be called in the same goroutine as the test"
# good job Protobuffs!
- "method XXX"
- "SA1019" - "SA1019"
# EXC0001 errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
- Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked
exclude-rules: exclude-rules:
# https://github.com/go-critic/go-critic/issues/926
- linters:
- gocritic
text: "unnecessaryDefer:"
# Exclude some linters from running on test files. # Exclude some linters from running on test files.
- path: _test\.go$|^tests/|^integration/|^samples/|templates\.go$ - path: _test\.go$|^tests/|^integration/|^samples/|templates\.go$
linters: linters:
@ -146,26 +69,10 @@ issues:
- scopelint - scopelint
- gosec - gosec
- gosimple - gosimple
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# erroneously thinks google api url is a cred
- path: internal/identity/google.go
text: "Potential hardcoded credentials"
linters:
- gosec
# deprecated but every example still uses New
- path: internal/identity/google.go
text: "please use NewService instead"
linters:
- staticcheck
- path: internal/identity/oauth/github/github.go - path: internal/identity/oauth/github/github.go
text: "Potential hardcoded credentials" text: "Potential hardcoded credentials"
linters: linters:
- gosec - gosec
- linters: [golint]
text: "should have a package comment"
- text: "G112:" - text: "G112:"
linters: linters:
- gosec - gosec

View file

@ -649,8 +649,10 @@ func TestPolicyEvaluatorReuse(t *testing.T) {
// Make changes to some of the policies. // Make changes to some of the policies.
newPolicies := []config.Policy{ newPolicies := []config.Policy{
{To: singleToURL("https://to1.example.com")}, {To: singleToURL("https://to1.example.com")},
{To: singleToURL("https://to2.example.com"), {
AllowedUsers: []string{"user-id-1"}}, // change just the policy itself To: singleToURL("https://to2.example.com"),
AllowedUsers: []string{"user-id-1"},
}, // change just the policy itself
{To: singleToURL("https://to3.example.com")}, {To: singleToURL("https://to3.example.com")},
{To: singleToURL("https://foo.example.com"), // change route ID too {To: singleToURL("https://foo.example.com"), // change route ID too
AllowAnyAuthenticatedUser: true}, AllowAnyAuthenticatedUser: true},

View file

@ -59,7 +59,6 @@ type AutocertOptions struct {
// Validate ensures the Options fields are valid, and hydrated. // Validate ensures the Options fields are valid, and hydrated.
func (o *AutocertOptions) Validate() error { func (o *AutocertOptions) Validate() error {
// validate ACME EAB settings // validate ACME EAB settings
if o.EABKeyID != "" && o.EABMACKey == "" { if o.EABKeyID != "" && o.EABMACKey == "" {
return errors.New("config: Autocert EAB MAC Key required when Key ID is provided") return errors.New("config: Autocert EAB MAC Key required when Key ID is provided")

View file

@ -31,7 +31,6 @@ func TestBuilder_buildACMETLSALPNCluster(t *testing.T) {
b.buildACMETLSALPNCluster(&config.Config{ b.buildACMETLSALPNCluster(&config.Config{
ACMETLSALPNPort: "1234", ACMETLSALPNPort: "1234",
})) }))
} }
func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) { func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) {

View file

@ -213,6 +213,7 @@ func (b *Builder) buildPolicyEndpoints(
) ([]Endpoint, error) { ) ([]Endpoint, error) {
var endpoints []Endpoint var endpoints []Endpoint
for _, dst := range policy.To { for _, dst := range policy.To {
dst := dst
ts, err := b.buildPolicyTransportSocket(ctx, cfg, policy, dst.URL) ts, err := b.buildPolicyTransportSocket(ctx, cfg, policy, dst.URL)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -20,9 +20,7 @@ type LayeredSource struct {
ChangeDispatcher ChangeDispatcher
} }
var ( var _ = Source(&LayeredSource{})
_ = Source(&LayeredSource{})
)
// NewLayeredSource creates a new config source that is watching the underlying source for changes // NewLayeredSource creates a new config source that is watching the underlying source for changes
func NewLayeredSource(ctx context.Context, underlying Source, builder func(*Config) error) (*LayeredSource, error) { func NewLayeredSource(ctx context.Context, underlying Source, builder func(*Config) error) (*LayeredSource, error) {

View file

@ -14,7 +14,7 @@ func TestDownstreamMTLSSettingsGetCA(t *testing.T) {
fakeCACert := []byte("--- FAKE CA CERT ---") fakeCACert := []byte("--- FAKE CA CERT ---")
caFile := filepath.Join(t.TempDir(), "CA.pem") caFile := filepath.Join(t.TempDir(), "CA.pem")
os.WriteFile(caFile, fakeCACert, 0644) os.WriteFile(caFile, fakeCACert, 0o644)
cases := []struct { cases := []struct {
label string label string
@ -41,7 +41,7 @@ func TestDownstreamMTLSSettingsGetCRL(t *testing.T) {
fakeCRL := []byte("--- FAKE CRL ---") fakeCRL := []byte("--- FAKE CRL ---")
crlFile := filepath.Join(t.TempDir(), "CRL.pem") crlFile := filepath.Join(t.TempDir(), "CRL.pem")
os.WriteFile(crlFile, fakeCRL, 0644) os.WriteFile(crlFile, fakeCRL, 0o644)
cases := []struct { cases := []struct {
label string label string
@ -71,17 +71,23 @@ func TestDownstreamMTLSSettingsGetEnforcement(t *testing.T) {
settings DownstreamMTLSSettings settings DownstreamMTLSSettings
expected MTLSEnforcement expected MTLSEnforcement
}{ }{
{"default", {
DownstreamMTLSSettings{}, MTLSEnforcementPolicyWithDefaultDeny, "default",
DownstreamMTLSSettings{},
MTLSEnforcementPolicyWithDefaultDeny,
}, },
{"policy", {
DownstreamMTLSSettings{Enforcement: "policy"}, MTLSEnforcementPolicy, "policy",
DownstreamMTLSSettings{Enforcement: "policy"},
MTLSEnforcementPolicy,
}, },
{"policy_with_default_deny", {
"policy_with_default_deny",
DownstreamMTLSSettings{Enforcement: "policy_with_default_deny"}, DownstreamMTLSSettings{Enforcement: "policy_with_default_deny"},
MTLSEnforcementPolicyWithDefaultDeny, MTLSEnforcementPolicyWithDefaultDeny,
}, },
{"reject_connection", {
"reject_connection",
DownstreamMTLSSettings{Enforcement: "reject_connection"}, DownstreamMTLSSettings{Enforcement: "reject_connection"},
MTLSEnforcementRejectConnection, MTLSEnforcementRejectConnection,
}, },
@ -122,20 +128,41 @@ func TestDownstreamMTLSSettingsValidate(t *testing.T) {
errorMsg string errorMsg string
}{ }{
{"not set", DownstreamMTLSSettings{}, ""}, {"not set", DownstreamMTLSSettings{}, ""},
{"both CA and CA file", DownstreamMTLSSettings{CA: "CA", CAFile: "CAFile"}, {
"cannot set both ca and ca_file"}, "both CA and CA file",
{"bad CA", DownstreamMTLSSettings{CA: "not%valid%base64%data"}, DownstreamMTLSSettings{CA: "CA", CAFile: "CAFile"},
"CA: illegal base64 data at input byte 3"}, "cannot set both ca and ca_file",
{"bad CA file", DownstreamMTLSSettings{CAFile: "-"}, },
"CA file: open -: no such file or directory"}, {
{"both CRL and CRL file", DownstreamMTLSSettings{CRL: "CRL", CRLFile: "CRLFile"}, "bad CA",
"cannot set both crl and crl_file"}, DownstreamMTLSSettings{CA: "not%valid%base64%data"},
{"bad CRL", DownstreamMTLSSettings{CRL: "dGhpc2lzZmluZQo="}, "CA: illegal base64 data at input byte 3",
"CRL: cryptutil: non-PEM data in CRL bundle"}, },
{"bad CRL file", DownstreamMTLSSettings{CRLFile: "-"}, {
"CRL file: open -: no such file or directory"}, "bad CA file",
{"bad enforcement mode", DownstreamMTLSSettings{Enforcement: "whatever"}, DownstreamMTLSSettings{CAFile: "-"},
"unknown enforcement option"}, "CA file: open -: no such file or directory",
},
{
"both CRL and CRL file",
DownstreamMTLSSettings{CRL: "CRL", CRLFile: "CRLFile"},
"cannot set both crl and crl_file",
},
{
"bad CRL",
DownstreamMTLSSettings{CRL: "dGhpc2lzZmluZQo="},
"CRL: cryptutil: non-PEM data in CRL bundle",
},
{
"bad CRL file",
DownstreamMTLSSettings{CRLFile: "-"},
"CRL file: open -: no such file or directory",
},
{
"bad enforcement mode",
DownstreamMTLSSettings{Enforcement: "whatever"},
"unknown enforcement option",
},
{"bad SAN type", DownstreamMTLSSettings{MatchSubjectAltNames: []SANMatcher{ {"bad SAN type", DownstreamMTLSSettings{MatchSubjectAltNames: []SANMatcher{
{Type: "whatever"}, {Type: "whatever"},
}}, `unknown SAN type "whatever"`}, }}, `unknown SAN type "whatever"`},

View file

@ -269,7 +269,7 @@ type Options struct {
// GoogleCloudServerlessAuthenticationServiceAccount is the service account to use for GCP serverless authentication. // GoogleCloudServerlessAuthenticationServiceAccount is the service account to use for GCP serverless authentication.
// If unset, the GCP metadata server will be used to query for identity tokens. // If unset, the GCP metadata server will be used to query for identity tokens.
GoogleCloudServerlessAuthenticationServiceAccount string `mapstructure:"google_cloud_serverless_authentication_service_account" yaml:"google_cloud_serverless_authentication_service_account,omitempty"` //nolint GoogleCloudServerlessAuthenticationServiceAccount string `mapstructure:"google_cloud_serverless_authentication_service_account" yaml:"google_cloud_serverless_authentication_service_account,omitempty"`
// UseProxyProtocol configures the HTTP listener to require the HAProxy proxy protocol (either v1 or v2) on incoming requests. // UseProxyProtocol configures the HTTP listener to require the HAProxy proxy protocol (either v1 or v2) on incoming requests.
UseProxyProtocol bool `mapstructure:"use_proxy_protocol" yaml:"use_proxy_protocol,omitempty" json:"use_proxy_protocol,omitempty"` UseProxyProtocol bool `mapstructure:"use_proxy_protocol" yaml:"use_proxy_protocol,omitempty" json:"use_proxy_protocol,omitempty"`
@ -293,7 +293,7 @@ type Options struct {
EnvoyBindConfigFreebind null.Bool `mapstructure:"envoy_bind_config_freebind" yaml:"envoy_bind_config_freebind,omitempty"` EnvoyBindConfigFreebind null.Bool `mapstructure:"envoy_bind_config_freebind" yaml:"envoy_bind_config_freebind,omitempty"`
// ProgrammaticRedirectDomainWhitelist restricts the allowed redirect URLs when using programmatic login. // ProgrammaticRedirectDomainWhitelist restricts the allowed redirect URLs when using programmatic login.
ProgrammaticRedirectDomainWhitelist []string `mapstructure:"programmatic_redirect_domain_whitelist" yaml:"programmatic_redirect_domain_whitelist,omitempty" json:"programmatic_redirect_domain_whitelist,omitempty"` //nolint ProgrammaticRedirectDomainWhitelist []string `mapstructure:"programmatic_redirect_domain_whitelist" yaml:"programmatic_redirect_domain_whitelist,omitempty" json:"programmatic_redirect_domain_whitelist,omitempty"`
// CodecType is the codec to use for downstream connections. // CodecType is the codec to use for downstream connections.
CodecType CodecType `mapstructure:"codec_type" yaml:"codec_type"` CodecType CodecType `mapstructure:"codec_type" yaml:"codec_type"`

View file

@ -53,13 +53,13 @@ type Policy struct {
// Path Rewrite Options // Path Rewrite Options
PrefixRewrite string `mapstructure:"prefix_rewrite" yaml:"prefix_rewrite,omitempty" json:"prefix_rewrite,omitempty"` PrefixRewrite string `mapstructure:"prefix_rewrite" yaml:"prefix_rewrite,omitempty" json:"prefix_rewrite,omitempty"`
RegexRewritePattern string `mapstructure:"regex_rewrite_pattern" yaml:"regex_rewrite_pattern,omitempty" json:"regex_rewrite_pattern,omitempty"` RegexRewritePattern string `mapstructure:"regex_rewrite_pattern" yaml:"regex_rewrite_pattern,omitempty" json:"regex_rewrite_pattern,omitempty"`
RegexRewriteSubstitution string `mapstructure:"regex_rewrite_substitution" yaml:"regex_rewrite_substitution,omitempty" json:"regex_rewrite_substitution,omitempty"` //nolint RegexRewriteSubstitution string `mapstructure:"regex_rewrite_substitution" yaml:"regex_rewrite_substitution,omitempty" json:"regex_rewrite_substitution,omitempty"`
// Host Rewrite Options // Host Rewrite Options
HostRewrite string `mapstructure:"host_rewrite" yaml:"host_rewrite,omitempty" json:"host_rewrite,omitempty"` HostRewrite string `mapstructure:"host_rewrite" yaml:"host_rewrite,omitempty" json:"host_rewrite,omitempty"`
HostRewriteHeader string `mapstructure:"host_rewrite_header" yaml:"host_rewrite_header,omitempty" json:"host_rewrite_header,omitempty"` HostRewriteHeader string `mapstructure:"host_rewrite_header" yaml:"host_rewrite_header,omitempty" json:"host_rewrite_header,omitempty"`
HostPathRegexRewritePattern string `mapstructure:"host_path_regex_rewrite_pattern" yaml:"host_path_regex_rewrite_pattern,omitempty" json:"host_path_regex_rewrite_pattern,omitempty"` //nolint HostPathRegexRewritePattern string `mapstructure:"host_path_regex_rewrite_pattern" yaml:"host_path_regex_rewrite_pattern,omitempty" json:"host_path_regex_rewrite_pattern,omitempty"`
HostPathRegexRewriteSubstitution string `mapstructure:"host_path_regex_rewrite_substitution" yaml:"host_path_regex_rewrite_substitution,omitempty" json:"host_path_regex_rewrite_substitution,omitempty"` //nolint HostPathRegexRewriteSubstitution string `mapstructure:"host_path_regex_rewrite_substitution" yaml:"host_path_regex_rewrite_substitution,omitempty" json:"host_path_regex_rewrite_substitution,omitempty"`
// Allow unauthenticated HTTP OPTIONS requests as per the CORS spec // Allow unauthenticated HTTP OPTIONS requests as per the CORS spec
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests
@ -156,14 +156,14 @@ type Policy struct {
// EnableGoogleCloudServerlessAuthentication adds "Authorization: Bearer ID_TOKEN" headers // EnableGoogleCloudServerlessAuthentication adds "Authorization: Bearer ID_TOKEN" headers
// to upstream requests. // to upstream requests.
EnableGoogleCloudServerlessAuthentication bool `mapstructure:"enable_google_cloud_serverless_authentication" yaml:"enable_google_cloud_serverless_authentication,omitempty"` //nolint EnableGoogleCloudServerlessAuthentication bool `mapstructure:"enable_google_cloud_serverless_authentication" yaml:"enable_google_cloud_serverless_authentication,omitempty"`
SubPolicies []SubPolicy `mapstructure:"sub_policies" yaml:"sub_policies,omitempty" json:"sub_policies,omitempty"` SubPolicies []SubPolicy `mapstructure:"sub_policies" yaml:"sub_policies,omitempty" json:"sub_policies,omitempty"`
EnvoyOpts *envoy_config_cluster_v3.Cluster `mapstructure:"_envoy_opts" yaml:"-" json:"-"` EnvoyOpts *envoy_config_cluster_v3.Cluster `mapstructure:"_envoy_opts" yaml:"-" json:"-"`
// RewriteResponseHeaders rewrites response headers. This can be used to change the Location header. // RewriteResponseHeaders rewrites response headers. This can be used to change the Location header.
RewriteResponseHeaders []RewriteHeader `mapstructure:"rewrite_response_headers" yaml:"rewrite_response_headers,omitempty" json:"rewrite_response_headers,omitempty"` //nolint RewriteResponseHeaders []RewriteHeader `mapstructure:"rewrite_response_headers" yaml:"rewrite_response_headers,omitempty" json:"rewrite_response_headers,omitempty"`
// SetResponseHeaders sets response headers. // SetResponseHeaders sets response headers.
SetResponseHeaders map[string]string `mapstructure:"set_response_headers" yaml:"set_response_headers,omitempty"` SetResponseHeaders map[string]string `mapstructure:"set_response_headers" yaml:"set_response_headers,omitempty"`

View file

@ -527,7 +527,7 @@ func TestPomeriumJWT(t *testing.T) {
// format of the iat and exp timestamps. // format of the iat and exp timestamps.
// (https://github.com/pomerium/pomerium/issues/4149) // (https://github.com/pomerium/pomerium/issues/4149)
p := rawJWTPayload(t, headerJWT) p := rawJWTPayload(t, headerJWT)
var digitsOnly = regexp.MustCompile(`^\d+$`) digitsOnly := regexp.MustCompile(`^\d+$`)
assert.Regexp(t, digitsOnly, p["iat"]) assert.Regexp(t, digitsOnly, p["iat"])
assert.Regexp(t, digitsOnly, p["exp"]) assert.Regexp(t, digitsOnly, p["exp"])

View file

@ -125,13 +125,13 @@ func Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, e
c := priv.PublicKey.Curve c := priv.PublicKey.Curve
N := c.Params().N N := c.Params().N
var k, kInv *big.Int //nolint var k, kInv *big.Int
for { for {
for { for {
k, err = randFieldElement(c, rand) k, err = randFieldElement(c, rand)
if err != nil { if err != nil {
r = nil r = nil
return return r, s, err
} }
kInv = new(big.Int).ModInverse(k, N) kInv = new(big.Int).ModInverse(k, N)
@ -152,5 +152,5 @@ func Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, e
} }
} }
return //nolint return r, s, err
} }

View file

@ -57,7 +57,7 @@ func TestReadFileUpTo(t *testing.T) {
d := t.TempDir() d := t.TempDir()
input := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} input := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}
fname := path.Join(d, "test") fname := path.Join(d, "test")
require.NoError(t, os.WriteFile(fname, input, 0600)) require.NoError(t, os.WriteFile(fname, input, 0o600))
for _, tc := range []struct { for _, tc := range []struct {
size int size int

View file

@ -1,24 +0,0 @@
package httputil
import (
"reflect"
"testing"
"github.com/gorilla/mux"
)
func TestNewRouter(t *testing.T) {
tests := []struct {
name string
want *mux.Router
}{
{"this is a gorilla router right?", mux.NewRouter()},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewRouter(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewRouter() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -29,7 +29,6 @@ func TestNewServer(t *testing.T) {
// want *http.Server // want *http.Server
wantErr bool wantErr bool
}{ }{
{ {
"good basic http handler", "good basic http handler",
&ServerOptions{ &ServerOptions{

View file

@ -252,7 +252,8 @@ func TestManager_refreshSession(t *testing.T) {
FieldMask: &fieldmaskpb.FieldMask{ FieldMask: &fieldmaskpb.FieldMask{
Paths: []string{"oauth_token", "id_token", "claims"}, Paths: []string{"oauth_token", "id_token", "claims"},
}, },
}}). },
}).
Return(nil /* this result is currently unused */, nil) Return(nil /* this result is currently unused */, nil)
mgr.refreshSession(context.Background(), "user-id", "session-id") mgr.refreshSession(context.Background(), "user-id", "session-id")

View file

@ -28,7 +28,6 @@ func (e *terminalError) Unwrap() error {
// Is implements errors.Is for terminalError // Is implements errors.Is for terminalError
func (e *terminalError) Is(err error) bool { func (e *terminalError) Is(err error) bool {
//nolint:errorlint
_, ok := err.(*terminalError) _, ok := err.(*terminalError)
return ok return ok
} }

View file

@ -124,7 +124,8 @@ func GRPCClientInterceptor(service string) grpc.UnaryClientInterceptor {
reply interface{}, reply interface{},
cc *grpc.ClientConn, cc *grpc.ClientConn,
invoker grpc.UnaryInvoker, invoker grpc.UnaryInvoker,
opts ...grpc.CallOption) error { opts ...grpc.CallOption,
) error {
// Split the method into parts for better slicing // Split the method into parts for better slicing
rpcInfo := strings.SplitN(method, "/", 3) rpcInfo := strings.SplitN(method, "/", 3)
var rpcMethod string var rpcMethod string

View file

@ -46,7 +46,7 @@ func SaveBootstrapConfigToFile(src *cluster_api.BootstrapConfig, fp string, ciph
} }
ciphertext := cryptutil.Encrypt(cipher, plaintext, nil) ciphertext := cryptutil.Encrypt(cipher, plaintext, nil)
err = os.WriteFile(fp, ciphertext, 0600) err = os.WriteFile(fp, ciphertext, 0o600)
if err != nil { if err != nil {
return fmt.Errorf("write bootstrap config: %w", err) return fmt.Errorf("write bootstrap config: %w", err)
} }

View file

@ -12,16 +12,12 @@ import (
cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster" cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster"
) )
var ( var _ = config.Source(new(source))
_ = config.Source(new(source))
)
var ( var cmpOpts = []cmp.Option{
cmpOpts = []cmp.Option{
cmpopts.IgnoreUnexported(config.Options{}), cmpopts.IgnoreUnexported(config.Options{}),
cmpopts.EquateEmpty(), cmpopts.EquateEmpty(),
} }
)
type source struct { type source struct {
cfg atomicutil.Value[*config.Config] cfg atomicutil.Value[*config.Config]

View file

@ -16,7 +16,6 @@ import (
) )
func TestReadRecords(t *testing.T) { func TestReadRecords(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
fd, err := os.CreateTemp(dir, "config") fd, err := os.CreateTemp(dir, "config")
require.NoError(t, err) require.NoError(t, err)
@ -34,7 +33,7 @@ func TestReadRecords(t *testing.T) {
} }
func writeSampleRecords(dst io.Writer) error { func writeSampleRecords(dst io.Writer) error {
var marshalOpts = protodelim.MarshalOptions{ marshalOpts := protodelim.MarshalOptions{
MarshalOptions: proto.MarshalOptions{ MarshalOptions: proto.MarshalOptions{
AllowPartial: false, AllowPartial: false,
Deterministic: true, Deterministic: true,

View file

@ -73,7 +73,6 @@ func TestQueueMarkForSyncLater(t *testing.T) {
assert.Equal(t, "bundle1", id4) assert.Equal(t, "bundle1", id4)
assert.False(t, ok5, "Expected no more bundles to sync") assert.False(t, ok5, "Expected no more bundles to sync")
assert.Empty(t, id5) assert.Empty(t, id5)
} }
func TestQueueGetNextBundleToSync(t *testing.T) { func TestQueueGetNextBundleToSync(t *testing.T) {

View file

@ -37,10 +37,8 @@ const (
BundleCacheEntryRecordType = "pomerium.io/BundleCacheEntry" BundleCacheEntryRecordType = "pomerium.io/BundleCacheEntry"
) )
var (
// ErrBundleCacheEntryNotFound is returned when a bundle cache entry is not found // ErrBundleCacheEntryNotFound is returned when a bundle cache entry is not found
ErrBundleCacheEntryNotFound = errors.New("bundle cache entry not found") var ErrBundleCacheEntryNotFound = errors.New("bundle cache entry not found")
)
// GetBundleCacheEntry gets a bundle cache entry from the databroker // GetBundleCacheEntry gets a bundle cache entry from the databroker
func (c *service) GetBundleCacheEntry(ctx context.Context, id string) (*BundleCacheEntry, error) { func (c *service) GetBundleCacheEntry(ctx context.Context, id string) (*BundleCacheEntry, error) {

View file

@ -8,8 +8,10 @@ package base58
import "math/big" import "math/big"
var bigRadix = big.NewInt(58) var (
var bigZero = big.NewInt(0) bigRadix = big.NewInt(58)
bigZero = big.NewInt(0)
)
// Decode decodes a modified base58 string to a byte slice. // Decode decodes a modified base58 string to a byte slice.
func Decode(b string) []byte { func Decode(b string) []byte {

View file

@ -20,7 +20,7 @@ type retryableError struct {
} }
func (err retryableError) Is(target error) bool { func (err retryableError) Is(target error) bool {
if _, ok := target.(retryableError); ok { //nolint:errorlint if _, ok := target.(retryableError); ok {
return true return true
} }
return false return false

View file

@ -10,8 +10,7 @@ import (
"github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/log"
) )
type healthCheckSrv struct { type healthCheckSrv struct{}
}
// NewHealthCheckServer returns a basic health checker // NewHealthCheckServer returns a basic health checker
func NewHealthCheckServer() grpc_health.HealthServer { func NewHealthCheckServer() grpc_health.HealthServer {

View file

@ -32,7 +32,8 @@ func TestClientCertificate(t *testing.T) {
cert string cert string
expected A expected A
}{ }{
{"no certificate", {
"no certificate",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -40,7 +41,8 @@ func TestClientCertificate(t *testing.T) {
"", "",
A{false, A{ReasonClientCertificateUnauthorized}, M{}}, A{false, A{ReasonClientCertificateUnauthorized}, M{}},
}, },
{"no fingerprint match", {
"no fingerprint match",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -48,7 +50,8 @@ func TestClientCertificate(t *testing.T) {
testCert, testCert,
A{false, A{ReasonClientCertificateUnauthorized}, M{}}, A{false, A{ReasonClientCertificateUnauthorized}, M{}},
}, },
{"fingerprint match", {
"fingerprint match",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -56,7 +59,8 @@ func TestClientCertificate(t *testing.T) {
testCert, testCert,
A{true, A{ReasonClientCertificateOK}, M{}}, A{true, A{ReasonClientCertificateOK}, M{}},
}, },
{"fingerprint list match", {
"fingerprint list match",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -66,7 +70,8 @@ func TestClientCertificate(t *testing.T) {
testCert, testCert,
A{true, A{ReasonClientCertificateOK}, M{}}, A{true, A{ReasonClientCertificateOK}, M{}},
}, },
{"spki hash match", {
"spki hash match",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -74,7 +79,8 @@ func TestClientCertificate(t *testing.T) {
testCert, testCert,
A{true, A{ReasonClientCertificateOK}, M{}}, A{true, A{ReasonClientCertificateOK}, M{}},
}, },
{"spki hash list match", {
"spki hash list match",
`allow: `allow:
or: or:
- client_certificate: - client_certificate:
@ -114,29 +120,36 @@ func TestCanonicalCertFingerprint(t *testing.T) {
output string output string
err string err string
}{ }{
{"object", {
"object",
`{}`, "", "certificate fingerprint must be a string (was {})", `{}`, "", "certificate fingerprint must be a string (was {})",
}, },
{"empty", {
"empty",
`""`, "", "certificate fingerprint must not be empty", `""`, "", "certificate fingerprint must not be empty",
}, },
{"SHA-1 fingerprint", {
"SHA-1 fingerprint",
`"B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36"`, `"B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36"`,
"", "unsupported certificate fingerprint format (B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36)", "", "unsupported certificate fingerprint format (B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36)",
}, },
{"uppercase short", {
"uppercase short",
`"DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A"`, `"DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A"`,
"", "unsupported certificate fingerprint format (DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A)", "", "unsupported certificate fingerprint format (DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A)",
}, },
{"valid short", {
"valid short",
`"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a"`, `"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a"`,
"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "", "df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "",
}, },
{"lowercase long", {
"lowercase long",
`"df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a"`, `"df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a"`,
"", "unsupported certificate fingerprint format (df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a)", "", "unsupported certificate fingerprint format (df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a)",
}, },
{"valid long", {
"valid long",
`"DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A"`, `"DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A"`,
"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "", "df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "",
}, },
@ -169,16 +182,20 @@ func TestSPKIHashFormatErrors(t *testing.T) {
input string input string
err string err string
}{ }{
{"object", {
"object",
`{}`, "certificate SPKI hash condition expects a string or array of strings", `{}`, "certificate SPKI hash condition expects a string or array of strings",
}, },
{"not base64", {
"not base64",
`"not%valid%base64%data"`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was not%valid%base64%data)", `"not%valid%base64%data"`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was not%valid%base64%data)",
}, },
{"SHA-1 hash", {
"SHA-1 hash",
`"VYby3BAoHawLLtsyckwo5Q=="`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was VYby3BAoHawLLtsyckwo5Q==)", `"VYby3BAoHawLLtsyckwo5Q=="`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was VYby3BAoHawLLtsyckwo5Q==)",
}, },
{"valid", {
"valid",
`"FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U="`, "", `"FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U="`, "",
}, },
} }

View file

@ -57,7 +57,8 @@ func TestOverwriteMaskedErrors(t *testing.T) {
s2.OauthToken = &session.OAuthToken{AccessToken: "access-token"} s2.OauthToken = &session.OAuthToken{AccessToken: "access-token"}
err = protoutil.OverwriteMasked(&s1, &s2, &fieldmaskpb.FieldMask{ err = protoutil.OverwriteMasked(&s1, &s2, &fieldmaskpb.FieldMask{
Paths: []string{"oauth_token.foo"}}) Paths: []string{"oauth_token.foo"},
})
assert.Equal(t, `cannot overwrite unknown field "foo" in message session.OAuthToken`, assert.Equal(t, `cannot overwrite unknown field "foo" in message session.OAuthToken`,
err.Error()) err.Error())

View file

@ -10,10 +10,8 @@ import (
"path/filepath" "path/filepath"
) )
var (
//go:embed dist/* //go:embed dist/*
uiFS embed.FS var uiFS embed.FS
)
func openFile(name string) (f fs.File, etag string, err error) { func openFile(name string) (f fs.File, etag string, err error) {
f, err = os.Open(filepath.Join("ui", name)) f, err = os.Open(filepath.Join("ui", name))