1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-06-15 00:15:00 +02:00

Add API route config (#1760)

* Add API route config

In addition to requests with Accept header `application/json` return 401 instead of 302 to login page on requests matching API paths regex.

* Update changelog

* Refactor

* Remove unnecessary comment

* Reorder checks

* Lint Api -> API

Co-authored-by: Sebastian Halder <sebastian.halder@boehringer-ingelheim.com>
This commit is contained in:
Segfault16
2022-09-11 17:09:32 +02:00
committed by GitHub
parent b82593b9cc
commit 965fab422d
9 changed files with 188 additions and 17 deletions

View File

@ -1533,7 +1533,8 @@ func (st *SignatureTest) Close() {
// fakeNetConn simulates an http.Request.Body buffer that will be consumed
// when it is read by the hmacauth.HmacAuth if not handled properly. See:
// https://github.com/18F/hmacauth/pull/4
//
// https://github.com/18F/hmacauth/pull/4
type fakeNetConn struct {
reqBody string
}
@ -2421,6 +2422,116 @@ func Test_buildRoutesAllowlist(t *testing.T) {
}
}
func TestApiRoutes(t *testing.T) {
ajaxAPIServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
_, err := w.Write([]byte("AJAX API Request"))
if err != nil {
t.Fatal(err)
}
}))
t.Cleanup(ajaxAPIServer.Close)
apiServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
_, err := w.Write([]byte("API Request"))
if err != nil {
t.Fatal(err)
}
}))
t.Cleanup(apiServer.Close)
uiServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
_, err := w.Write([]byte("API Request"))
if err != nil {
t.Fatal(err)
}
}))
t.Cleanup(uiServer.Close)
opts := baseTestOptions()
opts.UpstreamServers = options.UpstreamConfig{
Upstreams: []options.Upstream{
{
ID: apiServer.URL,
Path: "/api",
URI: apiServer.URL,
},
{
ID: ajaxAPIServer.URL,
Path: "/ajaxapi",
URI: ajaxAPIServer.URL,
},
{
ID: uiServer.URL,
Path: "/ui",
URI: uiServer.URL,
},
},
}
opts.APIRoutes = []string{
"^/api",
}
opts.SkipProviderButton = true
err := validation.Validate(opts)
assert.NoError(t, err)
proxy, err := NewOAuthProxy(opts, func(_ string) bool { return true })
if err != nil {
t.Fatal(err)
}
testCases := []struct {
name string
contentType string
url string
shouldRedirect bool
}{
{
name: "AJAX request matching API regex",
contentType: "application/json",
url: "/api/v1/UserInfo",
shouldRedirect: false,
},
{
name: "AJAX request not matching API regex",
contentType: "application/json",
url: "/ajaxapi/v1/UserInfo",
shouldRedirect: false,
},
{
name: "Other Request matching API regex",
contentType: "application/grpcwebtext",
url: "/api/v1/UserInfo",
shouldRedirect: false,
},
{
name: "UI request",
contentType: "html",
url: "/ui/index.html",
shouldRedirect: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
req, err := http.NewRequest("GET", tc.url, nil)
req.Header.Set("Accept", tc.contentType)
assert.NoError(t, err)
rw := httptest.NewRecorder()
proxy.ServeHTTP(rw, req)
if tc.shouldRedirect {
assert.Equal(t, 302, rw.Code)
} else {
assert.Equal(t, 401, rw.Code)
}
})
}
}
func TestAllowedRequest(t *testing.T) {
upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)