1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"regexp"
"testing"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/badgateway"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/testhelper"
"github.com/dgrijalva/jwt-go-v3"
)
func okHandler(w http.ResponseWriter, _ *http.Request, _ *api.Response) {
w.WriteHeader(201)
fmt.Fprint(w, "{\"status\":\"ok\"}")
}
func runPreAuthorizeHandler(t *testing.T, ts *httptest.Server, suffix string, url *regexp.Regexp, apiResponse interface{}, returnCode, expectedCode int) *httptest.ResponseRecorder {
if ts == nil {
ts = testAuthServer(url, returnCode, apiResponse)
defer ts.Close()
}
// Create http request
httpRequest, err := http.NewRequest("GET", "/address", nil)
if err != nil {
t.Fatal(err)
}
parsedURL := helper.URLMustParse(ts.URL)
a := api.NewAPI(parsedURL, "123", testhelper.SecretPath(), badgateway.TestRoundTripper(parsedURL))
response := httptest.NewRecorder()
a.PreAuthorizeHandler(okHandler, suffix).ServeHTTP(response, httpRequest)
testhelper.AssertResponseCode(t, response, expectedCode)
return response
}
func TestPreAuthorizeHappyPath(t *testing.T) {
runPreAuthorizeHandler(
t, nil, "/authorize",
regexp.MustCompile(`/authorize\z`),
&api.Response{},
200, 201)
}
func TestPreAuthorizeSuffix(t *testing.T) {
runPreAuthorizeHandler(
t, nil, "/different-authorize",
regexp.MustCompile(`/authorize\z`),
&api.Response{},
200, 404)
}
func TestPreAuthorizeJsonFailure(t *testing.T) {
runPreAuthorizeHandler(
t, nil, "/authorize",
regexp.MustCompile(`/authorize\z`),
"not-json",
200, 500)
}
func TestPreAuthorizeContentTypeFailure(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write([]byte(`{"hello":"world"}`)); err != nil {
t.Fatalf("write auth response: %v", err)
}
}))
defer ts.Close()
runPreAuthorizeHandler(
t, ts, "/authorize",
regexp.MustCompile(`/authorize\z`),
"",
200, 500)
}
func TestPreAuthorizeJWT(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token, err := jwt.Parse(r.Header.Get(api.RequestHeader), func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
secretBytes, err := (&api.Secret{Path: testhelper.SecretPath()}).Bytes()
if err != nil {
return nil, fmt.Errorf("read secret from file: %v", err)
}
return secretBytes, nil
})
if err != nil {
t.Fatalf("decode token: %v", err)
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
t.Fatal("claims cast failed")
}
if !token.Valid {
t.Fatal("JWT token invalid")
}
if claims["iss"] != "gitlab-workhorse" {
t.Fatalf("execpted issuer gitlab-workhorse, got %q", claims["iss"])
}
w.Header().Set("Content-Type", api.ResponseContentType)
if _, err := w.Write([]byte(`{"hello":"world"}`)); err != nil {
t.Fatalf("write auth response: %v", err)
}
}))
defer ts.Close()
runPreAuthorizeHandler(
t, ts, "/authorize",
regexp.MustCompile(`/authorize\z`),
"",
200, 201)
}
|