https://github.com/ickk/hook
A simple webserver intended to respond to webhook events.
https://github.com/ickk/hook
Last synced: about 1 month ago
JSON representation
A simple webserver intended to respond to webhook events.
- Host: GitHub
- URL: https://github.com/ickk/hook
- Owner: ickk
- Created: 2021-04-25T12:24:10.000Z (about 5 years ago)
- Default Branch: dev
- Last Pushed: 2021-05-15T09:09:55.000Z (about 5 years ago)
- Last Synced: 2025-01-08T18:45:26.366Z (over 1 year ago)
- Language: Rust
- Homepage:
- Size: 11.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Hook
====
Hook is a simple webserver intended to respond to webhook events.
Currently Hook has a Git module that will respond to GitHub Webhook *push*
events. One use-case is to host the source code of a website in a git
repository and use Hook to allow easily updating the live website by pushing
changes to the repository.
Other kinds of webhooks responses should be straight-forward to add without
changing the overall architecture of Hook.
**Table of Contents**
- [Configuration](#configuration)
- [Modules](#modules)
- [Git](#git)
- [Configuration](#configuration-1)
- [Build Instructions](#build-instructions)
- [Architecture](#architecture)
- [Git](#git-1)
### Configuration ###
Hook reads all it's configuration values from
[RON](https://github.com/ron-rs/ron) formatted configuration files found in a
`config/` folder relative to the current working directory when running the
Hook binary: `$PWD/config/*.ron`.
Hook itself takes some configuration options:
`config/hook.ron`:
```ron
(
address: "localhost",
port: 7267,
url_base: "/hook",
modules: [
Git (mount_path: "/git"),
],
)
```
* `address` and `port` are the interface to serve Hook at.
* `url_base` should be set if Hook is being served at a path by a reverse proxy
instead of from the site root. The base path will be prepended to any
internally generated urls to correct for the reverse proxy.
* `modules` takes a list of Hook modules to enable, and each module takes a
`mount_path` that it will be served under.
Configuration of individual modules is covered in each [Modules](#modules)
subsection.
Modules
-------
### Git ###
The Git module will respond to [Github webhook events](https://docs.github.com/en/developers/webhooks-and-events/about-webhooks>`).
The *push* event is currently supported with a corresponding *pull* action,
allowing Hook to automatically pull changes into a git repository when new
changes are available on the remote. Basic validation of the event is done;
HTTP headers are checked, the HMAC signature of the event is verified.
To use the Git module, it must first be enabled in the `config/hook.ron`
configuration file:
#### Configuration ####
`config/hook.ron`:
```ron
(
modules: [
Git (mount_path: "/git"),
],
)
```
Then the Git module can be configured with the `config/git.ron` configuration
file:
`config/git.ron`:
```ron
(
policies: [
( service: Github,
repo_name: "user_a/repository_1",
secret: "super_secret_74830921478320147830214783021478187",
event: Push,
action: Pull (path: "/home/user_a/repository_1",
remote: "origin",
branch: "main",
ssh_key_path: "config/repository_1.id_rsa") ),
( service: Github,
repo_name: "user_b/repository_2",
secret: "meta_secret_748930216874830214316248923017483201",
event: Push,
action: Pull (path: "/home/user_b/repository_2",
remote: "origin",
branch: "prod",
ssh_key_path: "config/repository_2.id_rsa") ),
],
)
```
`policies` is a list of Policy definitions for which events to respond to and
what actions to take. For each Policy:
* `service` takes the `Github` class.
* `repo_name` defines the *full repository name*. i.e. the
user_name/repository_name.
* `secret` is the shared secret that is used to cryptographically sign
webhooks. It should be a long random string of characters.
* `event` is the type of event to respond to. It takes the `Push` class to
respond to Github *push* webhook events.
* `action` is the type of action to take in response to the event. The `action`
field takes a `Pull` class with it's own fields:
* `path`: The path of the git repository on the local disk.
* `remote`,`branch`: The git *remote* and *branch* to pull.
* `ssh_key_path`: The path to an ssh private key file authorized to pull from
the specified remote.
Note: On Github you can add *read-only* ssh keys from the *Deploy keys* section
on a repository's settings page. It is recommended to use a Deploy key with
unattended services such as Hook.
Build Instructions
------------------
Dependencies:
* [Rust/Cargo](https://rustup.rs),
* GNUMake.
Build with:
```sh
make build
```
Run with:
```sh
./hook
```
Note: First setup [configuration](#configuration) files.
Architecture
------------
Hook is a [Rocket](https://rocket.rs/)-based web application. Rust modules form
collections of end-points related to a single service. Each module provides a
`pub fn routes() -> Vec` implementation that returns all of the relevant
Rocket routes.
A selection of modules are enabled in the `hook.ron` configuration file and
then `main.rs` mounts the specified modules to Hook's request router.
### Git ###
The service and event type are pulled from the request's HTTP headers (In this
context *service* refers to Github, Gitlab, etc. and *event* refers to pull,
push, issue, etc.)
Multiple request handlers may implement the `/` end-point, with each
handler targeting a different service/event combination to handle their
service-specific quirks.