Skip to content

Instantly share code, notes, and snippets.

@maartenvanvliet
Created December 11, 2018 15:34
Show Gist options
  • Save maartenvanvliet/5f3df0bc740dd481c2cfeb9901e79987 to your computer and use it in GitHub Desktop.
Save maartenvanvliet/5f3df0bc740dd481c2cfeb9901e79987 to your computer and use it in GitHub Desktop.
mandrill webhook
defmodule SimplePlug.Handle do
@behaviour Plug
@behaviour PlugWebhook
def init(options) do
# initialize options
options
end
def call(conn, _opts) do
Jason.decode(conn.params["mandrill_events"]) |> IO.inspect()
conn |> Plug.Conn.send_resp(200, "ok") |> Plug.Conn.halt()
end
def verify_signature(conn, body, _opts) do
url = ""
secret = ""
signature = build_signature(url, body, secret)
[expected] = Plug.Conn.get_req_header(conn, "x-mandrill-signature")
if Plug.Crypto.secure_compare(signature, expected) do
conn
else
conn
|> Plug.Conn.send_resp(400, "bad signature")
|> Plug.Conn.halt()
end
end
defp build_signature(url, body, secret) do
signed_data =
body
|> parse_body
|> Map.to_list()
|> Enum.sort_by(fn {key, _value} -> key end)
|> Enum.reduce(url, fn {key, value}, acc ->
acc <> key <> value
end)
:crypto.hmac(:sha, secret, signed_data)
|> Base.encode64()
end
defp parse_body(body) do
Plug.Conn.Utils.validate_utf8!(body, Plug.Parsers.BadEncodingError, "urlencoded body")
Plug.Conn.Query.decode(body)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment