Commit 90622795ab
Verified · cmc
Layout: unified · split
internal/config/config.go +28 −1
| @@ -209,10 +209,34 @@ type Limits struct { | ||
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | type Mail struct { |
| 212 | SMTPHost string `toml:"smtp_host"` // host:port (port defaults to 587) | |
| 212 | SMTPHost string `toml:"smtp_host"` // host:port (port defaults to 587, 465 with tls = "implicit") | |
| 213 | 213 | From string `toml:"from"` |
| 214 | 214 | SMTPUser string `toml:"smtp_user,omitempty"` |
| 215 | 215 | SMTPPass string `toml:"smtp_pass,omitempty"` |
| 216 | // RequireTLS fails delivery when the relay does not offer STARTTLS, | |
| 217 | // instead of sending in clear. Unset, it is on for any relay but | |
| 218 | // localhost or a loopback address (TLSRequired). | |
| 219 | RequireTLS *bool `toml:"require_tls,omitempty"` | |
| 220 | // TLS is "starttls" (the default, also when empty) or "implicit": | |
| 221 | // TLS from the first byte, as relays on port 465 expect. | |
| 222 | TLS string `toml:"tls,omitempty"` | |
| 223 | } | |
| 224 | ||
| 225 | // TLSRequired reports whether mail must not go to the relay in clear. | |
| 226 | func (m Mail) TLSRequired() bool { | |
| 227 | if m.RequireTLS != nil { | |
| 228 | return *m.RequireTLS | |
| 229 | } | |
| 230 | host := m.SMTPHost | |
| 231 | if h, _, err := net.SplitHostPort(host); err == nil { | |
| 232 | host = h | |
| 233 | } | |
| 234 | host = strings.Trim(host, "[]") | |
| 235 | if host == "localhost" { | |
| 236 | return false | |
| 237 | } | |
| 238 | ip := net.ParseIP(host) | |
| 239 | return ip == nil || !ip.IsLoopback() | |
| 216 | 240 | } |
| 217 | 241 | |
| 218 | 242 | // Push is APNs delivery to registered Apple devices. A key belongs to a |
| @@ -406,6 +430,9 @@ func (c Config) Validate() error { | ||
| 406 | 430 | if c.Mail.SMTPHost != "" && c.Mail.From == "" { |
| 407 | 431 | errs = append(errs, errors.New("[mail] from is required when smtp_host is set")) |
| 408 | 432 | } |
| 433 | if t := c.Mail.TLS; t != "" && t != "starttls" && t != "implicit" { | |
| 434 | errs = append(errs, fmt.Errorf("mail.tls must be starttls or implicit, got %q", t)) | |
| 435 | } | |
| 409 | 436 | if c.Registration.Mode != "closed" && c.Mail.SMTPHost == "" { |
| 410 | 437 | errs = append(errs, fmt.Errorf( |
| 411 | 438 | "registration.mode = %q requires [mail] smtp_host: email verification cannot run without SMTP", |
internal/config/config_test.go +26
| @@ -65,6 +65,11 @@ func TestContradictions(t *testing.T) { | ||
| 65 | 65 | minimal + "\n[ssh]\nmode = \"system\"\n[registration]\nmode = \"open\"\n[mail]\nsmtp_host = \"mx.example\"\nfrom = \"gitbay@example\"\n", |
| 66 | 66 | "requires registration.mode = \"closed\"", |
| 67 | 67 | }, |
| 68 | { | |
| 69 | "unknown mail.tls", | |
| 70 | minimal + "\n[mail]\nsmtp_host = \"mx.example\"\nfrom = \"gitbay@example\"\ntls = \"ssl\"\n", | |
| 71 | "mail.tls must be starttls or implicit", | |
| 72 | }, | |
| 68 | 73 | { |
| 69 | 74 | "password auth in view_only", |
| 70 | 75 | minimal + "\n[web]\nmode = \"view_only\"\npassword_auth = true\n", |
| @@ -249,3 +254,24 @@ func TestPushHost(t *testing.T) { | ||
| 249 | 254 | t.Fatalf("GITBAY_APNS_HOST ignored: %q", got) |
| 250 | 255 | } |
| 251 | 256 | } |
| 257 | ||
| 258 | func TestMailTLSRequired(t *testing.T) { | |
| 259 | off, on := false, true | |
| 260 | for _, tc := range []struct { | |
| 261 | m Mail | |
| 262 | want bool | |
| 263 | }{ | |
| 264 | {Mail{SMTPHost: "smtp.example.com:587"}, true}, | |
| 265 | {Mail{SMTPHost: "smtp.example.com"}, true}, | |
| 266 | {Mail{SMTPHost: "localhost:25"}, false}, | |
| 267 | {Mail{SMTPHost: "localhost"}, false}, | |
| 268 | {Mail{SMTPHost: "127.0.0.1:25"}, false}, | |
| 269 | {Mail{SMTPHost: "[::1]:25"}, false}, | |
| 270 | {Mail{SMTPHost: "smtp.example.com:587", RequireTLS: &off}, false}, | |
| 271 | {Mail{SMTPHost: "127.0.0.1:25", RequireTLS: &on}, true}, | |
| 272 | } { | |
| 273 | if got := tc.m.TLSRequired(); got != tc.want { | |
| 274 | t.Errorf("%+v: TLSRequired = %v, want %v", tc.m, got, tc.want) | |
| 275 | } | |
| 276 | } | |
| 277 | } | |