defmodule AuthToken.Plug do
@moduledoc """
Plugs for AuthToken
## Examples
import AuthToken.Plug
pipeline :auth do
plug :verify_token
end
scope "/protected/route", MyApp do
pipe_through :auth
resources "/", DoNastyStuffController
end
"""
import Plug.Conn
@doc """
Checks authentication token from authorization header.
If this fails, send 401 with message "error": "auth_fail" or "error": "timeout" as JSON
"""
@spec verify_token(Plug.Conn.t, any) :: Plug.Conn.t
def verify_token(conn, _options) do
token_header = get_req_header(conn, "authorization") |> List.first
crypto_token = if token_header, do: Regex.run(~r/(bearer\:? )?(.+)/, token_header) |> List.last
case AuthToken.decrypt_token(crypto_token) do
{:error} ->
conn
|> put_resp_content_type("application/json")
|> send_resp(:unauthorized, "{\"error\": \"auth_fail\"}")
|> halt
{:ok, token} ->
conn |> check_token_time(token)
end
end
@spec check_token_time(Plug.Conn.t, map) :: Plug.Conn.t
defp check_token_time(conn, token) do
cond do
AuthToken.is_timedout?(token) ->
conn
|> put_resp_content_type("application/json")
|> send_resp(:unauthorized, "{\"error\": \"timeout\"}")
|> halt
AuthToken.needs_refresh?(token) ->
conn
|> put_resp_content_type("application/json")
|> send_resp(:unauthorized, "{\"error\": \"needs_refresh\"}")
|> halt
true ->
conn
end
end
end