@@ -1482,28 +1482,28 @@ func TestAuthOnlyEndpointSetBasicAuthFalseRequestHeaders(t *testing.T) {
1484func TestAuthSkippedForPreflightRequests(t *testing.T) {
1484func TestAuthSkippedForPreflightRequests(t *testing.T) {
1485− upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1485+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1486 w.WriteHeader(200)
1486 w.WriteHeader(200)
1487 _, err := w.Write([]byte("response"))
1487 _, err := w.Write([]byte("response"))
1488 if err != nil {
1488 if err != nil {
1489 t.Fatal(err)
1489 t.Fatal(err)
1492− t.Cleanup(upstream.Close)
1492+ t.Cleanup(upstreamServer.Close)
1494 opts := baseTestOptions()
1494 opts := baseTestOptions()
1495 opts.UpstreamServers = options.Upstreams{
1495 opts.UpstreamServers = options.Upstreams{
1497− ID: upstream.URL,
1497+ ID: upstreamServer.URL,
1498 Path: "/",
1498 Path: "/",
1499− URI: upstream.URL,
1499+ URI: upstreamServer.URL,
1502 opts.SkipAuthPreflight = true
1502 opts.SkipAuthPreflight = true
1503 err := validation.Validate(opts)
1503 err := validation.Validate(opts)
1504 assert.NoError(t, err)
1504 assert.NoError(t, err)
1506− upstreamURL, _ := url.Parse(upstream.URL)
1506+ upstreamURL, _ := url.Parse(upstreamServer.URL)
1507 opts.SetProvider(NewTestProvider(upstreamURL, ""))
1507 opts.SetProvider(NewTestProvider(upstreamURL, ""))
1509 proxy, err := NewOAuthProxy(opts, func(string) bool { return false })
1509 proxy, err := NewOAuthProxy(opts, func(string) bool { return false })
@@ -1561,17 +1561,17 @@ func NewSignatureTest() (*SignatureTest, error) {
1561 opts.EmailDomains = []string{"acm.org"}
1561 opts.EmailDomains = []string{"acm.org"}
1563 authenticator := &SignatureAuthenticator{}
1563 authenticator := &SignatureAuthenticator{}
1564− upstream := httptest.NewServer(
1564+ upstreamServer := httptest.NewServer(
1565 http.HandlerFunc(authenticator.Authenticate))
1565 http.HandlerFunc(authenticator.Authenticate))
1566− upstreamURL, err := url.Parse(upstream.URL)
1566+ upstreamURL, err := url.Parse(upstreamServer.URL)
1567 if err != nil {
1567 if err != nil {
1568 return nil, err
1568 return nil, err
1570 opts.UpstreamServers = options.Upstreams{
1570 opts.UpstreamServers = options.Upstreams{
1572− ID: upstream.URL,
1572+ ID: upstreamServer.URL,
1573 Path: "/",
1573 Path: "/",
1574− URI: upstream.URL,
1574+ URI: upstreamServer.URL,
@@ -1590,7 +1590,7 @@ func NewSignatureTest() (*SignatureTest, error) {
1591 return &SignatureTest{
1591 return &SignatureTest{
1593− upstream,
1593+ upstreamServer,
1594 upstreamURL.Host,
1594 upstreamURL.Host,
1595 provider,
1595 provider,
1596 make(http.Header),
1596 make(http.Header),
@@ -1974,20 +1974,20 @@ func Test_prepareNoCache(t *testing.T) {
1976func Test_noCacheHeaders(t *testing.T) {
1976func Test_noCacheHeaders(t *testing.T) {
1977− upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1977+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1978 _, err := w.Write([]byte("upstream"))
1978 _, err := w.Write([]byte("upstream"))
1979 if err != nil {
1979 if err != nil {
1980 t.Error(err)
1980 t.Error(err)
1983− t.Cleanup(upstream.Close)
1983+ t.Cleanup(upstreamServer.Close)
1985 opts := baseTestOptions()
1985 opts := baseTestOptions()
1986 opts.UpstreamServers = options.Upstreams{
1986 opts.UpstreamServers = options.Upstreams{
1988− ID: upstream.URL,
1988+ ID: upstreamServer.URL,
1989 Path: "/",
1989 Path: "/",
1990− URI: upstream.URL,
1990+ URI: upstreamServer.URL,
1993 opts.SkipAuthRegex = []string{".*"}
1993 opts.SkipAuthRegex = []string{".*"}
@@ -2224,7 +2224,8 @@ func TestTrustedIPs(t *testing.T) {
2224 opts.TrustedIPs = tt.trustedIPs
2224 opts.TrustedIPs = tt.trustedIPs
2225 opts.ReverseProxy = tt.reverseProxy
2225 opts.ReverseProxy = tt.reverseProxy
2226 opts.RealClientIPHeader = tt.realClientIPHeader
2226 opts.RealClientIPHeader = tt.realClientIPHeader
2227− validation.Validate(opts)
2227+ err := validation.Validate(opts)
2228+ assert.NoError(t, err)
2229 proxy, err := NewOAuthProxy(opts, func(string) bool { return true })
2230 proxy, err := NewOAuthProxy(opts, func(string) bool { return true })
2230 assert.NoError(t, err)
2231 assert.NoError(t, err)
@@ -2240,6 +2241,237 @@ func TestTrustedIPs(t *testing.T) {
2244+func Test_buildRoutesAllowlist(t *testing.T) {
2245+ testCases := []struct {
2247+ skipAuthRegex []string
2248+ skipAuthRoutes []string
2249+ expectedMethods []string
2250+ expectedRegexes []string
2254+ name: "No skip auth configured",
2255+ skipAuthRegex: []string{},
2256+ skipAuthRoutes: []string{},
2257+ expectedMethods: []string{},
2258+ expectedRegexes: []string{},
2259+ shouldError: false,
2262+ name: "Only skipAuthRegex configured",
2263+ skipAuthRegex: []string{
2265+ "^/baz/[0-9]+/thing",
2267+ skipAuthRoutes: []string{},
2268+ expectedMethods: []string{
2272+ expectedRegexes: []string{
2274+ "^/baz/[0-9]+/thing",
2276+ shouldError: false,
2279+ name: "Only skipAuthRoutes configured",
2280+ skipAuthRegex: []string{},
2281+ skipAuthRoutes: []string{
2283+ "POST=^/baz/[0-9]+/thing",
2285+ "WEIRD=^/methods/are/allowed",
2286+ "PATCH=/second/equals?are=handled&just=fine",
2288+ expectedMethods: []string{
2295+ expectedRegexes: []string{
2297+ "^/baz/[0-9]+/thing",
2299+ "^/methods/are/allowed",
2300+ "/second/equals?are=handled&just=fine",
2302+ shouldError: false,
2305+ name: "Both skipAuthRegexes and skipAuthRoutes configured",
2306+ skipAuthRegex: []string{
2308+ "^/baz/[0-9]+/thing/regex",
2310+ skipAuthRoutes: []string{
2312+ "POST=^/baz/[0-9]+/thing",
2315+ expectedMethods: []string{
2322+ expectedRegexes: []string{
2324+ "^/baz/[0-9]+/thing/regex",
2326+ "^/baz/[0-9]+/thing",
2329+ shouldError: false,
2332+ name: "Invalid skipAuthRegex entry",
2333+ skipAuthRegex: []string{
2335+ "^/baz/[0-9]+/thing",
2338+ skipAuthRoutes: []string{},
2339+ expectedMethods: []string{},
2340+ expectedRegexes: []string{},
2344+ name: "Invalid skipAuthRoutes entry",
2345+ skipAuthRegex: []string{},
2346+ skipAuthRoutes: []string{
2348+ "POST=^/baz/[0-9]+/thing",
2352+ expectedMethods: []string{},
2353+ expectedRegexes: []string{},
2358+ for _, tc := range testCases {
2359+ t.Run(tc.name, func(t *testing.T) {
2360+ opts := &options.Options{
2361+ SkipAuthRegex: tc.skipAuthRegex,
2362+ SkipAuthRoutes: tc.skipAuthRoutes,
2364+ routes, err := buildRoutesAllowlist(opts)
2365+ if tc.shouldError {
2366+ assert.Error(t, err)
2369+ assert.NoError(t, err)
2371+ for i, route := range routes {
2372+ assert.Greater(t, len(tc.expectedMethods), i)
2373+ assert.Equal(t, route.method, tc.expectedMethods[i])
2374+ assert.Greater(t, len(tc.expectedRegexes), i)
2375+ assert.Equal(t, route.pathRegex.String(), tc.expectedRegexes[i])
2381+func TestAllowedRequest(t *testing.T) {
2382+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2384+ _, err := w.Write([]byte("Allowed Request"))
2389+ t.Cleanup(upstreamServer.Close)
2391+ opts := baseTestOptions()
2392+ opts.UpstreamServers = options.Upstreams{
2394+ ID: upstreamServer.URL,
2396+ URI: upstreamServer.URL,
2399+ opts.SkipAuthRegex = []string{
2400+ "^/skip/auth/regex$",
2402+ opts.SkipAuthRoutes = []string{
2403+ "GET=^/skip/auth/routes/get",
2405+ err := validation.Validate(opts)
2406+ assert.NoError(t, err)
2407+ proxy, err := NewOAuthProxy(opts, func(_ string) bool { return true })
2412+ testCases := []struct {
2419+ name: "Regex GET allowed",
2421+ url: "/skip/auth/regex",
2425+ name: "Regex POST allowed ",
2427+ url: "/skip/auth/regex",
2431+ name: "Regex denied",
2433+ url: "/wrong/denied",
2437+ name: "Route allowed",
2439+ url: "/skip/auth/routes/get",
2443+ name: "Route denied with wrong method",
2445+ url: "/skip/auth/routes/get",
2449+ name: "Route denied with wrong path",
2451+ url: "/skip/auth/routes/wrong/path",
2456+ for _, tc := range testCases {
2457+ t.Run(tc.name, func(t *testing.T) {
2458+ req, err := http.NewRequest(tc.method, tc.url, nil)
2459+ assert.NoError(t, err)
2460+ assert.Equal(t, tc.allowed, proxy.isAllowedRoute(req))
2462+ rw := httptest.NewRecorder()
2463+ proxy.ServeHTTP(rw, req)
2466+ assert.Equal(t, 200, rw.Code)
2467+ assert.Equal(t, "Allowed Request", rw.Body.String())
2469+ assert.Equal(t, 403, rw.Code)
2243func TestProxyAllowedGroups(t *testing.T) {
2475func TestProxyAllowedGroups(t *testing.T) {
2244 tests := []struct {
2476 tests := []struct {
2245 name string
2477 name string
@@ -2265,18 +2497,18 @@ func TestProxyAllowedGroups(t *testing.T) {
2265 CreatedAt: &created,
2497 CreatedAt: &created,
2268− upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2500+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2269 w.WriteHeader(200)
2501 w.WriteHeader(200)
2271− t.Cleanup(upstream.Close)
2503+ t.Cleanup(upstreamServer.Close)
2273 test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
2505 test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
2274 opts.AllowedGroups = tt.allowedGroups
2506 opts.AllowedGroups = tt.allowedGroups
2275 opts.UpstreamServers = options.Upstreams{
2507 opts.UpstreamServers = options.Upstreams{
2277− ID: upstream.URL,
2509+ ID: upstreamServer.URL,
2278 Path: "/",
2510 Path: "/",
2279− URI: upstream.URL,
2511+ URI: upstreamServer.URL,
@@ -2287,7 +2519,8 @@ func TestProxyAllowedGroups(t *testing.T) {
2287 test.req, _ = http.NewRequest("GET", "/", nil)
2519 test.req, _ = http.NewRequest("GET", "/", nil)
2289 test.req.Header.Add("accept", applicationJSON)
2521 test.req.Header.Add("accept", applicationJSON)
2290− test.SaveSession(session)
2522+ err = test.SaveSession(session)
2523+ assert.NoError(t, err)
2291 test.proxy.ServeHTTP(test.rw, test.req)
2524 test.proxy.ServeHTTP(test.rw, test.req)
2293 if tt.expectUnauthorized {
2526 if tt.expectUnauthorized {