Skip to content
Snippets Groups Projects
Commit ef7fd18e authored by Will McCutchen's avatar Will McCutchen
Browse files

Add /hidden-basic-auth/:user/:pass handler

parent f5242f20
No related branches found
No related tags found
No related merge requests found
......@@ -310,3 +310,29 @@ func (h *HTTPBin) BasicAuth(w http.ResponseWriter, r *http.Request) {
})
writeJSON(w, body, status)
}
// HiddenBasicAuth requires HTTP Basic authentication but returns a status of
// 404 if the request is unauthorized
func (h *HTTPBin) HiddenBasicAuth(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) != 4 {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
expectedUser := parts[2]
expectedPass := parts[3]
givenUser, givenPass, _ := r.BasicAuth()
authorized := givenUser == expectedUser && givenPass == expectedPass
if !authorized {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
body, _ := json.Marshal(&authResponse{
Authorized: authorized,
User: givenUser,
})
writeJSON(w, body, http.StatusOK)
}
......@@ -992,3 +992,67 @@ func TestBasicAuth(t *testing.T) {
})
}
}
func TestHiddenBasicAuth(t *testing.T) {
t.Run("ok", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/hidden-basic-auth/user/pass", nil)
r.SetBasicAuth("user", "pass")
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
assertStatusCode(t, w, http.StatusOK)
assertContentType(t, w, jsonContentType)
resp := &authResponse{}
json.Unmarshal(w.Body.Bytes(), resp)
expectedResp := &authResponse{
Authorized: true,
User: "user",
}
if !reflect.DeepEqual(resp, expectedResp) {
t.Fatalf("expected response %#v, got %#v", expectedResp, resp)
}
})
t.Run("error/no auth", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/hidden-basic-auth/user/pass", nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
assertStatusCode(t, w, http.StatusNotFound)
if w.Header().Get("WWW-Authenticate") != "" {
t.Fatal("did not expect WWW-Authenticate header")
}
})
t.Run("error/bad auth", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/hidden-basic-auth/user/pass", nil)
r.SetBasicAuth("bad", "auth")
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
assertStatusCode(t, w, http.StatusNotFound)
if w.Header().Get("WWW-Authenticate") != "" {
t.Fatal("did not expect WWW-Authenticate header")
}
})
var errorTests = []struct {
url string
status int
}{
{"/hidden-basic-auth", http.StatusNotFound},
{"/hidden-basic-auth/user", http.StatusNotFound},
{"/hidden-basic-auth/user/pass/extra", http.StatusNotFound},
}
for _, test := range errorTests {
t.Run("error"+test.url, func(t *testing.T) {
r, _ := http.NewRequest("GET", test.url, nil)
r.SetBasicAuth("foo", "bar")
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
assertStatusCode(t, w, test.status)
})
}
}
......@@ -85,12 +85,14 @@ func (h *HTTPBin) Handler() http.Handler {
mux.HandleFunc("/cookies/delete", h.DeleteCookies)
mux.HandleFunc("/basic-auth/", h.BasicAuth)
mux.HandleFunc("/hidden-basic-auth/", h.HiddenBasicAuth)
// Make sure our ServeMux doesn't "helpfully" redirect these invalid
// endpoints by adding a trailing slash. See the ServeMux docs for more
// info: https://golang.org/pkg/net/http/#ServeMux
mux.HandleFunc("/absolute-redirect", http.NotFound)
mux.HandleFunc("/basic-auth", http.NotFound)
mux.HandleFunc("/hidden-basic-auth", http.NotFound)
mux.HandleFunc("/redirect", http.NotFound)
mux.HandleFunc("/relative-redirect", http.NotFound)
mux.HandleFunc("/status", http.NotFound)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment