Files
mailgoserver/internal/webui/dav_enablement_test.go
T

102 lines
3.4 KiB
Go

package webui
import (
"net/http"
"net/http/httptest"
"testing"
"mailgoserver/internal/db"
)
// createTestMailboxWithAppPasswordDAVOff is createTestMailboxWithAppPassword without the
// domain/mailbox CalDAV+CardDAV opt-ins — for tests that need to exercise the
// enablement gate itself rather than have it pre-satisfied.
func createTestMailboxWithAppPasswordDAVOff(t *testing.T, app *App, email string, domainID int64) int64 {
t.Helper()
mailboxID := createTestMailboxWithPassword(t, app, email, domainID, "portal-password-unused-1!")
hash, err := db.HashPassword(carddavTestAppPassword)
if err != nil {
t.Fatal(err)
}
if _, err := app.DB.CreateAppPassword(mailboxID, "dav test", hash, nil); err != nil {
t.Fatal(err)
}
return mailboxID
}
// TestDAVDisabledByDefault confirms both protocols reject an otherwise-valid
// app-password login with 403 (not 401 — credentials are fine, the feature is just
// off) when neither the domain nor the mailbox has opted in, matching the requested
// default of "disabled for everyone."
func TestDAVDisabledByDefault(t *testing.T) {
app := newTestApp(t)
domains, _ := app.DB.ListDomains()
createTestMailboxWithAppPasswordDAVOff(t, app, "davoff@example.com", domains[0].ID)
srv := httptest.NewServer(app.Mux())
defer srv.Close()
for _, path := range []string{
"/caldav/davoff@example.com/calendars/default/",
"/carddav/davoff@example.com/addressbooks/default/",
} {
req, _ := http.NewRequest("PROPFIND", srv.URL+path, nil)
req.Header.Set("Depth", "0")
req.SetBasicAuth("davoff@example.com", carddavTestAppPassword)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusForbidden {
t.Fatalf("%s: status=%d, want 403 (disabled by default)", path, resp.StatusCode)
}
}
}
// TestDAVRequiresBothDomainAndMailboxOptIn confirms neither the domain-wide admin
// switch nor the mailbox's own opt-in is sufficient alone — both must be on.
func TestDAVRequiresBothDomainAndMailboxOptIn(t *testing.T) {
app := newTestApp(t)
domains, _ := app.DB.ListDomains()
domainID := domains[0].ID
createTestMailboxWithAppPasswordDAVOff(t, app, "domainonly@example.com", domainID)
bothID := createTestMailboxWithAppPasswordDAVOff(t, app, "both@example.com", domainID)
if err := app.DB.SetDomainCalDAVEnabled(domainID, true); err != nil {
t.Fatal(err)
}
if err := app.DB.SetMailboxDAVEnabled(bothID, true, false); err != nil {
t.Fatal(err)
}
srv := httptest.NewServer(app.Mux())
defer srv.Close()
propfind := func(email string) int {
req, _ := http.NewRequest("PROPFIND", srv.URL+"/caldav/"+email+"/calendars/default/", nil)
req.Header.Set("Depth", "0")
req.SetBasicAuth(email, carddavTestAppPassword)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
return resp.StatusCode
}
if got := propfind("domainonly@example.com"); got != http.StatusForbidden {
t.Fatalf("domain-only (mailbox not opted in): status=%d, want 403", got)
}
if got := propfind("both@example.com"); got != http.StatusMultiStatus {
t.Fatalf("domain+mailbox both on: status=%d, want 207", got)
}
// Now flip it around: mailbox opted in, but the domain-wide switch off.
if err := app.DB.SetDomainCalDAVEnabled(domainID, false); err != nil {
t.Fatal(err)
}
if got := propfind("both@example.com"); got != http.StatusForbidden {
t.Fatalf("mailbox on but domain off: status=%d, want 403", got)
}
}