Skip to content
This repository was archived by the owner on Apr 20, 2021. It is now read-only.
This repository was archived by the owner on Apr 20, 2021. It is now read-only.

Webhook support is missing #17

@maxannear

Description

@maxannear

This SDK doesn't have any support for web-hooks.

Fortunately its pretty easy to implement. The documentation about validating the x-xero-signature is as good as useless but hopefully the code below will help any future implementors get it sorted! I just ported the .NET code to Go and its working correctly.

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"net/http"
)

func XeroWebhookHandler(w http.ResponseWriter, r *http.Request) {

	xeroSignature := r.Header.Get("x-xero-signature")
	if xeroSignature == "" {
		http.Error(w, "Xero webhook endpoint got hit without a 'x-xero-signature' header", 400)
		return
	}

	defer r.Body.Close()
	//Because this endpoint will be unauthenticated, be careful reading the entire body
	//To minimise any DDoS risk only read up to a certain size (50kB)
	bodyReaderWithSizeLimit := http.MaxBytesReader(w, r.Body, 50*1024)
	bodyBytes, err := ioutil.ReadAll(bodyReaderWithSizeLimit)
	if err != nil {
		http.Error(w, "webhook had unreadable body.", 500)
		return
	}

	//Store the xeroWebhookKey somewhere safe
	xeroWebhookKey := "Get this value from the webhook config on developer.xero.com"
	expectedSignature := GetExpectedXeroSignature(bodyBytes, xeroWebhookKey)

	signatureGood := xeroSignature == expectedSignature
	if !signatureGood {
		fmt.Println("Xero Failed to verify xero signature")
		w.WriteHeader(401)
		return
	}

	//Process webhook
	fmt.Println("Xero webhook recieved")
	fmt.Println(string(bodyBytes))

	w.WriteHeader(200)
}

func GetExpectedXeroSignature(requestBodyBytes []byte, clientSecret string) string {
	key := []byte(clientSecret)
	hash := hmac.New(sha256.New, key)
	hash.Write(requestBodyBytes)
	return base64.StdEncoding.EncodeToString(hash.Sum(nil))
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions