Skip to content

Commit b1f6956

Browse files
committed
Merge branch 'development'
2 parents 9c7f8c1 + 159cb4a commit b1f6956

24 files changed

+1701
-336
lines changed

.github/workflows/build.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: build
2+
on: [push, pull_request]
3+
jobs:
4+
build:
5+
strategy:
6+
matrix:
7+
go-version: [1.14.x, 1.15.x]
8+
os: [ubuntu-latest, macos-latest, windows-latest]
9+
10+
runs-on: ${{ matrix.os }}
11+
12+
steps:
13+
- uses: actions/checkout@v2
14+
- uses: actions/setup-go@v2
15+
with:
16+
go-version: ${{ matrix.go-version }}
17+
id: go
18+
19+
- name: Build
20+
run: go build -v
21+
22+
- name: Test
23+
run: go test -v ./...

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: go
22

33
go:
4-
- 1.13.x
4+
- 1.14.x
55
- master
66

77
os:

README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# What is webhook?
1+
# What is webhook? ![build-status][badge]
22

33
<img src="https://github.com/adnanh/webhook/raw/development/docs/logo/logo-128x128.png" alt="Webhook" align="left" />
44

@@ -29,7 +29,7 @@ If you don't have time to waste configuring, hosting, debugging and maintaining
2929
# Getting started
3030
## Installation
3131
### Building from source
32-
To get started, first make sure you've properly set up your [Go](http://golang.org/doc/install) 1.12 or newer environment and then run
32+
To get started, first make sure you've properly set up your [Go](http://golang.org/doc/install) 1.14 or newer environment and then run
3333
```bash
3434
$ go build github.com/adnanh/webhook
3535
```
@@ -49,7 +49,9 @@ If you are using Debian linux ("stretch" or later), you can install webhook usin
4949
Prebuilt binaries for different architectures are available at [GitHub Releases](https://github.com/adnanh/webhook/releases).
5050

5151
## Configuration
52-
Next step is to define some hooks you want [webhook][w] to serve. Begin by creating an empty file named `hooks.json`. This file will contain an array of hooks the [webhook][w] will serve. Check [Hook definition page](docs/Hook-Definition.md) to see the detailed description of what properties a hook can contain, and how to use them.
52+
Next step is to define some hooks you want [webhook][w] to serve.
53+
[webhook][w] supports JSON or YAML configuration files, but we'll focus primarily on JSON in the following example.
54+
Begin by creating an empty file named `hooks.json`. This file will contain an array of hooks the [webhook][w] will serve. Check [Hook definition page](docs/Hook-Definition.md) to see the detailed description of what properties a hook can contain, and how to use them.
5355

5456
Let's define a simple hook named `redeploy-webhook` that will run a redeploy script located in `/var/scripts/redeploy.sh`. Make sure that your bash script has `#!/bin/sh` shebang on top.
5557

@@ -64,6 +66,13 @@ Our `hooks.json` file will now look like this:
6466
]
6567
```
6668

69+
**NOTE:** If you prefer YAML, the equivalent `hooks.yaml` file would be:
70+
```yaml
71+
- id: redeploy-webhook
72+
execute-command: "/var/scripts/redeploy.sh"
73+
command-working-directory: "/var/webhook"
74+
```
75+
6776
You can now run [webhook][w] using
6877
```bash
6978
$ /path/to/webhook -hooks hooks.json -verbose
@@ -93,7 +102,7 @@ All files are ignored unless they match one of the following criteria:
93102
In either case, the given file part will be parsed as JSON and added to the `payload` map.
94103

95104
## Templates
96-
[webhook][w] can parse the `hooks.json` input file as a Go template when given the `-template` [CLI parameter](docs/Webhook-Parameters.md). See the [Templates page](docs/Templates.md) for more details on template usage.
105+
[webhook][w] can parse the hooks configuration file as a Go template when given the `-template` [CLI parameter](docs/Webhook-Parameters.md). See the [Templates page](docs/Templates.md) for more details on template usage.
97106

