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
with:
version: v1.52
version: v1.55
args: --timeout=10m

View file

@ -2,68 +2,31 @@ run:
deadline: 20m
linters-settings:
dupl:
threshold: 100
funlen:
lines: 100
statements: 50
gci:
local-prefixes: github.com/pomerium
goconst:
min-len: 2
min-occurrences: 2
gocritic:
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
custom-order: true
sections:
- standard
- default
- prefix(github.com/pomerium)
linters:
disable-all: true
enable:
- asasalint
- bodyclose
- depguard
- dogsled
- errcheck
- errorlint
- exportloopref
- gci
- gocheckcompilerdirectives
- gofmt
- gofumpt
- goimports
- goprintffuncname
- gosec
- gosimple
- govet
- ineffassign
- lll
- loggercheck
- misspell
- nakedret
- nolintlint
@ -71,13 +34,11 @@ linters:
- staticcheck
- stylecheck
- tenv
- typecheck
- unconvert
- unused
- usestdlibvars
issues:
exclude-use-default: false
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
@ -86,51 +47,13 @@ issues:
## Defaults we want from golangci-lint
# 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
# 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
##
## 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
- "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"
# 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:
# https://github.com/go-critic/go-critic/issues/926
- linters:
- gocritic
text: "unnecessaryDefer:"
# Exclude some linters from running on test files.
- path: _test\.go$|^tests/|^integration/|^samples/|templates\.go$
linters:
@ -146,26 +69,10 @@ issues:
- scopelint
- gosec
- 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
text: "Potential hardcoded credentials"
linters:
- gosec
- linters: [golint]
text: "should have a package comment"
- text: "G112:"
linters:
- gosec

View file

