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
package guardian
import (
"encoding/base64"
"encoding/json"
"io"
"net/http"
"strings"
"testing"
"time"
"github.com/armanlife/firefox-vpn-client/core/internal/controlplane"
)
func TestFetchProxyPassSendsNoCacheAndAnchorsExpiry(t *testing.T) {
previous := controlplane.Transport()
t.Cleanup(func() { controlplane.SetTransport(previous) })
// Claims eight hours in the past, as if Guardian's clock were skewed.
skewed := time.Now().Add(-8 * time.Hour)
token := testJWT(t, map[string]any{"sub": "s", "aud": "https://vpn.mozilla.org", "iss": "https://vpn.mozilla.org", "iat": skewed.Unix(), "nbf": skewed.Unix(), "exp": skewed.Add(10 * time.Minute).Unix()})
controlplane.SetTransport(roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.Header.Get("Cache-Control") != "max-age=0" || r.Header.Get("Pragma") != "" || r.Header.Get("Authorization") != "Bearer access" {
t.Errorf("unexpected Guardian request headers: %v", r.Header)
}
header := make(http.Header)
header.Set("X-Quota-Unlimited", "true")
return &http.Response{StatusCode: http.StatusOK, Header: header, Body: io.NopCloser(strings.NewReader(`{"token":"` + token + `"}`)), Request: r}, nil
}))
before := time.Now()
pass, err := FetchProxyPass(t.Context(), "https://guardian.invalid", "access")
if err != nil {
t.Fatal(err)
}
if pass.Usage == nil || !pass.Usage.Unlimited {
t.Fatalf("expected unlimited usage, got %#v", pass.Usage)
}
if remaining := time.Until(pass.ExpiresAt()); remaining < 9*time.Minute || pass.ExpiresAt().After(before.Add(10*time.Minute+2*time.Second)) {
t.Fatalf("expected anchored ten-minute lifetime, got expiry %s", pass.ExpiresAt())
}
}
type roundTripFunc func(*http.Request) (*http.Response, error)
func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) }
func testJWT(t *testing.T, claims map[string]any) string {
t.Helper()
payload, err := json.Marshal(claims)
if err != nil {
t.Fatal(err)
}
return "e30." + base64.RawURLEncoding.EncodeToString(payload) + ".sig"
}