~bigbes/sr-ht-dolt

ref: 5c5479c4040cb4ba231cfe09ddae8634879ad5d9 sr-ht-dolt/authn/cookie_test.go -rw-r--r-- 3.6 KiB
5c5479c4 — Eugene Blikh feat(web/beads): ready markers, milestone rollup, transitive dependency tree 29 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package authn

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"sourcecraft.dev/bigbes/sr-ht-core/auth"
)

// captureHandler records the caller present on the request context when reached.
func captureHandler(dst **auth.AuthContext, reached *bool) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		*reached = true
		*dst = CallerFromContext(r.Context())
		w.WriteHeader(http.StatusOK)
	})
}

func runCookieMiddleware(t *testing.T, cookie *http.Cookie) (*auth.AuthContext, int) {
	t.Helper()
	var got *auth.AuthContext
	var reached bool
	h := OptionalCookieMiddleware()(captureHandler(&got, &reached))

	req := httptest.NewRequest(http.MethodGet, "/", nil)
	if cookie != nil {
		req.AddCookie(cookie)
	}
	rec := httptest.NewRecorder()
	h.ServeHTTP(rec, req)

	if !reached {
		t.Fatal("middleware must always call next (never rejects)")
	}
	return got, rec.Code
}

func TestOptionalCookieMiddleware_NoCookie(t *testing.T) {
	withStubBackend(t, &stubBackend{users: map[string]auth.AuthContext{}})
	got, code := runCookieMiddleware(t, nil)
	if got != nil {
		t.Fatalf("expected anonymous, got %+v", got)
	}
	if code != http.StatusOK {
		t.Fatalf("expected 200, got %d", code)
	}
}

func TestOptionalCookieMiddleware_ValidCookie(t *testing.T) {
	withStubBackend(t, &stubBackend{users: map[string]auth.AuthContext{
		"bigbes": sampleUser(1, "bigbes", auth.USER_TYPE_USER),
	}})

	got, code := runCookieMiddleware(t, &http.Cookie{
		Name:  CookieName,
		Value: forgeCookie(t, "bigbes"),
	})
	if code != http.StatusOK {
		t.Fatalf("expected 200, got %d", code)
	}
	if got == nil {
		t.Fatal("expected an authenticated caller")
	}
	if got.Username != "bigbes" || got.UserID != 1 {
		t.Fatalf("wrong caller resolved: %+v", got)
	}
	if got.AuthMethod != auth.AUTH_COOKIE {
		t.Fatalf("AuthMethod = %q, want %q", got.AuthMethod, auth.AUTH_COOKIE)
	}
}

func TestOptionalCookieMiddleware_SuspendedStillResolves(t *testing.T) {
	withStubBackend(t, &stubBackend{users: map[string]auth.AuthContext{
		"susp": sampleUser(2, "susp", auth.USER_TYPE_SUSPENDED),
	}})
	got, _ := runCookieMiddleware(t, &http.Cookie{
		Name:  CookieName,
		Value: forgeCookie(t, "susp"),
	})
	if got == nil {
		t.Fatal("suspended users must still resolve (reads are allowed)")
	}
	if !AsCoreCaller(got).Suspended {
		t.Fatal("resolved caller must be flagged suspended")
	}
}

func TestOptionalCookieMiddleware_GarbageCookie(t *testing.T) {
	withStubBackend(t, &stubBackend{users: map[string]auth.AuthContext{}})
	got, code := runCookieMiddleware(t, &http.Cookie{
		Name:  CookieName,
		Value: "not-a-valid-fernet-token",
	})
	if got != nil {
		t.Fatalf("garbage cookie must degrade to anonymous, got %+v", got)
	}
	if code != http.StatusOK {
		t.Fatalf("must not reject: expected 200, got %d", code)
	}
}

func TestOptionalCookieMiddleware_UnknownUser(t *testing.T) {
	withStubBackend(t, &stubBackend{users: map[string]auth.AuthContext{}})
	got, code := runCookieMiddleware(t, &http.Cookie{
		Name:  CookieName,
		Value: forgeCookie(t, "ghost"),
	})
	if got != nil {
		t.Fatalf("unknown user must degrade to anonymous, got %+v", got)
	}
	if code != http.StatusOK {
		t.Fatalf("must not reject: expected 200, got %d", code)
	}
}

func TestOptionalCookieMiddleware_BackendDownIsAnonymous(t *testing.T) {
	withStubBackend(t, &stubBackend{lookupErr: errBackendDown})
	got, code := runCookieMiddleware(t, &http.Cookie{
		Name:  CookieName,
		Value: forgeCookie(t, "bigbes"),
	})
	if got != nil {
		t.Fatalf("backend failure must degrade to anonymous, got %+v", got)
	}
	if code != http.StatusOK {
		t.Fatalf("must not 500: expected 200, got %d", code)
	}
}