From 0c429370e549eaf81c21bb8701f9efb4398f2d5e Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Tue, 8 Oct 2019 10:33:37 -0700 Subject: [PATCH] Pass webhook conversation token back to backend (#225) --- pkg/proxy/endpoint.go | 16 +++++------ pkg/proxy/endpoint_test.go | 8 ++++-- pkg/proxy/proxy.go | 23 +++++++++++---- pkg/websocket/webhook_messages.go | 39 ++++++++++++++------------ pkg/websocket/webhook_messages_test.go | 7 ++++- 5 files changed, 59 insertions(+), 34 deletions(-) diff --git a/pkg/proxy/endpoint.go b/pkg/proxy/endpoint.go index c99f2f7ee..7fdbb3e1d 100644 --- a/pkg/proxy/endpoint.go +++ b/pkg/proxy/endpoint.go @@ -30,18 +30,18 @@ type EndpointConfig struct { // EndpointResponseHandler handles a response from the endpoint. type EndpointResponseHandler interface { - ProcessResponse(string, string, *http.Response) + ProcessResponse(string, string, string, *http.Response) } // EndpointResponseHandlerFunc is an adapter to allow the use of ordinary // functions as response handlers. If f is a function with the // appropriate signature, ResponseHandler(f) is a // ResponseHandler that calls f. -type EndpointResponseHandlerFunc func(string, string, *http.Response) +type EndpointResponseHandlerFunc func(string, string, string, *http.Response) -// ProcessResponse calls f(webhookID, resp). -func (f EndpointResponseHandlerFunc) ProcessResponse(webhookID, forwardURL string, resp *http.Response) { - f(webhookID, forwardURL, resp) +// ProcessResponse calls f(webhookID, webhookConversationID, resp). +func (f EndpointResponseHandlerFunc) ProcessResponse(webhookID, webhookConversationID, forwardURL string, resp *http.Response) { + f(webhookID, webhookConversationID, forwardURL, resp) } // EndpointClient is the client used to POST webhook requests to the local endpoint. @@ -75,7 +75,7 @@ func (c *EndpointClient) SupportsEventType(connect bool, eventType string) bool } // Post sends a message to the local endpoint. -func (c *EndpointClient) Post(webhookID string, body string, headers map[string]string) error { +func (c *EndpointClient) Post(webhookID, webhookConversationID, body string, headers map[string]string) error { c.cfg.Log.WithFields(log.Fields{ "prefix": "proxy.EndpointClient.Post", }).Debug("Forwarding event to local endpoint") @@ -113,7 +113,7 @@ func (c *EndpointClient) Post(webhookID string, body string, headers map[string] } defer resp.Body.Close() - c.cfg.ResponseHandler.ProcessResponse(webhookID, c.URL, resp) + c.cfg.ResponseHandler.ProcessResponse(webhookID, webhookConversationID, c.URL, resp) return nil } @@ -136,7 +136,7 @@ func NewEndpointClient(url string, headers []string, connect bool, events []stri } } if cfg.ResponseHandler == nil { - cfg.ResponseHandler = EndpointResponseHandlerFunc(func(string, string, *http.Response) {}) + cfg.ResponseHandler = EndpointResponseHandlerFunc(func(string, string, string, *http.Response) {}) } return &EndpointClient{ diff --git a/pkg/proxy/endpoint_test.go b/pkg/proxy/endpoint_test.go index b2c54a816..93731d449 100644 --- a/pkg/proxy/endpoint_test.go +++ b/pkg/proxy/endpoint_test.go @@ -38,6 +38,7 @@ func TestClientHandler(t *testing.T) { rcvBody := "" rcvForwardURL := "" rcvWebhookID := "" + rcvWebhookConversationID := "" client := NewEndpointClient( ts.URL, []string{" Host: hostname", "customHeader:customHeaderValue", "customHeader2: customHeaderValue 2", @@ -45,13 +46,14 @@ func TestClientHandler(t *testing.T) { false, []string{"*"}, &EndpointConfig{ - ResponseHandler: EndpointResponseHandlerFunc(func(webhookID, forwardURL string, resp *http.Response) { + ResponseHandler: EndpointResponseHandlerFunc(func(webhookID, webhookConversationID, forwardURL string, resp *http.Response) { buf, err := ioutil.ReadAll(resp.Body) require.Nil(t, err) rcvBody = string(buf) rcvForwardURL = forwardURL rcvWebhookID = webhookID + rcvWebhookConversationID = webhookConversationID wg.Done() }), @@ -59,13 +61,14 @@ func TestClientHandler(t *testing.T) { ) webhookID := "wh_123" + webhookConversationID := "wc_123" payload := "{}" headers := map[string]string{ "User-Agent": "TestAgent/v1", "Stripe-Signature": "t=123,v1=hunter2", } - err := client.Post(webhookID, payload, headers) + err := client.Post(webhookID, webhookConversationID, payload, headers) wg.Wait() @@ -73,4 +76,5 @@ func TestClientHandler(t *testing.T) { require.Equal(t, "OK!", rcvBody) require.Equal(t, ts.URL, rcvForwardURL) require.Equal(t, "wh_123", rcvWebhookID) + require.Equal(t, "wc_123", rcvWebhookConversationID) } diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index ce44a2622..cdaeb9cf5 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -175,8 +175,9 @@ func (p *Proxy) processWebhookEvent(msg websocket.IncomingMessage) { webhookEvent := msg.WebhookEvent p.cfg.Log.WithFields(log.Fields{ - "prefix": "proxy.Proxy.processWebhookEvent", - "webhook_id": webhookEvent.WebhookID, + "prefix": "proxy.Proxy.processWebhookEvent", + "webhook_id": webhookEvent.WebhookID, + "webhook_converesation_id": webhookEvent.WebhookConversationID, }).Debugf("Processing webhook event") if p.filterWebhookEvent(webhookEvent) { @@ -213,7 +214,12 @@ func (p *Proxy) processWebhookEvent(msg websocket.IncomingMessage) { for _, endpoint := range p.endpointClients { if endpoint.SupportsEventType(evt.isConnect(), evt.Type) { - go endpoint.Post(webhookEvent.WebhookID, webhookEvent.EventPayload, webhookEvent.HTTPHeaders) + go endpoint.Post( + webhookEvent.WebhookID, + webhookEvent.WebhookConversationID, + webhookEvent.EventPayload, + webhookEvent.HTTPHeaders, + ) } } } @@ -222,7 +228,7 @@ func (p *Proxy) processWebhookEvent(msg websocket.IncomingMessage) { // to pass back to Stripe } -func (p *Proxy) processEndpointResponse(webhookID, forwardURL string, resp *http.Response) { +func (p *Proxy) processEndpointResponse(webhookID, webhookConversationID, forwardURL string, resp *http.Response) { localTime := time.Now().Format(timeLayout) color := ansi.Color(os.Stdout) @@ -258,7 +264,14 @@ func (p *Proxy) processEndpointResponse(webhookID, forwardURL string, resp *http } if p.webSocketClient != nil { - msg := websocket.NewWebhookResponse(webhookID, forwardURL, resp.StatusCode, body, headers) + msg := websocket.NewWebhookResponse( + webhookID, + webhookConversationID, + forwardURL, + resp.StatusCode, + body, + headers, + ) p.webSocketClient.SendMessage(msg) } } diff --git a/pkg/websocket/webhook_messages.go b/pkg/websocket/webhook_messages.go index 375721e57..5f594818a 100644 --- a/pkg/websocket/webhook_messages.go +++ b/pkg/websocket/webhook_messages.go @@ -8,34 +8,37 @@ type WebhookEndpoint struct { // WebhookEvent represents incoming webhook event messages sent by Stripe. type WebhookEvent struct { - Endpoint WebhookEndpoint `json:"endpoint"` - EventPayload string `json:"event_payload"` - HTTPHeaders map[string]string `json:"http_headers"` - Type string `json:"type"` - WebhookID string `json:"webhook_id"` + Endpoint WebhookEndpoint `json:"endpoint"` + EventPayload string `json:"event_payload"` + HTTPHeaders map[string]string `json:"http_headers"` + Type string `json:"type"` + WebhookConversationID string `json:"webhook_conversation_id"` + WebhookID string `json:"webhook_id"` } // WebhookResponse represents outgoing webhook response messages sent to // Stripe. type WebhookResponse struct { - ForwardURL string `json:"forward_url"` - Status int `json:"status"` - HTTPHeaders map[string]string `json:"http_headers"` - Body string `json:"body"` - Type string `json:"type"` - WebhookID string `json:"webhook_id"` + ForwardURL string `json:"forward_url"` + Status int `json:"status"` + HTTPHeaders map[string]string `json:"http_headers"` + Body string `json:"body"` + Type string `json:"type"` + WebhookConversationID string `json:"webhook_conversation_id"` + WebhookID string `json:"webhook_id"` } // NewWebhookResponse returns a new webhookResponse message. -func NewWebhookResponse(webhookID string, forwardURL string, status int, body string, headers map[string]string) *OutgoingMessage { +func NewWebhookResponse(webhookID, webhookConversationID, forwardURL string, status int, body string, headers map[string]string) *OutgoingMessage { return &OutgoingMessage{ WebhookResponse: &WebhookResponse{ - WebhookID: webhookID, - ForwardURL: forwardURL, - Status: status, - Body: body, - HTTPHeaders: headers, - Type: "webhook_response", + WebhookID: webhookID, + WebhookConversationID: webhookConversationID, + ForwardURL: forwardURL, + Status: status, + Body: body, + HTTPHeaders: headers, + Type: "webhook_response", }, } } diff --git a/pkg/websocket/webhook_messages_test.go b/pkg/websocket/webhook_messages_test.go index a0da10c52..076f32566 100644 --- a/pkg/websocket/webhook_messages_test.go +++ b/pkg/websocket/webhook_messages_test.go @@ -9,7 +9,7 @@ import ( ) func TestUnmarshalWebhookEvent(t *testing.T) { - var data = `{"type": "webhook_event", "event_payload": "foo", "http_headers": {"Request-Header": "bar"}, "webhook_id": "wh_123"}` + var data = `{"type": "webhook_event", "event_payload": "foo", "http_headers": {"Request-Header": "bar"}, "webhook_id": "wh_123", "webhook_conversation_id": "wc_123"}` var msg IncomingMessage err := json.Unmarshal([]byte(data), &msg) @@ -22,11 +22,13 @@ func TestUnmarshalWebhookEvent(t *testing.T) { require.Equal(t, "bar", msg.WebhookEvent.HTTPHeaders["Request-Header"]) require.Equal(t, "webhook_event", msg.WebhookEvent.Type) require.Equal(t, "wh_123", msg.WebhookEvent.WebhookID) + require.Equal(t, "wc_123", msg.WebhookEvent.WebhookConversationID) } func TestMarshalWebhookResponse(t *testing.T) { msg := NewWebhookResponse( "wh_123", + "wc_123", "http://localhost:5000/webhooks", 200, "foo", @@ -38,6 +40,7 @@ func TestMarshalWebhookResponse(t *testing.T) { json := string(buf) require.Equal(t, "wh_123", gjson.Get(json, "webhook_id").String()) + require.Equal(t, "wc_123", gjson.Get(json, "webhook_conversation_id").String()) require.Equal(t, "http://localhost:5000/webhooks", gjson.Get(json, "forward_url").String()) require.Equal(t, 200, int(gjson.Get(json, "status").Num)) require.Equal(t, "foo", gjson.Get(json, "body").String()) @@ -47,6 +50,7 @@ func TestMarshalWebhookResponse(t *testing.T) { func TestNewWebhookResponse(t *testing.T) { msg := NewWebhookResponse( "wh_123", + "wc_123", "http://localhost:5000/webhooks", 200, "foo", @@ -56,6 +60,7 @@ func TestNewWebhookResponse(t *testing.T) { require.NotNil(t, msg.WebhookResponse) require.Equal(t, "webhook_response", msg.Type) require.Equal(t, "wh_123", msg.WebhookID) + require.Equal(t, "wc_123", msg.WebhookConversationID) require.Equal(t, "http://localhost:5000/webhooks", msg.ForwardURL) require.Equal(t, 200, msg.Status) require.Equal(t, "foo", msg.Body)