1// Copyright 2019 The Gitea Authors. All rights reserved. 2// Use of this source code is governed by a MIT-style 3// license that can be found in the LICENSE file. 4 5package setting 6 7import ( 8 "net/mail" 9 "time" 10 11 "code.gitea.io/gitea/modules/log" 12 13 shellquote "github.com/kballard/go-shellquote" 14) 15 16// Mailer represents mail service. 17type Mailer struct { 18 // Mailer 19 Name string 20 From string 21 EnvelopeFrom string 22 OverrideEnvelopeFrom bool `ini:"-"` 23 FromName string 24 FromEmail string 25 SendAsPlainText bool 26 MailerType string 27 SubjectPrefix string 28 29 // SMTP sender 30 Host string 31 User, Passwd string 32 DisableHelo bool 33 HeloHostname string 34 SkipVerify bool 35 UseCertificate bool 36 CertFile, KeyFile string 37 IsTLSEnabled bool 38 39 // Sendmail sender 40 SendmailPath string 41 SendmailArgs []string 42 SendmailTimeout time.Duration 43 SendmailConvertCRLF bool 44} 45 46var ( 47 // MailService the global mailer 48 MailService *Mailer 49) 50 51func newMailService() { 52 sec := Cfg.Section("mailer") 53 // Check mailer setting. 54 if !sec.Key("ENABLED").MustBool() { 55 return 56 } 57 58 MailService = &Mailer{ 59 Name: sec.Key("NAME").MustString(AppName), 60 SendAsPlainText: sec.Key("SEND_AS_PLAIN_TEXT").MustBool(false), 61 MailerType: sec.Key("MAILER_TYPE").In("", []string{"smtp", "sendmail", "dummy"}), 62 63 Host: sec.Key("HOST").String(), 64 User: sec.Key("USER").String(), 65 Passwd: sec.Key("PASSWD").String(), 66 DisableHelo: sec.Key("DISABLE_HELO").MustBool(), 67 HeloHostname: sec.Key("HELO_HOSTNAME").String(), 68 SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), 69 UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), 70 CertFile: sec.Key("CERT_FILE").String(), 71 KeyFile: sec.Key("KEY_FILE").String(), 72 IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(), 73 SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""), 74 75 SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"), 76 SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute), 77 SendmailConvertCRLF: sec.Key("SENDMAIL_CONVERT_CRLF").MustBool(true), 78 } 79 MailService.From = sec.Key("FROM").MustString(MailService.User) 80 MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("") 81 82 if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { 83 log.Warn("ENABLE_HTML_ALTERNATIVE is deprecated, use SEND_AS_PLAIN_TEXT") 84 MailService.SendAsPlainText = !sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false) 85 } 86 87 if sec.HasKey("USE_SENDMAIL") { 88 log.Warn("USE_SENDMAIL is deprecated, use MAILER_TYPE=sendmail") 89 if MailService.MailerType == "" && sec.Key("USE_SENDMAIL").MustBool(false) { 90 MailService.MailerType = "sendmail" 91 } 92 } 93 94 parsed, err := mail.ParseAddress(MailService.From) 95 if err != nil { 96 log.Fatal("Invalid mailer.FROM (%s): %v", MailService.From, err) 97 } 98 MailService.FromName = parsed.Name 99 MailService.FromEmail = parsed.Address 100 101 switch MailService.EnvelopeFrom { 102 case "": 103 MailService.OverrideEnvelopeFrom = false 104 case "<>": 105 MailService.EnvelopeFrom = "" 106 MailService.OverrideEnvelopeFrom = true 107 default: 108 parsed, err = mail.ParseAddress(MailService.EnvelopeFrom) 109 if err != nil { 110 log.Fatal("Invalid mailer.ENVELOPE_FROM (%s): %v", MailService.EnvelopeFrom, err) 111 } 112 MailService.OverrideEnvelopeFrom = true 113 MailService.EnvelopeFrom = parsed.Address 114 } 115 116 if MailService.MailerType == "" { 117 MailService.MailerType = "smtp" 118 } 119 120 if MailService.MailerType == "sendmail" { 121 MailService.SendmailArgs, err = shellquote.Split(sec.Key("SENDMAIL_ARGS").String()) 122 if err != nil { 123 log.Error("Failed to parse Sendmail args: %s with error %v", CustomConf, err) 124 } 125 } 126 127 log.Info("Mail Service Enabled") 128} 129 130func newRegisterMailService() { 131 if !Cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").MustBool() { 132 return 133 } else if MailService == nil { 134 log.Warn("Register Mail Service: Mail Service is not enabled") 135 return 136 } 137 Service.RegisterEmailConfirm = true 138 log.Info("Register Mail Service Enabled") 139} 140 141func newNotifyMailService() { 142 if !Cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").MustBool() { 143 return 144 } else if MailService == nil { 145 log.Warn("Notify Mail Service: Mail Service is not enabled") 146 return 147 } 148 Service.EnableNotifyMail = true 149 log.Info("Notify Mail Service Enabled") 150} 151