1
+ // Package githubhook implements handling and verification of github webhooks
1
2
package githubhook
2
3
3
4
import (
@@ -10,12 +11,29 @@ import (
10
11
"strings"
11
12
)
12
13
13
- // Hook describes an inbound github webhook
14
+ // Hook is an inbound github webhook
14
15
type Hook struct {
16
+
17
+ // Id specifies the Id of a github webhook request.
18
+ //
19
+ // Id is extracted from the inbound request's `X-Github-Delivery` header.
20
+ Id string
21
+
22
+ // Event specifies the event name of a github webhook request.
23
+ //
24
+ // Event is extracted from the inbound request's `X-GitHub-Event` header.
25
+ // See: https://developer.github.com/webhooks/#events
26
+ Event string
27
+
28
+ // Signature specifies the signature of a github webhook request.
29
+ //
30
+ // Signature is extracted from the inbound request's `X-Hub-Signature` header.
15
31
Signature string
16
- Event string
17
- Id string
18
- Payload []byte
32
+
33
+ // Payload contains the raw contents of the webhook request.
34
+ //
35
+ // Payload is extracted from the JSON-formatted body of the inbound request.
36
+ Payload []byte
19
37
}
20
38
21
39
const signaturePrefix = "sha1="
@@ -28,6 +46,9 @@ func signBody(secret, body []byte) []byte {
28
46
}
29
47
30
48
// SignedBy checks that the provided secret matches the hook Signature
49
+ //
50
+ // Implements validation described in github's documentation:
51
+ // https://developer.github.com/webhooks/securing/
31
52
func (h * Hook ) SignedBy (secret []byte ) bool {
32
53
if len (h .Signature ) != signatureLength || ! strings .HasPrefix (h .Signature , signaturePrefix ) {
33
54
return false
@@ -39,7 +60,7 @@ func (h *Hook) SignedBy(secret []byte) bool {
39
60
return hmac .Equal (signBody (secret , h .Payload ), actual )
40
61
}
41
62
42
- // New extracts a Hook from an incoming http. Request
63
+ // New reads a Hook from an incoming HTTP Request.
43
64
func New (req * http.Request ) (hook * Hook , err error ) {
44
65
hook = new (Hook )
45
66
if ! strings .EqualFold (req .Method , "POST" ) {
@@ -62,7 +83,7 @@ func New(req *http.Request) (hook *Hook, err error) {
62
83
return
63
84
}
64
85
65
- // Parse extracts and verifies a hook against a secret
86
+ // Parse reads and verifies the hook in an inbound request.
66
87
func Parse (secret []byte , req * http.Request ) (hook * Hook , err error ) {
67
88
hook , err = New (req )
68
89
if err == nil && ! hook .SignedBy (secret ) {
0 commit comments