Skip to content

Commit d1c3514

Browse files
authored
Merge pull request #209 from SkynetLabs/ivo/fix_email_panic
Fix a panic when the email configuration is invalid.
2 parents 8b76bb7 + 308c44f commit d1c3514

File tree

4 files changed

+23
-7
lines changed

4 files changed

+23
-7
lines changed

email/sender.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const (
2323
)
2424

2525
var (
26+
// ErrInvalidEmailConfiguration is returned when the email URI given in the
27+
// environment (ACCOUNTS_EMAIL_URI) is either empty or otherwise invalid.
28+
ErrInvalidEmailConfiguration = errors.New("missing or invalid email configuration field ACCOUNTS_EMAIL_URI")
2629
// From is the address we send emails from. It defaults to the user
2730
// from DefaultConnectionURI but can be overridden by the ACCOUNTS_EMAIL_FROM
2831
// environment variable.
@@ -202,6 +205,9 @@ func (s Sender) sendMultiple(m ...*mail.Message) error {
202205
// values from it.
203206
func config(connURI string) (emailConfig, error) {
204207
match := matchPattern.FindStringSubmatch(connURI)
208+
if len(match) == 0 {
209+
return emailConfig{}, ErrInvalidEmailConfiguration
210+
}
205211
result := make(map[string]string)
206212
for i, name := range matchPattern.SubexpNames() {
207213
if i != 0 && name != "" {
@@ -216,14 +222,14 @@ func config(connURI string) (emailConfig, error) {
216222
// These fields are obligatory, so we return an error if any of them are
217223
// missing.
218224
if !(e1 && e2 && e3 && e4) {
219-
return emailConfig{}, errors.New("missing obligatory email configuration field. One of server, port, user, or password is missing")
225+
return emailConfig{}, ErrInvalidEmailConfiguration
220226
}
221227
user, err1 := url.QueryUnescape(user)
222228
password, err2 := url.QueryUnescape(password)
223229
port, err3 := strconv.Atoi(portStr)
224230
err := errors.Compose(err1, err2, err3)
225231
if err != nil {
226-
return emailConfig{}, errors.AddContext(err, "invalid value for username, password, or port in email connection string")
232+
return emailConfig{}, errors.Compose(err, ErrInvalidEmailConfiguration)
227233
}
228234
skip := result["skip_ssl_verify"]
229235
return emailConfig{

email/sender_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ package email
22

33
import (
44
"testing"
5+
6+
"gitlab.com/NebulousLabs/errors"
57
)
68

79
// TestConfig ensures that config properly parses email connection URIs.
810
func TestConfig(t *testing.T) {
11+
// Valid URI with skip_ssl_verify.
912
s := "smtps://test:test1@mailslurper:1025/?skip_ssl_verify=true"
1013
c, err := config(s)
1114
if err != nil {
@@ -14,7 +17,7 @@ func TestConfig(t *testing.T) {
1417
if c.Server != "mailslurper" || c.Port != 1025 || c.User != "test" || c.Pass != "test1" || !c.InsecureSkipVerify {
1518
t.Fatal("Unexpected result.")
1619
}
17-
20+
// Valid URI without skip_ssl_verify.
1821
s = "smtps://asdf:[email protected]:999"
1922
c, err = config(s)
2023
if err != nil {
@@ -23,6 +26,12 @@ func TestConfig(t *testing.T) {
2326
if c.Server != "mail.siasky.net" || c.Port != 999 || c.User != "asdf" || c.Pass != "fdsa" || c.InsecureSkipVerify {
2427
t.Fatal("Unexpected result.")
2528
}
29+
// Invalid URI (missing port).
30+
s = "smtps://asdf:[email protected]"
31+
c, err = config(s)
32+
if err == nil || !errors.Contains(err, ErrInvalidEmailConfiguration) {
33+
t.Fatalf("Expected error '%s', got '%s'", ErrInvalidEmailConfiguration, err)
34+
}
2635
}
2736

2837
// TestServerLockID make sure that ServerLockID is set in testing mode. If it's

main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ func parseConfiguration(logger *logrus.Logger) (ServiceConfig, error) {
171171
config.EmailURI = os.Getenv(envEmailURI)
172172
{
173173
if config.EmailURI == "" {
174-
return ServiceConfig{}, errors.New(envEmailURI + " is empty")
174+
return ServiceConfig{}, email.ErrInvalidEmailConfiguration
175175
}
176176
// Validate the given URI.
177177
uri, err := url.Parse(config.EmailURI)
178178
if err != nil || uri.Host == "" || uri.User == nil {
179-
return ServiceConfig{}, errors.New("invalid email URI given in " + envEmailURI)
179+
return ServiceConfig{}, email.ErrInvalidEmailConfiguration
180180
}
181181
// Set the FROM address to outgoing emails. This can be overridden by
182182
// the ACCOUNTS_EMAIL_FROM optional environment variable.

main_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99

1010
"github.com/SkynetLabs/skynet-accounts/database"
11+
"github.com/SkynetLabs/skynet-accounts/email"
1112
"github.com/sirupsen/logrus"
1213
"gitlab.com/NebulousLabs/errors"
1314
)
@@ -143,7 +144,7 @@ func TestParseConfiguration(t *testing.T) {
143144
t.Fatal(err)
144145
}
145146
_, err = parseConfiguration(logger)
146-
if err == nil || !strings.Contains(err.Error(), envEmailURI+" is empty") {
147+
if err == nil || !errors.Contains(err, email.ErrInvalidEmailConfiguration) {
147148
t.Fatal("Failed to error out on empty", envEmailURI)
148149
}
149150
// Invalid ACCOUNTS_EMAIL_URI
@@ -152,7 +153,7 @@ func TestParseConfiguration(t *testing.T) {
152153
t.Fatal(err)
153154
}
154155
_, err = parseConfiguration(logger)
155-
if err == nil || !strings.Contains(err.Error(), "invalid email URI") {
156+
if err == nil || !errors.Contains(err, email.ErrInvalidEmailConfiguration) {
156157
t.Log(err)
157158
t.Fatal("Failed to error out on invalid", envEmailURI)
158159
}

0 commit comments

Comments
 (0)