@@ -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,255 @@ func TestTrustedIPs(t *testing.T) {
2244+func Test_buildRoutesAllowlist(t *testing.T) {
2245+ type expectedAllowedRoute struct {
2250+ testCases := []struct {
2252+ skipAuthRegex []string
2253+ skipAuthRoutes []string
2254+ expectedRoutes []expectedAllowedRoute
2258+ name: "No skip auth configured",
2259+ skipAuthRegex: []string{},
2260+ skipAuthRoutes: []string{},
2261+ expectedRoutes: []expectedAllowedRoute{},
2262+ shouldError: false,
2265+ name: "Only skipAuthRegex configured",
2266+ skipAuthRegex: []string{
2268+ "^/baz/[0-9]+/thing",
2270+ skipAuthRoutes: []string{},
2271+ expectedRoutes: []expectedAllowedRoute{
2274+ regexString: "^/foo/bar",
2278+ regexString: "^/baz/[0-9]+/thing",
2281+ shouldError: false,
2284+ name: "Only skipAuthRoutes configured",
2285+ skipAuthRegex: []string{},
2286+ skipAuthRoutes: []string{
2288+ "POST=^/baz/[0-9]+/thing",
2290+ "WEIRD=^/methods/are/allowed",
2291+ "PATCH=/second/equals?are=handled&just=fine",
2293+ expectedRoutes: []expectedAllowedRoute{
2296+ regexString: "^/foo/bar",
2300+ regexString: "^/baz/[0-9]+/thing",
2304+ regexString: "^/all/methods$",
2308+ regexString: "^/methods/are/allowed",
2312+ regexString: "/second/equals?are=handled&just=fine",
2315+ shouldError: false,
2318+ name: "Both skipAuthRegexes and skipAuthRoutes configured",
2319+ skipAuthRegex: []string{
2321+ "^/baz/[0-9]+/thing/regex",
2323+ skipAuthRoutes: []string{
2325+ "POST=^/baz/[0-9]+/thing",
2328+ expectedRoutes: []expectedAllowedRoute{
2331+ regexString: "^/foo/bar/regex",
2335+ regexString: "^/baz/[0-9]+/thing/regex",
2339+ regexString: "^/foo/bar",
2343+ regexString: "^/baz/[0-9]+/thing",
2347+ regexString: "^/all/methods$",
2350+ shouldError: false,
2353+ name: "Invalid skipAuthRegex entry",
2354+ skipAuthRegex: []string{
2356+ "^/baz/[0-9]+/thing",
2359+ skipAuthRoutes: []string{},
2360+ expectedRoutes: []expectedAllowedRoute{},
2364+ name: "Invalid skipAuthRoutes entry",
2365+ skipAuthRegex: []string{},
2366+ skipAuthRoutes: []string{
2368+ "POST=^/baz/[0-9]+/thing",
2372+ expectedRoutes: []expectedAllowedRoute{},
2377+ for _, tc := range testCases {
2378+ t.Run(tc.name, func(t *testing.T) {
2379+ opts := &options.Options{
2380+ SkipAuthRegex: tc.skipAuthRegex,
2381+ SkipAuthRoutes: tc.skipAuthRoutes,
2383+ routes, err := buildRoutesAllowlist(opts)
2384+ if tc.shouldError {
2385+ assert.Error(t, err)
2388+ assert.NoError(t, err)
2390+ for i, route := range routes {
2391+ assert.Greater(t, len(tc.expectedRoutes), i)
2392+ assert.Equal(t, route.method, tc.expectedRoutes[i].method)
2393+ assert.Equal(t, route.pathRegex.String(), tc.expectedRoutes[i].regexString)
2399+func TestAllowedRequest(t *testing.T) {
2400+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2402+ _, err := w.Write([]byte("Allowed Request"))
2407+ t.Cleanup(upstreamServer.Close)
2409+ opts := baseTestOptions()
2410+ opts.UpstreamServers = options.Upstreams{
2412+ ID: upstreamServer.URL,
2414+ URI: upstreamServer.URL,
2417+ opts.SkipAuthRegex = []string{
2418+ "^/skip/auth/regex$",
2420+ opts.SkipAuthRoutes = []string{
2421+ "GET=^/skip/auth/routes/get",
2423+ err := validation.Validate(opts)
2424+ assert.NoError(t, err)
2425+ proxy, err := NewOAuthProxy(opts, func(_ string) bool { return true })
2430+ testCases := []struct {
2437+ name: "Regex GET allowed",
2439+ url: "/skip/auth/regex",
2443+ name: "Regex POST allowed ",
2445+ url: "/skip/auth/regex",
2449+ name: "Regex denied",
2451+ url: "/wrong/denied",
2455+ name: "Route allowed",
2457+ url: "/skip/auth/routes/get",
2461+ name: "Route denied with wrong method",
2463+ url: "/skip/auth/routes/get",
2467+ name: "Route denied with wrong path",
2469+ url: "/skip/auth/routes/wrong/path",
2474+ for _, tc := range testCases {
2475+ t.Run(tc.name, func(t *testing.T) {
2476+ req, err := http.NewRequest(tc.method, tc.url, nil)
2477+ assert.NoError(t, err)
2478+ assert.Equal(t, tc.allowed, proxy.isAllowedRoute(req))
2480+ rw := httptest.NewRecorder()
2481+ proxy.ServeHTTP(rw, req)
2484+ assert.Equal(t, 200, rw.Code)
2485+ assert.Equal(t, "Allowed Request", rw.Body.String())
2487+ assert.Equal(t, 403, rw.Code)
2243func TestProxyAllowedGroups(t *testing.T) {
2493func TestProxyAllowedGroups(t *testing.T) {
2244 tests := []struct {
2494 tests := []struct {
2245 name string
2495 name string
@@ -2265,18 +2515,18 @@ func TestProxyAllowedGroups(t *testing.T) {
2265 CreatedAt: &created,
2515 CreatedAt: &created,
2268− upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2518+ upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2269 w.WriteHeader(200)
2519 w.WriteHeader(200)
2271− t.Cleanup(upstream.Close)
2521+ t.Cleanup(upstreamServer.Close)
2273 test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
2523 test, err := NewProcessCookieTestWithOptionsModifiers(func(opts *options.Options) {
2274 opts.AllowedGroups = tt.allowedGroups
2524 opts.AllowedGroups = tt.allowedGroups
2275 opts.UpstreamServers = options.Upstreams{
2525 opts.UpstreamServers = options.Upstreams{
2277− ID: upstream.URL,
2527+ ID: upstreamServer.URL,
2278 Path: "/",
2528 Path: "/",
2279− URI: upstream.URL,
2529+ URI: upstreamServer.URL,
@@ -2287,7 +2537,8 @@ func TestProxyAllowedGroups(t *testing.T) {
2287 test.req, _ = http.NewRequest("GET", "/", nil)
2537 test.req, _ = http.NewRequest("GET", "/", nil)
2289 test.req.Header.Add("accept", applicationJSON)
2539 test.req.Header.Add("accept", applicationJSON)
2290− test.SaveSession(session)
2540+ err = test.SaveSession(session)
2541+ assert.NoError(t, err)
2291 test.proxy.ServeHTTP(test.rw, test.req)
2542 test.proxy.ServeHTTP(test.rw, test.req)
2293 if tt.expectUnauthorized {
2544 if tt.expectUnauthorized {