From 09d3149932c7581d15fdc1d90545fbf1d1675dc9 Mon Sep 17 00:00:00 2001 From: Thomas Maurice Date: Tue, 13 Feb 2024 18:30:54 +0100 Subject: [PATCH] feat(mail): adds a test subcomand --- pkg/cmd/root.go | 12 ++++++- pkg/cmd/test.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ pkg/config/config.go | 5 +++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 pkg/cmd/test.go diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index ce86c25..bd5029b 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -1,6 +1,9 @@ package cmd import ( + "os" + "path" + "git.maurice.fr/thomas/mailout/pkg/config" "github.com/spf13/cobra" ) @@ -32,6 +35,13 @@ func InitRootCmd() { RootCmd.AddCommand(InitDBCmd) RootCmd.AddCommand(UserCmd) RootCmd.AddCommand(DKIMKeyCmd) + RootCmd.AddCommand(TestCmd) - RootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "mailout.yml", "Configuration file") + homeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + defaultConfigFile := path.Join(homeDir, ".mailout.yml") + + RootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", defaultConfigFile, "Configuration file") } diff --git a/pkg/cmd/test.go b/pkg/cmd/test.go new file mode 100644 index 0000000..6d99200 --- /dev/null +++ b/pkg/cmd/test.go @@ -0,0 +1,85 @@ +package cmd + +import ( + "crypto/tls" + "fmt" + "log" + "net/smtp" + "strings" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var TestCmd = &cobra.Command{ + Use: "test", + Short: "sends an email through the configured server", + Long: ``, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if cfg.Test == nil { + logrus.Fatal("you need to specify a `test` config block") + } + + tlsConfig := &tls.Config{ + InsecureSkipVerify: true, + ServerName: strings.Split(cfg.Test.Address, ":")[0], + } + + conn, err := tls.Dial("tcp", cfg.Test.Address, tlsConfig) + if err != nil { + log.Panic(err) + } + + c, err := smtp.NewClient(conn, strings.Split(cfg.Test.Address, ":")[0]) + if err != nil { + log.Panic(err) + } + + headers := make(map[string]string) + headers["From"] = cfg.Test.Username + headers["To"] = args[0] + headers["Subject"] = "This is a test email from the command line" + + message := "" + for k, v := range headers { + message += fmt.Sprintf("%s: %s\r\n", k, v) + } + message += "\r\n" + + message += "This is a test email message sent through the command line utility." + + auth := smtp.PlainAuth("", cfg.Test.Username, cfg.Test.Password, strings.Split(cfg.Test.Address, ":")[0]) + + if err = c.Auth(auth); err != nil { + logrus.WithError(err).Fatal("could not authenticate to server") + } + + if err = c.Mail(cfg.Test.Username); err != nil { + logrus.WithError(err).Fatal("could not create email") + } + + if err = c.Rcpt(args[0]); err != nil { + logrus.WithError(err).Fatal("could not set email destination") + } + + w, err := c.Data() + if err != nil { + logrus.WithError(err).Fatal("could not set email data") + } + + _, err = w.Write([]byte(message)) + if err != nil { + logrus.WithError(err).Fatal("could not set email data") + } + + err = w.Close() + if err != nil { + logrus.WithError(err).Fatal("close email") + } + + c.Quit() + + logrus.Info("sent test email") + }, +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 15811e8..a282700 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -20,6 +20,11 @@ type Config struct { Providers struct { OVH *providerConfigs.OVHConfig `yaml:"ovh"` } `yaml:"providers"` + Test *struct { + Address string `yaml:"address"` + Username string `yaml:"username"` + Password string `yaml:"password"` + } `yaml:"test"` } func LoadConfig(path string) (*Config, error) {