forked from vikunja/vikunja
Pass HMAC in header for integrity
This commit is contained in:
parent
c9e67570ea
commit
1745dbb85d
|
@ -160,8 +160,9 @@ const (
|
||||||
MetricsUsername Key = `metrics.username`
|
MetricsUsername Key = `metrics.username`
|
||||||
MetricsPassword Key = `metrics.password`
|
MetricsPassword Key = `metrics.password`
|
||||||
|
|
||||||
WebhookEnabled Key = "webhook.enabled"
|
WebhookNotificationsEnabled Key = "notifications.webhook.enabled"
|
||||||
WebhookEndpointURL Key = "webhook.endpointurl"
|
WebhookNotificationEndpointURL Key = "notifications.webhook.endpointurl"
|
||||||
|
WebhookNotificationSignatureSecret Key = "notifications.webhook.signaturesecret"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetString returns a string config value
|
// GetString returns a string config value
|
||||||
|
@ -370,8 +371,9 @@ func InitDefaultConfig() {
|
||||||
KeyvalueType.setDefault("memory")
|
KeyvalueType.setDefault("memory")
|
||||||
// Metrics
|
// Metrics
|
||||||
MetricsEnabled.setDefault(false)
|
MetricsEnabled.setDefault(false)
|
||||||
// Webhook Notifications
|
// Webhook Notification
|
||||||
WebhookEnabled.setDefault(false)
|
WebhookNotificationsEnabled.setDefault(false)
|
||||||
|
WebhookNotificationSignatureSecret.setDefault("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitConfig initializes the config, sets defaults etc.
|
// InitConfig initializes the config, sets defaults etc.
|
||||||
|
|
|
@ -16,7 +16,6 @@ func DoPost(url string, body string, headers map[string]string) (resp *http.Resp
|
||||||
for k, v := range headers {
|
for k, v := range headers {
|
||||||
req.Header.Add(k, v)
|
req.Header.Add(k, v)
|
||||||
}
|
}
|
||||||
req.Header.Add("Content-Type", "application/json")
|
|
||||||
hc := http.Client{}
|
hc := http.Client{}
|
||||||
return hc.Do(req)
|
return hc.Do(req)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ func Notify(notifiable Notifiable, notification Notification) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.WebhookEnabled.GetBool() {
|
if config.WebhookNotificationsEnabled.GetBool() {
|
||||||
err = notifyWebhook(notifiable, notification)
|
err = notifyWebhook(notifiable, notification)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -90,10 +90,14 @@ func notifyWebhook(notifiable Notifiable, notification Notification) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signature := GenerateHMAC(string(content))
|
||||||
webhookNotification := &WebhookNotification{
|
webhookNotification := &WebhookNotification{
|
||||||
endpointURL: config.DatabasePassword.GetString(),
|
endpointURL: config.WebhookNotificationEndpointURL.GetString(),
|
||||||
headers: map[string]string{}, // TODO: allow passing user-configurable headers
|
headers: map[string]string{
|
||||||
body: string(content),
|
webhookNotificationSignatureHeader: signature,
|
||||||
|
webhookNotificationContentTypeHeader: "application/json",
|
||||||
|
},
|
||||||
|
body: string(content),
|
||||||
}
|
}
|
||||||
|
|
||||||
return SendWebhook(webhookNotification)
|
return SendWebhook(webhookNotification)
|
||||||
|
|
|
@ -16,6 +16,19 @@
|
||||||
|
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
|
||||||
|
"code.vikunja.io/api/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
webhookNotificationSignatureHeader = "x-vikunja-signature"
|
||||||
|
webhookNotificationContentTypeHeader = "Content-Type"
|
||||||
|
)
|
||||||
|
|
||||||
// WebhookNotification represents a notification that published to a http endpoint
|
// WebhookNotification represents a notification that published to a http endpoint
|
||||||
type WebhookNotification struct {
|
type WebhookNotification struct {
|
||||||
endpointURL string
|
endpointURL string
|
||||||
|
@ -23,6 +36,13 @@ type WebhookNotification struct {
|
||||||
body string
|
body string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateHMAC generates a HMAC code for the webhook body signed with the configured secret
|
||||||
|
func GenerateHMAC(requestBody string) string {
|
||||||
|
h := hmac.New(sha256.New, []byte(config.WebhookNotificationSignatureSecret.GetString()))
|
||||||
|
h.Write([]byte(requestBody))
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
// SendWebhook sends the notification to the configured endpoint
|
// SendWebhook sends the notification to the configured endpoint
|
||||||
func SendWebhook(w *WebhookNotification) error {
|
func SendWebhook(w *WebhookNotification) error {
|
||||||
resp, err := DoPost(w.endpointURL, w.body, w.headers)
|
resp, err := DoPost(w.endpointURL, w.body, w.headers)
|
||||||
|
|
Loading…
Reference in New Issue