diff --git a/.golangci.yml b/.golangci.yml index 3d9ebd267..330f853c5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,163 +1,102 @@ -# forked from istio -service: - # When updating this, also update bin/linters.sh accordingly - golangci-lint-version: 1.21.x # use the fixed version to not introduce new linters unexpectedly run: - # timeout for analysis, e.g. 30s, 5m, default is 1m deadline: 20m - # which dirs to skip: they won't be analyzed; - # can use regexp here: generated.*, regexp is applied on full path; - # default value is empty list, but next dirs are always skipped independently - # from this option's value: - # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - skip-dirs: - - genfiles$ - - vendor$ - - # which files to skip: they will be analyzed, but issues from them - # won't be reported. Default value is empty list, but there is - # no need to include all autogenerated files, we confidently recognize - # autogenerated files. If it's not please let us know. - skip-files: - - ".*\\.pb\\.go" - - ".*\\.gen\\.go" +linters-settings: + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + gci: + local-prefixes: github.com/pomerium/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/pomerium + golint: + min-confidence: 0 + 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: - enable-all: true - disable: + disable-all: true + enable: + - bodyclose + - deadcode - depguard - - dupl - - funlen - - gochecknoglobals - - gochecknoinits - - gocognit - - goconst - - gocyclo - - godox - - interfacer - - maligned + - dogsled + - errcheck + - gofmt + - goimports + - golint + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - lll + - misspell - nakedret - - prealloc - - scopelint - - whitespace - - wsl - fast: false - -linters-settings: - errcheck: - # report about not checking of errors in type assetions: `a := b.(MyStruct)`; - # default is false: such cases aren't reported by default. - check-type-assertions: false - - # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; - # default is false: such cases aren't reported by default. - check-blank: false - - govet: - # report about shadowed variables - check-shadowing: false - golint: - # minimal confidence for issues, default is 0.8 - min-confidence: 0.8 - gofmt: - # simplify code: gofmt with `-s` option, true by default - simplify: true - misspell: - # Correct spellings using locale preferences for US or UK. - # Default is to use a neutral variety of English. - # Setting locale to US will correct the British spelling of 'colour' to 'color'. - locale: US - lll: - # max line length, lines longer will be reported. Default is 120. - # '\t' is counted as 1 character by default, and can be changed with the tab-width option - line-length: 160 - # tab width in spaces. Default to 1. - tab-width: 1 - goimports: - # put imports beginning with prefix after 3rd-party packages; - # it's a comma-separated list of prefixes - local-prefixes: github.com/pomerium/pomerium - unused: - # treat code as a program (not a library) and report unused exported identifiers; default is false. - # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find funcs usages. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: false - unparam: - # call graph construction algorithm (cha, rta). In general, use cha for libraries, - # and rta for programs with main packages. Default is cha. - algo: cha - - # Inspect exported functions, default is false. Set to true if no external program/library imports your code. - # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find external interfaces. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: false - gocritic: - enabled-checks: - - appendCombine - - argOrder - - assignOp - - badCond - - boolExprSimplify - - builtinShadow - - captLocal - - caseOrder - - codegenComment - - commentedOutCode - - commentedOutImport - - defaultCaseOrder - - deprecatedComment - - docStub - - dupArg - - dupBranchBody - - dupCase - - dupSubExpr - - elseif - - emptyFallthrough - - equalFold - - flagDeref - - flagName - - hexLiteral - - indexAlloc - - initClause - - methodExprCall - - nilValReturn - - offBy1 - - rangeExprCopy - - regexpMust - - sloppyLen - - stringXbytes - - switchTrue - - typeAssertChain - - typeSwitchVar - - typeUnparen - - underef - - unlambda - - unnecessaryBlock - - unslice - - valSwap - - weakCond - - yodaStyleExpr - - # Unused - # - appendAssign - # - commentFormatting - # - emptyStringTest - # - exitAfterDefer - # - ifElseChain - # - hugeParam - # - importShadow - # - nestingReduce - # - paramTypeCombine - # - ptrToRefParam - # - rangeValCopy - # - singleCaseSwitch - # - sloppyReassign - # - unlabelStmt - # - unnamedResult - # - wrapperFunc + - nolintlint + - rowserrcheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + # - asciicheck + # - dupl + # - exhaustive + # - funlen + # - gochecknoglobals + # - gochecknoinits + # - gocognit + # - goconst + # - gocritic + # - gocyclo + # - godot + # - godox + # - goerr113 + # - gomnd + # - interfacer + # - maligned + # - nestif + # - noctx + # - prealloc + # - scopelint + # - testpackage + # - whitespace + # - wsl issues: # List of regexps of issue texts to exclude, empty list by default. @@ -204,16 +143,26 @@ issues: - "SA1019" 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: - - errcheck - - maligned - - lll - - gosec - bodyclose + - errcheck + - gomnd + - gosec + - lll + - maligned + - staticcheck - unparam - unused + - scopelint + - gosec + - gosimple + # erroneously thinks google api url is a cred - path: internal/identity/google.go text: "Potential hardcoded credentials" @@ -228,14 +177,8 @@ issues: text: "Potential hardcoded credentials" linters: - gosec - # Independently from option `exclude` we use default exclude patterns, - # it can be disabled by this option. To list all - # excluded by default patterns execute `golangci-lint run --help`. - # Default value for this option is true. - exclude-use-default: false - # Maximum issues count per one linter. Set to 0 to disable. Default is 50. - max-per-linter: 0 - - # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. - max-same-issues: 0 +# golangci.com configuration +# https://github.com/golangci/golangci/wiki/Configuration +service: + golangci-lint-version: 1.34.x # use the fixed version to not introduce new linters unexpectedly diff --git a/Makefile b/Makefile index 7bad4ccf4..bdafe82b3 100644 --- a/Makefile +++ b/Makefile @@ -32,10 +32,11 @@ GOOSARCHES = linux/amd64 darwin/amd64 windows/amd64 GOOS = $(shell $(GO) env GOOS) GOARCH= $(shell $(GO) env GOARCH) MISSPELL_VERSION = v0.3.4 -GOLANGCI_VERSION = v1.21.0 +GOLANGCI_VERSION = v1.34.1 OPA_VERSION = v0.25.2 GETENVOY_VERSION = v0.2.0 GORELEASER_VERSION = v0.150.0 + .PHONY: all all: clean build-deps test lint spellcheck build ## Runs a clean, build, fmt, lint, test, and vet. diff --git a/authenticate/authenticate_test.go b/authenticate/authenticate_test.go index 419bacc44..1d0ae9898 100644 --- a/authenticate/authenticate_test.go +++ b/authenticate/authenticate_test.go @@ -10,7 +10,6 @@ import ( ) func newTestOptions(t *testing.T) *config.Options { - opts := config.NewDefaultOptions() opts.AuthenticateURLString = "https://authenticate.example" opts.AuthorizeURLString = "https://authorize.example" diff --git a/authenticate/handlers.go b/authenticate/handlers.go index 8f30daede..c4fe0d3d7 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -13,11 +13,12 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/google/uuid" "github.com/gorilla/mux" - "github.com/pomerium/csrf" "github.com/rs/cors" "golang.org/x/oauth2" "gopkg.in/square/go-jose.v2/jwt" + "github.com/pomerium/csrf" + "github.com/pomerium/pomerium/internal/httputil" "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/identity/manager" diff --git a/authenticate/handlers_test.go b/authenticate/handlers_test.go index 81753434d..75f872056 100644 --- a/authenticate/handlers_test.go +++ b/authenticate/handlers_test.go @@ -113,7 +113,6 @@ func TestAuthenticate_Handler(t *testing.T) { if body == "" { t.Errorf("handler returned unexpected body: got %v want %v", body, expected) } - } func TestAuthenticate_SignIn(t *testing.T) { @@ -593,6 +592,7 @@ func TestJwksEndpoint(t *testing.T) { expected := "{\"keys\":[{\"use\":\"sig\",\"kty\":\"EC\",\"kid\":\"5b419ade1895fec2d2def6cd33b1b9a018df60db231dc5ecb85cbed6d942813c\",\"crv\":\"P-256\",\"alg\":\"ES256\",\"x\":\"UG5xCP0JTT1H6Iol8jKuTIPVLM04CgW9PlEypNRmWlo\",\"y\":\"KChF0fR09zm884ymInM29PtSsFdnzExNfLsP-ta1AgQ\"}]}\n" assert.Equal(t, expected, body) } + func TestAuthenticate_Dashboard(t *testing.T) { t.Parallel() @@ -706,7 +706,6 @@ func TestAuthenticate_FrontchannelLogout(t *testing.T) { }, get: func(ctx context.Context, in *databroker.GetRequest, opts ...grpc.CallOption) (*databroker.GetResponse, error) { if !tt.widthSession { - return nil, nil } diff --git a/authorize/authorize_test.go b/authorize/authorize_test.go index 3da74e399..b90525d57 100644 --- a/authorize/authorize_test.go +++ b/authorize/authorize_test.go @@ -18,39 +18,57 @@ func TestNew(t *testing.T) { config config.Options wantErr bool }{ - {"good", + { + "good", config.Options{ AuthenticateURL: mustParseURL("https://authN.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"), SharedKey: "2p/Wi2Q6bYDfzmoSEbKqYKtg+DUoLWTEHHs7vOhvL7w=", - Policies: policies}, - false}, - {"bad shared secret", + Policies: policies, + }, + false, + }, + { + "bad shared secret", config.Options{ AuthenticateURL: mustParseURL("https://authN.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"), SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", - Policies: policies}, true}, - {"really bad shared secret", + Policies: policies, + }, + true, + }, + { + "really bad shared secret", config.Options{ AuthenticateURL: mustParseURL("https://authN.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"), SharedKey: "sup", - Policies: policies}, true}, - {"validation error, short secret", + Policies: policies, + }, + true, + }, + { + "validation error, short secret", config.Options{ AuthenticateURL: mustParseURL("https://authN.example.com"), DataBrokerURL: mustParseURL("https://cache.example.com"), SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", - Policies: policies}, true}, + Policies: policies, + }, + true, + }, {"empty options", config.Options{}, true}, - {"bad cache url", + { + "bad cache url", config.Options{ AuthenticateURL: mustParseURL("https://authN.example.com"), DataBrokerURL: &url.URL{}, SharedKey: "AZA85podM73CjLCjViDNz1EUvvejKpWp7Hysr0knXA==", - Policies: policies}, - true}, + Policies: policies, + }, + true, + }, } for _, tt := range tests { tt := tt diff --git a/authorize/check_response.go b/authorize/check_response.go index 55b0a6e56..64a38ef92 100644 --- a/authorize/check_response.go +++ b/authorize/check_response.go @@ -50,7 +50,6 @@ func (a *Authorize) deniedResponse( in *envoy_service_auth_v2.CheckRequest, code int32, reason string, headers map[string]string, ) *envoy_service_auth_v2.CheckResponse { - returnHTMLError := true inHeaders := in.GetAttributes().GetRequest().GetHttp().GetHeaders() if inHeaders != nil { @@ -67,7 +66,6 @@ func (a *Authorize) htmlDeniedResponse( in *envoy_service_auth_v2.CheckRequest, code int32, reason string, headers map[string]string, ) *envoy_service_auth_v2.CheckResponse { - opts := a.currentOptions.Load() debugEndpoint := opts.GetAuthenticateURL().ResolveReference(&url.URL{Path: "/.pomerium/"}) diff --git a/authorize/evaluator/custom_test.go b/authorize/evaluator/custom_test.go index 724e7bce8..5ee4ce3b8 100644 --- a/authorize/evaluator/custom_test.go +++ b/authorize/evaluator/custom_test.go @@ -53,5 +53,4 @@ func TestCustomEvaluator(t *testing.T) { } assert.NotNil(t, res) }) - } diff --git a/authorize/evaluator/evaluator.go b/authorize/evaluator/evaluator.go index 9bf868525..33405eccb 100644 --- a/authorize/evaluator/evaluator.go +++ b/authorize/evaluator/evaluator.go @@ -222,6 +222,7 @@ func (e *Evaluator) JWTPayload(req *Request) map[string]interface{} { return payload } + func newSigner(options *config.Options) (jose.Signer, *jose.JSONWebKey, error) { // if we don't have a signing key, generate one if options.SigningKey == "" { @@ -257,7 +258,6 @@ func newSigner(options *config.Options) (jose.Signer, *jose.JSONWebKey, error) { Algorithm: jose.SignatureAlgorithm(jwk.Algorithm), Key: jwk, }, signerOpt.WithHeader("kid", jwk.KeyID)) - if err != nil { return nil, nil, fmt.Errorf("couldn't create signer: %w", err) } diff --git a/authorize/google_cloud_serverless.go b/authorize/google_cloud_serverless.go index 416d522ed..aad8f1329 100644 --- a/authorize/google_cloud_serverless.go +++ b/authorize/google_cloud_serverless.go @@ -71,14 +71,12 @@ type gcpTokenSourceKey struct { audience string } -var ( - gcpTokenSources = struct { - sync.Mutex - m map[gcpTokenSourceKey]oauth2.TokenSource - }{ - m: make(map[gcpTokenSourceKey]oauth2.TokenSource), - } -) +var gcpTokenSources = struct { + sync.Mutex + m map[gcpTokenSourceKey]oauth2.TokenSource +}{ + m: make(map[gcpTokenSourceKey]oauth2.TokenSource), +} func normalizeServiceAccount(serviceAccount string) (string, error) { serviceAccount = strings.TrimSpace(serviceAccount) diff --git a/authorize/grpc_test.go b/authorize/grpc_test.go index 5225db73c..859a63614 100644 --- a/authorize/grpc_test.go +++ b/authorize/grpc_test.go @@ -111,7 +111,6 @@ func Test_getEvaluatorRequest(t *testing.T) { } func Test_handleForwardAuth(t *testing.T) { - tests := []struct { name string checkReq *envoy_service_auth_v2.CheckRequest @@ -452,6 +451,7 @@ func TestSync(t *testing.T) { }) } } + func mustParseURL(str string) *url.URL { u, err := url.Parse(str) if err != nil { @@ -492,7 +492,8 @@ func TestAuthorize_Check(t *testing.T) { want *envoy_service_auth_v2.CheckResponse wantErr bool }{ - {"basic deny", + { + "basic deny", &envoy_service_auth_v2.CheckRequest{ Attributes: &envoy_service_auth_v2.AttributeContext{ Source: &envoy_service_auth_v2.AttributeContext_Peer{ @@ -520,8 +521,10 @@ func TestAuthorize_Check(t *testing.T) { DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{}, }, }, - false}, - {"basic forward-auth deny", + false, + }, + { + "basic forward-auth deny", &envoy_service_auth_v2.CheckRequest{ Attributes: &envoy_service_auth_v2.AttributeContext{ Source: &envoy_service_auth_v2.AttributeContext_Peer{ @@ -543,11 +546,11 @@ func TestAuthorize_Check(t *testing.T) { DeniedResponse: &envoy_service_auth_v2.DeniedHttpResponse{}, }, }, - false}, + false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := a.Check(context.TODO(), tt.in) if (err != nil) != tt.wantErr { t.Errorf("Authorize.Check() error = %v, wantErr %v", err, tt.wantErr) @@ -557,7 +560,6 @@ func TestAuthorize_Check(t *testing.T) { if diff := cmp.Diff(got, tt.want, cmpOpts...); diff != "" { t.Errorf("NewStore() = %s", diff) } - }) } } diff --git a/cache/cache.go b/cache/cache.go index 9ad68afa4..db856f035 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -36,8 +36,8 @@ type Cache struct { localListener net.Listener localGRPCServer *grpc.Server localGRPCConnection *grpc.ClientConn - dataBrokerStorageType string //TODO remove in v0.11 - deprecatedCacheClusterDomain string //TODO: remove in v0.11 + dataBrokerStorageType string // TODO remove in v0.11 + deprecatedCacheClusterDomain string // TODO: remove in v0.11 mu sync.Mutex directoryProvider directory.Provider diff --git a/cmd/pomerium-cli/cache.go b/cmd/pomerium-cli/cache.go index 729729b86..505fdd14a 100644 --- a/cmd/pomerium-cli/cache.go +++ b/cmd/pomerium-cli/cache.go @@ -17,7 +17,7 @@ func configHome() string { } ch := filepath.Join(cfgDir, "pomerium-cli") - err = os.MkdirAll(ch, 0755) + err = os.MkdirAll(ch, 0o755) if err != nil { fatalf("error creating user config dir: %v", err) } @@ -69,7 +69,7 @@ func loadCachedCredential(serverURL string) *ExecCredential { func saveCachedCredential(serverURL string, creds *ExecCredential) { fn := cachedCredentialPath(serverURL) - err := os.MkdirAll(filepath.Dir(fn), 0755) + err := os.MkdirAll(filepath.Dir(fn), 0o755) if err != nil { fmt.Fprintf(os.Stderr, "failed to create cache directory: %v", err) return diff --git a/cmd/pomerium/main.go b/cmd/pomerium/main.go index c167c1647..5000d7b61 100644 --- a/cmd/pomerium/main.go +++ b/cmd/pomerium/main.go @@ -10,8 +10,10 @@ import ( "github.com/pomerium/pomerium/internal/version" ) -var versionFlag = flag.Bool("version", false, "prints the version") -var configFile = flag.String("config", "", "Specify configuration file location") +var ( + versionFlag = flag.Bool("version", false, "prints the version") + configFile = flag.String("config", "", "Specify configuration file location") +) func main() { if err := run(context.Background()); err != nil { diff --git a/config/helpers_test.go b/config/helpers_test.go index 0f03aee49..e9e878e90 100644 --- a/config/helpers_test.go +++ b/config/helpers_test.go @@ -42,7 +42,6 @@ func Test_isAuthenticate(t *testing.T) { {"jiberish", "xd23", false}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { if got := IsAuthenticate(tt.service); got != tt.want { t.Errorf("isAuthenticate() = %v, want %v", got, tt.want) @@ -66,7 +65,6 @@ func Test_isAuthorize(t *testing.T) { {"jiberish", "xd23", false}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { if got := IsAuthorize(tt.service); got != tt.want { t.Errorf("isAuthenticate() = %v, want %v", got, tt.want) @@ -74,6 +72,7 @@ func Test_isAuthorize(t *testing.T) { }) } } + func Test_IsProxy(t *testing.T) { tests := []struct { name string @@ -87,7 +86,6 @@ func Test_IsProxy(t *testing.T) { {"jiberish", "xd23", false}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { if got := IsProxy(tt.service); got != tt.want { t.Errorf("IsProxy() = %v, want %v", got, tt.want) @@ -111,7 +109,6 @@ func Test_IsCache(t *testing.T) { {"cache", "cache", true}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { if got := IsCache(tt.service); got != tt.want { t.Errorf("IsCache() = %v, want %v", got, tt.want) diff --git a/config/http.go b/config/http.go index 83267c238..f8ac27138 100644 --- a/config/http.go +++ b/config/http.go @@ -35,7 +35,8 @@ func (t *httpTransport) update(options *Options) { rootCAs, err := cryptutil.GetCertPool(options.CA, options.CAFile) if err == nil { nt.TLSClientConfig = &tls.Config{ - RootCAs: rootCAs, + RootCAs: rootCAs, + MinVersion: tls.VersionTLS12, } } else { log.Error().Err(err).Msg("config: error getting cert pool") diff --git a/config/options.go b/config/options.go index 5033d8c8f..4b041ade1 100644 --- a/config/options.go +++ b/config/options.go @@ -224,9 +224,9 @@ type Options struct { GRPCClientTimeout time.Duration `mapstructure:"grpc_client_timeout" yaml:"grpc_client_timeout,omitempty"` GRPCClientDNSRoundRobin bool `mapstructure:"grpc_client_dns_roundrobin" yaml:"grpc_client_dns_roundrobin,omitempty"` - //GRPCServerMaxConnectionAge sets MaxConnectionAge in the grpc ServerParameters used to create GRPC Services + // GRPCServerMaxConnectionAge sets MaxConnectionAge in the grpc ServerParameters used to create GRPC Services GRPCServerMaxConnectionAge time.Duration `mapstructure:"grpc_server_max_connection_age" yaml:"grpc_server_max_connection_age,omitempty"` - //GRPCServerMaxConnectionAgeGrace sets MaxConnectionAgeGrace in the grpc ServerParameters used to create GRPC Services + // GRPCServerMaxConnectionAgeGrace sets MaxConnectionAgeGrace in the grpc ServerParameters used to create GRPC Services GRPCServerMaxConnectionAgeGrace time.Duration `mapstructure:"grpc_server_max_connection_age_grace,omitempty" yaml:"grpc_server_max_connection_age_grace,omitempty"` //nolint: lll // ForwardAuthEndpoint allows for a given route to be used as a forward-auth @@ -418,7 +418,6 @@ func (o *Options) parseHeaders() error { headerFields := strings.SplitN(headerSlice[n], ":", 2) if len(headerFields) == 2 { headers[headerFields[0]] = headerFields[1] - } else { // Something went wrong return fmt.Errorf("failed to decode headers from '%s'", o.HeadersEnv) diff --git a/config/options_test.go b/config/options_test.go index 36972e7ad..d8e87ac43 100644 --- a/config/options_test.go +++ b/config/options_test.go @@ -146,7 +146,6 @@ func Test_parseHeaders(t *testing.T) { } }) } - } func Test_parsePolicyFile(t *testing.T) { @@ -188,7 +187,6 @@ func Test_parsePolicyFile(t *testing.T) { t.Errorf("parsePolicyEnv() = diff:%s", diff) } } - }) } } @@ -227,7 +225,8 @@ func TestOptionsFromViper(t *testing.T) { want *Options wantErr bool }{ - {"good", + { + "good", []byte(`{"autocert_dir":"","insecure_server":true,"policy":[{"from": "https://from.example","to":"https://to.example"}]}`), &Options{ Policies: []Policy{{From: "https://from.example", To: "https://to.example"}}, @@ -248,8 +247,10 @@ func TestOptionsFromViper(t *testing.T) { QPS: 1.0, DataBrokerStorageType: "memory", }, - false}, - {"good disable header", + false, + }, + { + "good disable header", []byte(`{"autocert_dir":"","insecure_server":true,"headers": {"disable":"true"},"policy":[{"from": "https://from.example","to":"https://to.example"}]}`), &Options{ Policies: []Policy{{From: "https://from.example", To: "https://to.example"}}, @@ -266,7 +267,8 @@ func TestOptionsFromViper(t *testing.T) { QPS: 1.0, DataBrokerStorageType: "memory", }, - false}, + false, + }, {"bad url", []byte(`{"policy":[{"from": "https://","to":"https://to.example"}]}`), nil, true}, {"bad policy", []byte(`{"policy":[{"allow_public_unauthenticated_access": "dog","to":"https://to.example"}]}`), nil, true}, {"bad file", []byte(`{''''}`), nil, true}, @@ -358,7 +360,6 @@ func Test_AutoCertOptionsFromEnvVar(t *testing.T) { if o.AutocertOptions.Folder != "/test" { t.Errorf("o.AutocertOptions.Folder: want /test, got %s", o.AutocertOptions.Folder) } - } func TestHTTPRedirectAddressStripQuotes(t *testing.T) { @@ -440,7 +441,8 @@ func TestCompareByteSliceSlice(t *testing.T) { {0, 1, 2, 3}, }, }, - {-1, + { + -1, Bytes{ {0, 1, 2, 3}, }, @@ -449,7 +451,8 @@ func TestCompareByteSliceSlice(t *testing.T) { {4, 5, 6, 7}, }, }, - {1, + { + 1, Bytes{ {0, 1, 2, 3}, {4, 5, 6, 7}, diff --git a/integration/backends/httpdetails/main.go b/integration/backends/httpdetails/main.go index 61395413a..c1e34f231 100644 --- a/integration/backends/httpdetails/main.go +++ b/integration/backends/httpdetails/main.go @@ -12,9 +12,7 @@ import ( ) func main() { - var ( - certFile, keyFile, mutualAuthCAFile, bindAddr string - ) + var certFile, keyFile, mutualAuthCAFile, bindAddr string flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use") flag.StringVar(&keyFile, "key-file", "", "the tls key file to use") diff --git a/integration/backends/ws-echo/main.go b/integration/backends/ws-echo/main.go index 5b377981f..f928a7d30 100644 --- a/integration/backends/ws-echo/main.go +++ b/integration/backends/ws-echo/main.go @@ -10,9 +10,7 @@ import ( ) func main() { - var ( - certFile, keyFile, bindAddr string - ) + var certFile, keyFile, bindAddr string flag.StringVar(&certFile, "cert-file", "", "the tls cert file to use") flag.StringVar(&keyFile, "key-file", "", "the tls key file to use") diff --git a/integration/control_plane_test.go b/integration/control_plane_test.go index c482b09f1..fa89e05e4 100644 --- a/integration/control_plane_test.go +++ b/integration/control_plane_test.go @@ -141,5 +141,4 @@ func TestHealth(t *testing.T) { }) } } - } diff --git a/integration/internal/cluster/certs.go b/integration/internal/cluster/certs.go index 5b192fe3c..dcdea65d1 100644 --- a/integration/internal/cluster/certs.go +++ b/integration/internal/cluster/certs.go @@ -29,14 +29,14 @@ type TLSCertsBundle struct { func bootstrapCerts(ctx context.Context) (*TLSCertsBundle, error) { wd := filepath.Join(os.TempDir(), "pomerium-integration-tests", "certs") - err := os.MkdirAll(wd, 0755) + err := os.MkdirAll(wd, 0o755) if err != nil { return nil, fmt.Errorf("error creating integration tests working directory: %w", err) } var bundle TLSCertsBundle - var generators = []struct { + generators := []struct { certs *TLSCerts caroot string install bool @@ -48,7 +48,7 @@ func bootstrapCerts(ctx context.Context) (*TLSCertsBundle, error) { } for _, generator := range generators { - err = os.MkdirAll(generator.caroot, 0755) + err = os.MkdirAll(generator.caroot, 0o755) if err != nil { return nil, fmt.Errorf("error creating integration tests %s working directory: %w", filepath.Base(generator.caroot), err) diff --git a/integration/internal/cluster/setup.go b/integration/internal/cluster/setup.go index 6897285a3..7f1f5f094 100644 --- a/integration/internal/cluster/setup.go +++ b/integration/internal/cluster/setup.go @@ -72,8 +72,10 @@ func (cluster *Cluster) Setup(ctx context.Context) error { func (cluster *Cluster) GetNodePortAddr(ctx context.Context, namespace, svcName string) (hostport string, err error) { var buf bytes.Buffer - args := []string{"get", "service", "--namespace", namespace, "--output", "json", - svcName} + args := []string{ + "get", "service", "--namespace", namespace, "--output", "json", + svcName, + } err = run(ctx, "kubectl", withArgs(args...), withStdout(&buf)) if err != nil { return "", fmt.Errorf("error getting service details with kubectl: %w", err) diff --git a/integration/internal/forms/forms.go b/integration/internal/forms/forms.go index e0ccf2d6c..2161106e4 100644 --- a/integration/internal/forms/forms.go +++ b/integration/internal/forms/forms.go @@ -87,7 +87,7 @@ func (f *Form) NewRequestWithContext(ctx context.Context, baseURL *url.URL) (*ht if err != nil { return nil, err } - //TODO: handle multipart forms + // TODO: handle multipart forms req.Header.Set("Content-Type", "application/x-www-form-urlencoded") return req, nil } diff --git a/integration/internal/netutil/netutil.go b/integration/internal/netutil/netutil.go index 578a8ab95..6096bd61d 100644 --- a/integration/internal/netutil/netutil.go +++ b/integration/internal/netutil/netutil.go @@ -46,5 +46,4 @@ func (d *localDialer) remapHost(ctx context.Context, hostport string) string { } return dst - } diff --git a/integration/policy_test.go b/integration/policy_test.go index 9e336df5a..50dadb61a 100644 --- a/integration/policy_test.go +++ b/integration/policy_test.go @@ -115,7 +115,6 @@ func TestPreserveHostHeader(t *testing.T) { assert.NotEqual(t, "httpdetails.localhost.pomerium.io", result.Host, "destination host should not be preserved in %v", result) }) - } func TestSetRequestHeaders(t *testing.T) { @@ -146,7 +145,6 @@ func TestSetRequestHeaders(t *testing.T) { assert.Equal(t, "custom-request-header-value", result.Headers["X-Custom-Request-Header"], "expected custom request header to be sent upstream") - } func TestRemoveRequestHeaders(t *testing.T) { @@ -178,7 +176,6 @@ func TestRemoveRequestHeaders(t *testing.T) { _, exist := result.Headers["X-Custom-Request-Header-To-Remove"] assert.False(t, exist, "expected X-Custom-Request-Header-To-Remove not to be present.") - } func TestWebsocket(t *testing.T) { diff --git a/internal/autocert/manager_test.go b/internal/autocert/manager_test.go index 5b3b9f0e0..28a813c25 100644 --- a/internal/autocert/manager_test.go +++ b/internal/autocert/manager_test.go @@ -130,7 +130,7 @@ func TestConfig(t *testing.T) { mockACME = newMockACME(srv) tmpdir := filepath.Join(os.TempDir(), uuid.New().String()) - _ = os.MkdirAll(tmpdir, 0755) + _ = os.MkdirAll(tmpdir, 0o755) defer os.RemoveAll(tmpdir) li, err := net.Listen("tcp", "127.0.0.1:0") diff --git a/internal/cliutil/jwtcache.go b/internal/cliutil/jwtcache.go index 71afd21a2..e69d0a119 100644 --- a/internal/cliutil/jwtcache.go +++ b/internal/cliutil/jwtcache.go @@ -44,7 +44,7 @@ func NewLocalJWTCache() (*LocalJWTCache, error) { dir := filepath.Join(root, "pomerium-cli", "jwts") - err = os.MkdirAll(dir, 0755) + err = os.MkdirAll(dir, 0o755) if err != nil { return nil, fmt.Errorf("error creating user cache directory: %w", err) } @@ -81,7 +81,7 @@ func (cache *LocalJWTCache) LoadJWT(key string) (rawJWT string, err error) { // StoreJWT stores a raw JWT in the local cache. func (cache *LocalJWTCache) StoreJWT(key string, rawJWT string) error { path := filepath.Join(cache.dir, cache.fileName(key)) - err := ioutil.WriteFile(path, []byte(rawJWT), 0600) + err := ioutil.WriteFile(path, []byte(rawJWT), 0o600) if err != nil { return err } diff --git a/internal/cliutil/jwtcache_test.go b/internal/cliutil/jwtcache_test.go index 984adbbdd..c42dc1818 100644 --- a/internal/cliutil/jwtcache_test.go +++ b/internal/cliutil/jwtcache_test.go @@ -19,7 +19,7 @@ func TestLocalJWTCache(t *testing.T) { dir: filepath.Join(os.TempDir(), uuid.New().String()), } - err := os.MkdirAll(c.dir, 0755) + err := os.MkdirAll(c.dir, 0o755) if !assert.NoError(t, err) { return } diff --git a/internal/controlplane/grpc_xds.go b/internal/controlplane/grpc_xds.go index 1c2907b5a..d404f3e53 100644 --- a/internal/controlplane/grpc_xds.go +++ b/internal/controlplane/grpc_xds.go @@ -132,5 +132,5 @@ func (srv *Server) streamAggregatedResourcesOutgoingStep( // DeltaAggregatedResources is not implemented. func (srv *Server) DeltaAggregatedResources(in envoy_service_discovery_v3.AggregatedDiscoveryService_DeltaAggregatedResourcesServer) error { - return fmt.Errorf("DeltaAggregatedResources not implemented") + return fmt.Errorf("method DeltaAggregatedResources not implemented") } diff --git a/internal/controlplane/xds.go b/internal/controlplane/xds.go index 3dddd3930..20468ec7b 100644 --- a/internal/controlplane/xds.go +++ b/internal/controlplane/xds.go @@ -143,14 +143,14 @@ func inlineBytesAsFilename(name string, bs []byte) *envoy_config_core_v3.DataSou cacheDir = filepath.Join(os.TempDir()) } cacheDir = filepath.Join(cacheDir, "pomerium", "envoy", "files") - if err = os.MkdirAll(cacheDir, 0755); err != nil { + if err = os.MkdirAll(cacheDir, 0o755); err != nil { log.Error().Err(err).Msg("error creating cache directory, falling back to inline bytes") return inlineBytes(bs) } fp := filepath.Join(cacheDir, name) if _, err = os.Stat(fp); os.IsNotExist(err) { - err = ioutil.WriteFile(fp, bs, 0600) + err = ioutil.WriteFile(fp, bs, 0o600) if err != nil { log.Error().Err(err).Msg("error writing cache file, falling back to inline bytes") return inlineBytes(bs) @@ -227,7 +227,6 @@ func getRootCertificateAuthority() (string, error) { log.Error().Strs("known-locations", knownRootLocations). Msgf("no root certificates were found in any of the known locations") } else { - log.Info().Msgf("using %s as the system root certificate authority bundle", rootCABundle.value) } }) diff --git a/internal/controlplane/xds_clusters.go b/internal/controlplane/xds_clusters.go index 5ea2f7214..066c42c7c 100644 --- a/internal/controlplane/xds_clusters.go +++ b/internal/controlplane/xds_clusters.go @@ -41,7 +41,8 @@ func (srv *Server) buildClusters(options *config.Options) []*envoy_config_cluste clusters = append(clusters, buildInternalCluster(options, authzURL.Host, authzURL, true)) if config.IsProxy(options.Services) { - for _, policy := range options.Policies { + for i := range options.Policies { + policy := options.Policies[i] clusters = append(clusters, buildPolicyCluster(options, &policy)) } } diff --git a/internal/controlplane/xds_routes.go b/internal/controlplane/xds_routes.go index fb0814d31..bbae1a97c 100644 --- a/internal/controlplane/xds_routes.go +++ b/internal/controlplane/xds_routes.go @@ -180,7 +180,8 @@ func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_r var routes []*envoy_config_route_v3.Route responseHeadersToAdd := toEnvoyHeaders(options.Headers) - for i, policy := range options.Policies { + for i := range options.Policies { + policy := options.Policies[i] if !hostMatchesDomain(policy.Source.URL, domain) { continue } diff --git a/internal/controlplane/xds_routes_test.go b/internal/controlplane/xds_routes_test.go index 9cfdb9f3a..575524146 100644 --- a/internal/controlplane/xds_routes_test.go +++ b/internal/controlplane/xds_routes_test.go @@ -536,7 +536,6 @@ func Test_buildPolicyRoutes(t *testing.T) { } ] `, routes) - }) } diff --git a/internal/databroker/config_source.go b/internal/databroker/config_source.go index d9a754300..537045252 100644 --- a/internal/databroker/config_source.go +++ b/internal/databroker/config_source.go @@ -19,9 +19,7 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/databroker" ) -var ( - configTypeURL string -) +var configTypeURL string func init() { any, _ := ptypes.MarshalAny(new(configpb.Config)) diff --git a/internal/directory/auth0/auth0_test.go b/internal/directory/auth0/auth0_test.go index 451d48ff1..7eaf5fdab 100644 --- a/internal/directory/auth0/auth0_test.go +++ b/internal/directory/auth0/auth0_test.go @@ -275,7 +275,6 @@ func TestProvider_UserGroups(t *testing.T) { listOptionMatcher{expected: management.IncludeTotals(true)}, listOptionMatcher{expected: management.Page(0)}, ).Return(&management.UserList{}, nil) - }, expectedGroups: []*directory.Group{ { @@ -351,7 +350,6 @@ func TestProvider_UserGroups(t *testing.T) { {ID: stringPtr("i-am-user-id-3")}, }, }, nil) - }, expectedGroups: []*directory.Group{ { @@ -507,7 +505,6 @@ func TestProvider_UserGroups(t *testing.T) { assert.Equal(t, expectedServiceAccount, mNewManagersFunc.CalledWithServiceAccount) }) } - } func TestParseServiceAccount(t *testing.T) { @@ -517,7 +514,8 @@ func TestParseServiceAccount(t *testing.T) { expectedServiceAccount *ServiceAccount expectedError error }{ - {"valid", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCIsInNlY3JldCI6ImktYW0tc2VjcmV0In0K", + { + "valid", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCIsInNlY3JldCI6ImktYW0tc2VjcmV0In0K", &ServiceAccount{ ClientID: "i-am-client-id", Secret: "i-am-secret", diff --git a/internal/directory/auth0/mock_auth0/mock.go b/internal/directory/auth0/mock_auth0/mock.go index 09eaf5fb6..b9299b122 100644 --- a/internal/directory/auth0/mock_auth0/mock.go +++ b/internal/directory/auth0/mock_auth0/mock.go @@ -5,9 +5,10 @@ package mock_auth0 import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" management "gopkg.in/auth0.v4/management" - reflect "reflect" ) // MockRoleManager is a mock of RoleManager interface diff --git a/internal/directory/github/github.go b/internal/directory/github/github.go index c30e73166..e9f014b96 100644 --- a/internal/directory/github/github.go +++ b/internal/directory/github/github.go @@ -24,12 +24,10 @@ import ( // Name is the provider name. const Name = "github" -var ( - defaultURL = &url.URL{ - Scheme: "https", - Host: "api.github.com", - } -) +var defaultURL = &url.URL{ + Scheme: "https", + Host: "api.github.com", +} type config struct { httpClient *http.Client diff --git a/internal/directory/gitlab/gitlab.go b/internal/directory/gitlab/gitlab.go index fec3f243f..ade66c563 100644 --- a/internal/directory/gitlab/gitlab.go +++ b/internal/directory/gitlab/gitlab.go @@ -22,12 +22,10 @@ import ( // Name is the provider name. const Name = "gitlab" -var ( - defaultURL = &url.URL{ - Scheme: "https", - Host: "gitlab.com", - } -) +var defaultURL = &url.URL{ + Scheme: "https", + Host: "gitlab.com", +} type config struct { httpClient *http.Client diff --git a/internal/encoding/ecjson/ecjson.go b/internal/encoding/ecjson/ecjson.go index f73e574f6..61bb43628 100644 --- a/internal/encoding/ecjson/ecjson.go +++ b/internal/encoding/ecjson/ecjson.go @@ -7,6 +7,7 @@ import ( "crypto/cipher" "encoding/base64" "encoding/json" + "errors" "fmt" "io" @@ -14,6 +15,12 @@ import ( "github.com/pomerium/pomerium/pkg/cryptutil" ) +// 10mb reasonable default? +const maxMemory = int64(10 << 20) + +// ErrMessageTooLarge is returned if the data is too large to be processed. +var ErrMessageTooLarge = errors.New("ecjson: message too large") + // EncryptedCompressedJSON implements SecureEncoder for JSON using an AEAD cipher. // // See https://en.wikipedia.org/wiki/Authenticated_encryption @@ -74,7 +81,6 @@ func (c *EncryptedCompressedJSON) Unmarshal(data []byte, s interface{}) error { return err } return nil - } // compress gzips a set of bytes @@ -104,8 +110,12 @@ func decompress(data []byte) ([]byte, error) { } defer reader.Close() var buf bytes.Buffer - if _, err = io.Copy(&buf, reader); err != nil { + n, err := io.CopyN(&buf, reader, maxMemory+1) + if err != nil && err != io.EOF { return nil, err } + if n > maxMemory { + return nil, ErrMessageTooLarge + } return buf.Bytes(), nil } diff --git a/internal/encoding/mock/mock_encoder.go b/internal/encoding/mock/mock_encoder.go index 384d4615b..6166fe0be 100644 --- a/internal/encoding/mock/mock_encoder.go +++ b/internal/encoding/mock/mock_encoder.go @@ -5,9 +5,11 @@ import ( "github.com/pomerium/pomerium/internal/encoding" ) -var _ encoding.MarshalUnmarshaler = &Encoder{} -var _ encoding.Marshaler = &Encoder{} -var _ encoding.Unmarshaler = &Encoder{} +var ( + _ encoding.MarshalUnmarshaler = &Encoder{} + _ encoding.Marshaler = &Encoder{} + _ encoding.Unmarshaler = &Encoder{} +) // Encoder MockCSRFStore is a mock implementation of Cipher. type Encoder struct { diff --git a/internal/envoy/embed.go b/internal/envoy/embed.go index fdc10c23f..10c159e32 100644 --- a/internal/envoy/embed.go +++ b/internal/envoy/embed.go @@ -28,7 +28,7 @@ func extractEmbeddedEnvoy() (outPath string, err error) { } defer rc.Close() - err = os.MkdirAll(embeddedFilesDirectory, 0755) + err = os.MkdirAll(embeddedFilesDirectory, 0o755) if err != nil { return "", fmt.Errorf("error creating embedded file directory: (directory=%s): %w", embeddedFilesDirectory, err) } @@ -51,7 +51,7 @@ func extractEmbeddedEnvoy() (outPath string, err error) { return "", fmt.Errorf("error extracting embedded envoy binary to temporary directory (path=%s): %w", outPath, err) } - err = os.Chmod(outPath, 0755) + err = os.Chmod(outPath, 0o755) if err != nil { return "", fmt.Errorf("error chmoding embedded envoy binary: %w", err) } diff --git a/internal/envoy/envoy.go b/internal/envoy/envoy.go index a07f57636..0afb5ba14 100644 --- a/internal/envoy/envoy.go +++ b/internal/envoy/envoy.go @@ -65,7 +65,7 @@ type Server struct { // NewServer creates a new server with traffic routed by envoy. func NewServer(src config.Source, grpcPort, httpPort string) (*Server, error) { wd := filepath.Join(os.TempDir(), workingDirectoryName) - err := os.MkdirAll(wd, 0755) + err := os.MkdirAll(wd, 0o755) if err != nil { return nil, fmt.Errorf("error creating temporary working directory for envoy: %w", err) } diff --git a/internal/fileutil/fileutil_test.go b/internal/fileutil/fileutil_test.go index 4ec0f5c9a..4361827a1 100644 --- a/internal/fileutil/fileutil_test.go +++ b/internal/fileutil/fileutil_test.go @@ -6,7 +6,6 @@ import ( ) func TestIsReadableFile(t *testing.T) { - tests := []struct { name string args string diff --git a/internal/hashutil/hashutil_test.go b/internal/hashutil/hashutil_test.go index 6b2d6c707..64aa3c00f 100644 --- a/internal/hashutil/hashutil_test.go +++ b/internal/hashutil/hashutil_test.go @@ -17,20 +17,26 @@ func TestHash(t *testing.T) { }{ {"string", "string", 6134271061086542852, false}, {"num", 7, 609900476111905877, false}, - {"compound struct", struct { - NESCarts []string - numberOfCarts int - }{ - []string{"Battletoads", "Mega Man 1", "Clash at Demonhead"}, - 12, + { + "compound struct", + struct { + NESCarts []string + numberOfCarts int + }{ + []string{"Battletoads", "Mega Man 1", "Clash at Demonhead"}, + 12, + }, + 1349584765528830812, false, }, - 1349584765528830812, false}, - {"compound struct with embedded func (errors!)", struct { - AnswerToEverythingFn func() int - }{ - func() int { return 42 }, + { + "compound struct with embedded func (errors!)", + struct { + AnswerToEverythingFn func() int + }{ + func() int { return 42 }, + }, + 0, true, }, - 0, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/httputil/errors.go b/internal/httputil/errors.go index 9654bfad0..ef1b16b77 100644 --- a/internal/httputil/errors.go +++ b/internal/httputil/errors.go @@ -10,8 +10,10 @@ import ( "github.com/pomerium/pomerium/internal/version" ) -var errorTemplate = template.Must(frontend.NewTemplates()) -var fullVersion = version.FullVersion() +var ( + errorTemplate = template.Must(frontend.NewTemplates()) + fullVersion = version.FullVersion() +) // HTTPError contains an HTTP status code and wrapped error. type HTTPError struct { diff --git a/internal/httputil/errors_test.go b/internal/httputil/errors_test.go index 7069d9af7..c073852a5 100644 --- a/internal/httputil/errors_test.go +++ b/internal/httputil/errors_test.go @@ -10,7 +10,6 @@ import ( ) func TestHTTPError_ErrorResponse(t *testing.T) { - tests := []struct { name string Status int @@ -46,7 +45,6 @@ func TestHTTPError_ErrorResponse(t *testing.T) { t.Errorf("ErrorResponse status:\n %s", diff) } } - }) } } @@ -69,7 +67,6 @@ func TestNewError(t *testing.T) { if err != nil && !errors.Is(err, tt.err) { t.Errorf("NewError() unwrap fail = %v, wantErr %v", err, tt.wantErr) } - }) } } diff --git a/internal/httputil/handlers_test.go b/internal/httputil/handlers_test.go index d5a04f2e8..2786bae9c 100644 --- a/internal/httputil/handlers_test.go +++ b/internal/httputil/handlers_test.go @@ -28,7 +28,6 @@ func TestHealthCheck(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := httptest.NewRequest(tt.method, "/", nil) w := httptest.NewRecorder() @@ -56,7 +55,6 @@ func TestRedirect(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := httptest.NewRequest(tt.method, "/", nil) w := httptest.NewRecorder() @@ -72,7 +70,6 @@ func TestRedirect(t *testing.T) { } func TestHandlerFunc_ServeHTTP(t *testing.T) { - tests := []struct { name string f HandlerFunc @@ -95,7 +92,6 @@ func TestHandlerFunc_ServeHTTP(t *testing.T) { } func TestRenderJSON(t *testing.T) { - tests := []struct { name string code int @@ -103,7 +99,8 @@ func TestRenderJSON(t *testing.T) { wantBody string wantCode int }{ - {"simple", + { + "simple", http.StatusTeapot, struct { A string @@ -117,7 +114,8 @@ func TestRenderJSON(t *testing.T) { "{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n", http.StatusTeapot, }, - {"map", + { + "map", http.StatusOK, map[string]interface{}{ "C": 1, // notice order does not matter @@ -127,12 +125,14 @@ func TestRenderJSON(t *testing.T) { // alphabetical "{\"A\":\"A\",\"B\":\"B\",\"C\":1}\n", http.StatusOK, }, - {"bad!", + { + "bad!", http.StatusOK, map[string]interface{}{ "BAD BOI": math.Inf(1), }, - `{"error":"json: unsupported value: +Inf"}`, http.StatusInternalServerError}, + `{"error":"json: unsupported value: +Inf"}`, http.StatusInternalServerError, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/httputil/router.go b/internal/httputil/router.go index f68ac7e0f..982a11f66 100644 --- a/internal/httputil/router.go +++ b/internal/httputil/router.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/pomerium/csrf" ) diff --git a/internal/httputil/server_test.go b/internal/httputil/server_test.go index 8321cf7db..78310d290 100644 --- a/internal/httputil/server_test.go +++ b/internal/httputil/server_test.go @@ -18,7 +18,6 @@ import ( ) func TestNewServer(t *testing.T) { - // to support envs that won't let us use 443 without root defaultServerOptions.Addr = ":0" @@ -31,7 +30,8 @@ func TestNewServer(t *testing.T) { wantErr bool }{ - {"good basic http handler", + { + "good basic http handler", &ServerOptions{ Addr: ":0", Insecure: true, @@ -39,45 +39,56 @@ func TestNewServer(t *testing.T) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - false}, - {"bad neither insecure nor certs set", + false, + }, + { + "bad neither insecure nor certs set", &ServerOptions{ Addr: ":0", }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - true}, - {"good no address", + true, + }, + { + "good no address", &ServerOptions{ Insecure: true, }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - false}, - {"empty handler", + false, + }, + { + "empty handler", nil, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - true}, - {"bad port - invalid port range ", + true, + }, + { + "bad port - invalid port range ", &ServerOptions{ Addr: ":65536", Insecure: true, }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - true}, - {"good tls set", + true, + }, + { + "good tls set", &ServerOptions{ TLSConfig: &tls.Config{}, }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, http") }), - false}, + false, + }, } for _, tt := range tests { @@ -113,10 +124,10 @@ func TestNewServer(t *testing.T) { syscall.Kill(syscall.Getpid(), syscall.SIGINT) waitSig(t, c, syscall.SIGINT) } - }) } } + func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { select { case s := <-c: diff --git a/internal/log/log_test.go b/internal/log/log_test.go index 2acf18abb..77bb65237 100644 --- a/internal/log/log_test.go +++ b/internal/log/log_test.go @@ -41,7 +41,6 @@ func ExampleWith() { sublog := log.With().Str("foo", "bar").Logger() sublog.Debug().Msg("hello world") // Output: {"level":"debug","foo":"bar","time":1199811905,"message":"hello world"} - } // Simple logging example using the Printf function in the log package diff --git a/internal/log/middleware_test.go b/internal/log/middleware_test.go index f311cae05..dff755b55 100644 --- a/internal/log/middleware_test.go +++ b/internal/log/middleware_test.go @@ -292,6 +292,7 @@ func TestLogHeadersHandler(t *testing.T) { t.Errorf("Invalid log output, got: %s, want: %s", got, want) } } + func TestAccessHandler(t *testing.T) { out := &bytes.Buffer{} @@ -300,7 +301,6 @@ func TestAccessHandler(t *testing.T) { h := AccessHandler(func(r *http.Request, status, size int, duration time.Duration) { l := FromRequest(r) l.Log().Int("status", status).Int("size", size).Msg("info") - })(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { l := FromRequest(r) l.Log().Msg("some inner logging") @@ -316,5 +316,4 @@ func TestAccessHandler(t *testing.T) { if diff := cmp.Diff(want, got); diff != "" { t.Errorf("TestAccessHandler: %s", diff) } - } diff --git a/internal/middleware/middleware_test.go b/internal/middleware/middleware_test.go index 1075faca1..cb0fc72d6 100644 --- a/internal/middleware/middleware_test.go +++ b/internal/middleware/middleware_test.go @@ -32,7 +32,6 @@ func TestSetHeaders(t *testing.T) { if got := w.Header().Get(k); want != got { t.Errorf("want %s got %q", want, got) } - } }) rr := httptest.NewRecorder() @@ -80,7 +79,6 @@ func TestStripCookie(t *testing.T) { handler := StripCookie(tt.pomeriumCookie)(testHandler) handler.ServeHTTP(rr, req) - }) } } diff --git a/internal/middleware/responsewriter/wrap_writer.go b/internal/middleware/responsewriter/wrap_writer.go index 0309a3473..6bf031131 100644 --- a/internal/middleware/responsewriter/wrap_writer.go +++ b/internal/middleware/responsewriter/wrap_writer.go @@ -162,10 +162,12 @@ func (f *httpFancyWriter) ReadFrom(r io.Reader) (int64, error) { return n, err } -var _ http.Flusher = &httpFancyWriter{} -var _ http.Hijacker = &httpFancyWriter{} -var _ http.Pusher = &http2FancyWriter{} -var _ io.ReaderFrom = &httpFancyWriter{} +var ( + _ http.Flusher = &httpFancyWriter{} + _ http.Hijacker = &httpFancyWriter{} + _ http.Pusher = &http2FancyWriter{} + _ io.ReaderFrom = &httpFancyWriter{} +) // http2FancyWriter is a HTTP2 writer that additionally satisfies // http.Flusher, and io.ReaderFrom. It exists for the common case diff --git a/internal/sessions/cookie/cookie_store.go b/internal/sessions/cookie/cookie_store.go index dc13ca905..a06d9f9dd 100644 --- a/internal/sessions/cookie/cookie_store.go +++ b/internal/sessions/cookie/cookie_store.go @@ -12,8 +12,10 @@ import ( "github.com/pomerium/pomerium/internal/sessions" ) -var _ sessions.SessionStore = &Store{} -var _ sessions.SessionLoader = &Store{} +var ( + _ sessions.SessionStore = &Store{} + _ sessions.SessionLoader = &Store{} +) // timeNow is time.Now but pulled out as a variable for tests. var timeNow = time.Now diff --git a/internal/sessions/cookie/cookie_store_test.go b/internal/sessions/cookie/cookie_store_test.go index a4a4fb75d..2c7ad51a1 100644 --- a/internal/sessions/cookie/cookie_store_test.go +++ b/internal/sessions/cookie/cookie_store_test.go @@ -56,6 +56,7 @@ func TestNewStore(t *testing.T) { }) } } + func TestNewCookieLoader(t *testing.T) { cipher, err := cryptutil.NewAEADCipher(cryptutil.NewKey()) if err != nil { diff --git a/internal/sessions/middleware_test.go b/internal/sessions/middleware_test.go index 10640e14d..be09fda9c 100644 --- a/internal/sessions/middleware_test.go +++ b/internal/sessions/middleware_test.go @@ -97,7 +97,6 @@ func TestVerifier(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := httptest.NewRequest(http.MethodGet, "/", nil) r.Header.Set("Accept", "application/json") w := httptest.NewRecorder() diff --git a/internal/sessions/mock/mock_store.go b/internal/sessions/mock/mock_store.go index c880b98ed..058787d90 100644 --- a/internal/sessions/mock/mock_store.go +++ b/internal/sessions/mock/mock_store.go @@ -9,8 +9,10 @@ import ( "github.com/pomerium/pomerium/internal/sessions" ) -var _ sessions.SessionStore = &Store{} -var _ sessions.SessionLoader = &Store{} +var ( + _ sessions.SessionStore = &Store{} + _ sessions.SessionLoader = &Store{} +) // Store is a mock implementation of the SessionStore interface type Store struct { diff --git a/internal/sessions/mock/mock_store_test.go b/internal/sessions/mock/mock_store_test.go index f20d70322..026257f5b 100644 --- a/internal/sessions/mock/mock_store_test.go +++ b/internal/sessions/mock/mock_store_test.go @@ -17,7 +17,8 @@ func TestStore(t *testing.T) { wantLoadErr bool wantSaveErr bool }{ - {"basic", + { + "basic", &Store{ ResponseSession: "test", Session: &sessions.State{Subject: "0101"}, @@ -27,7 +28,8 @@ func TestStore(t *testing.T) { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtYXRpYyI6ZmFsc2UsInN1YiI6IjAxMDEifQ.xQQPXGN3q3j_CHbz6p9D-vZ1DaiPWwKdQhNxNHoYzvM", &sessions.State{Subject: "0101"}, false, - false}, + false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/sessions/queryparam/query_store.go b/internal/sessions/queryparam/query_store.go index 46008149a..c4f1e277c 100644 --- a/internal/sessions/queryparam/query_store.go +++ b/internal/sessions/queryparam/query_store.go @@ -9,8 +9,10 @@ import ( "github.com/pomerium/pomerium/internal/sessions" ) -var _ sessions.SessionStore = &Store{} -var _ sessions.SessionLoader = &Store{} +var ( + _ sessions.SessionStore = &Store{} + _ sessions.SessionLoader = &Store{} +) const ( defaultQueryParamKey = "pomerium_session" diff --git a/internal/sessions/queryparam/query_store_test.go b/internal/sessions/queryparam/query_store_test.go index 36f82b176..2777d9412 100644 --- a/internal/sessions/queryparam/query_store_test.go +++ b/internal/sessions/queryparam/query_store_test.go @@ -14,7 +14,6 @@ import ( ) func TestNewQueryParamStore(t *testing.T) { - tests := []struct { name string State *sessions.State diff --git a/internal/telemetry/grpc.go b/internal/telemetry/grpc.go index 339a68d90..41909158a 100644 --- a/internal/telemetry/grpc.go +++ b/internal/telemetry/grpc.go @@ -23,7 +23,6 @@ type GRPCServerStatsHandler struct { // TagRPC implements grpc.stats.Handler and adds metrics and tracing metadata to the context of a given RPC func (h *GRPCServerStatsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context { - handledCtx := h.Handler.TagRPC(ctx, tagInfo) metricCtx := h.metricsHandler.TagRPC(handledCtx, tagInfo) diff --git a/internal/telemetry/grpc_test.go b/internal/telemetry/grpc_test.go index d2e208f2b..a50664f68 100644 --- a/internal/telemetry/grpc_test.go +++ b/internal/telemetry/grpc_test.go @@ -21,7 +21,6 @@ func (m *mockTagHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagIn } func Test_GRPCServerStatsHandler(t *testing.T) { - metricsHandler := &mockTagHandler{} h := &GRPCServerStatsHandler{ metricsHandler: metricsHandler, diff --git a/internal/telemetry/http.go b/internal/telemetry/http.go index 02f5f6d32..41f289e3c 100644 --- a/internal/telemetry/http.go +++ b/internal/telemetry/http.go @@ -8,12 +8,10 @@ import ( // HTTPStatsRoundTripper creates tracing and metrics RoundTripper for a pomerium service func HTTPStatsRoundTripper(service string, destination string) func(next http.RoundTripper) http.RoundTripper { - return metrics.HTTPMetricsRoundTripper(ServiceName(service), destination) } // HTTPStatsHandler creates tracing and metrics Handler for a pomerium service func HTTPStatsHandler(service string) func(next http.Handler) http.Handler { - return metrics.HTTPMetricsHandler(ServiceName(service)) } diff --git a/internal/telemetry/metrics/grpc.go b/internal/telemetry/metrics/grpc.go index c51e7b36a..ef992766b 100644 --- a/internal/telemetry/metrics/grpc.go +++ b/internal/telemetry/metrics/grpc.go @@ -20,13 +20,15 @@ var ( GRPCClientRequestCountView, GRPCClientRequestDurationView, GRPCClientResponseSizeView, - GRPCClientRequestSizeView} + GRPCClientRequestSizeView, + } // GRPCServerViews contains opencensus views for GRPC Server metrics. GRPCServerViews = []*view.View{ GRPCServerRequestCountView, GRPCServerRequestDurationView, GRPCServerResponseSizeView, - GRPCServerRequestSizeView} + GRPCServerRequestSizeView, + } // GRPCServerRequestCountView is an OpenCensus view which counts GRPC Server // requests by pomerium service, grpc service, grpc method, and status @@ -123,7 +125,6 @@ func GRPCClientInterceptor(service string) grpc.UnaryClientInterceptor { cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - // Split the method into parts for better slicing rpcInfo := strings.SplitN(method, "/", 3) var rpcMethod string @@ -148,7 +149,6 @@ func GRPCClientInterceptor(service string) grpc.UnaryClientInterceptor { // Calls the invoker to execute RPC return invoker(taggedCtx, method, req, reply, cc, opts...) } - } // GRPCServerMetricsHandler implements a telemetry tagRPCHandler methods for metrics @@ -163,7 +163,6 @@ func NewGRPCServerMetricsHandler(service string) *GRPCServerMetricsHandler { // TagRPC handles adding any metrics related values to the incoming context func (h *GRPCServerMetricsHandler) TagRPC(ctx context.Context, tagInfo *grpcstats.RPCTagInfo) context.Context { - // Split the method into parts for better slicing rpcInfo := strings.SplitN(tagInfo.FullMethodName, "/", 3) var rpcMethod string diff --git a/internal/telemetry/metrics/grpc_test.go b/internal/telemetry/metrics/grpc_test.go index 641aeacf8..96ba28dab 100644 --- a/internal/telemetry/metrics/grpc_test.go +++ b/internal/telemetry/metrics/grpc_test.go @@ -55,8 +55,8 @@ func newTestCC(t *testing.T) *grpc.ClientConn { } return testCC } -func Test_GRPCClientInterceptor(t *testing.T) { +func Test_GRPCClientInterceptor(t *testing.T) { interceptor := GRPCClientInterceptor("test_service") tests := []struct { @@ -99,7 +99,6 @@ func Test_GRPCClientInterceptor(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - view.Unregister(GRPCClientViews...) view.Register(GRPCClientViews...) @@ -115,7 +114,6 @@ func Test_GRPCClientInterceptor(t *testing.T) { testDataRetrieval(GRPCClientRequestDurationView, t, tt.wantgrpcClientRequestDuration) testDataRetrieval(GRPCClientRequestCountView, t, tt.wantgrpcClientRequestCount) testDataRetrieval(GRPCClientRequestSizeView, t, tt.wantgrpcClientRequestSize) - }) } } @@ -128,8 +126,8 @@ func mockServerRPCHandle(metricsHandler *GRPCServerMetricsHandler, method string statsHandler.HandleRPC(ctx, &stats.InPayload{Client: false, Length: len(message)}) statsHandler.HandleRPC(ctx, &stats.OutPayload{Client: false, Length: len(message)}) statsHandler.HandleRPC(ctx, &stats.End{Client: false, Error: errorCode}) - } + func Test_GRPCServerMetricsHandler(t *testing.T) { tests := []struct { name string @@ -171,7 +169,6 @@ func Test_GRPCServerMetricsHandler(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - view.Unregister(GRPCServerViews...) view.Register(GRPCServerViews...) @@ -182,7 +179,6 @@ func Test_GRPCServerMetricsHandler(t *testing.T) { testDataRetrieval(GRPCServerRequestDurationView, t, tt.wantgrpcServerRequestDuration) testDataRetrieval(GRPCServerRequestCountView, t, tt.wantgrpcServerRequestCount) testDataRetrieval(GRPCServerRequestSizeView, t, tt.wantgrpcServerRequestSizeView) - }) } } diff --git a/internal/telemetry/metrics/http.go b/internal/telemetry/metrics/http.go index a553eecf2..ddced1a6d 100644 --- a/internal/telemetry/metrics/http.go +++ b/internal/telemetry/metrics/http.go @@ -18,13 +18,15 @@ var ( HTTPClientViews = []*view.View{ HTTPClientRequestCountView, HTTPClientRequestDurationView, - HTTPClientResponseSizeView} + HTTPClientResponseSizeView, + } // HTTPServerViews contains opencensus views for HTTP Server metrics. HTTPServerViews = []*view.View{ HTTPServerRequestCountView, HTTPServerRequestDurationView, HTTPServerRequestSizeView, - HTTPServerResponseSizeView} + HTTPServerResponseSizeView, + } // HTTPServerRequestCountView is an OpenCensus View that tracks HTTP server // requests by pomerium service, host, method and status @@ -97,7 +99,7 @@ var ( } // HTTPClientRequestSizeView is an OpenCensus view that tracks HTTP client - //request size by pomerium service, destination, host and method + // request size by pomerium service, destination, host and method HTTPClientRequestSizeView = &view.View{ Name: "http/client/response_size_bytes", Measure: ochttp.ClientSentBytes, diff --git a/internal/telemetry/metrics/http_test.go b/internal/telemetry/metrics/http_test.go index fbad2488a..69a042a29 100644 --- a/internal/telemetry/metrics/http_test.go +++ b/internal/telemetry/metrics/http_test.go @@ -22,7 +22,6 @@ func testDataRetrieval(v *view.View, t *testing.T, want string) { } name := v.Name data, err := view.RetrieveData(name) - if err != nil { t.Fatalf("%s: failed to retrieve data line %s", name, err) } @@ -53,7 +52,6 @@ func newTestMux() http.Handler { } func Test_HTTPMetricsHandler(t *testing.T) { - tests := []struct { name string url string diff --git a/internal/telemetry/metrics/info.go b/internal/telemetry/metrics/info.go index 4ba2560bd..e596de179 100644 --- a/internal/telemetry/metrics/info.go +++ b/internal/telemetry/metrics/info.go @@ -50,7 +50,6 @@ var ( // SetConfigInfo records the status, checksum and timestamp of a configuration // reload. You must register InfoViews or the related config views before calling func SetConfigInfo(service string, success bool) { - if success { serviceTag := tag.Insert(TagKeyService, service) if err := stats.RecordWithTags( diff --git a/internal/telemetry/metrics/kv_test.go b/internal/telemetry/metrics/kv_test.go index d0a7f81ce..8a9adfa18 100644 --- a/internal/telemetry/metrics/kv_test.go +++ b/internal/telemetry/metrics/kv_test.go @@ -30,5 +30,4 @@ func Test_AddRedisMetrics(t *testing.T) { testMetricRetrieval(registry.registry.Read(), t, labelValues, tt.want, tt.name) }) } - } diff --git a/internal/telemetry/metrics/providers.go b/internal/telemetry/metrics/providers.go index 6521fde68..d92eb981e 100644 --- a/internal/telemetry/metrics/providers.go +++ b/internal/telemetry/metrics/providers.go @@ -74,7 +74,6 @@ func registerDefaultViews() error { // newProxyMetricsHandler creates a subrequest to the envoy control plane for metrics and // combines them with our own func newProxyMetricsHandler(promHandler http.Handler, envoyURL url.URL) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { defer promHandler.ServeHTTP(w, r) diff --git a/internal/telemetry/metrics/providers_test.go b/internal/telemetry/metrics/providers_test.go index a366db2c7..b5a499caa 100644 --- a/internal/telemetry/metrics/providers_test.go +++ b/internal/telemetry/metrics/providers_test.go @@ -10,7 +10,6 @@ import ( ) func newEnvoyMetricsHandler() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(` # TYPE envoy_server_initialization_time_ms histogram @@ -47,7 +46,6 @@ func getMetrics(t *testing.T, envoyURL *url.URL) []byte { } func Test_PrometheusHandler(t *testing.T) { - t.Run("no envoy", func(t *testing.T) { b := getMetrics(t, &url.URL{}) @@ -67,7 +65,5 @@ func Test_PrometheusHandler(t *testing.T) { if m, _ := regexp.Match(`(?m)^# TYPE envoy_.*`, b); !m { t.Errorf("Metrics endpoint did not contain envoy metrics: %s", b) } - }) - } diff --git a/internal/telemetry/metrics/registry.go b/internal/telemetry/metrics/registry.go index 79005b504..1d3efd80f 100644 --- a/internal/telemetry/metrics/registry.go +++ b/internal/telemetry/metrics/registry.go @@ -11,9 +11,7 @@ import ( "github.com/pomerium/pomerium/internal/version" ) -var ( - registry = newMetricRegistry() -) +var registry = newMetricRegistry() // metricRegistry holds the non-view metrics and handles safe // initialization and updates. Behavior without using newMetricRegistry() @@ -108,7 +106,6 @@ func (r *metricRegistry) setConfigChecksum(service string, checksum uint64) { } func (r *metricRegistry) addInt64DerivedGaugeMetric(name string, desc string, service string, f func() int64) { - m, err := r.registry.AddInt64DerivedGauge(name, metric.WithDescription(desc), metric.WithLabelKeys("service")) if err != nil { log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric") @@ -123,7 +120,6 @@ func (r *metricRegistry) addInt64DerivedGaugeMetric(name string, desc string, se } func (r *metricRegistry) addInt64DerivedCumulativeMetric(name string, desc string, service string, f func() int64) { - m, err := r.registry.AddInt64DerivedCumulative(name, metric.WithDescription(desc), metric.WithLabelKeys("service")) if err != nil { log.Error().Err(err).Str("service", service).Msg("telemetry/metrics: failed to register metric") diff --git a/internal/telemetry/metrics/storage.go b/internal/telemetry/metrics/storage.go index af571cd6d..4f3171c07 100644 --- a/internal/telemetry/metrics/storage.go +++ b/internal/telemetry/metrics/storage.go @@ -50,7 +50,7 @@ func RecordStorageOperation(ctx context.Context, tags *StorageOperationTags, dur tag.Upsert(TagKeyStorageOperation, tags.Operation), tag.Upsert(TagKeyStorageResult, result), tag.Upsert(TagKeyStorageBackend, tags.Backend), - //TODO service tag does not consistently come in from RPCs. Requires + // TODO service tag does not consistently come in from RPCs. Requires // follow up tag.Upsert(TagKeyService, "databroker"), }, diff --git a/internal/telemetry/metrics/storage_test.go b/internal/telemetry/metrics/storage_test.go index 6073e791b..cb703df77 100644 --- a/internal/telemetry/metrics/storage_test.go +++ b/internal/telemetry/metrics/storage_test.go @@ -10,7 +10,6 @@ import ( ) func Test_RecordStorageOperation(t *testing.T) { - tests := []struct { name string tags *StorageOperationTags diff --git a/internal/telemetry/util_test.go b/internal/telemetry/util_test.go index d67463b30..8886758b9 100644 --- a/internal/telemetry/util_test.go +++ b/internal/telemetry/util_test.go @@ -7,7 +7,6 @@ import ( ) func Test_ServiceName(t *testing.T) { - t.Parallel() tests := []struct { name string diff --git a/internal/tripper/chain_test.go b/internal/tripper/chain_test.go index e69a00fb3..4bbfc2f2c 100644 --- a/internal/tripper/chain_test.go +++ b/internal/tripper/chain_test.go @@ -26,7 +26,6 @@ func (t *mockTransport) RoundTrip(r *http.Request) (*http.Response, error) { func mockMiddleware(id string) func(next http.RoundTripper) http.RoundTripper { return func(next http.RoundTripper) http.RoundTripper { return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { - resp, _ := next.RoundTrip(r) body, _ := ioutil.ReadAll(resp.Body) @@ -77,7 +76,6 @@ func TestNilThen(t *testing.T) { if NewChain().Then(nil) != http.DefaultTransport { t.Error("Then does not treat nil as DefaultTransport") } - } func TestAppend(t *testing.T) { diff --git a/internal/urlutil/signed_test.go b/internal/urlutil/signed_test.go index 761cadf03..4370eeb71 100644 --- a/internal/urlutil/signed_test.go +++ b/internal/urlutil/signed_test.go @@ -20,11 +20,14 @@ func TestSignedURL(t *testing.T) { want url.URL wantErr bool }{ - {"good", "test-key", url.URL{Scheme: "https", Host: "pomerium.io"}, + { + "good", "test-key", + url.URL{Scheme: "https", Host: "pomerium.io"}, func() time.Time { return original }, func() time.Time { return original }, "https://pomerium.io?pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D", url.URL{Scheme: "https", Host: "pomerium.io", RawQuery: "pomerium_expiry=1574118151&pomerium_issued=1574117851&pomerium_signature=XtvM-Y-oPvoGGV2Q5G0vrQ_CgNeYhVyTG5dHIqLsBOU%3D"}, - false}, + false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/urlutil/url_test.go b/internal/urlutil/url_test.go index 25eb2b33d..47fedbe96 100644 --- a/internal/urlutil/url_test.go +++ b/internal/urlutil/url_test.go @@ -169,7 +169,6 @@ func TestParseEnvoyQueryParams(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := ParseEnvoyQueryParams(tt.u) if diff := cmp.Diff(got, tt.want); diff != "" { t.Errorf("ParseEnvoyQueryParams() = %v", diff) diff --git a/internal/version/version_test.go b/internal/version/version_test.go index 3ea66af7f..bdfa78d92 100644 --- a/internal/version/version_test.go +++ b/internal/version/version_test.go @@ -34,6 +34,7 @@ func TestFullVersionVersion(t *testing.T) { } } } + func BenchmarkFullVersion(b *testing.B) { Version = "1.0.0" GitCommit = "314501b" diff --git a/pkg/cryptutil/certificates_test.go b/pkg/cryptutil/certificates_test.go index ee895190c..fa33debd8 100644 --- a/pkg/cryptutil/certificates_test.go +++ b/pkg/cryptutil/certificates_test.go @@ -32,7 +32,6 @@ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ= ` func TestCertifcateFromBase64(t *testing.T) { - tests := []struct { name string cert string @@ -40,18 +39,24 @@ func TestCertifcateFromBase64(t *testing.T) { // want *tls.Certificate wantErr bool }{ - {"good", + { + "good", "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", - false}, - {"bad cert", + false, + }, + { + "bad cert", "!=", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", - true}, - {"bad key", + true, + }, + { + "bad key", "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", "!=", - true}, + true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -91,7 +96,6 @@ func TestPublicKeyMarshaling(t *testing.T) { if !bytes.Equal(pemBytes, []byte(pemECPublicKeyP256)) { t.Fatal("public key encoding did not match") } - } func TestPrivateKeyBadDecode(t *testing.T) { diff --git a/pkg/cryptutil/hmac.go b/pkg/cryptutil/hmac.go index 677f9bade..efdb20056 100644 --- a/pkg/cryptutil/hmac.go +++ b/pkg/cryptutil/hmac.go @@ -24,7 +24,6 @@ func GenerateHMAC(data []byte, key string) []byte { h := hmac.New(sha512.New512_256, []byte(key)) h.Write(data) return h.Sum(nil) - } // CheckHMAC securely checks the supplied MAC against a message using the diff --git a/pkg/cryptutil/jose_test.go b/pkg/cryptutil/jose_test.go index 5e4943208..f0f2c334d 100644 --- a/pkg/cryptutil/jose_test.go +++ b/pkg/cryptutil/jose_test.go @@ -18,13 +18,15 @@ func TestPrivateJWKFromBytes(t *testing.T) { want string wantErr bool }{ - {"good RS256", + { + "good RS256", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", jose.RS256, `{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB","d":"wE-MrL1o0XM6qyajkcWjgNg3MFpNi_0VvF5gIWRXUl7r9gj5ZWjDK8z3y5-WCH4bdx97POoBxmLM4GfIm22pF-RhAisu8kB-p4MRCs0E4244wOXcCh7T1z0a343eXGi7OYqe9YpQVxdUq1wx4rtq6pof3VNPl3S_93_noE_c5U_XOK0aPL758nF89a9rmhFb0y5V7paHIsRJK9ifUtpaMmk6JBDbHtN4iFmWczOCGKmdPGzcaB1_twLnlyx0PrBQydl2VFiiRRtLtmcBpe21YhNT-cGwBpoNgseQe0vrXdjyUVqpKHqnKrxFgbLRP0A6dYlPAfM2wMLXK3cPTL8woQ","p":"82jhXbXPSPPWAOiR4xLLCuD9rwUFHd29wtiZ7JTLaeDDG6euqXDpJv72CTyP-qr-y48fxTDeMewlrAUmyg0SPj6-hVHe76U2Usv2iaTWmFIYy5m2jGeeCYtScFPRvnelMUHJeT_E0GUiTKADpf05z7KeCS2PpOtWzU8NK-4hwrk","q":"9-OkTcZrOpBHOXM3igu98BsC8oGBg6FKDOWX4Up8expsXoae1a655pxAddld7TmyQqlbuVcLCMAxtCvsGB6Tv737d0in9OBt8FuzAr7NXHuCCHJz7D5YRrWGmtjrNrCq8BkdBKIs8a4-PJik-RDp1YOzd9esWBZ42DEkdJ8Zk40","dp":"rJjXDULpK_qy6cv__nsJ_LnTSLKPkUD12N8MLmTH5FjbIJYDVOTafqtVvPDzyzRLHf5r8cCYHeAsSlEQ0z73i6mkIRcPtPB6l7VHKQz4mePE70Ic3mxu9KeVGk9lL-DZAxd6DH76SScdbiYc0CvCPZOTWkCzVacG0uhWF6twxwk","dq":"jrQeAigX0r78QbZyYqYf0fm62KB1TrGrT4FczfVzc-riOAiHp7vOiVOqSC26RLbSSE3239ucHo2GD5K5d6kipV9ZRHIvPml04MnpY8szrensEbDRy06Ywxv9QWdfATzzKwVKD0DNXtRQP9IgJsH121TWHEesj4lgSBUCR6DPuIE","qi":"gXD4BAh4HTcxP8gGWTTgI8vYOMz7jyFN1C_zTTQcA59BuTQRg_UJooa0KbzrXMB_Syr_kMpgIjP38ZLdcUzgGaQU6BxJZMI7p98uArep8LfFfae9kf1d1wkvj5_BpwvGxsj7xpBw1O2ajN1HXcGx9Fv4eNP-Pu8aRtCAkcE4rbM"}`, false, }, - {"good SS256", + { + "good SS256", "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=", jose.ES256, `{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU","d":"F7ROqat0ilhczuzNEMNVvBb3_sRsZSFK1AiNeVOxbc8"}`, @@ -63,27 +65,31 @@ func TestPublicJWKFromBytes(t *testing.T) { want string wantErr bool }{ - {"good RS256", + { + "good RS256", "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", jose.RS256, `{"use":"sig","kty":"RSA","kid":"f0cc8033b422c2a199dcb456dde29589a9f5edd27d1c345bdf308957e957becf","alg":"RS256","n":"67KjqmQYGq0MVtACVpeCmXminlQbDPGLmsZAUEwueHQnrt3WtvpDOm6AlaJMUnW-Hu55jjokalKeVjTKmgYGbqUzVDoMbPDaHekltdBTMGlOUFsP4UJSDrO4zdN-zo428TX2PnG2FCdVKGy4PE8ilHbWLcr871YjV51fw8CLDX9PZJNu861CF7V9iEJm6sSfQlmnhN8j3-WzVbPQNy1WsR7i9e9j63EqKt22Q9OXL-WAcKskoISmCNVRUAjU8YRVcgQJB-zQ34AQPlz0Op5O_QN_MedjaF8wLS-iv_zviS8cqPbxo6sLq6FNTltk_QkxeCeKKTQe_3kPYvQAdnl65Q","e":"AQAB"}`, false, }, - {"good ES256", + { + "good ES256", "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJlMFRxbXJkSXBZWE03c3pSRERWYndXOS83RWJHVWhTdFFJalhsVHNXM1BvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFb0xaRDI2bEdYREhRQmhhZkdlbEVmRDdlNmYzaURjWVJPVjdUbFlIdHF1Y1BFL2hId2dmYQpNY3FBUEZsRmpueUpySXJhYTFlQ2xZRTJ6UktTQk5kNXBRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=", jose.ES256, `{"use":"sig","kty":"EC","kid":"d591aa6e01e57ea8b80f349dc5de8517aa7b1f12f77700d89cbdba83938c0c61","crv":"P-256","alg":"ES256","x":"oLZD26lGXDHQBhafGelEfD7e6f3iDcYROV7TlYHtquc","y":"DxP4R8IH2jHKgDxZRY58iayK2mtXgpWBNs0SkgTXeaU"}`, false, }, - {"good ed25519", + { + "good ed25519", "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUZiNDN6SkVqblMvOHdxZVMwRlhiNDNWdlV5ZmhRL3UvWGd3UVV2bDVnaloKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=", jose.EdDSA, `{"use":"sig","kty":"OKP","kid":"3aa847838906f3c930f55c2d5885943ac7bede8f780d388015575334f88e77ef","crv":"Ed25519","alg":"EdDSA","x":"xsg1A67wECXAmRnSib8lSsgatcNcYm7vvspQnocPQNc"}`, false, }, - {"bad key decode", + { + "bad key decode", "LS0t", jose.RS256, `null`, diff --git a/pkg/cryptutil/tls.go b/pkg/cryptutil/tls.go index 4edc5b013..2138da236 100644 --- a/pkg/cryptutil/tls.go +++ b/pkg/cryptutil/tls.go @@ -47,9 +47,9 @@ func GetCertPool(ca, caFile string) (*x509.CertPool, error) { // Finally if there are no matching certificates one will be generated. func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tls.Certificate, error) { // first try a direct name match - for _, cert := range certificates { - if matchesDomain(&cert, domain) { - return &cert, nil + for i := range certificates { + if matchesDomain(&certificates[i], domain) { + return &certificates[i], nil } } diff --git a/pkg/grpc/client.go b/pkg/grpc/client.go index 33b17dac4..e49454f7e 100644 --- a/pkg/grpc/client.go +++ b/pkg/grpc/client.go @@ -103,7 +103,7 @@ func NewGRPCClientConn(opts *Options) (*grpc.ClientConn, error) { return nil, err } - cert := credentials.NewTLS(&tls.Config{RootCAs: rootCAs}) + cert := credentials.NewTLS(&tls.Config{RootCAs: rootCAs, MinVersion: tls.VersionTLS12}) // override allowed certificate name string, typically used when doing behind ingress connection if opts.OverrideCertificateName != "" { diff --git a/pkg/grpc/client_test.go b/pkg/grpc/client_test.go index 4847cd986..a01b3b773 100644 --- a/pkg/grpc/client_test.go +++ b/pkg/grpc/client_test.go @@ -12,7 +12,6 @@ import ( ) func Test_grpcTimeoutInterceptor(t *testing.T) { - mockInvoker := func(sleepTime time.Duration, wantFail bool) grpc.UnaryInvoker { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error { time.Sleep(sleepTime) @@ -37,7 +36,6 @@ func Test_grpcTimeoutInterceptor(t *testing.T) { to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut*2, true)) to(context.Background(), "test", nil, nil, nil, mockInvoker(timeOut/2, false)) - } func TestNewGRPC(t *testing.T) { @@ -73,7 +71,6 @@ func TestNewGRPC(t *testing.T) { } if got != nil && got.Target() != tt.wantTarget { t.Errorf("New() target = %v expected %v", got.Target(), tt.wantTarget) - } }) } diff --git a/proxy/handlers_test.go b/proxy/handlers_test.go index 47c03dabe..4714a9abc 100644 --- a/proxy/handlers_test.go +++ b/proxy/handlers_test.go @@ -124,7 +124,6 @@ func TestProxy_SignOut(t *testing.T) { if status := w.Code; status != tt.wantStatus { t.Errorf("status code: got %v want %v", status, tt.wantStatus) } - }) } } @@ -344,7 +343,6 @@ func TestProxy_ProgrammaticLogin(t *testing.T) { t.Errorf("wrong body\n%s", diff) } } - }) } } @@ -386,9 +384,11 @@ func TestProxy_ProgrammaticCallback(t *testing.T) { http.MethodGet, "http://pomerium.io/", nil, - map[string]string{urlutil.QueryIsProgrammatic: "true", + map[string]string{ + urlutil.QueryIsProgrammatic: "true", urlutil.QueryCallbackURI: "ok", - urlutil.QuerySessionEncrypted: goodEncryptionString}, + urlutil.QuerySessionEncrypted: goodEncryptionString, + }, &mock.Encoder{MarshalResponse: []byte("x")}, &mstore.Store{Session: &sessions.State{Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Minute))}}, http.StatusFound, @@ -497,7 +497,6 @@ func TestProxy_ProgrammaticCallback(t *testing.T) { } func TestProxy_jwt(t *testing.T) { - // without downstream headers being set req, _ := http.NewRequest("GET", "https://www.example.com/.pomerium/jwt", nil) w := httptest.NewRecorder() diff --git a/proxy/state.go b/proxy/state.go index 70fe99858..ebb34ba45 100644 --- a/proxy/state.go +++ b/proxy/state.go @@ -79,7 +79,8 @@ func newProxyStateFromConfig(cfg *config.Config) (*proxyState, error) { state.sessionLoaders = []sessions.SessionLoader{ state.sessionStore, header.NewStore(state.encoder, httputil.AuthorizationTypePomerium), - queryparam.NewStore(state.encoder, "pomerium_session")} + queryparam.NewStore(state.encoder, "pomerium_session"), + } return state, nil }