mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2026-04-23 02:34:48 -05:00
Add support for Svix webhooks (#2996)
* support Svix webhooks * add migration * use http status codes * comment fix * custom svix verification logic * copilot comments * copilot comments
This commit is contained in:
@@ -356,22 +356,14 @@ func computeHMACSignature(payload []byte, secret []byte, algorithm sqlcv1.V1Inco
|
||||
}
|
||||
}
|
||||
|
||||
type HttpResponseCode int
|
||||
|
||||
const (
|
||||
Http400 HttpResponseCode = iota
|
||||
Http403
|
||||
Http500
|
||||
)
|
||||
|
||||
type ValidationError struct {
|
||||
Code HttpResponseCode
|
||||
Code int
|
||||
ErrorText string
|
||||
}
|
||||
|
||||
func (vr ValidationError) ToResponse() (gen.V1WebhookReceiveResponseObject, error) {
|
||||
switch vr.Code {
|
||||
case Http400:
|
||||
case http.StatusBadRequest:
|
||||
return gen.V1WebhookReceive400JSONResponse{
|
||||
Errors: []gen.APIError{
|
||||
{
|
||||
@@ -379,7 +371,7 @@ func (vr ValidationError) ToResponse() (gen.V1WebhookReceiveResponseObject, erro
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
case Http403:
|
||||
case http.StatusForbidden:
|
||||
return gen.V1WebhookReceive403JSONResponse{
|
||||
Errors: []gen.APIError{
|
||||
{
|
||||
@@ -387,7 +379,7 @@ func (vr ValidationError) ToResponse() (gen.V1WebhookReceiveResponseObject, erro
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
case Http500:
|
||||
case http.StatusInternalServerError:
|
||||
return nil, errors.New(vr.ErrorText)
|
||||
default:
|
||||
return nil, fmt.Errorf("no validation error set")
|
||||
@@ -429,161 +421,11 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
) {
|
||||
switch webhook.SourceName {
|
||||
case sqlcv1.V1IncomingWebhookSourceNameSLACK:
|
||||
timestampHeader := request.Header.Get("X-Slack-Request-Timestamp")
|
||||
|
||||
if timestampHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: "missing or invalid timestamp header: X-Slack-Request-Timestamp",
|
||||
}
|
||||
}
|
||||
|
||||
timestamp, err := strconv.ParseInt(strings.TrimSpace(timestampHeader), 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: "Invalid timestamp in header",
|
||||
}
|
||||
}
|
||||
|
||||
// qq: should this be utc?
|
||||
if time.Unix(timestamp, 0).UTC().Before(time.Now().Add(-5 * time.Minute)) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: "timestamp in header is out of range",
|
||||
}
|
||||
}
|
||||
|
||||
algorithm := webhook.AuthHmacAlgorithm.V1IncomingWebhookHmacAlgorithm
|
||||
encoding := webhook.AuthHmacEncoding.V1IncomingWebhookHmacEncoding
|
||||
decryptedSigningSecret, err := w.config.Encryption.Decrypt(webhook.AuthHmacWebhookSigningSecret, "v1_webhook_hmac_signing_secret")
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt HMAC signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
sigBaseString := fmt.Sprintf("v0:%d:%s", timestamp, webhookPayload)
|
||||
|
||||
hash, err := computeHMACSignature([]byte(sigBaseString), decryptedSigningSecret, algorithm, encoding)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
ErrorText: fmt.Sprintf("failed to compute HMAC signature: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
expectedSignature := fmt.Sprintf("v0=%s", hash)
|
||||
|
||||
signatureHeader := request.Header.Get(webhook.AuthHmacSignatureHeaderName.String)
|
||||
|
||||
if signatureHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
if !signaturesMatch(signatureHeader, expectedSignature) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: "invalid HMAC signature",
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return w.validateSlackWebhook(webhookPayload, webhook, request)
|
||||
case sqlcv1.V1IncomingWebhookSourceNameSTRIPE:
|
||||
signatureHeader := request.Header.Get(webhook.AuthHmacSignatureHeaderName.String)
|
||||
|
||||
if signatureHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
splitHeader := strings.Split(signatureHeader, ",")
|
||||
headersMap := make(map[string]string)
|
||||
|
||||
for _, header := range splitHeader {
|
||||
parts := strings.Split(header, "=")
|
||||
if len(parts) != 2 {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: fmt.Sprintf("invalid signature header format: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
headersMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
|
||||
timestampHeader, hasTimestampHeader := headersMap["t"]
|
||||
v1SignatureHeader, hasV1SignatureHeader := headersMap["v1"]
|
||||
|
||||
if timestampHeader == "" || v1SignatureHeader == "" || !hasTimestampHeader || !hasV1SignatureHeader {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
timestamp := strings.TrimPrefix(timestampHeader, "t=")
|
||||
signature := strings.TrimPrefix(v1SignatureHeader, "v1=")
|
||||
|
||||
if timestamp == "" || signature == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
parsedTimestamp, err := strconv.ParseInt(timestamp, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: "Invalid timestamp in signature header",
|
||||
}
|
||||
}
|
||||
|
||||
if time.Unix(parsedTimestamp, 0).UTC().Before(time.Now().Add(-10 * time.Minute)) {
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
ErrorText: "timestamp in signature header is out of range",
|
||||
}
|
||||
}
|
||||
|
||||
decryptedSigningSecret, err := w.config.Encryption.Decrypt(webhook.AuthHmacWebhookSigningSecret, "v1_webhook_hmac_signing_secret")
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt HMAC signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
algorithm := webhook.AuthHmacAlgorithm.V1IncomingWebhookHmacAlgorithm
|
||||
encoding := webhook.AuthHmacEncoding.V1IncomingWebhookHmacEncoding
|
||||
|
||||
signedPayload := fmt.Sprintf("%s.%s", timestamp, webhookPayload)
|
||||
|
||||
expectedSignature, err := computeHMACSignature([]byte(signedPayload), decryptedSigningSecret, algorithm, encoding)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: fmt.Sprintf("failed to compute HMAC signature: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
if !signaturesMatch(signature, expectedSignature) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
ErrorText: "invalid HMAC signature",
|
||||
}
|
||||
}
|
||||
return w.validateStripeWebhook(webhookPayload, webhook, request)
|
||||
case sqlcv1.V1IncomingWebhookSourceNameSVIX:
|
||||
return w.validateSvixWebhook(webhookPayload, webhook, request)
|
||||
case sqlcv1.V1IncomingWebhookSourceNameGITHUB:
|
||||
fallthrough
|
||||
case sqlcv1.V1IncomingWebhookSourceNameLINEAR:
|
||||
@@ -595,7 +437,7 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if !ok {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "missing or invalid authorization header",
|
||||
}
|
||||
}
|
||||
@@ -604,14 +446,14 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt basic auth password: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
if username != webhook.AuthBasicUsername.String || password != string(decryptedPassword) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "invalid basic auth credentials",
|
||||
}
|
||||
}
|
||||
@@ -620,7 +462,7 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if apiKey == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: fmt.Sprintf("missing or invalid api key header: %s", webhook.AuthApiKeyHeaderName.String),
|
||||
}
|
||||
}
|
||||
@@ -629,14 +471,14 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt api key: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
if apiKey != string(decryptedApiKey) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: fmt.Sprintf("invalid api key: %s", webhook.AuthApiKeyHeaderName.String),
|
||||
}
|
||||
}
|
||||
@@ -645,7 +487,7 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if signature == "" {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
@@ -654,7 +496,7 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt HMAC signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
@@ -666,26 +508,26 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: Http500,
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to compute HMAC signature: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
if !signaturesMatch(signature, expectedSignature) {
|
||||
return false, &ValidationError{
|
||||
Code: Http403,
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "invalid HMAC signature",
|
||||
}
|
||||
}
|
||||
default:
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("unsupported auth type: %s", webhook.AuthMethod),
|
||||
}
|
||||
}
|
||||
default:
|
||||
return false, &ValidationError{
|
||||
Code: Http400,
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("unsupported source name: %+v", webhook.SourceName),
|
||||
}
|
||||
}
|
||||
@@ -693,6 +535,263 @@ func (w *V1WebhooksService) validateWebhook(webhookPayload []byte, webhook sqlcv
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (w *V1WebhooksService) validateSlackWebhook(webhookPayload []byte, webhook sqlcv1.V1IncomingWebhook, request http.Request) (
|
||||
IsValid,
|
||||
*ValidationError,
|
||||
) {
|
||||
timestampHeader := request.Header.Get("X-Slack-Request-Timestamp")
|
||||
|
||||
if timestampHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "missing or invalid timestamp header: X-Slack-Request-Timestamp",
|
||||
}
|
||||
}
|
||||
|
||||
timestamp, err := strconv.ParseInt(strings.TrimSpace(timestampHeader), 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "Invalid timestamp in header",
|
||||
}
|
||||
}
|
||||
|
||||
// qq: should this be utc?
|
||||
if time.Unix(timestamp, 0).UTC().Before(time.Now().Add(-5 * time.Minute)) {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "timestamp in header is out of range",
|
||||
}
|
||||
}
|
||||
|
||||
algorithm := webhook.AuthHmacAlgorithm.V1IncomingWebhookHmacAlgorithm
|
||||
encoding := webhook.AuthHmacEncoding.V1IncomingWebhookHmacEncoding
|
||||
decryptedSigningSecret, err := w.config.Encryption.Decrypt(webhook.AuthHmacWebhookSigningSecret, "v1_webhook_hmac_signing_secret")
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt HMAC signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
sigBaseString := fmt.Sprintf("v0:%d:%s", timestamp, webhookPayload)
|
||||
|
||||
hash, err := computeHMACSignature([]byte(sigBaseString), decryptedSigningSecret, algorithm, encoding)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to compute HMAC signature: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
expectedSignature := fmt.Sprintf("v0=%s", hash)
|
||||
|
||||
signatureHeader := request.Header.Get(webhook.AuthHmacSignatureHeaderName.String)
|
||||
|
||||
if signatureHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
if !signaturesMatch(signatureHeader, expectedSignature) {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "invalid HMAC signature",
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (w *V1WebhooksService) validateStripeWebhook(webhookPayload []byte, webhook sqlcv1.V1IncomingWebhook, request http.Request) (
|
||||
IsValid,
|
||||
*ValidationError,
|
||||
) {
|
||||
signatureHeader := request.Header.Get(webhook.AuthHmacSignatureHeaderName.String)
|
||||
|
||||
if signatureHeader == "" {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
splitHeader := strings.Split(signatureHeader, ",")
|
||||
headersMap := make(map[string]string)
|
||||
|
||||
for _, header := range splitHeader {
|
||||
parts := strings.Split(header, "=")
|
||||
if len(parts) != 2 {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("invalid signature header format: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
headersMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
|
||||
timestampHeader, hasTimestampHeader := headersMap["t"]
|
||||
v1SignatureHeader, hasV1SignatureHeader := headersMap["v1"]
|
||||
|
||||
if timestampHeader == "" || v1SignatureHeader == "" || !hasTimestampHeader || !hasV1SignatureHeader {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
timestamp := strings.TrimPrefix(timestampHeader, "t=")
|
||||
signature := strings.TrimPrefix(v1SignatureHeader, "v1=")
|
||||
|
||||
if timestamp == "" || signature == "" {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("missing or invalid signature header: %s", webhook.AuthHmacSignatureHeaderName.String),
|
||||
}
|
||||
}
|
||||
|
||||
parsedTimestamp, err := strconv.ParseInt(timestamp, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: "Invalid timestamp in signature header",
|
||||
}
|
||||
}
|
||||
|
||||
if time.Unix(parsedTimestamp, 0).UTC().Before(time.Now().Add(-10 * time.Minute)) {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: "timestamp in signature header is out of range",
|
||||
}
|
||||
}
|
||||
|
||||
decryptedSigningSecret, err := w.config.Encryption.Decrypt(webhook.AuthHmacWebhookSigningSecret, "v1_webhook_hmac_signing_secret")
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt HMAC signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
algorithm := webhook.AuthHmacAlgorithm.V1IncomingWebhookHmacAlgorithm
|
||||
encoding := webhook.AuthHmacEncoding.V1IncomingWebhookHmacEncoding
|
||||
|
||||
signedPayload := fmt.Sprintf("%s.%s", timestamp, webhookPayload)
|
||||
|
||||
expectedSignature, err := computeHMACSignature([]byte(signedPayload), decryptedSigningSecret, algorithm, encoding)
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: fmt.Sprintf("failed to compute HMAC signature: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
if !signaturesMatch(signature, expectedSignature) {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "invalid HMAC signature",
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (w *V1WebhooksService) validateSvixWebhook(webhookPayload []byte, webhook sqlcv1.V1IncomingWebhook, request http.Request) (
|
||||
IsValid,
|
||||
*ValidationError,
|
||||
) {
|
||||
decryptedSigningSecret, err := w.config.Encryption.Decrypt(webhook.AuthHmacWebhookSigningSecret, "v1_webhook_hmac_signing_secret")
|
||||
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decrypt SVIX signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
key, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(string(decryptedSigningSecret), "whsec_"))
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to decode SVIX signing secret: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
headers := request.Header
|
||||
|
||||
msgId := headers.Get("svix-id")
|
||||
msgSignature := headers.Get("svix-signature")
|
||||
msgTimestamp := headers.Get("svix-timestamp")
|
||||
|
||||
if msgId == "" || msgSignature == "" || msgTimestamp == "" {
|
||||
msgId = headers.Get("webhook-id")
|
||||
msgSignature = headers.Get("webhook-signature")
|
||||
msgTimestamp = headers.Get("webhook-timestamp")
|
||||
if msgId == "" || msgSignature == "" || msgTimestamp == "" {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: "missing or invalid headers",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timestamp, err := svixParseTimestampHeader(msgTimestamp)
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("invalid timestamp header: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
err = svixVerifyTimestamp(timestamp)
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusBadRequest,
|
||||
ErrorText: fmt.Sprintf("invalid timestamp header: %s", err),
|
||||
}
|
||||
}
|
||||
|
||||
computedSignature, err := svixSign(key, msgId, timestamp, webhookPayload)
|
||||
if err != nil {
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusInternalServerError,
|
||||
ErrorText: fmt.Sprintf("failed to sign SVIX payload: %s", err),
|
||||
}
|
||||
}
|
||||
expectedSignature := []byte(strings.Split(computedSignature, ",")[1])
|
||||
|
||||
passedSignatures := strings.SplitSeq(msgSignature, " ")
|
||||
|
||||
for versionedSignature := range passedSignatures {
|
||||
sigParts := strings.Split(versionedSignature, ",")
|
||||
if len(sigParts) < 2 {
|
||||
continue
|
||||
}
|
||||
version := sigParts[0]
|
||||
signature := []byte(sigParts[1])
|
||||
|
||||
if version != "v1" {
|
||||
continue
|
||||
}
|
||||
|
||||
if hmac.Equal(signature, expectedSignature) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, &ValidationError{
|
||||
Code: http.StatusForbidden,
|
||||
ErrorText: "invalid SVIX signature",
|
||||
}
|
||||
}
|
||||
|
||||
func signaturesMatch(providedSignature, expectedSignature string) bool {
|
||||
providedSignature = strings.TrimSpace(providedSignature)
|
||||
expectedSignature = strings.TrimSpace(expectedSignature)
|
||||
@@ -711,3 +810,40 @@ func removePrefixesFromSignature(signature string) string {
|
||||
|
||||
return signature
|
||||
}
|
||||
|
||||
var errInvalidHeaders = errors.New("invalid headers")
|
||||
var errMessageTooOld = errors.New("message too old")
|
||||
var errMessageTooNew = errors.New("message too new")
|
||||
var tolerance = 5 * time.Minute
|
||||
|
||||
func svixParseTimestampHeader(timestampHeader string) (time.Time, error) {
|
||||
timeInt, err := strconv.ParseInt(timestampHeader, 10, 64)
|
||||
if err != nil {
|
||||
return time.Time{}, errInvalidHeaders
|
||||
}
|
||||
timestamp := time.Unix(timeInt, 0)
|
||||
return timestamp, nil
|
||||
}
|
||||
|
||||
func svixVerifyTimestamp(timestamp time.Time) error {
|
||||
now := time.Now()
|
||||
|
||||
if now.Sub(timestamp) > tolerance {
|
||||
return errMessageTooOld
|
||||
}
|
||||
if timestamp.Unix() > now.Add(tolerance).Unix() {
|
||||
return errMessageTooNew
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func svixSign(key []byte, msgId string, timestamp time.Time, payload []byte) (string, error) {
|
||||
toSign := fmt.Sprintf("%s.%d.%s", msgId, timestamp.Unix(), payload)
|
||||
|
||||
h := hmac.New(sha256.New, key)
|
||||
h.Write([]byte(toSign))
|
||||
sig := make([]byte, base64.StdEncoding.EncodedLen(h.Size()))
|
||||
base64.StdEncoding.Encode(sig, h.Sum(nil))
|
||||
return fmt.Sprintf("v1,%s", sig), nil
|
||||
}
|
||||
|
||||
@@ -299,6 +299,7 @@ const (
|
||||
LINEAR V1WebhookSourceName = "LINEAR"
|
||||
SLACK V1WebhookSourceName = "SLACK"
|
||||
STRIPE V1WebhookSourceName = "STRIPE"
|
||||
SVIX V1WebhookSourceName = "SVIX"
|
||||
)
|
||||
|
||||
// Defines values for V1WorkflowType.
|
||||
@@ -16137,13 +16138,13 @@ func (sh *strictHandler) WorkflowVersionGet(ctx echo.Context, workflow openapi_t
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/+y9e3PbOLI4+lVYurfqN1Ml+ZXJnDmp+v2h2EqiiWN7JTm5e+akvBAJSxhTJJcA7WhT",
|
||||
"H4sIAAAAAAAC/+y9e3PbOLIo/lVY+v2q7kyV5Fcmc+ak6v6h2EqiiWN7JTm5e+ekvBAJSxhTJJcA7WhT",
|
||||
"/u638CJBEiBBvSwlrNracUQ8Go3uRqPRj+8dN1xEYQADgjtvvnewO4cLwP7s3wwHcRzG9O8oDiMYEwTZ",
|
||||
"Fzf0IP2vB7Ebo4igMOi86QDHTTAJF84HQNw5JA6kvR3WuNuB38Ai8mHnzelvJyfdzn0YLwDpvOkkKCC/",
|
||||
"/9bpdsgygp03HRQQOINx57mbH748m/Jv5z6MHTJHmM+pTtfpZw0foYBpATEGM5jNikmMghmbNHTxnY+C",
|
||||
"B92U9HeHhA6ZQ8cL3WQBAwI0AHQddO8g4sBvCBOcA2eGyDyZHrnh4njO8dTz4KP8WwfRPYK+V4aGwsA+",
|
||||
"OWQOiDK5g7ADMA5dBAj0nCdE5gweEEU+csHUz21HJwALDSKeu50Y/jtBMfQ6b/7KTf01bRxO/4YuoTBK",
|
||||
"WsFlYoHp74jABfvj/43hfedN5/85zmjvWBDecUp1z+k0II7BsgSSGNcAzSdIQBkW4Pvh0/kcBDN4AzB+",
|
||||
"WsFlYoHp74jABfvj/4/hfedN5/87zmjvWBDecUp1z+k0II7BsgSSGNcAzSdIQBkW4Pvh0/kcBDN4AzB+",
|
||||
"CmMNYp/mkMxh7ISxE4TESTCMseOCwHFZR7r5KHYi2V/BJYkTmIIzDUMfgoDCw6eNISBwAgMQkCaTsm5O",
|
||||
"AJ8cwvpi6xmHwSMifOGWkyHWwwnZV/4zo3aEHRRgAgIXWs8+RrMgiRpMjtEscJIoY6VGUyZkbkFalCz6",
|
||||
"tOlztxOFmMzDmWWvG9Gadlz6YdCPoqGBK2/od8puzvCCrSbBkPWhXE+piDg4iaIwJjlGPD179dvr3//r",
|
||||
@@ -16166,7 +16167,7 @@ var swaggerSpec = []string{
|
||||
"GM1mMDbuY0ZlnxS1pzSwG4fBoJpuaZMrsQFlpZmKPe3IUYzCGJFlkbSZeBHSqfPmFTu8+N+nZZIvKQh0",
|
||||
"tq5ucQqcpVV9TTFYfVbrcVYgurRNKupTCmQnqbLNGTL0YzGGshvgQXeJo/3ZKWTonm2TuhnlMeRXKXrT",
|
||||
"cZocC+Vh2ScGHBvQuUc+gRSiek7g11GGtWzzxldjxbpg3EUSRsjtxyZ2XID/hIEjFXyHUozzS3909atc",
|
||||
"/fhq7LAx1hFjqaa7QMH/Pe0uwLf/e/b697LKmwJr5npudOz7MCaDBUD++zhMIrP8pk2wTlj6CBO6Rt5C",
|
||||
"/fhq7LAx1hFjqaa7QMH/Pu0uwLf/ffb697LKmwJr5npudOz7MCaDBUD++zhMIrP8pk2wTlj6CBO6Rt5C",
|
||||
"mrZieiJa2n1WWL6HHmGXzVheuwC1buU1lxw+uHav2Se5rXStVJ/gl4yN7K1cV7cTh36tbsRX8wlSfWxE",
|
||||
"22vx0RGD1WHFjI9ghgL4GcZSoNfDJBs/dzsweERxGCwgN3PX9x0oHawvytwWvok9YEgMg2kIYg8Fswsh",
|
||||
"Z/U6Fjc/G+V5NgyXyiR0MAljyB5h9HBne4P9ZGYQg34y2/zCu+LNiZ14zwYTJQNKT0mZJoFtD8IqpGoV",
|
||||
@@ -16225,7 +16226,7 @@ var swaggerSpec = []string{
|
||||
"EXUT+sjVpAvlGn/VJTitnMebapSGBmI3z351PqACOPPqhAXUVqAaBZJSDUDKo88nnW7n86lelHC3yR3E",
|
||||
"5BnDPLk/cJOCNxV55Z/TAceauAVzIZE1Xb2rvbw5QD9jcQ915TVR9xupq2HU3FRARP+XB8TMagdtKW4N",
|
||||
"TS9paNqiAWgrpd0aGPJXtsMbuPAL83kyJyzANyDButxgKptwxykHYSdirR0QeI4LgiAkDmClW1lNeJnX",
|
||||
"unRg6aDDuvt4rT0KeF4MMVbtUjktWho6yuYp+uEDwHPdcTMHeK4O+X9wYTpxAHFFlJdUH/Pq5M75nBVM",
|
||||
"unRg6aDDuvt4rT0KeF4MMVbtUjktWho6yuYp+uEDwHPdcTMHeK4O+b9wYTpxAHFFlJdUH/Pq5M75nBVM",
|
||||
"1k/4GcboHtWhl1nXqAx6FM1FWf8cDHpOmAN8I4v/280BnEh0cDAkBv7axkuWh3Dkg2WOEeT+NTZk5bH7",
|
||||
"1UBg53MQzKBEkJEJAvhkRiLjXfiUYU1q1HrYV9A75Mhs3VElICkQlfhbD4ZSBlbxpZvDkwnll+EMBatX",
|
||||
"N1uNv9cqdrZ3GJdrjOpwLfNeHRS67U5Ig2DYw92S9c1tN01Vq/EcRfhQjawlo/MOT/NtnDJ8Mt22fT49",
|
||||
@@ -16268,192 +16269,192 @@ var swaggerSpec = []string{
|
||||
"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",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
Reference in New Issue
Block a user