Merge branch 'master' into docs/skip-auth-preflight-nginx

This commit is contained in:
Mayowa Fajobi 2026-06-11 19:38:43 +01:00 committed by GitHub
commit 3bed9fc05f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 357 additions and 171 deletions

View File

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.25
FROM mcr.microsoft.com/vscode/devcontainers/go:1-1.26
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

View File

@ -1,6 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: OAuth2-Proxy Slack
url: https://gophers.slack.com/messages/CM2RSS25N
- name: OAuth2 Proxy Slack
url: https://cloud-native.slack.com/archives/C098Y5URZ2N
about: Feel free to ask any questions here.

View File

@ -6,8 +6,35 @@
## Breaking Changes
## Changes since v7.15.3
# V7.15.3
## Release Highlights
- 🔵 Golang version upgrade to v1.26.4
- Upgrade of all dependencies to their latest versions
- 🕵️‍♀️ Vulnerabilities have ben addressed
- [CVE-2026-33811](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-33814](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-39820](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-39836](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-42499](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-42504](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-39823](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-39826](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-39825](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-27145](https://nvd.nist.gov/vuln/detail/)
- [CVE-2026-42507](https://nvd.nist.gov/vuln/detail/)
## Important Notes
## Breaking Changes
## Changes since v7.15.2
- [#3477](https://github.com/oauth2-proxy/oauth2-proxy/pull/3477) chore(dep): bump go to 1.26 and migrate of reverse proxy handling
# V7.15.2
## Release Highlights

View File

@ -12,7 +12,7 @@
OAuth2 Proxy is a flexible, open-source tool that can act as either a standalone reverse proxy or a middleware component integrated into existing reverse proxy or load balancer setups. It provides a simple and secure way to protect your web applications with OAuth2 / OIDC authentication. As a reverse proxy, it intercepts requests to your application and redirects users to an OAuth2 provider for authentication. As a middleware, it can be seamlessly integrated into your existing infrastructure to handle authentication for multiple applications.
OAuth2 Proxy supports a lot of OAuth2 as well as OIDC providers. Either through a generic OIDC client or a specific implementation for Google, Microsoft Entra ID, GitHub, login.gov and others. Through specialised provider implementations oauth2-proxy can extract more details about the user like preferred usernames and groups. Those details can then be forwarded as HTTP headers to your upstream applications.
OAuth2 Proxy supports a lot of OAuth2 as well as OIDC providers. Either through a generic OIDC client or a specific implementation for Google, Microsoft Entra ID, GitHub, login.gov and others. Through specialised provider implementations OAuth2 Proxy can extract more details about the user like preferred usernames and groups. Those details can then be forwarded as HTTP headers to your upstream applications.
![Simplified Architecture](docs/static/img/simplified-architecture.svg)
@ -23,7 +23,7 @@ OAuth2 Proxy's [Installation Docs](https://oauth2-proxy.github.io/oauth2-proxy/i
## Releases
### Binaries
We publish oauth2-proxy as compiled binaries on GitHub for all major architectures as well as more exotic ones like `ppc64le` as well as `s390x`.
We publish OAuth2 Proxy as compiled binaries on GitHub for all major architectures as well as more exotic ones like `ppc64le` as well as `s390x`.
Check out the [latest release](https://github.com/oauth2-proxy/oauth2-proxy/releases/latest).
@ -49,9 +49,9 @@ SAP Open Source Program
Microsoft Azure credits for open source projects
## Getting Involved
[![Slack](https://img.shields.io/badge/slack-Gopher_%23oauth2--proxy-red?logo=slack)](https://gophers.slack.com/archives/CM2RSS25N)
[![Slack](https://img.shields.io/badge/slack-CNCF_%23oauth2--proxy-blue?logo=slack)](https://cloud-native.slack.com/archives/C098Y5URZ2N)
Join the #oauth2-proxy [Slack channel](https://gophers.slack.com/archives/CM2RSS25N) to chat with other users of oauth2-proxy or reach out to the maintainers directly. Use the [public invite link](https://invite.slack.golangbridge.org/) to get an invite for the Gopher Slack space.
Join the #oauth2-proxy [Slack channel](https://cloud-native.slack.com/archives/C098Y5URZ2N) to chat with other users of OAuth2 Proxy or reach out to the maintainers directly. Use the [public invite link](https://communityinviter.com/apps/cloud-native/cncf) to get an invite for the Gopher Slack space.
OAuth2 Proxy is a community-driven project. We rely on the contributions of our users to continually improve it. While review times can vary, we appreciate your patience and understanding. As a volunteer-driven project, we strive to keep this project stable and might take longer to merge changes.

View File

@ -14,7 +14,7 @@ version: "3.0"
services:
oauth2-proxy:
container_name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
command: --config /oauth2-proxy.cfg --alpha-config /oauth2-proxy-alpha-config.yaml
hostname: oauth2-proxy
volumes:

View File

@ -14,7 +14,7 @@ version: '3.0'
services:
oauth2-proxy:
container_name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
command: --config /oauth2-proxy.cfg
hostname: oauth2-proxy
volumes:

View File

@ -14,7 +14,7 @@ version: "3.0"
services:
oauth2-proxy:
container_name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
command: --config /oauth2-proxy.cfg
hostname: oauth2-proxy
volumes:

View File

@ -22,7 +22,7 @@
version: "3.0"
services:
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
ports: []
hostname: oauth2-proxy
container_name: oauth2-proxy

View File

@ -23,7 +23,7 @@ version: '3.0'
services:
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
ports: []
hostname: oauth2-proxy
volumes:

View File

@ -13,7 +13,7 @@ version: "3.0"
services:
oauth2-proxy:
container_name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3
command: --config /oauth2-proxy.cfg
hostname: oauth2-proxy
volumes:

View File

@ -5,7 +5,7 @@ title: Installation
1. Choose how to deploy:
a. Using a [Prebuilt Binary](https://github.com/oauth2-proxy/oauth2-proxy/releases) (current release is `v7.15.2`)
a. Using a [Prebuilt Binary](https://github.com/oauth2-proxy/oauth2-proxy/releases) (current release is `v7.15.3`)
b. Using Go to install the latest release
```bash

View File

@ -105,7 +105,7 @@ const config = {
dropdownActiveClassDisabled: true,
},
{
href: 'https://gophers.slack.com/messages/CM2RSS25N',
href: 'https://cloud-native.slack.com/archives/C098Y5URZ2N',
label: 'Slack',
position: 'right',
},

View File

@ -5,7 +5,7 @@ title: Installation
1. Choose how to deploy:
a. Using a [Prebuilt Binary](https://github.com/oauth2-proxy/oauth2-proxy/releases) (current release is `v7.15.2`)
a. Using a [Prebuilt Binary](https://github.com/oauth2-proxy/oauth2-proxy/releases) (current release is `v7.15.3`)
b. Using Go to install the latest release
```bash

60
go.mod
View File

@ -1,17 +1,17 @@
module github.com/oauth2-proxy/oauth2-proxy/v7
go 1.25.0
go 1.26.0
require (
cloud.google.com/go/compute/metadata v0.9.0
github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb
github.com/a8m/envsubst v1.4.3
github.com/alicebob/miniredis/v2 v2.37.0
github.com/alicebob/miniredis/v2 v2.38.0
github.com/bitly/go-simplejson v0.5.1
github.com/bsm/redislock v0.9.4
github.com/bsm/redislock v0.10.0
github.com/coreos/go-oidc/v3 v3.18.0
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/fsnotify/fsnotify v1.9.0
github.com/fsnotify/fsnotify v1.10.1
github.com/go-jose/go-jose/v3 v3.0.5
github.com/go-jose/go-jose/v4 v4.1.4
github.com/go-viper/mapstructure/v2 v2.5.0
@ -21,30 +21,30 @@ require (
github.com/gorilla/mux v1.8.1
github.com/justinas/alice v1.2.0
github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25
github.com/onsi/ginkgo/v2 v2.28.1
github.com/onsi/gomega v1.39.1
github.com/pierrec/lz4/v4 v4.1.26
github.com/onsi/ginkgo/v2 v2.29.0
github.com/onsi/gomega v1.41.0
github.com/pierrec/lz4/v4 v4.1.27
github.com/prometheus/client_golang v1.23.2
github.com/redis/go-redis/v9 v9.18.0
github.com/redis/go-redis/v9 v9.20.0
github.com/spf13/cast v1.10.0
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
github.com/vmihailenco/msgpack/v5 v5.4.1
go.yaml.in/yaml/v3 v3.0.4
golang.org/x/crypto v0.50.0
golang.org/x/net v0.53.0
golang.org/x/crypto v0.52.0
golang.org/x/net v0.55.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sync v0.20.0
google.golang.org/api v0.275.0
google.golang.org/api v0.283.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
k8s.io/apimachinery v0.35.3
k8s.io/apimachinery v0.36.1
)
require (
cloud.google.com/go/auth v0.20.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@ -53,35 +53,35 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
github.com/google/pprof v0.0.0-20260604005048-7023385849c0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
github.com/googleapis/gax-go/v2 v2.21.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.16 // indirect
github.com/googleapis/gax-go/v2 v2.22.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.3.0 // indirect
github.com/pelletier/go-toml/v2 v2.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/common v0.68.1 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
github.com/yuin/gopher-lua v1.1.2 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect
go.opentelemetry.io/otel v1.43.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 // indirect
go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
golang.org/x/mod v0.35.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/tools v0.44.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/grpc v1.80.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
golang.org/x/mod v0.36.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect
golang.org/x/tools v0.45.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc v1.81.1 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

62
go.sum
View File

@ -12,12 +12,16 @@ github.com/FZambia/sentinel v1.0.0 h1:KJ0ryjKTZk5WMp0dXvSdNqp3lFaW1fNFuEYfrkLOYI
github.com/FZambia/sentinel v1.0.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/a8m/envsubst v1.4.3 h1:kDF7paGK8QACWYaQo6KtyYBozY2jhQrTuNNuUxQkhJY=
github.com/a8m/envsubst v1.4.3/go.mod h1:4jjHWQlZoaXPoLQUb7H2qT4iLkZDdmEQiOUogdUmqVU=
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE=
github.com/alicebob/miniredis/v2 v2.37.0 h1:RheObYW32G1aiJIj81XVt78ZHJpHonHLHW7OLIshq68=
github.com/alicebob/miniredis/v2 v2.37.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM=
github.com/alicebob/miniredis/v2 v2.38.0 h1:nZAzCR+Lj+Vxk4ZXzm2NuKq2O33RXj1XxJ2e2uP9jiw=
github.com/alicebob/miniredis/v2 v2.38.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
@ -28,6 +32,8 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw=
github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk=
github.com/bsm/redislock v0.10.0 h1:NAe1OHDnwPmWEzD+LpWBZXAdZrWld/xj/wmqEcQednQ=
github.com/bsm/redislock v0.10.0/go.mod h1:M05WZGjPbX/8ne7LmB7AbOsa2kv7Jzx4fqkLpDFZvJs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@ -50,6 +56,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
@ -88,6 +96,8 @@ github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc h1:VBbFa1lDYWEeV5FZKU
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg=
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/pprof v0.0.0-20260604005048-7023385849c0 h1:h1QTMDl6q9wDvDCJVpKQSjgleGFYnd2fOxmg2K+6BGE=
github.com/google/pprof v0.0.0-20260604005048-7023385849c0/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -95,10 +105,14 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8=
github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
github.com/googleapis/enterprise-certificate-proxy v0.3.16 h1:F/VPrx0YPBdksZJQdCAp0WUsqnNmZpUZszzfYt0M5Dw=
github.com/googleapis/enterprise-certificate-proxy v0.3.16/go.mod h1:9Yb0eAkH/Xqhvv3zbeKf/+wMJqCeocWc6KIhDvEAuYE=
github.com/googleapis/gax-go/v2 v2.19.0 h1:fYQaUOiGwll0cGj7jmHT/0nPlcrZDFPrZRhTsoCr8hE=
github.com/googleapis/gax-go/v2 v2.19.0/go.mod h1:w2ROXVdfGEVFXzmlciUU4EdjHgWvB5h2n6x/8XSTTJA=
github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI=
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4=
github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
@ -109,6 +123,7 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -127,14 +142,22 @@ github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25 h1:9bCMuD3Tc
github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25/go.mod h1:eDjgYHYDJbPLBLsyZ6qRaugP0mX8vePOhZ5id1fdzJw=
github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag=
github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA=
github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM=
github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY=
github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
github.com/pierrec/lz4/v4 v4.1.27 h1:+PhzhWDrjRj89TH2sw43nE3+4+W8lSxIuQadEHZyjUk=
github.com/pierrec/lz4/v4 v4.1.27/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -144,10 +167,14 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/common v0.68.1 h1:omjRRl4QP4komogpXuhfeOiisQg7xdy8VM1UY+pStaY=
github.com/prometheus/common v0.68.1/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs=
github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0=
github.com/redis/go-redis/v9 v9.20.0 h1:WnQYxLkgO2xiXTCJY0ldIiI8dNqCDlQAG+AtaH7a2a0=
github.com/redis/go-redis/v9 v9.20.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
@ -183,8 +210,11 @@ github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBU
github.com/yuin/gopher-lua v0.0.0-20191213034115-f46add6fdb5c/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
github.com/yuin/gopher-lua v1.1.2 h1:yF/FjE3hD65tBbt0VXLE13HWS9h34fdzJmrWRXwobGA=
github.com/yuin/gopher-lua v1.1.2/go.mod h1:7aRmXIWl37SqRf0koeyylBEzJ+aPt8A+mmkQ4f1ntR8=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
@ -194,24 +224,34 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:Oyrsyzu
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho=
go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc=
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI=
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo=
go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts=
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA=
go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc=
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY=
go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc=
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -227,12 +267,16 @@ golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@ -242,6 +286,8 @@ golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -262,6 +308,8 @@ golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -277,6 +325,8 @@ golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -287,6 +337,8 @@ golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
@ -295,6 +347,8 @@ google.golang.org/api v0.272.0 h1:eLUQZGnAS3OHn31URRf9sAmRk3w2JjMx37d2k8AjJmA=
google.golang.org/api v0.272.0/go.mod h1:wKjowi5LNJc5qarNvDCvNQBn3rVK8nSy6jg2SwRwzIA=
google.golang.org/api v0.275.0 h1:vfY5d9vFVJeWEZT65QDd9hbndr7FyZ2+6mIzGAh71NI=
google.golang.org/api v0.275.0/go.mod h1:Fnag/EWUPIcJXuIkP1pjoTgS5vdxlk3eeemL7Do6bvw=
google.golang.org/api v0.283.0 h1:0lkp8u0MPwJVHqRL+nJlMAoZVVzbmiXmFHXMOTmSPik=
google.golang.org/api v0.283.0/go.mod h1:6Wssta4c5n9qHq5CBhmlai5h/PUa1djdDAIhYEHyvcM=
google.golang.org/genproto v0.0.0-20260316180232-0b37fe3546d5 h1:JNfk58HZ8lfmXbYK2vx/UvsqIL59TzByCxPIX4TDmsE=
google.golang.org/genproto v0.0.0-20260316180232-0b37fe3546d5/go.mod h1:x5julN69+ED4PcFk/XWayw35O0lf/nGa4aNgODCmNmw=
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0=
@ -305,12 +359,18 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@ -321,3 +381,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8=
k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA=
k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8=

View File

@ -587,7 +587,7 @@ func (p *OAuthProxy) ErrorPage(rw http.ResponseWriter, req *http.Request, code i
// IsAllowedRequest is used to check if auth should be skipped for this request
func (p *OAuthProxy) IsAllowedRequest(req *http.Request) bool {
isPreflightRequestAllowed := p.skipAuthPreflight && req.Method == "OPTIONS"
isPreflightRequestAllowed := p.skipAuthPreflight && req.Method == http.MethodOptions
return isPreflightRequestAllowed || p.isAllowedRoute(req) || p.isTrustedIP(req)
}
@ -669,7 +669,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
// ManualSignIn handles basic auth logins to the proxy
func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool, int) {
if req.Method != "POST" || p.basicAuthValidator == nil {
if req.Method != http.MethodPost || p.basicAuthValidator == nil {
return "", false, http.StatusOK
}
user := req.FormValue("username")

View File

@ -54,7 +54,7 @@ func TestRobotsTxt(t *testing.T) {
t.Fatal(err)
}
rw := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/robots.txt", nil)
req, _ := http.NewRequest(http.MethodGet, "/robots.txt", nil)
proxy.ServeHTTP(rw, req)
assert.Equal(t, 200, rw.Code)
assert.Equal(t, "User-agent: *\nDisallow: /\n", rw.Body.String())
@ -241,7 +241,7 @@ func TestBasicAuthPassword(t *testing.T) {
// Save the required session
rw := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
err = proxy.sessionStore.Save(rw, req, &sessions.SessionState{
Email: emailAddress,
})
@ -250,7 +250,7 @@ func TestBasicAuthPassword(t *testing.T) {
// Extract the cookie value to inject into the test request
cookie := rw.Header().Values("Set-Cookie")[0]
req, _ = http.NewRequest("GET", "/", nil)
req, _ = http.NewRequest(http.MethodGet, "/", nil)
req.Header.Set("Cookie", cookie)
rw = httptest.NewRecorder()
proxy.ServeHTTP(rw, req)
@ -300,14 +300,14 @@ func TestPassGroupsHeadersWithGroups(t *testing.T) {
// Save the required session
rw := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
err = proxy.sessionStore.Save(rw, req, session)
assert.NoError(t, err)
// Extract the cookie value to inject into the test request
cookie := rw.Header().Values("Set-Cookie")[0]
req, _ = http.NewRequest("GET", "/", nil)
req, _ = http.NewRequest(http.MethodGet, "/", nil)
req.Header.Set("Cookie", cookie)
rw = httptest.NewRecorder()
proxy.ServeHTTP(rw, req)
@ -457,7 +457,7 @@ func (patTest *PassAccessTokenTest) getEndpointWithCookie(cookie string, endpoin
return 0, ""
}
req, err := http.NewRequest("GET", endpoint, strings.NewReader(""))
req, err := http.NewRequest(http.MethodGet, endpoint, strings.NewReader(""))
if err != nil {
return 0, ""
}
@ -608,7 +608,7 @@ func NewSignInPageTest(skipProvider bool) (*SignInPageTest, error) {
func (sipTest *SignInPageTest) GetEndpoint(endpoint string) (int, string) {
rw := httptest.NewRecorder()
req, _ := http.NewRequest("GET", endpoint, strings.NewReader(""))
req, _ := http.NewRequest(http.MethodGet, endpoint, strings.NewReader(""))
sipTest.proxy.ServeHTTP(rw, req)
return rw.Code, rw.Body.String()
}
@ -894,7 +894,7 @@ func NewProcessCookieTest(opts ProcessCookieTestOpts, modifiers ...OptionsModifi
// access_token validation.
pcTest.proxy.CookieOptions.Refresh = time.Duration(0)
pcTest.rw = httptest.NewRecorder()
pcTest.req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
pcTest.req, _ = http.NewRequest(http.MethodGet, "/", strings.NewReader(""))
pcTest.validateUser = true
return &pcTest, nil
}
@ -1027,7 +1027,7 @@ func NewUserInfoEndpointTest() (*ProcessCookieTest, error) {
if err != nil {
return nil, err
}
pcTest.req, _ = http.NewRequest("GET",
pcTest.req, _ = http.NewRequest(http.MethodGet,
pcTest.opts.ProxyPrefix+"/userinfo", nil)
return pcTest, nil
}
@ -1135,7 +1135,7 @@ func NewAuthOnlyEndpointTest(querystring string, modifiers ...OptionsModifier) (
return nil, err
}
pcTest.req, _ = http.NewRequest(
"GET",
http.MethodGet,
fmt.Sprintf("%s/auth%s", pcTest.opts.ProxyPrefix, querystring),
nil)
return pcTest, nil
@ -1274,7 +1274,7 @@ func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
pcTest.validateUser = true
pcTest.rw = httptest.NewRecorder()
pcTest.req, _ = http.NewRequest("GET",
pcTest.req, _ = http.NewRequest(http.MethodGet,
pcTest.opts.ProxyPrefix+authOnlyPath, nil)
created := time.Now()
@ -1367,7 +1367,7 @@ func TestAuthOnlyEndpointSetBasicAuthTrueRequestHeaders(t *testing.T) {
pcTest.validateUser = true
pcTest.rw = httptest.NewRecorder()
pcTest.req, _ = http.NewRequest("GET",
pcTest.req, _ = http.NewRequest(http.MethodGet,
pcTest.opts.ProxyPrefix+authOnlyPath, nil)
created := time.Now()
@ -1447,7 +1447,7 @@ func TestAuthOnlyEndpointSetBasicAuthFalseRequestHeaders(t *testing.T) {
pcTest.validateUser = true
pcTest.rw = httptest.NewRecorder()
pcTest.req, _ = http.NewRequest("GET",
pcTest.req, _ = http.NewRequest(http.MethodGet,
pcTest.opts.ProxyPrefix+authOnlyPath, nil)
created := time.Now()
@ -1495,7 +1495,7 @@ func TestAuthSkippedForPreflightRequests(t *testing.T) {
}
proxy.provider = NewTestProvider(upstreamURL, "")
rw := httptest.NewRecorder()
req, _ := http.NewRequest("OPTIONS", "/preflight-request", nil)
req, _ := http.NewRequest(http.MethodOptions, "/preflight-request", nil)
proxy.ServeHTTP(rw, req)
assert.Equal(t, 200, rw.Code)
@ -1670,19 +1670,19 @@ func TestRequestSignature(t *testing.T) {
resp string
}{
"No request signature": {
method: "GET",
method: http.MethodGet,
body: "",
key: "",
resp: "no signature received",
},
"Get request": {
method: "GET",
method: http.MethodGet,
body: "",
key: "7d9e1aa87a5954e6f9fc59266b3af9d7c35fda2d",
resp: "signatures match",
},
"Post request": {
method: "POST",
method: http.MethodPost,
body: `{ "hello": "world!" }`,
key: "d90df39e2d19282840252612dd7c81421a372f61",
resp: "signatures match",
@ -2207,7 +2207,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: false,
realClientIPHeader: "X-Real-IP", // Default value
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
return req
}(),
expectTrusted: false,
@ -2219,7 +2219,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: false,
realClientIPHeader: "X-Real-IP",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.RemoteAddr = "@"
return req
}(),
@ -2232,7 +2232,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: false,
realClientIPHeader: "X-Real-IP",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.RemoteAddr = "@"
return req
}(),
@ -2245,7 +2245,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: false,
realClientIPHeader: "X-Real-IP", // Default value
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.RemoteAddr = "127.0.0.1:43670"
return req
}(),
@ -2258,7 +2258,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Real-IP", // Default value
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.RemoteAddr = "127.0.0.1:44324"
return req
}(),
@ -2271,7 +2271,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Forwarded-For", "127.0.0.1")
return req
}(),
@ -2284,7 +2284,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Forwarded-For", "::1")
return req
}(),
@ -2297,7 +2297,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Forwarded-For", "12.34.56.78")
return req
}(),
@ -2310,7 +2310,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Forwarded-For", "::2")
return req
}(),
@ -2323,7 +2323,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Real-IP", "::1")
return req
}(),
@ -2336,7 +2336,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: true,
realClientIPHeader: "X-Forwarded-For",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.Header.Add("X-Forwarded-For", "adsfljk29242as!!")
return req
}(),
@ -2349,7 +2349,7 @@ func TestTrustedIPs(t *testing.T) {
reverseProxy: false,
realClientIPHeader: "X-Real-IP",
req: func() *http.Request {
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
req.RemoteAddr = "adsfljk29242as!!"
return req
}(),
@ -2445,12 +2445,12 @@ func Test_buildRoutesAllowlist(t *testing.T) {
},
expectedRoutes: []expectedAllowedRoute{
{
method: "GET",
method: http.MethodGet,
negate: false,
regexString: "^/foo/bar",
},
{
method: "POST",
method: http.MethodPost,
negate: false,
regexString: "^/baz/[0-9]+/thing",
},
@ -2503,11 +2503,11 @@ func Test_buildRoutesAllowlist(t *testing.T) {
regexString: "^/baz/[0-9]+/thing/regex",
},
{
method: "GET",
method: http.MethodGet,
regexString: "^/foo/bar",
},
{
method: "POST",
method: http.MethodPost,
regexString: "^/baz/[0-9]+/thing",
},
{
@ -2659,7 +2659,7 @@ func TestApiRoutes(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
req, err := http.NewRequest("GET", tc.url, nil)
req, err := http.NewRequest(http.MethodGet, tc.url, nil)
req.Header.Set("Accept", tc.contentType)
assert.NoError(t, err)
@ -2718,37 +2718,37 @@ func TestAllowedRequest(t *testing.T) {
}{
{
name: "Regex GET allowed",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/regex",
allowed: true,
},
{
name: "Regex POST allowed ",
method: "POST",
method: http.MethodPost,
url: "/skip/auth/regex",
allowed: true,
},
{
name: "Regex denied",
method: "GET",
method: http.MethodGet,
url: "/wrong/denied",
allowed: false,
},
{
name: "Regex allowed with fragment-free path",
method: "GET",
method: http.MethodGet,
url: "/public/legit/endpoint",
allowed: true,
},
{
name: "Regex denied when path contains encoded fragment suffix",
method: "GET",
method: http.MethodGet,
url: "/public/secret%23/endpoint",
allowed: false,
},
{
name: "Route allowed",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/routes/get",
allowed: true,
},
@ -2760,25 +2760,25 @@ func TestAllowedRequest(t *testing.T) {
},
{
name: "Route denied with wrong path",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/routes/wrong/path",
allowed: false,
},
{
name: "Route denied with wrong path and method",
method: "POST",
method: http.MethodPost,
url: "/skip/auth/routes/wrong/path",
allowed: false,
},
{
name: "Route allowed with fragment-free path",
method: "GET",
method: http.MethodGet,
url: "/foo/public/bar",
allowed: true,
},
{
name: "Route denied when path contains encoded fragment suffix",
method: "GET",
method: http.MethodGet,
url: "/foo/secret%23/bar",
allowed: false,
},
@ -2843,37 +2843,37 @@ func TestAllowedRequestWithForwardedUriHeader(t *testing.T) {
}{
{
name: "Regex GET allowed",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/regex",
allowed: true,
},
{
name: "Regex POST allowed ",
method: "POST",
method: http.MethodPost,
url: "/skip/auth/regex",
allowed: true,
},
{
name: "Regex denied",
method: "GET",
method: http.MethodGet,
url: "/wrong/denied",
allowed: false,
},
{
name: "Regex allowed with fragment-free path",
method: "GET",
method: http.MethodGet,
url: "/public/legit/endpoint",
allowed: true,
},
{
name: "Regex denied when X-Forwarded-Uri contains an encoded fragment suffix",
method: "GET",
method: http.MethodGet,
url: "/public/secret%23/endpoint",
allowed: false,
},
{
name: "Route allowed",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/routes/get",
allowed: true,
},
@ -2885,25 +2885,25 @@ func TestAllowedRequestWithForwardedUriHeader(t *testing.T) {
},
{
name: "Route denied with wrong path",
method: "GET",
method: http.MethodGet,
url: "/skip/auth/routes/wrong/path",
allowed: false,
},
{
name: "Route denied with wrong path and method",
method: "POST",
method: http.MethodPost,
url: "/skip/auth/routes/wrong/path",
allowed: false,
},
{
name: "Route allowed with fragment-free path",
method: "GET",
method: http.MethodGet,
url: "/foo/public/bar",
allowed: true,
},
{
name: "Route denied when X-Forwarded-Uri contains an encoded fragment suffix",
method: "GET",
method: http.MethodGet,
url: "/foo/secret%23/bar",
allowed: false,
},
@ -3004,37 +3004,37 @@ func TestAllowedRequestNegateWithoutMethod(t *testing.T) {
}{
{
name: "Some static file allowed",
method: "GET",
method: http.MethodGet,
url: "/static/file.txt",
allowed: true,
},
{
name: "POST to contact form allowed",
method: "POST",
method: http.MethodPost,
url: "/contact",
allowed: true,
},
{
name: "Regex POST allowed",
method: "POST",
method: http.MethodPost,
url: "/api/public-entity",
allowed: true,
},
{
name: "Regex POST with trailing slash allowed",
method: "POST",
method: http.MethodPost,
url: "/api/public-entity/",
allowed: true,
},
{
name: "Regex GET api route denied",
method: "GET",
method: http.MethodGet,
url: "/api/users",
allowed: false,
},
{
name: "Regex POST api route denied",
method: "POST",
method: http.MethodPost,
url: "/api/users",
allowed: false,
},
@ -3104,37 +3104,37 @@ func TestAllowedRequestNegateWithMethod(t *testing.T) {
}{
{
name: "Some static file allowed",
method: "GET",
method: http.MethodGet,
url: "/static/file.txt",
allowed: true,
},
{
name: "POST to contact form not allowed",
method: "POST",
method: http.MethodPost,
url: "/contact",
allowed: false,
},
{
name: "Regex POST allowed",
method: "POST",
method: http.MethodPost,
url: "/api/public-entity",
allowed: true,
},
{
name: "Regex POST with trailing slash allowed",
method: "POST",
method: http.MethodPost,
url: "/api/public-entity/",
allowed: true,
},
{
name: "Regex GET api route denied",
method: "GET",
method: http.MethodGet,
url: "/api/users",
allowed: false,
},
{
name: "Regex POST api route denied",
method: "POST",
method: http.MethodPost,
url: "/api/users",
allowed: false,
},
@ -3274,7 +3274,7 @@ func TestProxyAllowedGroups(t *testing.T) {
t.Fatal(err)
}
test.req, _ = http.NewRequest("GET", fmt.Sprintf("/%s", tt.querystring), nil)
test.req, _ = http.NewRequest(http.MethodGet, fmt.Sprintf("/%s", tt.querystring), nil)
test.req.Header.Add("accept", applicationJSON)
err = test.SaveSession(session)
@ -3418,7 +3418,7 @@ func TestAuthOnlyAllowedGroupsWithSkipMethods(t *testing.T) {
{
name: "UserWithGroupSkipAuthPreflight",
groups: []string{"a", "c"},
method: "OPTIONS",
method: http.MethodOptions,
ip: "1.2.3.5:43670",
withSession: true,
expectedStatusCode: http.StatusAccepted,
@ -3426,7 +3426,7 @@ func TestAuthOnlyAllowedGroupsWithSkipMethods(t *testing.T) {
{
name: "UserWithGroupTrustedIp",
groups: []string{"a", "c"},
method: "GET",
method: http.MethodGet,
ip: "1.2.3.4:43670",
withSession: true,
expectedStatusCode: http.StatusAccepted,
@ -3434,7 +3434,7 @@ func TestAuthOnlyAllowedGroupsWithSkipMethods(t *testing.T) {
{
name: "UserWithoutGroupSkipAuthPreflight",
groups: []string{"c"},
method: "OPTIONS",
method: http.MethodOptions,
ip: "1.2.3.5:43670",
withSession: true,
expectedStatusCode: http.StatusForbidden,
@ -3442,21 +3442,21 @@ func TestAuthOnlyAllowedGroupsWithSkipMethods(t *testing.T) {
{
name: "UserWithoutGroupTrustedIp",
groups: []string{"c"},
method: "GET",
method: http.MethodGet,
ip: "1.2.3.4:43670",
withSession: true,
expectedStatusCode: http.StatusForbidden,
},
{
name: "UserWithoutSessionSkipAuthPreflight",
method: "OPTIONS",
method: http.MethodOptions,
ip: "1.2.3.5:43670",
withSession: false,
expectedStatusCode: http.StatusAccepted,
},
{
name: "UserWithoutSessionTrustedIp",
method: "GET",
method: http.MethodGet,
ip: "1.2.3.4:43670",
withSession: false,
expectedStatusCode: http.StatusAccepted,
@ -3808,14 +3808,14 @@ func TestIdTokenPlaceholderInSignOut(t *testing.T) {
// Save the required session
rw := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest(http.MethodGet, "/", nil)
err = proxy.sessionStore.Save(rw, req, session)
assert.NoError(t, err)
rw = httptest.NewRecorder()
rdUrl := url.QueryEscape("https://my-oidc-provider.example.com/sign_out_page?id_token_hint={id_token}&post_logout_redirect_uri=https://my-app.example.com/")
req, _ = http.NewRequest("GET", "/oauth2/sign_out?rd="+rdUrl, nil)
req, _ = http.NewRequest(http.MethodGet, "/oauth2/sign_out?rd="+rdUrl, nil)
req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{
RequestID: "11111111-2222-4333-8444-555555555555",
Session: session,

View File

@ -145,7 +145,7 @@ func loadAndSubstituteEnvs(configFileName string) ([]byte, error) {
func registerFlags(v *viper.Viper, prefix string, flagSet *pflag.FlagSet, options interface{}) error {
val := reflect.ValueOf(options)
var typ reflect.Type
if val.Kind() == reflect.Ptr {
if val.Kind() == reflect.Pointer {
typ = val.Elem().Type()
} else {
typ = val.Type()

View File

@ -286,7 +286,7 @@ func TestSendAuthenticatedPostRequestToServer(t *testing.T) {
upstream := httptest.NewServer(
http.HandlerFunc(authenticator.Authenticate))
req, err := http.NewRequest("POST", upstream.URL+"/foo/bar",
req, err := http.NewRequest(http.MethodPost, upstream.URL+"/foo/bar",
io.NopCloser(&fakeNetConn{reqBody: payload}))
if err != nil {
panic(err)

View File

@ -31,7 +31,7 @@ var _ = Describe("Builder suite", func() {
Context("with a basic request", func() {
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: baseHeaders,
Body: []byte{},
RequestURI: "/json/path",
@ -52,7 +52,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: baseHeaders,
Body: []byte{},
RequestURI: "/json/path",
@ -78,7 +78,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: header,
Body: []byte(body),
RequestURI: "/json/path",
@ -93,11 +93,11 @@ var _ = Describe("Builder suite", func() {
BeforeEach(func() {
buf := bytes.NewBuffer([]byte(body))
b = b.WithMethod("POST").WithBody(buf)
b = b.WithMethod(http.MethodPost).WithBody(buf)
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "POST",
Method: http.MethodPost,
Header: header,
Body: []byte(body),
RequestURI: "/json/path",
@ -109,11 +109,11 @@ var _ = Describe("Builder suite", func() {
header.Set("Content-Length", "0")
BeforeEach(func() {
b = b.WithMethod("POST")
b = b.WithMethod(http.MethodPost)
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "POST",
Method: http.MethodPost,
Header: header,
Body: []byte{},
RequestURI: "/json/path",
@ -122,11 +122,11 @@ var _ = Describe("Builder suite", func() {
Context("OPTIONS", func() {
BeforeEach(func() {
b = b.WithMethod("OPTIONS")
b = b.WithMethod(http.MethodOptions)
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "OPTIONS",
Method: http.MethodOptions,
Header: baseHeaders,
Body: []byte{},
RequestURI: "/json/path",
@ -152,7 +152,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: header,
Body: []byte{},
RequestURI: "/json/path",
@ -170,7 +170,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: replacementHeaders,
Body: []byte{},
RequestURI: "/json/path",
@ -190,7 +190,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: replacementHeaders,
Body: []byte{},
RequestURI: "/json/path",
@ -205,7 +205,7 @@ var _ = Describe("Builder suite", func() {
})
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: header,
Body: []byte{},
RequestURI: "/json/path",
@ -219,12 +219,12 @@ var _ = Describe("Builder suite", func() {
result := b.Do()
Expect(result.Error()).ToNot(HaveOccurred())
b.WithMethod("POST")
b.WithMethod(http.MethodPost)
})
Context("should not redo the request", func() {
assertSuccessfulRequest(getBuilder, testHTTPRequest{
Method: "GET",
Method: http.MethodGet,
Header: baseHeaders,
Body: []byte{},
RequestURI: "/json/path",

View File

@ -123,7 +123,7 @@ func (t *unixRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
// The proxy should render an error page if there are failures connecting to the
// upstream server.
func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler ProxyErrorHandler) http.Handler {
proxy := httputil.NewSingleHostReverseProxy(target)
proxy := newSingleHostReverseProxy(target)
// Inherit default transport options from Go's stdlib
transport := http.DefaultTransport.(*http.Transport).Clone()
@ -155,7 +155,7 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr
}
// Ensure we always pass the original request path
setProxyDirector(proxy)
setProxyRewrite(proxy)
// TODO (@tuunit) - this should be inverted or get a better name in the future to set the upstream host header
// only if PassHostHeader is explicitly set to true. Currently this would be a breaking change.
@ -179,32 +179,71 @@ func newReverseProxy(target *url.URL, upstream options.Upstream, errorHandler Pr
return proxy
}
// setProxyUpstreamHostHeader sets the proxy.Director so that upstream requests
// receive a host header matching the target URL.
func setProxyUpstreamHostHeader(proxy *httputil.ReverseProxy, target *url.URL) {
director := proxy.Director
proxy.Director = func(req *http.Request) {
director(req)
req.Host = target.Host
func newSingleHostReverseProxy(target *url.URL) *httputil.ReverseProxy {
return &httputil.ReverseProxy{
Rewrite: func(proxyReq *httputil.ProxyRequest) {
proxyReq.SetURL(target)
proxyReq.Out.Host = proxyReq.In.Host
setProxyForwardingHeaders(proxyReq)
},
}
}
// setProxyDirector sets the proxy.Director so that request URIs are escaped
// setProxyUpstreamHostHeader sets the proxy.Rewrite so that upstream requests
// receive a host header matching the target URL.
func setProxyUpstreamHostHeader(proxy *httputil.ReverseProxy, target *url.URL) {
rewrite := proxy.Rewrite
proxy.Rewrite = func(proxyReq *httputil.ProxyRequest) {
rewrite(proxyReq)
proxyReq.Out.Host = target.Host
}
}
// setProxyRewrite sets the proxy.Rewrite so that request URIs are escaped
// when proxying to usptream servers.
func setProxyDirector(proxy *httputil.ReverseProxy) {
director := proxy.Director
proxy.Director = func(req *http.Request) {
director(req)
func setProxyRewrite(proxy *httputil.ReverseProxy) {
rewrite := proxy.Rewrite
proxy.Rewrite = func(proxyReq *httputil.ProxyRequest) {
rewrite(proxyReq)
// use RequestURI so that we aren't unescaping encoded slashes in the request path
req.URL.Opaque = req.RequestURI
req.URL.RawQuery = ""
req.URL.ForceQuery = false
proxyReq.Out.URL.Opaque = proxyReq.In.RequestURI
proxyReq.Out.URL.RawQuery = ""
proxyReq.Out.URL.ForceQuery = false
}
}
func setProxyForwardingHeaders(proxyReq *httputil.ProxyRequest) {
// TODO (@tuunit): Preserve the legacy Director-based forwarding header behavior
// for backwards compatibility. Harden this with saner defaults and/or
// explicit flags in the future.
for _, header := range []string{"Forwarded", "X-Forwarded-Host", "X-Forwarded-Proto"} {
if values, ok := proxyReq.In.Header[header]; ok {
proxyReq.Out.Header[header] = append([]string(nil), values...)
}
}
prior, ok := proxyReq.In.Header["X-Forwarded-For"]
if ok {
proxyReq.Out.Header["X-Forwarded-For"] = append([]string(nil), prior...)
}
clientIP, _, err := net.SplitHostPort(proxyReq.In.RemoteAddr)
if err != nil {
return
}
omit := ok && prior == nil
if len(prior) > 0 {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
if !omit {
proxyReq.Out.Header.Set("X-Forwarded-For", clientIP)
}
}
// newWebSocketReverseProxy creates a new reverse proxy for proxying websocket connections.
func newWebSocketReverseProxy(u *url.URL, skipTLSVerify *bool, passHostHeader *bool) http.Handler {
wsProxy := httputil.NewSingleHostReverseProxy(u)
wsProxy := newSingleHostReverseProxy(u)
// Inherit default transport options from Go's stdlib
transport := http.DefaultTransport.(*http.Transport).Clone()

View File

@ -361,7 +361,12 @@ var _ = Describe("HTTP Upstream Suite", func() {
return http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
proxy, ok := h.(*httputil.ReverseProxy)
Expect(ok).To(BeTrue())
proxy.Director(req)
outReq := req.Clone(req.Context())
proxy.Rewrite(&httputil.ProxyRequest{
In: req,
Out: outReq,
})
req.Host = outReq.Host
})
}
httpUpstream.handler = requestInterceptor(httpUpstream.handler)
@ -370,6 +375,54 @@ var _ = Describe("HTTP Upstream Suite", func() {
Expect(req.Host).To(Equal(strings.TrimPrefix(serverAddr, "http://")))
})
It("ServeHTTP preserves forwarding headers when using Rewrite", func() {
req := httptest.NewRequest("", "http://example.localhost/foo", nil)
req.RemoteAddr = "192.0.2.10:1234"
req.Header.Set("Forwarded", "for=192.0.2.1;proto=https;host=example.localhost")
req.Header.Set("X-Forwarded-Host", "forwarded.example.localhost")
req.Header.Set("X-Forwarded-Proto", "https")
req.Header.Set("X-Forwarded-For", "192.0.2.1")
req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{})
rw := httptest.NewRecorder()
upstream := options.Upstream{
ID: "preserveForwardedHeaders",
PassHostHeader: ptr.To(true),
ProxyWebSockets: ptr.To(false),
InsecureSkipTLSVerify: ptr.To(false),
FlushInterval: &defaultFlushInterval,
Timeout: &defaultTimeout,
}
u, err := url.Parse(serverAddr)
Expect(err).ToNot(HaveOccurred())
handler := newHTTPUpstreamProxy(upstream, u, nil, nil)
httpUpstream, ok := handler.(*httpUpstreamProxy)
Expect(ok).To(BeTrue())
requestInterceptor := func(h http.Handler) http.Handler {
return http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
proxy, ok := h.(*httputil.ReverseProxy)
Expect(ok).To(BeTrue())
outReq := req.Clone(req.Context())
proxy.Rewrite(&httputil.ProxyRequest{
In: req,
Out: outReq,
})
Expect(outReq.Header.Values("Forwarded")).To(Equal([]string{"for=192.0.2.1;proto=https;host=example.localhost"}))
Expect(outReq.Header.Values("X-Forwarded-Host")).To(Equal([]string{"forwarded.example.localhost"}))
Expect(outReq.Header.Values("X-Forwarded-Proto")).To(Equal([]string{"https"}))
Expect(outReq.Header.Values("X-Forwarded-For")).To(Equal([]string{"192.0.2.1, 192.0.2.10"}))
})
}
httpUpstream.handler = requestInterceptor(httpUpstream.handler)
httpUpstream.ServeHTTP(rw, req)
})
type newUpstreamTableInput struct {
proxyWebSockets bool
flushInterval time.Duration
@ -405,6 +458,7 @@ var _ = Describe("HTTP Upstream Suite", func() {
proxy, ok := upstreamProxy.handler.(*httputil.ReverseProxy)
Expect(ok).To(BeTrue())
Expect(proxy.Rewrite).ToNot(BeNil())
Expect(proxy.FlushInterval).To(Equal(in.flushInterval))
transport, ok := proxy.Transport.(*http.Transport)
Expect(ok).To(BeTrue())

View File

@ -79,7 +79,7 @@ var _ = Describe("Proxy Suite", func() {
{
ID: "bad-http-backend",
Path: "/bad-http/",
URI: "http://::1",
URI: invalidServer,
},
{
ID: "single-path-backend",

View File

@ -24,7 +24,7 @@ var (
serverAddr string
unixServer *httptest.Server
unixServerAddr string
invalidServer = "http://::1"
invalidServer = "http://127.0.0.1:1"
)
func TestUpstreamSuite(t *testing.T) {

View File

@ -193,8 +193,8 @@ var _ = Describe("Sessions", func() {
unreachableRedisDelMsg = "unable to delete the redis initialization key: dial tcp 127.0.0.1:65535: connect: connection refused"
unreachableSentinelSetMsg = "unable to set a redis initialization key: redis: all sentinels specified in configuration are unreachable: redis: nil"
unrechableSentinelDelMsg = "unable to delete the redis initialization key: redis: all sentinels specified in configuration are unreachable: redis: nil"
refusedSentinelSetMsg = "unable to set a redis initialization key: redis: all sentinels specified in configuration are unreachable: context deadline exceeded"
refusedSentinelDelMsg = "unable to delete the redis initialization key: redis: all sentinels specified in configuration are unreachable: context deadline exceeded"
refusedSentinelSetMsg = "unable to set a redis initialization key: redis: all sentinels specified in configuration are unreachable: dial tcp 127.0.0.1:65535: connect: connection refused"
refusedSentinelDelMsg = "unable to delete the redis initialization key: redis: all sentinels specified in configuration are unreachable: dial tcp 127.0.0.1:65535: connect: connection refused"
)
type redisStoreTableInput struct {

View File

@ -166,7 +166,7 @@ func (p *AzureProvider) Redeem(ctx context.Context, redirectURL, code, codeVerif
err = requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do().
@ -334,7 +334,7 @@ func (p *AzureProvider) redeemRefreshToken(ctx context.Context, s *sessions.Sess
err = requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do().

View File

@ -219,7 +219,7 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code, codeVeri
err = requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do().
@ -543,7 +543,7 @@ func (p *GoogleProvider) redeemRefreshToken(ctx context.Context, s *sessions.Ses
err = requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do().

View File

@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"math/big"
"net/http"
"net/url"
"os"
"time"
@ -237,7 +238,7 @@ func (p *LoginGovProvider) Redeem(ctx context.Context, _, code, codeVerifier str
}
err = requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do().

View File

@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"regexp"
@ -304,7 +305,7 @@ func (p *MicrosoftEntraIDProvider) checkTenantMatchesTenantList(tenant string, a
func (p *MicrosoftEntraIDProvider) fetchToken(ctx context.Context, params url.Values) (*oauth2.Token, error) {
resp := requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do()

View File

@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
@ -71,7 +72,7 @@ func (p *ProviderData) Redeem(ctx context.Context, redirectURL, code, codeVerifi
result := requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do()

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"net/http"
"net/url"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
@ -75,7 +76,7 @@ func NewSourceHutProvider(p *ProviderData) *SourceHutProvider {
func (p *SourceHutProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error {
json, err := requests.New(p.ProfileURL.String()).
WithContext(ctx).
WithMethod("POST").
WithMethod(http.MethodPost).
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", "Bearer "+s.AccessToken).
WithBody(bytes.NewBufferString(`{"query": "{ me { username, email } }"}`)).