~netlandish/gobwebs-ses-feedback

0133484711b2c6eb088576cdc58e8ec22c5eed60 — Peter Sanchez 1 year, 11 months ago 861fff2
Adding (un)subscribe confirmation
1 files changed, 26 insertions(+), 10 deletions(-)

M feedback.go
M feedback.go => feedback.go +26 -10
@@ 9,6 9,7 @@ import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"


@@ 68,7 69,7 @@ type Record struct {
	UnsubscribeURL   string `json:"UnsubscribeURL"`
}

func (r Record) getBytesToSign() []byte {
func (r *Record) getBytesToSign() []byte {
	var fields []string
	var lines bytes.Buffer
	if r.Type == "Notification" {


@@ 91,14 92,14 @@ func (r Record) getBytesToSign() []byte {
	return lines.Bytes()
}

func (r Record) signatureAlgorithm() x509.SignatureAlgorithm {
func (r *Record) signatureAlgorithm() x509.SignatureAlgorithm {
	if r.SignatureVersion == "2" {
		return x509.SHA256WithRSA
	}
	return x509.SHA1WithRSA
}

func (r Record) verify() error {
func (r *Record) verify() error {
	// Get signature
	signature, err := base64.StdEncoding.DecodeString(r.Signature)
	if err != nil {


@@ 147,7 148,7 @@ func (r Record) verify() error {
func (s *Service) Feedback(c echo.Context) error {
	gctx := c.(*server.Context)
	req := c.Request()
	var data Record
	var data *Record
	err := json.NewDecoder(req.Body).Decode(&data)
	if err != nil {
		return c.JSON(http.StatusOK, err)


@@ 165,7 166,10 @@ func (s *Service) Feedback(c echo.Context) error {
	case "Notification":
		// For Notification, the Message field is a json-like string
		var message map[string]any
		json.Unmarshal([]byte(data.Message), &message)
		err = json.Unmarshal([]byte(data.Message), &message)
		if err != nil {
			return err
		}

		// According to some settings `eventType` might be called `notificationType`
		// https://docs.aws.amazon.com/ses/latest/dg/event-publishing-retrieving-sns-contents.html#event-publishing-retrieving-sns-contents-subscription-object


@@ 193,11 197,23 @@ func (s *Service) Feedback(c echo.Context) error {
		}
		gctx.Server.Logger().Printf("Received %s notification", eventType)

	case "SubscriptionConfirmation":
		err = s.actions.Subscribe(data.Message)
		gctx.Server.Logger().Printf("Received %s notification", data.Type)
	case "UnsubscribeConfirmation":
		err = s.actions.Unsubscribe(data.Message)
	case "SubscriptionConfirmation", "UnsubscribeConfirmation":
		resp, err := http.Get(data.SubscribeURL)
		if err != nil {
			return err
		}
		defer resp.Body.Close()

		_, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}

		if data.Type == "SubscribeConfirmation" {
			err = s.actions.Subscribe(data.Message)
		} else {
			err = s.actions.Unsubscribe(data.Message)
		}
		gctx.Server.Logger().Printf("Received %s notification", data.Type)
	default:
		gctx.Server.Logger().Printf("Error: Received unknown notification type: %s.", data.Type)