@ -649,8 +649,10 @@ func TestPolicyEvaluatorReuse(t *testing.T) {
// Make changes to some of the policies.
newPolicies := []config.Policy{
{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://foo.example.com"), // change route ID too
AllowAnyAuthenticatedUser: true},

View file

@ -59,7 +59,6 @@ type AutocertOptions struct {
// Validate ensures the Options fields are valid, and hydrated.
func (o *AutocertOptions) Validate() error {
// validate ACME EAB settings
if o.EABKeyID != "" && o.EABMACKey == "" {
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{
ACMETLSALPNPort: "1234",
}))
}
func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) {

View file

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

View file

@ -20,9 +20,7 @@ type LayeredSource struct {
ChangeDispatcher
}
var (
_ = Source(&LayeredSource{})
)
var _ = Source(&LayeredSource{})
// 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) {

View file

@ -14,7 +14,7 @@ func TestDownstreamMTLSSettingsGetCA(t *testing.T) {
fakeCACert := []byte("--- FAKE CA CERT ---")
caFile := filepath.Join(t.TempDir(), "CA.pem")
os.WriteFile(caFile, fakeCACert, 0644)
os.WriteFile(caFile, fakeCACert, 0o644)
cases := []struct {
label string
@ -41,7 +41,7 @@ func TestDownstreamMTLSSettingsGetCRL(t *testing.T) {
fakeCRL := []byte("--- FAKE CRL ---")
crlFile := filepath.Join(t.TempDir(), "CRL.pem")
os.WriteFile(crlFile, fakeCRL, 0644)
os.WriteFile(crlFile, fakeCRL, 0o644)
cases := []struct {
label string
@ -71,17 +71,23 @@ func TestDownstreamMTLSSettingsGetEnforcement(t *testing.T) {
settings DownstreamMTLSSettings
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"},
MTLSEnforcementPolicyWithDefaultDeny,
},
{"reject_connection",
{
"reject_connection",
DownstreamMTLSSettings{Enforcement: "reject_connection"},
MTLSEnforcementRejectConnection,
},
@ -122,20 +128,41 @@ func TestDownstreamMTLSSettingsValidate(t *testing.T) {
errorMsg string
}{
{"not set", DownstreamMTLSSettings{}, ""},
{"both CA and CA file", DownstreamMTLSSettings{CA: "CA", CAFile: "CAFile"},
"cannot set both ca and ca_file"},
{"bad CA", DownstreamMTLSSettings{CA: "not%valid%base64%data"},
"CA: illegal base64 data at input byte 3"},
{"bad CA file", DownstreamMTLSSettings{CAFile: "-"},
"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"},
{
"both CA and CA file",
DownstreamMTLSSettings{CA: "CA", CAFile: "CAFile"},
"cannot set both ca and ca_file",
},
{
"bad CA",
DownstreamMTLSSettings{CA: "not%valid%base64%data"},
"CA: illegal base64 data at input byte 3",
},
{
"bad CA file",
DownstreamMTLSSettings{CAFile: "-"},
"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{
{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.
// 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 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"`
// 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 CodecType `mapstructure:"codec_type" yaml:"codec_type"`

View file

@ -53,13 +53,13 @@ type Policy struct {
// Path Rewrite Options
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"`
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
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"`
HostPathRegexRewritePattern string `mapstructure:"host_path_regex_rewrite_pattern" yaml:"host_path_regex_rewrite_pattern,omitempty" json:"host_path_regex_rewrite_pattern,omitempty"` //nolint
HostPathRegexRewriteSubstitution string `mapstructure:"host_path_regex_rewrite_substitution" yaml:"host_path_regex_rewrite_substitution,omitempty" json:"host_path_regex_rewrite_substitution,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"`
// Allow unauthenticated HTTP OPTIONS requests as per the CORS spec
// 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
// 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"`
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 []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 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.
// (https://github.com/pomerium/pomerium/issues/4149)
p := rawJWTPayload(t, headerJWT)
var digitsOnly = regexp.MustCompile(`^\d+$`)
digitsOnly := regexp.MustCompile(`^\d+$`)
assert.Regexp(t, digitsOnly, p["iat"])
assert.Regexp(t, digitsOnly, p["exp"])

View file

@ -248,7 +248,7 @@ func TestStatefulCallback(t *testing.T) {
}
r := httptest.NewRequest(http.MethodGet, uri.String(), nil)
//fmt.Println(uri.String())
// fmt.Println(uri.String())
r.Host = r.URL.Host
r.Header.Set("Accept", "application/json")

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
N := c.Params().N
var k, kInv *big.Int //nolint
var k, kInv *big.Int
for {
for {
k, err = randFieldElement(c, rand)
if err != nil {
r = nil
return
return r, s, err
}
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()
input := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}
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 {
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
wantErr bool
}{
{
"good basic http handler",
&ServerOptions{

View file

@ -252,7 +252,8 @@ func TestManager_refreshSession(t *testing.T) {
FieldMask: &fieldmaskpb.FieldMask{
Paths: []string{"oauth_token", "id_token", "claims"},
},
}}).
},
}).
Return(nil /* this result is currently unused */, nil)
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
func (e *terminalError) Is(err error) bool {
//nolint:errorlint
_, ok := err.(*terminalError)
return ok
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -32,7 +32,8 @@ func TestClientCertificate(t *testing.T) {
cert string
expected A
}{
{"no certificate",
{
"no certificate",
`allow:
or:
- client_certificate:
@ -40,7 +41,8 @@ func TestClientCertificate(t *testing.T) {
"",
A{false, A{ReasonClientCertificateUnauthorized}, M{}},
},
{"no fingerprint match",
{
"no fingerprint match",
`allow:
or:
- client_certificate:
@ -48,7 +50,8 @@ func TestClientCertificate(t *testing.T) {
testCert,
A{false, A{ReasonClientCertificateUnauthorized}, M{}},
},
{"fingerprint match",
{
"fingerprint match",
`allow:
or:
- client_certificate:
@ -56,7 +59,8 @@ func TestClientCertificate(t *testing.T) {
testCert,
A{true, A{ReasonClientCertificateOK}, M{}},
},
{"fingerprint list match",
{
"fingerprint list match",
`allow:
or:
- client_certificate:
@ -66,7 +70,8 @@ func TestClientCertificate(t *testing.T) {
testCert,
A{true, A{ReasonClientCertificateOK}, M{}},
},
{"spki hash match",
{
"spki hash match",
`allow:
or:
- client_certificate:
@ -74,7 +79,8 @@ func TestClientCertificate(t *testing.T) {
testCert,
A{true, A{ReasonClientCertificateOK}, M{}},
},
{"spki hash list match",
{
"spki hash list match",
`allow:
or:
- client_certificate:
@ -114,29 +120,36 @@ func TestCanonicalCertFingerprint(t *testing.T) {
output string
err string
}{
{"object",
{
"object",
`{}`, "", "certificate fingerprint must be a string (was {})",
},
{"empty",
{
"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"`,
"", "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"`,
"", "unsupported certificate fingerprint format (DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A)",
},
{"valid short",
{
"valid short",
`"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"`,
"", "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"`,
"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "",
},
@ -169,16 +182,20 @@ func TestSPKIHashFormatErrors(t *testing.T) {
input string
err string
}{
{"object",
{
"object",
`{}`, "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)",
},
{"SHA-1 hash",
{
"SHA-1 hash",
`"VYby3BAoHawLLtsyckwo5Q=="`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was VYby3BAoHawLLtsyckwo5Q==)",
},
{"valid",
{
"valid",
`"FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U="`, "",
},
}

View file

@ -57,7 +57,8 @@ func TestOverwriteMaskedErrors(t *testing.T) {
s2.OauthToken = &session.OAuthToken{AccessToken: "access-token"}
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`,
err.Error())

View file

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