package service import ( "context" "crypto/tls" "fmt" htpl "html/template" "io/ioutil" "strings" intAuth "github.com/cortezaproject/corteza/server/pkg/auth" "github.com/cortezaproject/corteza/server/pkg/mail" "github.com/cortezaproject/corteza/server/pkg/options" "github.com/cortezaproject/corteza/server/system/types" gomail "gopkg.in/mail.v2" ) type ( smtpConfigurationChecker struct { settings *types.AppSettings ts TemplateService opt options.AuthOpt accessControl smtpCheckAccessController } smtpCheckAccessController interface { CanManageSettings(context.Context) bool } ) func SmtpConfigurationChecker(s *types.AppSettings, ts TemplateService, ac accessController, opt options.AuthOpt) *smtpConfigurationChecker { return &smtpConfigurationChecker{ settings: s, ts: ts, opt: opt, accessControl: ac, } } // Check SMTP server configurations and send a test email // to recipients if they're provided func (svc smtpConfigurationChecker) Check(ctx context.Context, smtpConfigs *types.SmtpConfiguration) (checkResults *types.SmtpCheckResult, err error) { if !svc.accessControl.CanManageSettings(ctx) { return nil, fmt.Errorf("not allowed to check SMTP configurations") } var ( tlsConfig = &tls.Config{} ) checkResults = &types.SmtpCheckResult{} if smtpConfigs.Port == 0 { smtpConfigs.Port = 25 } //check for validity of the host if !mail.IsValidHost(smtpConfigs.Host) { checkResults.Host = fmt.Sprintf("%s name is Invalid", smtpConfigs.Host) } // Applying TLS tlsConfig = &tls.Config{ServerName: smtpConfigs.Host} if smtpConfigs.TLSInsecure { tlsConfig.InsecureSkipVerify = true } if smtpConfigs.TLSServerName != "" { tlsConfig.ServerName = smtpConfigs.TLSServerName } checkResults.Server = mail.ConfigCheck(smtpConfigs.Host, smtpConfigs.Port, smtpConfigs.Username, smtpConfigs.Password, tlsConfig) //send the email there are recipients if checkResults.Server == "" { if len(smtpConfigs.Recipients) != 0 { checkResults.Send, err = svc.smtpSend(ctx, smtpConfigs.Recipients) } } return checkResults, err } func (svc smtpConfigurationChecker) smtpSend(ctx context.Context, recipients []string) (expected string, err error) { var ( ntf = mail.New() toHeader string // context with service user // we need this for retrieving & rendering email templates suCtx = intAuth.SetIdentityToContext(ctx, intAuth.ServiceUser()) ) if err = svc.procEmailRecipients(ntf, "To", recipients); err != nil { return "", err } toHeader = strings.Join(recipients, ",") ntf.SetAddressHeader("To", toHeader, "") st, ct, err := svc.findEmailTemplates(suCtx) // if we cannot find an email template if err != nil { ntf.SetHeader("Subject", "SMTP Configuration check") ntf.SetBody("text/html", "