98107
## Using HTTPS
99108
[webhook][w] by default serves hooks using http. If you want [webhook][w] to serve secure content using https, you can use the `-secure` flag while starting [webhook][w]. Files containing a certificate and matching private key for the server must be provided using the `-cert /path/to/cert.pem` and `-key /path/to/key.pem` flags. If the certificate is signed by a certificate authority, the cert file should be the concatenation of the server's certificate followed by the CA's certificate.
@@ -206,3 +215,4 @@ THE SOFTWARE.
206215

207216
[w]: https://github.com/adnanh/webhook
208217
[wc]: https://github.com/adnanh/webhook-contrib
218+
[badge]: https://github.com/adnanh/webhook/workflows/build/badge.svg

docs/Hook-Definition.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Hook definition
2-
Hooks are defined as JSON objects. Please note that in order to be considered valid, a hook object must contain the `id` and `execute-command` properties. All other properties are considered optional.
2+
3+
Hooks are defined as objects in the JSON or YAML hooks configuration file. Please note that in order to be considered valid, a hook object must contain the `id` and `execute-command` properties. All other properties are considered optional.
34

45
## Properties (keys)
56

@@ -21,6 +22,7 @@ Hooks are defined as JSON objects. Please note that in order to be considered va
2122
* `pass-file-to-command` - specifies a list of entries that will be serialized as a file. Incoming [data](Referencing-Request-Values.md) will be serialized in a request-temporary-file (otherwise parallel calls of the hook would lead to concurrent overwritings of the file). The filename to be addressed within the subsequent script is provided via an environment variable. Use `envname` to specify the name of the environment variable. If `envname` is not provided `HOOK_` and the name used to reference the request value are used. Defining `command-working-directory` will store the file relative to this location, if not provided, the systems temporary file directory will be used. If `base64decode` is true, the incoming binary data will be base 64 decoded prior to storing it into the file. By default the corresponding file will be removed after the webhook exited.
2223
* `trigger-rule` - specifies the rule that will be evaluated in order to determine should the hook be triggered. Check [Hook rules page](Hook-Rules.md) to see the list of valid rules and their usage
2324
* `trigger-rule-mismatch-http-response-code` - specifies the HTTP status code to be returned when the trigger rule is not satisfied
25+
* `trigger-signature-soft-failures` - allow signature validation failures within Or rules; by default, signature failures are treated as errors.
2426

2527
## Examples
2628
Check out [Hook examples page](Hook-Examples.md) for more complex examples of hooks.

