issue 1859: move the mail page into internal/web, so the local run can serve it
A program cannot import a main package; the page's code moves to modules/mesh-mail-web/internal/web, and cmd/mesh-mail-web is a two-line program calling it, so cmd/mail-page-dev (1859.5) serves the same handlers. Nothing the module does changes.
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 1283/AC1: a request whose Host is not mail.<node>.internal — a public name, an IP, or none — is answered
|
||||
// 404, naming nothing of the mail.
|
||||
func TestServerAnswers404ForAnyHostButItsOwnInternalName(t *testing.T) {
|
||||
s := NewServer(InternalHost("g14"), nil, nil)
|
||||
for _, host := range []string{"example.com", "203.0.113.5", "", "mail.other-node.internal"} {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
r.Host = host
|
||||
s.ServeHTTP(w, r)
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("host %q: status %d, want 404", host, w.Code)
|
||||
}
|
||||
if strings.Contains(strings.ToLower(w.Body.String()), "mail") {
|
||||
t.Fatalf("host %q: the 404 body names mail: %s", host, w.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Its own internal name is answered (not 404).
|
||||
func TestServerAnswersItsOwnInternalName(t *testing.T) {
|
||||
s := NewServer(InternalHost("g14"), nil, nil)
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
r.Host = InternalHost("g14")
|
||||
s.ServeHTTP(w, r)
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status %d, want 200", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// A Host with a port still matches, port and all (the mesh's own listen carries one).
|
||||
func TestServerAnswersItsOwnInternalNameWithAPort(t *testing.T) {
|
||||
s := NewServer(InternalHost("g14"), nil, nil)
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
r.Host = InternalHost("g14") + ":8099"
|
||||
s.ServeHTTP(w, r)
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status %d, want 200", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// 1283/AC2: every answer (200 and 404 alike) carries the content security policy.
|
||||
func TestServerSetsTheContentSecurityPolicyOnEveryAnswer(t *testing.T) {
|
||||
s := NewServer(InternalHost("g14"), nil, nil)
|
||||
cases := []string{"example.com", InternalHost("g14")}
|
||||
for _, host := range cases {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
r.Host = host
|
||||
s.ServeHTTP(w, r)
|
||||
if got := w.Header().Get("Content-Security-Policy"); got != CSP {
|
||||
t.Fatalf("host %q: CSP %q, want %q", host, got, CSP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1283/AC3: open with nothing given answers the root; with account, folder and uid together, that mail's own
|
||||
// address.
|
||||
func TestOpenAnswersTheRootOrOneMailsAddress(t *testing.T) {
|
||||
b := &Bundle{Env: Env{Node: "g14"}}
|
||||
out, err := b.openTool(map[string]any{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := out.(map[string]any)["url"]; got != "https://mail.g14.internal/" {
|
||||
t.Fatalf("root url: %v", got)
|
||||
}
|
||||
|
||||
out, err = b.openTool(map[string]any{"account": "mesh", "folder": "INBOX", "uid": float64(7)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
url := out.(map[string]any)["url"].(string)
|
||||
if !strings.HasPrefix(url, "https://mail.g14.internal/mail?") ||
|
||||
!strings.Contains(url, "account=mesh") || !strings.Contains(url, "folder=INBOX") || !strings.Contains(url, "uid=7") {
|
||||
t.Fatalf("mail url: %s", url)
|
||||
}
|
||||
|
||||
if _, err := b.openTool(map[string]any{"account": "mesh"}); err == nil {
|
||||
t.Fatalf("account alone, with no folder or uid, was not refused")
|
||||
}
|
||||
}
|
||||
|
||||
// 1283/AC4: with the working directory and home read-only, the server still starts and answers a page (it
|
||||
// writes nothing to disk).
|
||||
func TestServerStartsAndAnswersAPageWithACwdAndHomeReadOnly(t *testing.T) {
|
||||
ro := t.TempDir()
|
||||
if err := os.Chmod(ro, 0o500); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = os.Chmod(ro, 0o700) })
|
||||
|
||||
oldWd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldHome := os.Getenv("HOME")
|
||||
t.Cleanup(func() {
|
||||
_ = os.Chdir(oldWd)
|
||||
_ = os.Setenv("HOME", oldHome)
|
||||
})
|
||||
if err := os.Chdir(ro); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = os.Setenv("HOME", filepath.Join(ro, "home-does-not-exist"))
|
||||
|
||||
s := NewServer(InternalHost("g14"), nil, nil)
|
||||
srv := httptest.NewServer(s)
|
||||
defer srv.Close()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, srv.URL+"/", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req.Host = InternalHost("g14")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("status %d, want 200", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user