0.2.65 - End Credits wiring / Gateway: 0.1.45 - Credits
This commit is contained in:
@@ -123,13 +123,15 @@ func TestHealthAndAdminStayReachableDuringMaintenance(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// installerSessionExpiring mints a session with a chosen life left, which is the only way
|
||||
// to reach the renewal window without waiting six hours in a test.
|
||||
func installerSessionExpiring(t *testing.T, s *Server, remaining time.Duration) *http.Cookie {
|
||||
// browserSessionExpiring mints a session of one purpose with a chosen life left, which is
|
||||
// the only way to reach the renewal window without waiting weeks in a test.
|
||||
func browserSessionExpiring(
|
||||
t *testing.T, s *Server, purpose string, remaining time.Duration,
|
||||
) *http.Cookie {
|
||||
t.Helper()
|
||||
payload := make([]byte, 8+16)
|
||||
binary.BigEndian.PutUint64(payload[:8], uint64(time.Now().Add(remaining).Unix()))
|
||||
signature := s.signInstallerValue("session", payload)
|
||||
signature := s.signInstallerValue(purpose, payload)
|
||||
return &http.Cookie{
|
||||
Name: installerCookieName,
|
||||
Value: base64.RawURLEncoding.EncodeToString(payload) + "." +
|
||||
@@ -137,10 +139,15 @@ func installerSessionExpiring(t *testing.T, s *Server, remaining time.Duration)
|
||||
}
|
||||
}
|
||||
|
||||
func adminSessionExpiring(t *testing.T, s *Server, remaining time.Duration) *http.Cookie {
|
||||
t.Helper()
|
||||
return browserSessionExpiring(t, s, adminSessionPurpose, remaining)
|
||||
}
|
||||
|
||||
func adminRequest(s *Server, remaining time.Duration, t *testing.T) *http.Request {
|
||||
req := httptest.NewRequest(http.MethodGet, "/admin/api/status", nil)
|
||||
req.AddCookie(&http.Cookie{Name: adminCookieName, Value: s.cfg.AdminToken})
|
||||
req.AddCookie(installerSessionExpiring(t, s, remaining))
|
||||
req.AddCookie(adminSessionExpiring(t, s, remaining))
|
||||
return req
|
||||
}
|
||||
|
||||
@@ -182,7 +189,7 @@ func TestAdminSessionIsExtendedWhileTheOperatorIsWorking(t *testing.T) {
|
||||
}
|
||||
follow := httptest.NewRequest(http.MethodGet, "/admin/api/status", nil)
|
||||
follow.AddCookie(cookie)
|
||||
expires, ok := server.installerSessionExpiry(follow)
|
||||
expires, ok := server.browserSessionExpiry(follow, adminSessionPurpose)
|
||||
if !ok || time.Until(expires) < adminSessionTTL-time.Minute {
|
||||
t.Fatalf("renewed session should carry a full TTL, has %v (ok=%v)",
|
||||
time.Until(expires), ok)
|
||||
@@ -242,7 +249,7 @@ func TestAdminMutationExtendsTheSessionWithoutTheActivityHeader(t *testing.T) {
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/admin/api/sync", nil)
|
||||
req.AddCookie(&http.Cookie{Name: adminCookieName, Value: server.cfg.AdminToken})
|
||||
req.AddCookie(installerSessionExpiring(t, server, 2*time.Minute))
|
||||
req.AddCookie(adminSessionExpiring(t, server, 2*time.Minute))
|
||||
rec := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
@@ -550,7 +557,7 @@ func TestAdminAuthAcceptsPersistentCookie(t *testing.T) {
|
||||
})
|
||||
req := httptest.NewRequest(http.MethodGet, "/admin/api/status", nil)
|
||||
req.AddCookie(&http.Cookie{Name: adminCookieName, Value: "secret"})
|
||||
addInstallerSession(t, server, req)
|
||||
req.AddCookie(adminSessionExpiring(t, server, adminSessionTTL))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
@@ -560,6 +567,43 @@ func TestAdminAuthAcceptsPersistentCookie(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The installer is public: any member of the household signs in there to put Memby on a
|
||||
// new television. One cookie serves both gates, so the console has to be able to tell the
|
||||
// two sign-ins apart — otherwise a viewer's installer session reached /admin/, which then
|
||||
// handed them the admin token cookie.
|
||||
func TestInstallerSessionCannotReachTheAdminConsole(t *testing.T) {
|
||||
server := testServer(config.Config{
|
||||
AdminToken: "secret", ReleasePublishToken: "release-secret",
|
||||
})
|
||||
handler := server.adminAuth(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
req := httptest.NewRequest(http.MethodGet, "/admin/api/status", nil)
|
||||
req.AddCookie(&http.Cookie{Name: adminCookieName, Value: "secret"})
|
||||
addInstallerSession(t, server, req)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("an installer session reached the admin API: %d", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// The other direction is deliberately allowed: somebody who may administer the server may
|
||||
// certainly download the app.
|
||||
func TestAdminSessionIsAcceptedByTheInstaller(t *testing.T) {
|
||||
server := testServer(config.Config{
|
||||
AdminToken: "secret", ReleasePublishToken: "release-secret",
|
||||
})
|
||||
req := httptest.NewRequest(http.MethodGet, "/install", nil)
|
||||
req.AddCookie(adminSessionExpiring(t, server, adminSessionTTL))
|
||||
|
||||
if !server.validInstallerSession(req) {
|
||||
t.Fatal("an administrator's session should satisfy the installer gate")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminPageRequiresDiscreetEmbyGate(t *testing.T) {
|
||||
server := testServer(config.Config{
|
||||
AdminToken: "secret", ReleasePublishToken: "release-secret",
|
||||
|
||||
Reference in New Issue
Block a user