docs/Hook-Examples.md

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
1-
# Hook examples
2-
This page is still work in progress. Feel free to contribute!
1+
# Hook Examples
2+
3+
Hooks are defined in a hooks configuration file in either JSON or YAML format,
4+
although the examples on this page all use the JSON format.
5+
6+
🌱 This page is still a work in progress. Feel free to contribute!
7+
8+
### Table of Contents
9+
10+
* [Incoming Github webhook](#incoming-github-webhook)
11+
* [Incoming Bitbucket webhook](#incoming-bitbucket-webhook)
12+
* [Incoming Gitlab webhook](#incoming-gitlab-webhook)
13+
* [Incoming Gogs webhook](#incoming-gogs-webhook)
14+
* [Incoming Gitea webhook](#incoming-gitea-webhook)
15+
* [Slack slash command](#slack-slash-command)
16+
* [A simple webhook with a secret key in GET query](#a-simple-webhook-with-a-secret-key-in-get-query)
17+
* [JIRA Webhooks](#jira-webhooks)
18+
* [Pass File-to-command sample](#pass-file-to-command-sample)
19+
* [Incoming Scalr Webhook](#incoming-scalr-webhook)
20+
* [Travis CI webhook](#travis-ci-webhook)
21+
* [XML Payload](#xml-payload)
22+
* [Multipart Form Data](#multipart-form-data)
23+
* [Pass string arguments to command](#pass-string-arguments-to-command)
324

425
## Incoming Github webhook
526
```json
@@ -30,7 +51,7 @@ This page is still work in progress. Feel free to contribute!
3051
{
3152
"match":
3253
{
33-
"type": "payload-hash-sha1",
54+
"type": "payload-hmac-sha1",
3455
"secret": "mysecret",
3556
"parameter":
3657
{
@@ -150,7 +171,7 @@ Values in the request body can be accessed in the command or to the match rule b
150171
{
151172
"match":
152173
{
153-
"type": "payload-hash-sha256",
174+
"type": "payload-hmac-sha256",
154175
"secret": "mysecret",
155176
"parameter":
156177
{
@@ -425,6 +446,57 @@ Travis sends webhooks as `payload=<JSON_STRING>`, so the payload needs to be par
425446
]
426447
```
427448

449+
## JSON Array Payload
450+
451+
If the JSON payload is an array instead of an object, `webhook` will process the payload and place it into a "root" object.
452+
Therefore, references to payload values must begin with `root.`.
453+
454+
For example, given the following payload (taken from the Sendgrid Event Webhook documentation):
455+
```json
456+
[
457+
{
458+
"email": "[email protected]",
459+
"timestamp": 1513299569,
460+
"smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
461+
"event": "processed",
462+
"category": "cat facts",
463+
"sg_event_id": "sg_event_id",
464+
"sg_message_id": "sg_message_id"
465+
},
466+
{
467+
"email": "[email protected]",
468+
"timestamp": 1513299569,
469+
"smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
470+
"event": "deferred",
471+
"category": "cat facts",
472+
"sg_event_id": "sg_event_id",
473+
"sg_message_id": "sg_message_id",
474+
"response": "400 try again later",
475+
"attempt": "5"
476+
}
477+
]
478+
```
479+
480+
A reference to the second item in the array would look like this:
481+
```json
482+
[
483+
{
484+
"id": "sendgrid",
485+
"execute-command": "{{ .Hookecho }}",
486+
"trigger-rule": {
487+
"match": {
488+
"type": "value",
489+
"parameter": {
490+
"source": "payload",
491+
"name": "root.1.event"
492+
},
493+
"value": "deferred"
494+
}
495+
}
496+
}
497+
]
498+
```
499+
428500
## XML Payload
429501

430502
Given the following payload:
@@ -518,3 +590,34 @@ Content-Disposition: form-data; name="thumb"; filename="thumb.jpg"
518590
```
519591

520592
We key off of the `name` attribute in the `Content-Disposition` value.
593+
594+
## Pass string arguments to command
595+
596+
To pass simple string arguments to a command, use the `string` parameter source.
597+
The following example will pass two static string parameters ("-e 123123") to the
598+
`execute-command` before appending the `pusher.email` value from the payload:
599+
600+
```json
601+
[
602+
{
603+
"id": "webhook",
604+
"execute-command": "/home/adnan/redeploy-go-webhook.sh",
605+
"command-working-directory": "/home/adnan/go",
606+
"pass-arguments-to-command":
607+
[
608+
{
609+
"source": "string",
610+
"name": "-e"
611+
},
612+
{
613+
"source": "string",
614+
"name": "123123"
615+
},
616+
{
617+
"source": "payload",
618+
"name": "pusher.email"
619+
}
620+
]
621+
}
622+
]
623+
```

docs/Hook-Rules.md

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Hook rules
22

3+
### Table of Contents
4+
5+
* [And](#and)
6+
* [Or](#or)
7+
* [Not](#not)
8+
* [Multi-level](#multi-level)
9+
* [Match](#match)
10+
* [Match value](#match-value)
11+
* [Match regex](#match-regex)
12+
* [Match payload-hmac-sha1](#match-payload-hmac-sha1)
13+
* [Match payload-hmac-sha256](#match-payload-hmac-sha256)
14+
* [Match payload-hmac-sha512](#match-payload-hmac-sha512)
15+
* [Match Whitelisted IP range](#match-whitelisted-ip-range)
16+
* [Match scalr-signature](#match-scalr-signature)
17+
318
## And
419
*And rule* will evaluate to _true_, if and only if all of the sub rules evaluate to _true_.
520
```json
@@ -95,7 +110,7 @@
95110
"source": "header",
96111
"name": "X-Hub-Signature"
97112
},
98-
"type": "payload-hash-sha1",
113+
"type": "payload-hmac-sha1",
99114
"secret": "mysecret"
100115
}
101116
},
@@ -135,9 +150,7 @@
135150

136151
*Please note:* Due to technical reasons, _number_ and _boolean_ values in the _match rule_ must be wrapped around with a pair of quotes.
137152

138-
There are three different match rules:
139-
140-
### 1. Match value
153+
### Match value
141154
```json
142155
{
143156
"match":
@@ -153,7 +166,7 @@ There are three different match rules:
153166
}
154167
```
155168

156-
### 2. Match regex
169+
### Match regex
157170
For the regex syntax, check out <http://golang.org/pkg/regexp/syntax/>
158171
```json
159172
{
@@ -170,12 +183,13 @@ For the regex syntax, check out <http://golang.org/pkg/regexp/syntax/>
170183
}
171184
```
172185

173-
### 3. Match payload-hash-sha1
186+
### Match payload-hmac-sha1
187+
Validate the HMAC of the payload using the SHA1 hash and the given *secret*.
174188
```json
175189
{
176190
"match":
177191
{
178-
"type": "payload-hash-sha1",
192+
"type": "payload-hmac-sha1",
179193
"secret": "yoursecret",
180194
"parameter":
181195
{
@@ -193,12 +207,13 @@ will be tried unless a match is found. For example:
193207
X-Hub-Signature: sha1=the-first-signature,sha1=the-second-signature
194208
```
195209

196-
### 4. Match payload-hash-sha256
210+
### Match payload-hmac-sha256
211+
Validate the HMAC of the payload using the SHA256 hash and the given *secret*.
197212
```json
198213
{
199214
"match":
200215
{
201-
"type": "payload-hash-sha256",
216+
"type": "payload-hmac-sha256",
202217
"secret": "yoursecret",
203218
"parameter":
204219
{
@@ -216,12 +231,13 @@ will be tried unless a match is found. For example:
216231
X-Hub-Signature: sha256=the-first-signature,sha256=the-second-signature
217232
```
218233

219-
### 5. Match payload-hash-sha512
234+
### Match payload-hmac-sha512
235+
Validate the HMAC of the payload using the SHA512 hash and the given *secret*.
220236
```json
221237
{
222238
"match":
223239
{
224-
"type": "payload-hash-sha512",
240+
"type": "payload-hmac-sha512",
225241
"secret": "yoursecret",
226242
"parameter":
227243
{
@@ -239,7 +255,7 @@ will be tried unless a match is found. For example:
239255
X-Hub-Signature: sha512=the-first-signature,sha512=the-second-signature
240256
```
241257

242-
### 6. Match Whitelisted IP range
258+
### Match Whitelisted IP range
243259

244260
The IP can be IPv4- or IPv6-formatted, using [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_blocks). To match a single IP address only, use `/32`.
245261

@@ -253,7 +269,7 @@ The IP can be IPv4- or IPv6-formatted, using [CIDR notation](https://en.wikipedi
253269
}
254270
```
255271

256-
### 7. Match scalr-signature
272+
### Match scalr-signature
257273

258274
The trigger rule checks the scalr signature and also checks that the request was signed less than 5 minutes before it was received.
259275
A unqiue signing key is generated for each webhook endpoint URL you register in Scalr.
@@ -267,4 +283,4 @@ Given the time check make sure that NTP is enabled on both your Scalr and webhoo
267283
"secret": "Scalr-provided signing key"
268284
}
269285
}
270-
```
286+
```

0 commit comments

Comments
 (0)