mirror of
https://github.com/adnanh/webhook.git
synced 2025-05-16 10:30:09 +00:00
added support for x-hub-signature
This commit is contained in:
parent
450852e1be
commit
3c4c025233
2 changed files with 22 additions and 17 deletions
|
@ -45,6 +45,10 @@ func (h *Hook) UnmarshalJSON(j []byte) error {
|
||||||
h.Cwd = v.(string)
|
h.Cwd = v.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := m["secret"]; ok {
|
||||||
|
h.Secret = v.(string)
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := m["trigger-rule"]; ok {
|
if v, ok := m["trigger-rule"]; ok {
|
||||||
rule := v.(map[string]interface{})
|
rule := v.(map[string]interface{})
|
||||||
|
|
||||||
|
@ -126,7 +130,7 @@ func New(hookFile string) (*Hooks, error) {
|
||||||
func (h *Hooks) Match(id string, params interface{}) *Hook {
|
func (h *Hooks) Match(id string, params interface{}) *Hook {
|
||||||
for i := range h.list {
|
for i := range h.list {
|
||||||
if h.list[i].ID == id {
|
if h.list[i].ID == id {
|
||||||
if h.list[i].Rule != nil && h.list[i].Rule.Evaluate(params) {
|
if h.list[i].Rule == nil || (h.list[i].Rule != nil && h.list[i].Rule.Evaluate(params)) {
|
||||||
return &h.list[i]
|
return &h.list[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
33
webhook.go
33
webhook.go
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/adnanh/webhook/hooks"
|
"github.com/adnanh/webhook/hooks"
|
||||||
|
@ -14,13 +16,13 @@ import (
|
||||||
"github.com/go-martini/martini"
|
"github.com/go-martini/martini"
|
||||||
|
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha1"
|
||||||
|
|
||||||
l4g "code.google.com/p/log4go"
|
l4g "code.google.com/p/log4go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version string = "1.0.1"
|
version string = "1.0.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -69,24 +71,25 @@ func rootHandler() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookHandler(req *http.Request, params martini.Params) string {
|
func hookHandler(req *http.Request, params martini.Params) string {
|
||||||
p := make(map[string]interface{})
|
defer req.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(req.Body)
|
||||||
|
if err != nil {
|
||||||
|
l4g.Warn("Error occurred while trying to read the request body: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
payloadJSON := make(map[string]interface{})
|
||||||
|
|
||||||
if req.Header.Get("Content-Type") == "application/json" {
|
if req.Header.Get("Content-Type") == "application/json" {
|
||||||
decoder := json.NewDecoder(req.Body)
|
decoder := json.NewDecoder(strings.NewReader(string(body)))
|
||||||
decoder.UseNumber()
|
decoder.UseNumber()
|
||||||
|
|
||||||
err := decoder.Decode(&p)
|
err := decoder.Decode(&payloadJSON)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l4g.Warn("Error occurred while trying to parse the payload as JSON: %s", err)
|
l4g.Warn("Error occurred while trying to parse the payload as JSON: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(req.Body)
|
|
||||||
if err != nil {
|
|
||||||
l4g.Warn("Error occurred while trying to read the request body: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func(id string, body []byte, signature string, params interface{}) {
|
go func(id string, body []byte, signature string, params interface{}) {
|
||||||
if hook := webhooks.Match(id, params); hook != nil {
|
if hook := webhooks.Match(id, params); hook != nil {
|
||||||
if hook.Secret != "" {
|
if hook.Secret != "" {
|
||||||
|
@ -95,13 +98,11 @@ func hookHandler(req *http.Request, params martini.Params) string {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mac := hmac.New(sha256.New, []byte(hook.Secret))
|
mac := hmac.New(sha1.New, []byte(hook.Secret))
|
||||||
mac.Write(body)
|
mac.Write(body)
|
||||||
expectedMAC := mac.Sum(nil)
|
expectedMAC := hex.EncodeToString(mac.Sum(nil))
|
||||||
|
|
||||||
l4g.Info("Expected %s, got %s.", expectedMAC, signature)
|
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
|
||||||
|
|
||||||
if !hmac.Equal([]byte(signature), expectedMAC) {
|
|
||||||
l4g.Error("Hook %s got matched, but the request contained invalid signature. Expected %s, got %s.", hook.ID, expectedMAC, signature)
|
l4g.Error("Hook %s got matched, but the request contained invalid signature. Expected %s, got %s.", hook.ID, expectedMAC, signature)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ func hookHandler(req *http.Request, params martini.Params) string {
|
||||||
out, _ := cmd.Output()
|
out, _ := cmd.Output()
|
||||||
l4g.Info("Hook %s triggered successfully! Command output:\n%s", hook.ID, out)
|
l4g.Info("Hook %s triggered successfully! Command output:\n%s", hook.ID, out)
|
||||||
}
|
}
|
||||||
}(params["id"], body, req.Header.Get("X-Hub-Signature"), p)
|
}(params["id"], body, req.Header.Get("X-Hub-Signature")[5:], payloadJSON)
|
||||||
|
|
||||||
return "Got it, thanks. :-)"
|
return "Got it, thanks. :-)"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue