package fuphttp_test import ( "context" "io" "net/http" "net/http/httptest" "testing" "hg.lukegb.com/lukegb/depot/web/fup/fuphttp" ) func TestTokenAuthMiddlewareNoToken(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) ccfg := *cfg ccfg.AuthMiddleware = fuphttp.TokenAuthMiddleware("", "realm") a, err := fuphttp.New(ctx, &ccfg) if err != nil { t.Fatalf("fuphttp.New: %v", err) } s := httptest.NewServer(a.Handler()) t.Cleanup(s.Close) resp, err := s.Client().Get(s.URL) if err != nil { t.Fatalf("Get(%q): %v", s.URL, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("status code was %v; want %v", resp.StatusCode, http.StatusOK) } } func TestTokenAuthMiddleware(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) ccfg := *cfg ccfg.AuthMiddleware = fuphttp.TokenAuthMiddleware("token", "realm") a, err := fuphttp.New(ctx, &ccfg) if err != nil { t.Fatalf("fuphttp.New: %v", err) } s := httptest.NewServer(a.Handler()) t.Cleanup(s.Close) tcs := []struct { name string path string password string headerToken string wantStatus int wantText string }{{ name: "root, no creds", path: "/", wantStatus: http.StatusUnauthorized, wantText: "unparsable or no credentials\n", }, { name: "root, with bad creds", path: "/", password: "wrong password", wantStatus: http.StatusUnauthorized, wantText: "bad credentials\n", }, { name: "root, with good creds", path: "/", password: "token", wantStatus: http.StatusOK, }, { name: "root, with good creds as header", path: "/", headerToken: "token", wantStatus: http.StatusOK, }, { name: "raw", path: "/raw/foo.txt", wantStatus: http.StatusNotFound, }, { name: "raw, with bad creds", path: "/raw/foo.txt", password: "wrong password", wantStatus: http.StatusNotFound, }, { name: "raw, with good creds", path: "/raw/foo.txt", password: "token", wantStatus: http.StatusNotFound, }, { name: "pretty", path: "/foo.txt", wantStatus: http.StatusNotFound, }, { name: "pretty, with bad creds", path: "/foo.txt", password: "wrong password", wantStatus: http.StatusNotFound, }, { name: "pretty, with good creds", path: "/foo.txt", password: "token", wantStatus: http.StatusNotFound, }} for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { ctx, cancel := context.WithCancel(ctx) t.Cleanup(cancel) req, err := http.NewRequestWithContext(ctx, "GET", s.URL+tc.path, nil) if err != nil { t.Fatalf("NewRequestWithContext: %v", err) } if tc.password != "" { req.SetBasicAuth("", tc.password) } if tc.headerToken != "" { req.Header.Set("Fup-Token", tc.headerToken) } resp, err := s.Client().Do(req) if err != nil { t.Fatalf("Do(%q): %v", s.URL+tc.path, err) } defer resp.Body.Close() if resp.StatusCode != tc.wantStatus { t.Errorf("StatusCode = %v; want %v", resp.StatusCode, tc.wantStatus) } body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("ReadAll(Body): %v", err) } if tc.wantText != "" && string(body) != tc.wantText { t.Errorf("response body = %q; want %q", string(body), tc.wantText) } }) } }