Files
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

97 lines
2.9 KiB
Go

package web
import (
"bytes"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/justinas/nosurf"
)
func TestSecureHeaders(t *testing.T) {
rr := httptest.NewRecorder()
r, err := http.NewRequest(http.MethodGet, "/", nil)
if err != nil {
t.Fatal(err)
}
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
})
secureHeaders(next).ServeHTTP(rr, r)
rs := rr.Result()
expectedValue := "default-src 'self'; style-src 'self'; style-src-attr 'unsafe-inline'; script-src 'self'; img-src 'self' data: blob:; media-src 'self' blob:; manifest-src 'self'; connect-src 'self'"
if got := rs.Header.Get("Content-Security-Policy"); got != expectedValue {
t.Errorf("Content-Security-Policy: got %q, want %q", got, expectedValue)
}
expectedValue = "strict-origin-when-cross-origin"
if got := rs.Header.Get("Referrer-Policy"); got != expectedValue {
t.Errorf("Referrer-Policy: got %q, want %q", got, expectedValue)
}
expectedValue = "nosniff"
if got := rs.Header.Get("X-Content-Type-Options"); got != expectedValue {
t.Errorf("X-Content-Type-Options: got %q, want %q", got, expectedValue)
}
expectedValue = "deny"
if got := rs.Header.Get("X-Frame-Options"); got != expectedValue {
t.Errorf("X-Frame-Options: got %q, want %q", got, expectedValue)
}
if got := rs.Header.Get("Permissions-Policy"); got != "camera=(self), microphone=(self)" {
t.Errorf("Permissions-Policy: got %q, want %q", got, "camera=(self), microphone=(self)")
}
if rs.StatusCode != http.StatusOK {
t.Errorf("status: got %d, want %d", rs.StatusCode, http.StatusOK)
}
defer rs.Body.Close()
body, err := io.ReadAll(rs.Body)
if err != nil {
t.Fatal(err)
}
body = bytes.TrimSpace(body)
if got := string(body); got != "OK" {
t.Errorf("body: got %q, want %q", got, "OK")
}
}
func TestNoSurfAcceptsSameOriginHTTPFromLAN(t *testing.T) {
app := &application{config: Config{CookieSecure: false}}
handler := app.noSurf(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
_, _ = w.Write([]byte(nosurf.Token(r)))
return
}
w.WriteHeader(http.StatusNoContent)
}))
getRequest := httptest.NewRequest(http.MethodGet, "http://192.168.1.50:4040/login", nil)
getResponse := httptest.NewRecorder()
handler.ServeHTTP(getResponse, getRequest)
csrfCookie := getResponse.Result().Cookies()[0]
form := url.Values{"csrf_token": {getResponse.Body.String()}}
postRequest := httptest.NewRequest(http.MethodPost, "http://192.168.1.50:4040/login", bytes.NewBufferString(form.Encode()))
postRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
postRequest.Header.Set("Origin", "http://192.168.1.50:4040")
postRequest.AddCookie(csrfCookie)
postResponse := httptest.NewRecorder()
handler.ServeHTTP(postResponse, postRequest)
if postResponse.Code != http.StatusNoContent {
t.Fatalf("status: got %d, want %d", postResponse.Code, http.StatusNoContent)
}
}