Current section
Files
Jump to
Current section
Files
lib/gh_webhook_plug.ex
defmodule GhWebhookPlug do
import Plug.Conn
require Logger
def init(options) do
options
end
@doc """
Verifies secret and calls a handler with the webhook payload
"""
def call(conn, options) do
path = get_config(options, :path)
case conn.request_path do
^path ->
secret = get_config(options, :secret)
{module, function} = get_config(options, :action)
{:ok, payload, _conn} = read_body(conn)
[signature_in_header] = get_req_header(conn, "x-hub-signature")
if verify_signature(payload, secret, signature_in_header) do
apply(module, function, [conn, payload])
conn |> send_resp(200, "OK") |> halt()
else
conn |> send_resp(403, "Forbidden") |> halt()
end
_ -> conn
end
end
defp verify_signature(payload, secret, signature_in_header) do
signature = "sha1=" <> (:crypto.hmac(:sha, secret, payload) |> Base.encode16(case: :lower))
Plug.Crypto.secure_compare(signature, signature_in_header)
end
defp get_config(options, key) do
options[key] || get_config(key)
end
defp get_config(key) do
case Application.get_env(:gh_webhook_plug, key) do
nil ->
Logger.warn "GhWebhookPlug config key #{inspect key} is not configured."
""
val -> val
end
end
end