Files

77 lines
2.5 KiB
Go
Raw Permalink Normal View History

2026-08-26 06:41:07 +08:00
package httpapi
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
"data-terminal-cloud/internal/identity"
)
type fakeVerifier struct {
principal identity.Principal
err error
}
func (f fakeVerifier) Verify(context.Context, string) (identity.Principal, error) {
return f.principal, f.err
}
func TestBearerAuthRejectsMissingToken(t *testing.T) {
handler := BearerAuth(fakeVerifier{}, http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
t.Fatal("protected handler must not be called")
}))
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/api/v1/me", nil))
if recorder.Code != http.StatusUnauthorized {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusUnauthorized)
}
if recorder.Header().Get("WWW-Authenticate") != "Bearer" {
t.Fatal("WWW-Authenticate header is missing")
}
}
func TestBearerAuthRejectsInvalidToken(t *testing.T) {
handler := BearerAuth(fakeVerifier{err: errors.New("bad token")}, http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
t.Fatal("protected handler must not be called")
}))
request := httptest.NewRequest(http.MethodGet, "/api/v1/me", nil)
request.Header.Set("Authorization", "Bearer invalid")
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusUnauthorized {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusUnauthorized)
}
}
func TestBearerAuthStoresVerifiedPrincipal(t *testing.T) {
expected := identity.Principal{Issuer: "issuer", Subject: "subject"}
handler := BearerAuth(fakeVerifier{principal: expected}, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
actual, ok := identity.PrincipalFromContext(request.Context())
if !ok || actual != expected {
t.Fatalf("principal = %#v, %t, want %#v", actual, ok, expected)
}
writer.WriteHeader(http.StatusNoContent)
}))
request := httptest.NewRequest(http.MethodGet, "/api/v1/me", nil)
request.Header.Set("Authorization", "Bearer valid")
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusNoContent {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusNoContent)
}
}
func TestBearerTokenParsing(t *testing.T) {
if token, ok := bearerToken("bearer abc.def"); !ok || token != "abc.def" {
t.Fatalf("token = %q, ok = %t", token, ok)
}
for _, header := range []string{"", "Basic abc", "Bearer", "Bearer one two"} {
if _, ok := bearerToken(header); ok {
t.Fatalf("header %q should be rejected", header)
}
}
}