rastrillo / aviso Public

Clone
git clone https://amadan.net/rastrillo/aviso

Plain git — no account needed to clone.

Download

Download this file

1package aviso_test
2
3import (
4 "errors"
5 "testing"
6
7 "amadan.net/rastrillo/aviso"
8)
9
10func newService(t *testing.T) *aviso.Service {
11 t.Helper()
12 key, err := aviso.GenerateKey()
13 if err != nil {
14 t.Fatal(err)
15 }
16 s, err := aviso.New(aviso.Config{
17 DB: openDB(t), PrivateKey: key,
18 Contact: "mailto:ops@example.test", Origin: "https://app.example.test",
19 })
20 if err != nil {
21 t.Fatal(err)
22 }
23 return s
24}
25
26func TestNewRefusesBadConfig(t *testing.T) {
27 key, _ := aviso.GenerateKey()
28 good := aviso.Config{DB: openDB(t), PrivateKey: key, Contact: "mailto:x@y", Origin: "https://a"}
29 if _, err := aviso.New(good); err != nil {
30 t.Fatalf("good config refused: %v", err)
31 }
32 c := good
33 c.PrivateKey = ""
34 if _, err := aviso.New(c); !errors.Is(err, aviso.ErrEmptyPrivateKey) {
35 t.Errorf("empty key: %v", err)
36 }
37 c = good
38 c.PrivateKey = "not-a-key"
39 if _, err := aviso.New(c); !errors.Is(err, aviso.ErrInvalidPrivateKey) {
40 t.Errorf("bad key: %v", err)
41 }
42 c = good
43 c.DB = nil
44 if _, err := aviso.New(c); err == nil {
45 t.Error("nil DB accepted")
46 }
47 for _, contact := range []string{"ops@example.test", "mailto:", "mailto:nobody", "https://", "https://bad host", "http://example.test", "https://u:p@example.test"} {
48 c = good
49 c.Contact = contact
50 if _, err := aviso.New(c); err == nil {
51 t.Errorf("Contact %q accepted", contact)
52 }
53 }
54 for _, contact := range []string{"mailto:ops@example.test", "https://example.test/abuse"} {
55 c = good
56 c.Contact = contact
57 if _, err := aviso.New(c); err != nil {
58 t.Errorf("Contact %q refused: %v", contact, err)
59 }
60 }
61 // csrf.SameOrigin compares the Origin header to this string exactly,
62 // so anything beyond scheme://host[:port] would refuse every POST.
63 for _, origin := range []string{"app.example.test", "https://", "https://app.example.test/", "https://app.example.test/path", "https://app.example.test?x=1", "https://u:p@app.example.test", "ftp://app.example.test"} {
64 c = good
65 c.Origin = origin
66 if _, err := aviso.New(c); err == nil {
67 t.Errorf("Origin %q accepted", origin)
68 }
69 }
70 for _, origin := range []string{"https://app.example.test", "http://localhost:8080"} {
71 c = good
72 c.Origin = origin
73 if _, err := aviso.New(c); err != nil {
74 t.Errorf("Origin %q refused: %v", origin, err)
75 }
76 }
77}
78
79// The same private key must give the same public key across a
80// restart: browsers compare it on every load, and a key that drifted
81// would make every one of them re-enrol.
82func TestPublicKeyStringIsStableAcrossRestart(t *testing.T) {
83 key, _ := aviso.GenerateKey()
84 mk := func() *aviso.Service {
85 s, err := aviso.New(aviso.Config{DB: openDB(t), PrivateKey: key, Contact: "mailto:x@y", Origin: "https://a"})
86 if err != nil {
87 t.Fatal(err)
88 }
89 return s
90 }
91 a, b := mk(), mk()
92 if a.PublicKeyString() == "" || a.PublicKeyString() != b.PublicKeyString() {
93 t.Fatalf("public key not stable: %q vs %q", a.PublicKeyString(), b.PublicKeyString())
94 }
95}
96