defmodule Redirect do @moduledoc """ Simple plug for redirecting to Kanta UI """ import Plug.Conn alias Phoenix.Controller def init(opts) do cond do opts[:to] -> nil opts[:external] -> nil true -> raise ArgumentError, "expected :to or :external option" end unless opts[:type] do raise ArgumentError, "expected :type option" end case opts[:type] do :permanent -> nil :temporary -> nil _ -> raise ArgumentError, "expected :type option to be set to :permanent or :temporary" end opts |> Keyword.put( :preserve_query_string, Keyword.get(opts[:opts], :preserve_query_string, false) ) |> Keyword.delete(:opts) end def call(conn, opts) do conn |> put_redirect_status(opts[:type]) |> do_redirect(opts) |> halt() end defp put_redirect_status(conn, :permanent), do: put_status(conn, 301) defp put_redirect_status(conn, :temporary), do: put_status(conn, 302) defp do_redirect(conn, opts) do query_string = if opts[:preserve_query_string] && conn.params != %{} do "?#{URI.encode_query(conn.params)}" else "" end cond do to = opts[:to] -> Controller.redirect(conn, to: to <> query_string) external = opts[:external] -> Controller.redirect(conn, external: external <> query_string) end end defmacro redirect(path, to, type, opts \\ []) defmacro redirect(path, "http" <> _ = to, type, opts) do quote do match(:*, unquote(path), unquote(__MODULE__), external: unquote(to), type: unquote(type), opts: unquote(opts) ) end end defmacro redirect(path, to, type, opts) do quote do match(:*, unquote(path), unquote(__MODULE__), to: unquote(to), type: unquote(type), opts: unquote(opts) ) end end end