Current section
Files
Jump to
Current section
Files
lib/cipher/validate_plug.ex
defmodule Cipher.ValidatePlug do
import Plug.Conn
@moduledoc """
Plug that uses Cipher to validate signatures and halt with 401 when not valid.
Use like this:
```
# ...
plug Cipher.ValidatePlug
# ...
```
Or pass an `error_callback` to be able to do things before halting with 401:
```
# ...
plug Cipher.ValidatePlug, error_callback: &MyApp.my_validation_error_logging_callback/2
# ...
def my_validation_error_logging_callback(conn, error) do
# Do something with the `error` message and the `conn`, just like:
Logger.info(error)
# right before the plug halts with 401
end
# ...
```
"""
def init(opts), do: opts
def call(conn, opts \\ []) do
url = "#{conn.request_path}?#{conn.query_string}"
m = conn.method
validation = cond do
m in ["POST", "PUT"] ->
# here body is already parsed by `Plug.Parsers`
# so we need the signature to be done using `Cipher.sign_url_from_mapped_body`
Cipher.validate_signed_body(url, conn.body_params)
true ->
Cipher.validate_signed_url(url)
end
case validation do
{:ok, _} -> conn
{:error, error} ->
# call user fun if given
if opts[:error_callback], do: opts[:error_callback].(conn, error)
conn
|> send_resp(401, "unauthorized")
|> halt
end
end
end