Skip to content

Commit a5141d6

Browse files
author
Dean Karn
authored
Add customizable Logger interface + info,error and debugs (#14)
* Add customizable Logger interface + info,error and debugs * update travis.yml to atest golang versions
1 parent 9a8b92d commit a5141d6

File tree

11 files changed

+161
-22
lines changed

11 files changed

+161
-22
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: go
22
go:
3-
- 1.7.5
4-
- 1.8.1
3+
- 1.7.6
4+
- 1.8.3
55
- tip
66
matrix:
77
allow_failures:
@@ -34,6 +34,6 @@ script:
3434
- go test -race
3535

3636
after_success: |
37-
[ $TRAVIS_GO_VERSION = 1.8.1 ] &&
37+
[ $TRAVIS_GO_VERSION = 1.8.3 ] &&
3838
overalls -project="github.com/go-playground/webhooks" -covermode=count -ignore=.git,examples -debug &&
3939
goveralls -coverprofile=overalls.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Library webhooks
22
================
3-
<img align="right" src="https://raw.githubusercontent.com/go-playground/webhooks/v3/logo.png">![Project status](https://img.shields.io/badge/version-3.1.1-green.svg)
3+
<img align="right" src="https://raw.githubusercontent.com/go-playground/webhooks/v3/logo.png">![Project status](https://img.shields.io/badge/version-3.2.0-green.svg)
44
[![Build Status](https://travis-ci.org/go-playground/webhooks.svg?branch=v3)](https://travis-ci.org/go-playground/webhooks)
55
[![Coverage Status](https://coveralls.io/repos/go-playground/webhooks/badge.svg?branch=v3&service=github)](https://coveralls.io/github/go-playground/webhooks?branch=v3)
66
[![Go Report Card](https://goreportcard.com/badge/go-playground/webhooks)](https://goreportcard.com/report/go-playground/webhooks)

bitbucket/bitbucket.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package bitbucket
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io/ioutil"
67
"net/http"
78

@@ -69,38 +70,46 @@ func (hook Webhook) RegisterEvents(fn webhooks.ProcessPayloadFunc, events ...Eve
6970

7071
// ParsePayload parses and verifies the payload and fires off the mapped function, if it exists.
7172
func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
73+
webhooks.DefaultLog.Info("Parsing Payload...")
7274

7375
uuid := r.Header.Get("X-Hook-UUID")
7476
if uuid == "" {
77+
webhooks.DefaultLog.Error("Missing X-Hook-UUID Header")
7578
http.Error(w, "400 Bad Request - Missing X-Hook-UUID Header", http.StatusBadRequest)
7679
return
7780
}
81+
webhooks.DefaultLog.Debug(fmt.Sprintf("X-Hook-UUID:%s", uuid))
7882

7983
if uuid != hook.uuid {
80-
http.Error(w, "403 Forbidden - Missing X-Hook-UUID does not match", http.StatusForbidden)
84+
webhooks.DefaultLog.Error(fmt.Sprintf("X-Hook-UUID does not match configured uuid of %s", hook.uuid))
85+
http.Error(w, "403 Forbidden - X-Hook-UUID does not match", http.StatusForbidden)
8186
return
8287
}
8388

8489
event := r.Header.Get("X-Event-Key")
8590
if event == "" {
91+
webhooks.DefaultLog.Error("Missing X-Event-Key Header")
8692
http.Error(w, "400 Bad Request - Missing X-Event-Key Header", http.StatusBadRequest)
8793
return
8894
}
95+
webhooks.DefaultLog.Debug(fmt.Sprintf("X-Event-Key:%s", event))
8996

9097
bitbucketEvent := Event(event)
9198

9299
fn, ok := hook.eventFuncs[bitbucketEvent]
93100
// if no event registered
94101
if !ok {
102+
webhooks.DefaultLog.Info(fmt.Sprintf("Webhook Event %s not registered, it is recommended to setup only events in bitbucket that will be registered in the webhook to avoid unnecessary traffic and reduce potential attack vectors.", event))
95103
return
96104
}
97105

98106
payload, err := ioutil.ReadAll(r.Body)
99107
if err != nil || len(payload) == 0 {
100-
http.Error(w, "Error reading Body", http.StatusInternalServerError)
108+
webhooks.DefaultLog.Error("Issue reading Payload")
109+
http.Error(w, "Issue reading Payload", http.StatusInternalServerError)
101110
return
102111
}
103-
112+
webhooks.DefaultLog.Debug(fmt.Sprintf("Payload:%s", string(payload)))
104113
hd := webhooks.Header(r.Header)
105114

106115
switch bitbucketEvent {

examples/custom-logger/main.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strconv"
7+
8+
"gopkg.in/go-playground/webhooks.v3"
9+
"gopkg.in/go-playground/webhooks.v3/github"
10+
)
11+
12+
const (
13+
path = "/webhooks"
14+
port = 3016
15+
)
16+
17+
type myLogger struct {
18+
PrintDebugs bool
19+
}
20+
21+
func (l *myLogger) Info(msg string) {
22+
log.Println(msg)
23+
}
24+
25+
func (l *myLogger) Error(msg string) {
26+
log.Println(msg)
27+
}
28+
29+
func (l *myLogger) Debug(msg string) {
30+
if !l.PrintDebugs {
31+
return
32+
}
33+
log.Println(msg)
34+
}
35+
36+
func main() {
37+
// webhooks.DefaultLog=webhooks.NewLogger(true)
38+
//
39+
// or override with your own
40+
webhooks.DefaultLog = &myLogger{PrintDebugs: true}
41+
42+
hook := github.New(&github.Config{Secret: "MyGitHubSuperSecretSecrect...?"})
43+
hook.RegisterEvents(HandleMultiple, github.ReleaseEvent, github.PullRequestEvent) // Add as many as you want
44+
45+
err := webhooks.Run(hook, ":"+strconv.Itoa(port), path)
46+
if err != nil {
47+
fmt.Println(err)
48+
}
49+
}
50+
51+
// HandleMultiple handles multiple GitHub events
52+
func HandleMultiple(payload interface{}, header webhooks.Header) {
53+
fmt.Println("Handling Payload..")
54+
55+
switch payload.(type) {
56+
57+
case github.ReleasePayload:
58+
release := payload.(github.ReleasePayload)
59+
// Do whatever you want from here...
60+
fmt.Printf("%+v", release)
61+
62+
case github.PullRequestPayload:
63+
pullRequest := payload.(github.PullRequestPayload)
64+
// Do whatever you want from here...
65+
fmt.Printf("%+v", pullRequest)
66+
}
67+
}

examples/multiple-handlers/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const (
1414
)
1515

1616
func main() {
17-
1817
hook := github.New(&github.Config{Secret: "MyGitHubSuperSecretSecrect...?"})
1918
hook.RegisterEvents(HandleRelease, github.ReleaseEvent)
2019
hook.RegisterEvents(HandlePullRequest, github.PullRequestEvent)
@@ -27,7 +26,6 @@ func main() {
2726

2827
// HandleRelease handles GitHub release events
2928
func HandleRelease(payload interface{}, header webhooks.Header) {
30-
3129
fmt.Println("Handling Release")
3230

3331
pl := payload.(github.ReleasePayload)

examples/single-handler/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const (
1414
)
1515

1616
func main() {
17-
1817
hook := github.New(&github.Config{Secret: "MyGitHubSuperSecretSecrect...?"})
1918
hook.RegisterEvents(HandleMultiple, github.ReleaseEvent, github.PullRequestEvent) // Add as many as you want
2019

@@ -26,7 +25,6 @@ func main() {
2625

2726
// HandleMultiple handles multiple GitHub events
2827
func HandleMultiple(payload interface{}, header webhooks.Header) {
29-
3028
fmt.Println("Handling Payload..")
3129

3230
switch payload.(type) {

github/github.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/sha1"
66
"encoding/hex"
77
"encoding/json"
8+
"fmt"
89
"io/ioutil"
910
"net/http"
1011

@@ -96,43 +97,51 @@ func (hook Webhook) RegisterEvents(fn webhooks.ProcessPayloadFunc, events ...Eve
9697

9798
// ParsePayload parses and verifies the payload and fires off the mapped function, if it exists.
9899
func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
100+
webhooks.DefaultLog.Info("Parsing Payload...")
99101

100102
event := r.Header.Get("X-GitHub-Event")
101103
if len(event) == 0 {
104+
webhooks.DefaultLog.Error("Missing X-GitHub-Event Header")
102105
http.Error(w, "400 Bad Request - Missing X-GitHub-Event Header", http.StatusBadRequest)
103106
return
104107
}
108+
webhooks.DefaultLog.Debug(fmt.Sprintf("X-GitHub-Event:%s", event))
105109

106110
gitHubEvent := Event(event)
107111

108112
fn, ok := hook.eventFuncs[gitHubEvent]
109113
// if no event registered
110114
if !ok {
115+
webhooks.DefaultLog.Info(fmt.Sprintf("Webhook Event %s not registered, it is recommended to setup only events in github that will be registered in the webhook to avoid unnecessary traffic and reduce potential attack vectors.", event))
111116
return
112117
}
113118

114119
payload, err := ioutil.ReadAll(r.Body)
115120
if err != nil || len(payload) == 0 {
116-
http.Error(w, "Error reading Body", http.StatusInternalServerError)
121+
webhooks.DefaultLog.Error("Issue reading Payload")
122+
http.Error(w, "Issue reading Payload", http.StatusInternalServerError)
117123
return
118124
}
125+
webhooks.DefaultLog.Debug(fmt.Sprintf("Payload:%s", string(payload)))
119126

120127
// If we have a Secret set, we should check the MAC
121128
if len(hook.secret) > 0 {
122-
129+
webhooks.DefaultLog.Info("Checking secret")
123130
signature := r.Header.Get("X-Hub-Signature")
124-
125131
if len(signature) == 0 {
132+
webhooks.DefaultLog.Error("Missing X-Hub-Signature required for HMAC verification")
126133
http.Error(w, "403 Forbidden - Missing X-Hub-Signature required for HMAC verification", http.StatusForbidden)
127134
return
128135
}
136+
webhooks.DefaultLog.Debug(fmt.Sprintf("X-Hub-Signature:%s", signature))
129137

130138
mac := hmac.New(sha1.New, []byte(hook.secret))
131139
mac.Write(payload)
132140

133141
expectedMAC := hex.EncodeToString(mac.Sum(nil))
134142

135143
if !hmac.Equal([]byte(signature[5:]), []byte(expectedMAC)) {
144+
webhooks.DefaultLog.Error("HMAC verification failed")
136145
http.Error(w, "403 Forbidden - HMAC verification failed", http.StatusForbidden)
137146
return
138147
}

gitlab/gitlab.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gitlab
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io/ioutil"
67
"net/http"
78

@@ -59,33 +60,39 @@ func (hook Webhook) RegisterEvents(fn webhooks.ProcessPayloadFunc, events ...Eve
5960

6061
// ParsePayload parses and verifies the payload and fires off the mapped function, if it exists.
6162
func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) {
63+
webhooks.DefaultLog.Info("Parsing Payload...")
6264

6365
event := r.Header.Get("X-Gitlab-Event")
6466
if len(event) == 0 {
67+
webhooks.DefaultLog.Error("Missing X-Gitlab-Event Header")
6568
http.Error(w, "400 Bad Request - Missing X-Gitlab-Event Header", http.StatusBadRequest)
6669
return
6770
}
71+
webhooks.DefaultLog.Debug(fmt.Sprintf("X-Gitlab-Event:%s", event))
6872

6973
gitLabEvent := Event(event)
7074

7175
fn, ok := hook.eventFuncs[gitLabEvent]
7276
// if no event registered
7377
if !ok {
78+
webhooks.DefaultLog.Info(fmt.Sprintf("Webhook Event %s not registered, it is recommended to setup only events in gitlab that will be registered in the webhook to avoid unnecessary traffic and reduce potential attack vectors.", event))
7479
return
7580
}
7681

7782
payload, err := ioutil.ReadAll(r.Body)
7883
if err != nil || len(payload) == 0 {
79-
http.Error(w, "Error reading Body", http.StatusInternalServerError)
84+
webhooks.DefaultLog.Error("Issue reading Payload")
85+
http.Error(w, "Error reading Payload", http.StatusInternalServerError)
8086
return
8187
}
88+
webhooks.DefaultLog.Debug(fmt.Sprintf("Payload:%s", string(payload)))
8289

8390
// If we have a Secret set, we should check the MAC
8491
if len(hook.secret) > 0 {
85-
92+
webhooks.DefaultLog.Info("Checking secret")
8693
signature := r.Header.Get("X-Gitlab-Token")
87-
8894
if signature != hook.secret {
95+
webhooks.DefaultLog.Error(fmt.Sprintf("Invalid X-Gitlab-Token of '%s'", signature))
8996
http.Error(w, "403 Forbidden - Token missmatch", http.StatusForbidden)
9097
return
9198
}

logger.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package webhooks
2+
3+
import "log"
4+
5+
// DefaultLog contains the default logger for webhooks, and prints only info and error messages by default
6+
// for debugs override DefaultLog or see NewLogger for creating one without debugs.
7+
var DefaultLog Logger = new(logger)
8+
9+
// Logger allows for customizable logging
10+
type Logger interface {
11+
// Info prints basic information.
12+
Info(string)
13+
// Error prints error information.
14+
Error(string)
15+
// Debug prints information usefull for debugging.
16+
Debug(string)
17+
}
18+
19+
// NewLogger returns a new logger for use.
20+
func NewLogger(debug bool) Logger {
21+
return &logger{PrintDebugs: debug}
22+
}
23+
24+
type logger struct {
25+
PrintDebugs bool
26+
}
27+
28+
// Info prints basic information.
29+
func (l *logger) Info(msg string) {
30+
log.Println("INFO:", msg)
31+
}
32+
33+
// v prints error information.
34+
func (l *logger) Error(msg string) {
35+
log.Println("ERROR:", msg)
36+
}
37+
38+
// Debug prints information usefull for debugging.
39+
func (l *logger) Debug(msg string) {
40+
if !l.PrintDebugs {
41+
return
42+
}
43+
log.Println("DEBUG:", msg)
44+
}

0 commit comments

Comments
 (0)