diff --git a/config/smtp.go b/config/smtp.go
new file mode 100644
index 0000000..e4ca0f8
--- /dev/null
+++ b/config/smtp.go
@@ -0,0 +1,43 @@
+package config
+
+import (
+ "errors"
+ "fmt"
+)
+
+// mandatory parameters for the STMP server connection
+type SMTPConfig struct {
+ User string
+ Password string
+ Url string
+ Port string
+}
+
+func NewSMTPConfig(user, password, url, port string) (SMTPConfig, error) {
+ var config SMTPConfig
+ if user == "" {
+ return config, errors.New("SMTP user can't be empty")
+ }
+ config.User = user
+
+ if password == "" {
+ return config, errors.New("SMTP password can't be empty")
+ }
+ config.Password = password
+
+ if url == "" {
+ return config, errors.New("SMTP server url can't be empty")
+ }
+ config.Url = url
+
+ if port == "" {
+ return config, errors.New("SMTP server port can't be empty")
+ }
+ config.Port = port
+
+ return config, nil
+}
+
+func (c SMTPConfig) GetFullUrl() string {
+ return fmt.Sprintf("%s:%s", c.Url, c.Port)
+}
diff --git a/mail/mail.go b/mail/mail.go
new file mode 100644
index 0000000..768edef
--- /dev/null
+++ b/mail/mail.go
@@ -0,0 +1,49 @@
+package mail
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "strings"
+)
+
+type Email struct {
+ Sender string `json:"sender"`
+ Receivers []string `json:"receivers"`
+ Subject string `json:"subject"`
+ Content string `json:"content"`
+}
+
+func NewEmail(sender string, receivers []string, subject, content string) Email {
+ return Email{
+ Sender: sender,
+ Receivers: receivers,
+ Subject: subject,
+ Content: content,
+ }
+}
+
+func FromJSON(path string) error {
+ content, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+
+ var mail Email
+ if err := json.Unmarshal(content, &mail); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (e Email) Generate() []byte {
+ mail := fmt.Sprintf(
+ "To: %s\nFrom: %s\nContent-Type: text/html\nSubject: %s\n\n%s",
+ strings.Join(e.Receivers, ","),
+ e.Sender,
+ e.Sender,
+ e.Content,
+ )
+ return []byte(mail)
+}
diff --git a/main.go b/main.go
index a5f602e..55e3c4e 100644
--- a/main.go
+++ b/main.go
@@ -3,79 +3,22 @@ package main
import (
"errors"
"fmt"
- "net/smtp"
"os"
- "strings"
+
+ cfg "mailsrv/config"
+ "mailsrv/mail"
+ srv "mailsrv/services"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
- "gopkg.in/ini.v1"
+ ini "gopkg.in/ini.v1"
)
-// mandatory parameters to send an email
-type SMTPConfig struct {
- User string
- Password string
- Url string
- Port string
-}
-
-func NewSMTPConfig(user, password, url, port string) (SMTPConfig, error) {
- var config SMTPConfig
- if user == "" {
- return config, errors.New("SMTP user can't be empty")
- }
- config.User = user
-
- if password == "" {
- return config, errors.New("SMTP password can't be empty")
- }
- config.Password = password
-
- if url == "" {
- return config, errors.New("SMTP server url can't be empty")
- }
- config.Url = url
-
- if port == "" {
- return config, errors.New("SMTP server port can't be empty")
- }
- config.Port = port
-
- return config, nil
-}
-
-func (c SMTPConfig) getFullUrl() string {
- return fmt.Sprintf("%s:%s", c.Url, c.Port)
-}
-
-type Email struct {
- Sender string
- Receivers []string
- Subject string
- Content string
-}
-
-func NewEmail(sender string, receivers []string, subject, content string) Email {
- return Email{
- Sender: sender,
- Receivers: receivers,
- Subject: subject,
- Content: content,
- }
-}
-
-func (e Email) Generate() []byte {
- mail := fmt.Sprintf(
- "To: %s\nFrom: %s\nContent-Type: text/html\nSubject: %s\n\n%s",
- strings.Join(e.Receivers, ","),
- e.Sender,
- e.Sender,
- e.Content,
- )
- return []byte(mail)
-}
+const (
+ DefaultOutboxPath string = "outbox"
+)
+// simply collects binary arguments
func GetConfigPath() (string, error) {
switch len(os.Args) {
case 1:
@@ -87,21 +30,26 @@ func GetConfigPath() (string, error) {
}
}
-func LoadConfig(configPath string) (SMTPConfig, error) {
- var config SMTPConfig
-
+func LoadIni() (*ini.File, error) {
configPath, err := GetConfigPath()
if err != nil {
- return config, fmt.Errorf("unable to get the .ini config path err=%v", err)
+ return nil, fmt.Errorf("unable to get the .ini config path err=%v", err)
}
- cfg, err := ini.Load(configPath)
+ ini, err := ini.Load(configPath)
if err != nil {
- return config, fmt.Errorf("unable to load the .ini config path err=%v", err)
+ return nil, fmt.Errorf("unable to load the .ini config path err=%v", err)
}
- section := cfg.Section("server")
- config, err = NewSMTPConfig(
+ return ini, nil
+}
+
+// collects mandatory SMTP parameters to send an e-mail from the `.ini` file
+func LoadSMTPConfig(iniFile *ini.File) (cfg.SMTPConfig, error) {
+ var config cfg.SMTPConfig
+
+ section := iniFile.Section("server")
+ config, err := cfg.NewSMTPConfig(
section.Key("username").String(),
section.Key("password").String(),
section.Key("url").String(),
@@ -114,37 +62,48 @@ func LoadConfig(configPath string) (SMTPConfig, error) {
return config, nil
}
+// tries to get the outbox path from the `.ini` file and creates the directory
+// if the path does not exist, create a default one: `outbox` next to the binary
+func GetOutboxPath(iniFile *ini.File) (string, error) {
+ outboxPath := iniFile.Section("service").Key("outbox_path").String()
+ if outboxPath == "" {
+ outboxPath = DefaultOutboxPath
+ }
+
+ if err := os.MkdirAll(outboxPath, 0750); err != nil && !os.IsExist(err) {
+ return "", err
+ }
+
+ return outboxPath, nil
+}
+
func main() {
var logger log.Logger
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller, "service", "mailsrv")
- configPath, err := GetConfigPath()
+ iniFile, err := LoadIni()
if err != nil {
- level.Error(logger).Log("msg", "unable to get the .ini config path", "err", err)
- os.Exit(1)
+ level.Error(logger).Log("msg", "unable to load the .ini configuration file", "err", err)
+ return
}
- config, err := LoadConfig(configPath)
+ config, err := LoadSMTPConfig(iniFile)
if err != nil {
level.Error(logger).Log("msg", "unable to load the SMTP configuration", "err", err)
- os.Exit(1)
+ return
+ }
+
+ outboxPath, err := GetOutboxPath(iniFile)
+ if err != nil {
+ level.Error(logger).Log("msg", "unable to retrieve outputbox path", "err", err)
+ return
}
logger.Log("action", "send email test")
-
content := fmt.Sprintf("Hi!
This is an e-mail test, please do not reply.
Thegux Administrator
%s", `