depot/web/fup/fuphttp/auth_test.go

147 lines
3.4 KiB
Go

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)
}
})
}
}