Files
selfpost/internal/web/auth/seen_test.go
T
mixandClaude Opus 5.5 a8fd96c752 health-setup-checks: the certificate's name, Postfix's greeting, the proxy
Decided by the owner on 2026-10-13 (in place of preflight), taken up on
2026-10-16; mockups b2dcefc, cc33890, 0feaa55 (his: the greeting on a row
of its own, the name check a tag beside Names).

- The certificate: health.Certificate keeps its names (DNS names, or the
  CN without any) and ForHost holds it to SELFPOST_HOSTNAME as a TLS
  client does - VerifyHostname over the DNS names, the CN only without
  any, as OpenSSL's X509_check_host and so a sending Postfix still take it
  (src/tls/tls_client.c:439, 513). A certificate for another name fails;
  the tag beside Names says matches / not for the hostname.
- The greeting: postconf -x -h smtpd_banner, read once at the panel's
  start like the served certificate's path (main.cf is not rewritten
  after), is what smtpd writes after "220 " (src/smtpd/smtpd.c:5979). A
  first word other than the hostname warns, with what to set. A fact may
  now take the whole row (Fact.Wide, sp-wide) and carry a tag beside its
  label (Fact.LabelTag); both on the kit page.
- The proxy: auth.Module.Seen says the address the panel counts sign-ins
  against, the peer, and whether X-Forwarded-For was read or left unread
  for an untrusted peer; the Configuration card shows "Your address" and,
  in the second case, warns that every visitor shares one sign-in limit
  and names the /32 (or /128) to put in TRUSTED_PROXY_CIDR.

Tests: TestCertificateForHost (CN-only, DNS names, a wildcard, the CN
ignored beside DNS names), TestSeenAddress, TestHealthSaysWhereItSeesTheViewer,
TestHealthGreetingAndCertificateName; e2e reads the stand's right state on
Health (matches, "220 mail.e2e.test ESMTP", a direct client). go vet + go
test (26 packages) and make e2e on the test server for this tree.

Docs: help (word for word with the mockup), guide § Overview and Health,
CHANGELOG [Unreleased] § Added, roadmap row done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 23:51:42 +03:00

34 lines
1.1 KiB
Go

package auth
import (
"net"
"net/http/httptest"
"testing"
)
// Health says where the panel sees a request from: through a trusted proxy,
// the client's own address from X-Forwarded-For; through a proxy it does not
// trust, the proxy's, with the header left unread - every visitor then
// shares one sign-in limit; and with no header, the connection's own.
func TestSeenAddress(t *testing.T) {
_, proxyNet, _ := net.ParseCIDR("172.18.0.0/16")
m := &Module{trustedProxies: []*net.IPNet{proxyNet}}
untrusting := &Module{}
r := httptest.NewRequest("GET", "/server/health", nil)
r.RemoteAddr = "172.18.0.1:40112"
r.Header.Set("X-Forwarded-For", "198.51.100.7")
if s := m.Seen(r); s != (SeenAddress{Client: "198.51.100.7", Peer: "172.18.0.1", FromHeader: true}) {
t.Errorf("through a trusted proxy: %+v", s)
}
if s := untrusting.Seen(r); s != (SeenAddress{Client: "172.18.0.1", Peer: "172.18.0.1", HeaderIgnored: true}) {
t.Errorf("through a proxy not trusted: %+v", s)
}
r.Header.Del("X-Forwarded-For")
r.RemoteAddr = "203.0.113.9:5000"
if s := m.Seen(r); s != (SeenAddress{Client: "203.0.113.9", Peer: "203.0.113.9"}) {
t.Errorf("direct: %+v", s)
}
}