diff --git a/go.mod b/go.mod index d1ff9f5..b941546 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,18 @@ module github.com/blueimp/aws-smtp-relay -go 1.14 +go 1.19 require ( - github.com/aws/aws-sdk-go v1.38.61 - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-sql-driver/mysql v1.5.0 // indirect - github.com/kr/pretty v0.2.0 // indirect - github.com/mhale/smtpd v0.0.0-20210322105601-438c8edb069c - github.com/stretchr/testify v1.5.1 // indirect - golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + github.com/aws/aws-sdk-go-v2/service/pinpointemail v1.12.4 + github.com/aws/aws-sdk-go-v2/service/ses v1.15.3 + github.com/mhale/smtpd v0.8.0 + golang.org/x/crypto v0.6.0 +) + +require ( + github.com/aws/aws-sdk-go-v2 v1.17.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 // indirect + github.com/aws/smithy-go v1.13.5 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index 29e0690..c2b2589 100644 --- a/go.sum +++ b/go.sum @@ -1,56 +1,30 @@ -github.com/aws/aws-sdk-go v1.30.3 h1:tmaR+qpBSig6RfhP9IoxALJEE1m0vfLy5tlnEIXu6WI= -github.com/aws/aws-sdk-go v1.30.3/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.38.61 h1:wizuqQZe0K4iYJ+Slrs0aSQ4P94FAwqBUHwk46Iz5UA= -github.com/aws/aws-sdk-go v1.38.61/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go-v2 v1.17.5 h1:TzCUW1Nq4H8Xscph5M/skINUitxM5UBAyvm2s7XBzL4= +github.com/aws/aws-sdk-go-v2 v1.17.5/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 h1:9/aKwwus0TQxppPXFmf010DFrE+ssSbzroLVYINA+xE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29/go.mod h1:Dip3sIGv485+xerzVv24emnjX5Sg88utCL8fwGmCeWg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 h1:b/Vn141DBuLVgXbhRWIrl9g+ww7G+ScV5SzniWR13jQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ= +github.com/aws/aws-sdk-go-v2/service/pinpointemail v1.12.4 h1:NcxMBuHmNENvStkgvIJgAqvTmjBGv/drQSmxGuLRjVg= +github.com/aws/aws-sdk-go-v2/service/pinpointemail v1.12.4/go.mod h1:slY3ISjHIVPkU8yFb9qDa12tBDaITlqdHLSbF+wIy7c= +github.com/aws/aws-sdk-go-v2/service/ses v1.15.3 h1:O7gl6f1Zi80GLQkyWFJi2PYzF8c7qd/iUBmLIVVp8og= +github.com/aws/aws-sdk-go-v2/service/ses v1.15.3/go.mod h1:xIWGz5r8k9h6T0f0jhkFdLMZJ10abjOfxmUWoWevw14= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mhale/smtpd v0.0.0-20181125220505-3c4c908952b8 h1:DuLRJOD3tr0rbrwDXXw5mw8YRPl70y8RbFpUtCjzOkU= -github.com/mhale/smtpd v0.0.0-20181125220505-3c4c908952b8/go.mod h1:qqKwvL5sfYgFxcMy96Kjx3TCorMfDaQBvmEL2nvdidc= -github.com/mhale/smtpd v0.0.0-20210322105601-438c8edb069c h1:AjouS6Z9yUjUzX7Y2iC9z9XSOIZNx1pJuhpHoX526wg= -github.com/mhale/smtpd v0.0.0-20210322105601-438c8edb069c/go.mod h1:MQl+y2hwIEQCXtNhe5+55n0GZOjSmeqORDIXbqUL3x4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/mhale/smtpd v0.8.0 h1:5JvdsehCg33PQrZBvFyDMMUDQmvbzVpZgKob7eYBJc0= +github.com/mhale/smtpd v0.8.0/go.mod h1:MQl+y2hwIEQCXtNhe5+55n0GZOjSmeqORDIXbqUL3x4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/relay/pinpoint/relay.go b/internal/relay/pinpoint/relay.go index 4fc8740..c3956eb 100644 --- a/internal/relay/pinpoint/relay.go +++ b/internal/relay/pinpoint/relay.go @@ -1,18 +1,22 @@ package relay import ( + "context" "net" "regexp" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/pinpointemail" - "github.com/aws/aws-sdk-go/service/pinpointemail/pinpointemailiface" + "github.com/aws/aws-sdk-go-v2/service/pinpointemail" + pinpointemailtypes "github.com/aws/aws-sdk-go-v2/service/pinpointemail/types" "github.com/blueimp/aws-smtp-relay/internal/relay" ) +type PinpointEmailClient interface { + SendEmail(context.Context, *pinpointemail.SendEmailInput, ...func(*pinpointemail.Options)) (*pinpointemail.SendEmailOutput, error) +} + // Client implements the Relay interface. type Client struct { - pinpointAPI pinpointemailiface.PinpointEmailAPI + pinpointClient PinpointEmailClient setName *string allowFromRegExp *regexp.Regexp denyToRegExp *regexp.Regexp @@ -32,22 +36,19 @@ func (c Client) Send( c.denyToRegExp, ) if err != nil { - relay.Log(origin, &from, deniedRecipients, err) + relay.Log(origin, from, deniedRecipients, err) } if len(allowedRecipients) > 0 { - _, err := c.pinpointAPI.SendEmail(&pinpointemail.SendEmailInput{ - ConfigurationSetName: c.setName, - FromEmailAddress: &from, - Destination: &pinpointemail.Destination{ - ToAddresses: allowedRecipients, - }, - Content: &pinpointemail.EmailContent{ - Raw: &pinpointemail.RawMessage{ - Data: data, - }, - }, + _, err := c.pinpointClient.SendEmail(context.Background(), &pinpointemail.SendEmailInput{ + Content: &pinpointemailtypes.EmailContent{Raw: &pinpointemailtypes.RawMessage{Data: data}}, + Destination: &pinpointemailtypes.Destination{ToAddresses: allowedRecipients}, + ConfigurationSetName: c.setName, + EmailTags: []pinpointemailtypes.MessageTag{}, + FeedbackForwardingEmailAddress: new(string), + FromEmailAddress: &from, + ReplyToAddresses: to, }) - relay.Log(origin, &from, allowedRecipients, err) + relay.Log(origin, from, allowedRecipients, err) if err != nil { return err } @@ -62,7 +63,7 @@ func New( denyToRegExp *regexp.Regexp, ) Client { return Client{ - pinpointAPI: pinpointemail.New(session.Must(session.NewSession())), + pinpointClient: pinpointemail.New(pinpointemail.Options{}), setName: configurationSetName, allowFromRegExp: allowFromRegExp, denyToRegExp: denyToRegExp, diff --git a/internal/relay/pinpoint/relay_test.go b/internal/relay/pinpoint/relay_test.go index df6c9a7..b96f149 100644 --- a/internal/relay/pinpoint/relay_test.go +++ b/internal/relay/pinpoint/relay_test.go @@ -1,6 +1,7 @@ package relay import ( + "context" "errors" "io/ioutil" "net" @@ -8,8 +9,7 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go/service/pinpointemail" - "github.com/aws/aws-sdk-go/service/pinpointemail/pinpointemailiface" + "github.com/aws/aws-sdk-go-v2/service/pinpointemail" "github.com/blueimp/aws-smtp-relay/internal/relay" ) @@ -19,18 +19,12 @@ var testData = struct { }{} type mockPinpointEmailClient struct { - pinpointemailiface.PinpointEmailAPI -} - -func (m *mockPinpointEmailClient) CreateConfigurationSet( - input *pinpointemail.CreateConfigurationSetInput, -) (*pinpointemail.CreateConfigurationSetOutput, error) { - return &pinpointemail.CreateConfigurationSetOutput{}, nil } func (m *mockPinpointEmailClient) SendEmail( + context context.Context, input *pinpointemail.SendEmailInput, -) (*pinpointemail.SendEmailOutput, error) { + fns ...func(*pinpointemail.Options)) (*pinpointemail.SendEmailOutput, error) { testData.input = input return nil, testData.err } @@ -59,7 +53,7 @@ func sendHelper( os.Stderr = errWriter func() { c := Client{ - pinpointAPI: &mockPinpointEmailClient{}, + pinpointClient: &mockPinpointEmailClient{}, setName: configurationSetName, allowFromRegExp: allowFromRegExp, denyToRegExp: denyToRegExp, @@ -95,10 +89,10 @@ func TestSend(t *testing.T) { 1, ) } - if *input.Destination.ToAddresses[0] != to[0] { + if input.Destination.ToAddresses[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destination.ToAddresses[0], + input.Destination.ToAddresses[0], to[0], ) } @@ -128,10 +122,10 @@ func TestSendWithMultipleRecipients(t *testing.T) { 2, ) } - if *input.Destination.ToAddresses[0] != to[0] { + if input.Destination.ToAddresses[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destination.ToAddresses[0], + input.Destination.ToAddresses[0], to[0], ) } @@ -184,10 +178,10 @@ func TestSendWithDeniedRecipient(t *testing.T) { 1, ) } - if *input.Destination.ToAddresses[0] != to[1] { + if input.Destination.ToAddresses[0] != to[1] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destination.ToAddresses[0], + input.Destination.ToAddresses[0], to[1], ) } @@ -224,10 +218,10 @@ func TestSendWithApiError(t *testing.T) { 1, ) } - if *input.Destination.ToAddresses[0] != to[0] { + if input.Destination.ToAddresses[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destination.ToAddresses[0], + input.Destination.ToAddresses[0], to[0], ) } diff --git a/internal/relay/relay.go b/internal/relay/relay.go index 2246933..19c5d33 100644 --- a/internal/relay/relay.go +++ b/internal/relay/relay.go @@ -34,18 +34,18 @@ type Client interface { type logEntry struct { Time time.Time - IP *string - From *string - To []*string + IP string + From string + To []string Error *string } // Log creates a log entry and prints it as JSON to STDOUT. -func Log(origin net.Addr, from *string, to []*string, err error) { +func Log(origin net.Addr, from string, to []string, err error) { ip := origin.(*net.TCPAddr).IP.String() entry := &logEntry{ Time: time.Now().UTC(), - IP: &ip, + IP: ip, From: from, To: to, } @@ -67,9 +67,9 @@ func FilterAddresses( to []string, allowFromRegExp *regexp.Regexp, denyToRegExp *regexp.Regexp, -) (allowedRecipients []*string, deniedRecipients []*string, err error) { - allowedRecipients = []*string{} - deniedRecipients = []*string{} +) (allowedRecipients []string, deniedRecipients []string, err error) { + allowedRecipients = []string{} + deniedRecipients = []string{} if allowFromRegExp != nil && !allowFromRegExp.MatchString(from) { err = ErrDeniedSender } @@ -78,9 +78,9 @@ func FilterAddresses( // Deny all recipients if the sender address is not allowed if err != nil || (denyToRegExp != nil && denyToRegExp.MatchString(*recipient)) { - deniedRecipients = append(deniedRecipients, recipient) + deniedRecipients = append(deniedRecipients, *recipient) } else { - allowedRecipients = append(allowedRecipients, recipient) + allowedRecipients = append(allowedRecipients, *recipient) } } if err == nil && len(deniedRecipients) > 0 { diff --git a/internal/relay/relay_test.go b/internal/relay/relay_test.go index 49a0ddd..d23fb93 100644 --- a/internal/relay/relay_test.go +++ b/internal/relay/relay_test.go @@ -11,17 +11,7 @@ import ( "time" ) -func pointersToValues(pointers []*string) []string { - values := []string{} - for k := range pointers { - if pointers[k] != nil { - values = append(values, *(pointers)[k]) - } - } - return values -} - -func logHelper(addr net.Addr, from *string, to []*string, err error) ( +func logHelper(addr net.Addr, from string, to []string, err error) ( []byte, []byte, ) { @@ -52,8 +42,8 @@ func TestLog(t *testing.T) { "bob@example.org", "charlie@example.org", } - from := &emails[0] - to := []*string{&emails[1], &emails[2]} + from := emails[0] + to := []string{emails[1], emails[2]} timeBefore := time.Now() out, err := logHelper(&origin, from, to, nil) timeAfter := time.Now() @@ -65,18 +55,14 @@ func TestLog(t *testing.T) { if entry.Time.After(timeAfter) { t.Errorf("Unexpected 'Time' log: %s", entry.Time) } - if entry.IP == nil { - t.Errorf("Unexpected 'IP' log: %v. Expected: %s", nil, "127.0.0.1") - } else if *entry.IP != "127.0.0.1" { - t.Errorf("Unexpected 'IP' log: %s. Expected: %s", *entry.IP, "127.0.0.1") + if entry.IP != "127.0.0.1" { + t.Errorf("Unexpected 'IP' log: %s. Expected: %s", entry.IP, "127.0.0.1") } - if entry.From == nil { - t.Errorf("Unexpected 'From' log: %v. Expected: %s", nil, *from) - } else if *entry.From != *from { - t.Errorf("Unexpected 'From' log: %s. Expected: %s", *entry.From, *from) + if entry.From != from { + t.Errorf("Unexpected 'From' log: %s. Expected: %s", entry.From, from) } - toVals := pointersToValues(entry.To) - expectedToVals := pointersToValues(to) + toVals := entry.To + expectedToVals := to if len(toVals) != len(expectedToVals) || toVals[0] != expectedToVals[0] || toVals[1] != expectedToVals[1] { t.Errorf("Unexpected 'To' log: %s. Expected: %s", toVals, expectedToVals) @@ -98,15 +84,15 @@ func TestLogWithOriginIPv6(t *testing.T) { "bob@example.org", "charlie@example.org", } - from := &emails[0] - to := []*string{&emails[1], &emails[2]} + from := emails[0] + to := []string{emails[1], emails[2]} out, err := logHelper(&origin, from, to, nil) var entry logEntry json.Unmarshal(out, &entry) - if *entry.IP != "2001:4860:0:2001::68" { + if entry.IP != "2001:4860:0:2001::68" { t.Errorf( "Unexpected 'IP' log: %s. Expected: %s", - *entry.IP, + entry.IP, "2001:4860:0:2001::68", ) } @@ -125,8 +111,8 @@ func TestLogWithError(t *testing.T) { "bob@example.org", "charlie@example.org", } - from := &emails[0] - to := []*string{&emails[1], &emails[2]} + from := emails[0] + to := []string{emails[1], emails[2]} out, err := logHelper(&origin, from, to, errors.New("ERROR")) var entry logEntry json.Unmarshal(out, &entry) @@ -155,7 +141,7 @@ func TestFilterAddresses(t *testing.T) { if err != nil { t.Errorf("Unexpected error: %s. Expected: %v", err, nil) } - allowedRecipientsValues := pointersToValues(allowedRecipients) + allowedRecipientsValues := allowedRecipients if len(allowedRecipients) != 2 || allowedRecipientsValues[0] != to[0] || allowedRecipientsValues[1] != to[1] { t.Errorf( @@ -167,7 +153,7 @@ func TestFilterAddresses(t *testing.T) { if len(deniedRecipients) != 0 { t.Errorf( "Unexpected denied recipients: %s. Expected: %s", - pointersToValues(deniedRecipients), + deniedRecipients, []string{}, ) } @@ -200,11 +186,11 @@ func TestFilterAddressesWithDeniedSender(t *testing.T) { if len(allowedRecipients) != 0 { t.Errorf( "Unexpected allowed recipients: %s. Expected: %s", - pointersToValues(allowedRecipients), + allowedRecipients, []string{}, ) } - deniedRecipientsValues := pointersToValues(deniedRecipients) + deniedRecipientsValues := deniedRecipients if len(deniedRecipients) != 2 || deniedRecipientsValues[0] != to[0] || deniedRecipientsValues[1] != to[1] { t.Errorf( @@ -239,7 +225,7 @@ func TestFilterAddressesWithDeniedRecipients(t *testing.T) { expectedError.Error(), ) } - allowedRecipientsValues := pointersToValues(allowedRecipients) + allowedRecipientsValues := allowedRecipients if len(allowedRecipients) != 1 || allowedRecipientsValues[0] != to[1] { t.Errorf( "Unexpected allowed recipients: %s. Expected: %s", @@ -247,7 +233,7 @@ func TestFilterAddressesWithDeniedRecipients(t *testing.T) { []string{"charlie@example.org"}, ) } - deniedRecipientsValues := pointersToValues(deniedRecipients) + deniedRecipientsValues := deniedRecipients if len(deniedRecipients) != 1 || deniedRecipientsValues[0] != to[0] { t.Errorf( "Unexpected denied recipients: %s. Expected: %s", diff --git a/internal/relay/ses/relay.go b/internal/relay/ses/relay.go index cada4f6..1460dfb 100644 --- a/internal/relay/ses/relay.go +++ b/internal/relay/ses/relay.go @@ -1,18 +1,22 @@ package relay import ( + "context" "net" "regexp" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ses" - "github.com/aws/aws-sdk-go/service/ses/sesiface" + "github.com/aws/aws-sdk-go-v2/service/ses" + sestypes "github.com/aws/aws-sdk-go-v2/service/ses/types" "github.com/blueimp/aws-smtp-relay/internal/relay" ) +type SESEmailClient interface { + SendRawEmail(context.Context, *ses.SendRawEmailInput, ...func(*ses.Options)) (*ses.SendRawEmailOutput, error) +} + // Client implements the Relay interface. type Client struct { - sesAPI sesiface.SESAPI + sesClient SESEmailClient setName *string allowFromRegExp *regexp.Regexp denyToRegExp *regexp.Regexp @@ -32,16 +36,20 @@ func (c Client) Send( c.denyToRegExp, ) if err != nil { - relay.Log(origin, &from, deniedRecipients, err) + relay.Log(origin, from, deniedRecipients, err) } if len(allowedRecipients) > 0 { - _, err := c.sesAPI.SendRawEmail(&ses.SendRawEmailInput{ + _, err := c.sesClient.SendRawEmail(context.Background(), &ses.SendRawEmailInput{ + RawMessage: &sestypes.RawMessage{Data: data}, ConfigurationSetName: c.setName, - Source: &from, Destinations: allowedRecipients, - RawMessage: &ses.RawMessage{Data: data}, + FromArn: new(string), + ReturnPathArn: new(string), + Source: &from, + SourceArn: new(string), + Tags: []sestypes.MessageTag{}, }) - relay.Log(origin, &from, allowedRecipients, err) + relay.Log(origin, from, allowedRecipients, err) if err != nil { return err } @@ -56,7 +64,7 @@ func New( denyToRegExp *regexp.Regexp, ) Client { return Client{ - sesAPI: ses.New(session.Must(session.NewSession())), + sesClient: ses.New(ses.Options{}), setName: configurationSetName, allowFromRegExp: allowFromRegExp, denyToRegExp: denyToRegExp, diff --git a/internal/relay/ses/relay_test.go b/internal/relay/ses/relay_test.go index 5210cbc..5a85170 100644 --- a/internal/relay/ses/relay_test.go +++ b/internal/relay/ses/relay_test.go @@ -1,6 +1,7 @@ package relay import ( + "context" "errors" "io/ioutil" "net" @@ -8,8 +9,7 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go/service/ses" - "github.com/aws/aws-sdk-go/service/ses/sesiface" + "github.com/aws/aws-sdk-go-v2/service/ses" "github.com/blueimp/aws-smtp-relay/internal/relay" ) @@ -18,11 +18,10 @@ var testData = struct { err error }{} -type mockSESAPI struct { - sesiface.SESAPI +type mockSESClient struct { } -func (m *mockSESAPI) SendRawEmail(input *ses.SendRawEmailInput) ( +func (m mockSESClient) SendRawEmail(ctx context.Context, input *ses.SendRawEmailInput, optFns ...func(*ses.Options)) ( *ses.SendRawEmailOutput, error, ) { @@ -54,7 +53,7 @@ func sendHelper( os.Stderr = errWriter func() { c := Client{ - sesAPI: &mockSESAPI{}, + sesClient: &mockSESClient{}, setName: configurationSetName, allowFromRegExp: allowFromRegExp, denyToRegExp: denyToRegExp, @@ -90,10 +89,10 @@ func TestSend(t *testing.T) { 1, ) } - if *input.Destinations[0] != to[0] { + if input.Destinations[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destinations[0], + input.Destinations[0], to[0], ) } @@ -123,10 +122,10 @@ func TestSendWithMultipleRecipients(t *testing.T) { 2, ) } - if *input.Destinations[0] != to[0] { + if input.Destinations[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destinations[0], + input.Destinations[0], to[0], ) } @@ -179,10 +178,10 @@ func TestSendWithDeniedRecipient(t *testing.T) { 1, ) } - if *input.Destinations[0] != to[1] { + if input.Destinations[0] != to[1] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destinations[0], + input.Destinations[0], to[1], ) } @@ -219,10 +218,10 @@ func TestSendWithApiError(t *testing.T) { 1, ) } - if *input.Destinations[0] != to[0] { + if input.Destinations[0] != to[0] { t.Errorf( "Unexpected destination: %s. Expected: %s", - *input.Destinations[0], + input.Destinations[0], to[0], ) }