~bigbes/sr-ht-compare

ref: 65ffb96c316be74225e3405ca5f9ef2ab68825f9 sr-ht-compare/authz/identity_test.go -rw-r--r-- 3.1 KiB
65ffb96c — bigbes log: slog through auxilia's scribe, not logrus 9 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package authz

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"

	"sourcecraft.dev/bigbes/sr-ht-core/crypto"
	"sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest"
)

// TestMain installs ecore's fixed test keyset into core-go's process-global
// crypto, so Encrypt/Decrypt work offline. The keys are constants and the call
// is idempotent, which is what lets this package and web/ both initialise
// without the second rotating what the first sealed with.
func TestMain(m *testing.M) {
	ecoretest.InitCrypto()
	os.Exit(m.Run())
}

// sealCookie builds a valid unified-login cookie value carrying the given name.
func sealCookie(t *testing.T, name string) string {
	t.Helper()
	payload, err := json.Marshal(map[string]string{"name": name})
	if err != nil {
		t.Fatalf("marshal claims: %v", err)
	}
	return string(crypto.Encrypt(payload))
}

func TestUsernameFromRequest_RoundTrip(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	r.AddCookie(&http.Cookie{Name: CookieName, Value: sealCookie(t, "bigbes")})
	if got := UsernameFromRequest(r); got != "bigbes" {
		t.Fatalf("username = %q, want %q", got, "bigbes")
	}
}

func TestUsernameFromRequest_StripsTilde(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	r.AddCookie(&http.Cookie{Name: CookieName, Value: sealCookie(t, "~bigbes")})
	if got := UsernameFromRequest(r); got != "bigbes" {
		t.Fatalf("username = %q, want %q", got, "bigbes")
	}
}

func TestUsernameFromRequest_GarbageCookie(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	r.AddCookie(&http.Cookie{Name: CookieName, Value: "not-a-valid-fernet-token"})
	if got := UsernameFromRequest(r); got != "" {
		t.Fatalf("username = %q, want empty", got)
	}
}

func TestUsernameFromRequest_MissingCookie(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	if got := UsernameFromRequest(r); got != "" {
		t.Fatalf("username = %q, want empty", got)
	}
}

func TestUsernameFromRequest_NonJSONPayload(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	// A well-formed Fernet token whose plaintext is not JSON.
	r.AddCookie(&http.Cookie{Name: CookieName, Value: string(crypto.Encrypt([]byte("plain text")))})
	if got := UsernameFromRequest(r); got != "" {
		t.Fatalf("username = %q, want empty", got)
	}
}

func TestMiddlewareAndForContext(t *testing.T) {
	var seen string
	h := Middleware()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		seen = ForContext(r.Context())
	}))

	r := httptest.NewRequest(http.MethodGet, "/", nil)
	r.AddCookie(&http.Cookie{Name: CookieName, Value: sealCookie(t, "bigbes")})
	h.ServeHTTP(httptest.NewRecorder(), r)
	if seen != "bigbes" {
		t.Fatalf("ForContext = %q, want %q", seen, "bigbes")
	}

	// Anonymous request: middleware still runs, ForContext yields "".
	seen = "sentinel"
	h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil))
	if seen != "" {
		t.Fatalf("anonymous ForContext = %q, want empty", seen)
	}
}

func TestForContext_NoValue(t *testing.T) {
	if got := ForContext(httptest.NewRequest(http.MethodGet, "/", nil).Context()); got != "" {
		t.Fatalf("ForContext on bare context = %q, want empty", got)
	}
}