oficina / memoria Public

Clone
git clone https://amadan.net/oficina/memoria

Plain git — no account needed to clone.

Download

Download this file

1package memoria
2
3import (
4 "net/http"
5 "net/http/httptest"
6 "regexp"
7 "strings"
8 "testing"
9
10 "amadan.net/rastrillo/rastrillo"
11)
12
13// With Home configured, connect's middleware serves connect.FormPolicy:
14// rastrillo's default policy with form-action widened to the Home issuer,
15// and style-src kept at 'self' 'unsafe-inline'. Every other directive must
16// be the pinned framework's, so a tightening upstream is not silently
17// undone in Home mode.
18//
19// style-src is the one directive allowed to differ, and only in that one
20// way: rastrillo fb806a2 refuses inline styles by default, connect (at the
21// version pinned here) still allows them, and estilo's account-link page
22// (homeconnect home_link.html, Home-only) draws the address with
23// style="overflow-wrap: anywhere". The policy is connect's to tighten,
24// not this app's to override. No hash or nonce may ride along: either
25// would void 'unsafe-inline'.
26func TestHomeCSPPreservesPinnedFrameworkDirectives(t *testing.T) {
27 mux := http.NewServeMux()
28 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })
29 baselineHandler, closeBaseline, err := rastrillo.Handler(rastrillo.Options{Mux: mux})
30 if err != nil {
31 t.Fatal(err)
32 }
33 if closeBaseline != nil {
34 defer closeBaseline()
35 }
36 rec := httptest.NewRecorder()
37 baselineHandler.ServeHTTP(rec, httptest.NewRequest("GET", homeTestOrigin+"/", nil))
38 baseline := rec.Header().Get("Content-Security-Policy")
39 want := strings.Replace(baseline, "form-action 'self'", "form-action 'self' "+homeTestIssuer, 1)
40 if want == baseline {
41 t.Fatal("framework form-action changed")
42 }
43 styles := regexp.MustCompile(`style-src [^;]*`)
44 if !styles.MatchString(want) {
45 t.Fatal("framework policy has no style-src; this test's one exception no longer applies")
46 }
47 want = styles.ReplaceAllString(want, "style-src 'self' 'unsafe-inline'")
48 f := newHomeRouterFixture(t)
49 wrapped, done, err := rastrillo.Handler(rastrillo.Options{Mux: f.handler.(*http.ServeMux)})
50 if err != nil {
51 t.Fatal(err)
52 }
53 if done != nil {
54 defer done()
55 }
56 for _, path := range []string{"/signin/local", "/auth/start", "/account/home", "/signed-out"} {
57 rec := httptest.NewRecorder()
58 wrapped.ServeHTTP(rec, httptest.NewRequest("GET", homeTestOrigin+path, nil))
59 if got := rec.Header().Get("Content-Security-Policy"); got != want {
60 t.Fatalf("policy drift at %s: %q", path, got)
61 }
62 }
63}
64