From 3045392c1700d66345426fcb8aaf4311bae03eff Mon Sep 17 00:00:00 2001 From: Jacob Middag Date: Sun, 14 Jul 2024 22:09:17 +0200 Subject: [PATCH] feat: Replace default Go user-agent with oauth2-proxy and version (#2570) * feat: Replace default Go user-agent with oauth2-proxy and version * Add to CHANGELOG * Make userAgentTransport configurable and composable * Use correct naming convention for DefaultHTTPClient * Move version to own package and use named arguments * Update version path in Makefile * Fix import path in Makefile * Change importpath in dist.sh * Minor style issues --- CHANGELOG.md | 1 + Makefile | 2 +- dist.sh | 6 +++-- main.go | 3 ++- oauthproxy.go | 3 ++- pkg/providers/oidc/provider_verifier.go | 2 ++ pkg/requests/builder.go | 4 ++-- pkg/requests/builder_test.go | 4 +++- pkg/requests/http.go | 29 +++++++++++++++++++++++++ version.go => pkg/version/version.go | 2 +- providers/oidc.go | 7 ++++++ 11 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 pkg/requests/http.go rename version.go => pkg/version/version.go (80%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ff9a902..d47d93b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - [#2539](https://github.com/oauth2-proxy/oauth2-proxy/pull/2539) pkg/http: Fix leaky test (@isodude) - [#4917](https://github.com/oauth2-proxy/oauth2-proxy/pull/4917) Upgraded all modules to the latest version (@pierluigilenoci) +- [#2570](https://github.com/oauth2-proxy/oauth2-proxy/pull/2570) Set default user agent to oauth2-proxy/$version (from default Golang one) # V7.6.0 diff --git a/Makefile b/Makefile index c476ae4f..eddd68e4 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ lint: validate-go-version build: validate-go-version clean $(BINARY) $(BINARY): - CGO_ENABLED=0 $(GO) build -a -installsuffix cgo -ldflags="-X main.VERSION=${VERSION}" -o $@ github.com/oauth2-proxy/oauth2-proxy/v7 + CGO_ENABLED=0 $(GO) build -a -installsuffix cgo -ldflags="-X github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version.VERSION=${VERSION}" -o $@ github.com/oauth2-proxy/oauth2-proxy/v7 DOCKER_BUILD_PLATFORM ?= linux/amd64,linux/arm64,linux/ppc64le,linux/arm/v7 DOCKER_BUILD_RUNTIME_IMAGE ?= gcr.io/distroless/static:nonroot diff --git a/dist.sh b/dist.sh index dc11d225..7b3a3aff 100755 --- a/dist.sh +++ b/dist.sh @@ -32,10 +32,12 @@ for ARCH in "${ARCHS[@]}"; do # Create architecture specific binaries if [[ ${GO_ARCH} == armv* ]]; then GO_ARM=$(echo $GO_ARCH | awk -Fv '{print $2}') - GO111MODULE=on GOOS=${GO_OS} GOARCH=arm GOARM=${GO_ARM} CGO_ENABLED=0 go build -ldflags="-X main.VERSION=${VERSION}" \ + GO111MODULE=on GOOS=${GO_OS} GOARCH=arm GOARM=${GO_ARM} CGO_ENABLED=0 go build \ + -ldflags="-X github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version.VERSION=${VERSION}" \ -o release/${BINARY}-${VERSION}.${ARCH}/${BINARY} . else - GO111MODULE=on GOOS=${GO_OS} GOARCH=${GO_ARCH} CGO_ENABLED=0 go build -ldflags="-X main.VERSION=${VERSION}" \ + GO111MODULE=on GOOS=${GO_OS} GOARCH=${GO_ARCH} CGO_ENABLED=0 go build \ + -ldflags="-X github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version.VERSION=${VERSION}" \ -o release/${BINARY}-${VERSION}.${ARCH}/${BINARY} . fi diff --git a/main.go b/main.go index 5694e94e..cf7e964c 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/validation" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version" "github.com/spf13/pflag" ) @@ -28,7 +29,7 @@ func main() { configFlagSet.Parse(os.Args[1:]) if *showVersion { - fmt.Printf("oauth2-proxy %s (built with %s)\n", VERSION, runtime.Version()) + fmt.Printf("oauth2-proxy %s (built with %s)\n", version.VERSION, runtime.Version()) return } diff --git a/oauthproxy.go b/oauthproxy.go index df646f72..5a237ead 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -30,6 +30,7 @@ import ( "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption" proxyhttp "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/http" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/ip" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" @@ -142,7 +143,7 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr CustomLogo: opts.Templates.CustomLogo, ProxyPrefix: opts.ProxyPrefix, Footer: opts.Templates.Footer, - Version: VERSION, + Version: version.VERSION, Debug: opts.Templates.Debug, ProviderName: buildProviderName(provider, opts.Providers[0].Name), SignInMessage: buildSignInMessage(opts), diff --git a/pkg/providers/oidc/provider_verifier.go b/pkg/providers/oidc/provider_verifier.go index c83df5d3..cc12036b 100644 --- a/pkg/providers/oidc/provider_verifier.go +++ b/pkg/providers/oidc/provider_verifier.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/coreos/go-oidc/v3/oidc" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests" k8serrors "k8s.io/apimachinery/pkg/util/errors" ) @@ -130,6 +131,7 @@ func getVerifierBuilder(ctx context.Context, opts ProviderVerifierOptions) (veri // newVerifierBuilder returns a function to create a IDToken verifier from an OIDC config. func newVerifierBuilder(ctx context.Context, issuerURL, jwksURL string, supportedSigningAlgs []string) verifierBuilder { + ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient) keySet := oidc.NewRemoteKeySet(ctx, jwksURL) return func(oidcConfig *oidc.Config) *oidc.IDTokenVerifier { if len(supportedSigningAlgs) > 0 { diff --git a/pkg/requests/builder.go b/pkg/requests/builder.go index a9b084dc..50ac29f2 100644 --- a/pkg/requests/builder.go +++ b/pkg/requests/builder.go @@ -58,7 +58,7 @@ func (r *builder) WithMethod(method string) Builder { // WithHeaders replaces the request header map with the given header map. func (r *builder) WithHeaders(header http.Header) Builder { - r.header = header + r.header = header.Clone() return r } @@ -99,7 +99,7 @@ func (r *builder) do() Result { } req.Header = r.header - resp, err := http.DefaultClient.Do(req) + resp, err := DefaultHTTPClient.Do(req) if err != nil { r.result = &result{err: fmt.Errorf("error performing request: %v", err)} return r.result diff --git a/pkg/requests/builder_test.go b/pkg/requests/builder_test.go index 552741f7..7e1e6222 100644 --- a/pkg/requests/builder_test.go +++ b/pkg/requests/builder_test.go @@ -8,6 +8,8 @@ import ( "fmt" "net/http" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version" + "github.com/bitly/go-simplejson" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -19,7 +21,7 @@ var _ = Describe("Builder suite", func() { baseHeaders := http.Header{ "Accept-Encoding": []string{"gzip"}, - "User-Agent": []string{"Go-http-client/1.1"}, + "User-Agent": []string{"oauth2-proxy/" + version.VERSION}, } BeforeEach(func() { diff --git a/pkg/requests/http.go b/pkg/requests/http.go new file mode 100644 index 00000000..ed335b86 --- /dev/null +++ b/pkg/requests/http.go @@ -0,0 +1,29 @@ +package requests + +import ( + "net/http" + + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version" +) + +type userAgentTransport struct { + next http.RoundTripper + userAgent string +} + +func (t *userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { + r := req.Clone(req.Context()) + setDefaultUserAgent(r.Header, t.userAgent) + return t.next.RoundTrip(r) +} + +var DefaultHTTPClient = &http.Client{Transport: &userAgentTransport{ + next: http.DefaultTransport, + userAgent: "oauth2-proxy/" + version.VERSION, +}} + +func setDefaultUserAgent(header http.Header, userAgent string) { + if header != nil && len(header.Values("User-Agent")) == 0 { + header.Set("User-Agent", userAgent) + } +} diff --git a/version.go b/pkg/version/version.go similarity index 80% rename from version.go rename to pkg/version/version.go index d6fa19b9..8635c8ba 100644 --- a/version.go +++ b/pkg/version/version.go @@ -1,4 +1,4 @@ -package main +package version // VERSION contains version information var VERSION = "undefined" diff --git a/providers/oidc.go b/providers/oidc.go index 1225141d..43b5227e 100644 --- a/providers/oidc.go +++ b/providers/oidc.go @@ -7,9 +7,11 @@ import ( "net/url" "time" + "github.com/coreos/go-oidc/v3/oidc" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests" "golang.org/x/oauth2" ) @@ -83,6 +85,8 @@ func (p *OIDCProvider) Redeem(ctx context.Context, redirectURL, code, codeVerifi }, RedirectURL: redirectURL, } + + ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient) token, err := c.Exchange(ctx, code, opts...) if err != nil { return nil, fmt.Errorf("token exchange failed: %v", err) @@ -103,6 +107,7 @@ func (p *OIDCProvider) EnrichSession(_ context.Context, s *sessions.SessionState // ValidateSession checks that the session's IDToken is still valid func (p *OIDCProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { + ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient) _, err := p.Verifier.Verify(ctx, s.IDToken) if err != nil { logger.Errorf("id_token verification failed: %v", err) @@ -127,6 +132,7 @@ func (p *OIDCProvider) RefreshSession(ctx context.Context, s *sessions.SessionSt return false, nil } + ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient) err := p.redeemRefreshToken(ctx, s) if err != nil { return false, fmt.Errorf("unable to redeem refresh token: %v", err) @@ -185,6 +191,7 @@ func (p *OIDCProvider) redeemRefreshToken(ctx context.Context, s *sessions.Sessi // CreateSessionFromToken converts Bearer IDTokens into sessions func (p *OIDCProvider) CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error) { + ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient) idToken, err := p.Verifier.Verify(ctx, token) if err != nil { return nil, err