defmodule PotionIngredients.Plugs.AppToken do alias Plug.Conn def get_user(conn, opts) do secret = get_secret(opts) type_of_validation = get_validation_type(opts) try do signer = Joken.Signer.create("HS256", secret) headers = conn.req_headers {"app_token", app_token} = get_app_token(headers) app_token |> case do nil -> Conn.resp(conn, :forbidden, Poison.encode!(%{msg: "invalid.token", code: 009})) |> Conn.put_resp_content_type("application/json") |> Conn.halt() token -> get_user_from_token(token, signer, type_of_validation) end |> case do nil -> Conn.resp(conn, :forbidden, Poison.encode!(%{msg: "invalid.token", code: 009})) |> Conn.put_resp_content_type("application/json") |> Conn.halt() open_token -> Conn.put_req_header(conn, "app_token", Poison.encode!(open_token)) |> Conn.put_req_header("original_app_token", app_token) end rescue _ -> Conn.resp(conn, :forbidden, Poison.encode!(%{msg: "invalid.token", code: 009})) |> Conn.put_resp_content_type("application/json") |> Conn.halt() end end def get_app_token(headers) do Enum.find(headers, fn {key, _header} -> key == "app_token" end) end defp get_secret(opts) do try do secret = get_opt!(opts, :secret) secret rescue _ -> nil end end defp get_opt!(opts, opt) do found = Enum.find(opts, fn o -> {key, _} = o key == opt end) case found do {_key, value} -> value _ -> raise(:not_found) end end defp get_validation_type(opts) do try do check = get_opt!(opts, :check) check rescue _ -> :validate end end defp get_user_from_token(token, signer, validation_type) do case validation_type do :validate -> PotionIngredients.Utils.Token.verify_and_validate(token, signer) |> case do {:ok, decoded} -> decoded _ -> nil end _ -> PotionIngredients.Utils.Token.verify(token, signer) |> case do {:ok, decoded} -> decoded _ -> nil end end end end