Packages
pow
1.0.19
1.0.39
1.0.38
1.0.37
1.0.36
1.0.35
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.1.0-rc.1
0.1.0-alpha.8
0.1.0-alpha.7
retired
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha
Robust user authentication solution
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/pow/phoenix/controllers/controller.ex
defmodule Pow.Phoenix.Controller do
@moduledoc """
Used with Pow Phoenix controllers to handle messages, routes and callbacks.
## Usage
defmodule MyPowExtension.Phoenix.MyController do
use Pow.Phoenix.Controller
def process_new(conn, _params) do
{:ok, :response, conn}
end
def respond_new({:ok, :response, conn}) do
render(conn, "new.html")
end
end
## Configuration options
* `:messages_backend` - See `Pow.Phoenix.Messages` for more.
* `:routes_backend` - See `Pow.Phoenix.Routes` for more.
* `:controller_callbacks` - See
`Pow.Extension.Phoenix.ControllerCallbacks` for more.
"""
alias Plug.Conn
alias Pow.Config
alias Pow.Phoenix.{Messages, PlugErrorHandler, Routes, ViewHelpers}
alias Pow.Plug
@doc false
defmacro __using__(config) do
quote do
use Phoenix.Controller,
namespace: Pow.Phoenix
import unquote(__MODULE__), only: [require_authenticated: 2, require_not_authenticated: 2, put_no_cache_header: 2]
plug :pow_layout, unquote(config)
@doc """
See `Pow.Phoenix.Controller.action/3` for more.
"""
@spec action(Conn.t(), Keyword.t()) :: Conn.t()
def action(conn, _opts) do
unquote(__MODULE__).action(__MODULE__, conn, conn.params)
end
defp pow_layout(conn, _config), do: ViewHelpers.layout(conn)
unquote(__MODULE__).__define_helper_methods__()
end
end
@doc false
defmacro __define_helper_methods__ do
quote do
@doc """
See `Pow.Phoenix.Controller.messages/2` for more.
`Pow.Phoenix.Messages` is used as fallback.
"""
@spec messages(Conn.t()) :: atom()
def messages(conn) do
unquote(__MODULE__).messages(conn, Messages)
end
@doc """
See `Pow.Phoenix.Controller.routes/2` for more.
`Pow.Phoenix.Routes` is used as fallback.
"""
@spec routes(Conn.t()) :: atom()
def routes(conn) do
unquote(__MODULE__).routes(conn, Routes)
end
defoverridable messages: 1, routes: 1
end
end
@doc """
Handles the controller action call.
If a `:controller_callbacks` module has been set in the configuration,
then `before_process` and `before_respond` will be called on this module
on all actions.
"""
@spec action(atom(), Conn.t(), map()) :: Conn.t()
def action(controller, %{private: private} = conn, params) do
action = private.phoenix_action
config = Plug.fetch_config(conn)
callbacks = Config.get(config, :controller_callbacks)
conn
|> maybe_callback(callbacks, :before_process, controller, action, config)
|> process_action(controller, action, params)
|> maybe_callback(callbacks, :before_respond, controller, action, config)
|> respond_action(controller, action)
end
defp process_action(conn, controller, action, params) do
apply(controller, String.to_atom("process_#{action}"), [conn, params])
end
defp respond_action({:halt, conn}, _controller, _action), do: conn
defp respond_action(results, controller, action) do
apply(controller, String.to_atom("respond_#{action}"), [results])
end
defp maybe_callback(results, nil, _hook, _controller, _action, _config), do: results
defp maybe_callback(results, callbacks, hook, controller, action, config) do
apply(callbacks, hook, [controller, action, results, config])
end
@doc """
Fetches messages backend from configuration, or use fallback.
"""
@spec messages(Conn.t(), atom()) :: atom()
def messages(conn, fallback) do
conn
|> Plug.fetch_config()
|> Config.get(:messages_backend, fallback)
end
@doc """
Fetches routes backend from configuration, or use fallback.
"""
@spec routes(Conn.t(), atom()) :: atom()
def routes(conn, fallback) do
conn
|> Plug.fetch_config()
|> Config.get(:routes_backend, fallback)
end
@spec route_helper(atom()) :: binary()
def route_helper(plug) do
as = Phoenix.Naming.resource_name(plug, "Controller")
[base | _rest] = Module.split(plug)
base = Macro.underscore(base)
"#{base}_#{as}"
end
@doc """
Ensures that user has been authenticated.
`Pow.Phoenix.PlugErrorHandler` is used as error handler. See
`Pow.Plug.RequireAuthenticated` for more.
"""
@spec require_authenticated(Conn.t(), Keyword.t()) :: Conn.t()
def require_authenticated(conn, _opts) do
opts = Plug.RequireAuthenticated.init(error_handler: PlugErrorHandler)
Plug.RequireAuthenticated.call(conn, opts)
end
@doc """
Ensures that user hasn't been authenticated.
`Pow.Phoenix.PlugErrorHandler` is used as error handler. See
`Pow.Plug.RequireNotAuthenticated` for more.
"""
@spec require_not_authenticated(Conn.t(), Keyword.t()) :: Conn.t()
def require_not_authenticated(conn, _opts) do
opts = Plug.RequireNotAuthenticated.init(error_handler: PlugErrorHandler)
Plug.RequireNotAuthenticated.call(conn, opts)
end
@default_cache_control_header Conn.get_resp_header(struct(Conn), "cache-control")
@no_cache_control_header "no-cache, no-store, must-revalidate"
@doc """
Ensures that the page can't be cached in browser.
This will add a "cache-control" header with
"no-cache, no-store, must-revalidate" if the cache control header hasn't
been changed from the default value in the `Plug.Conn` struct.
"""
@spec put_no_cache_header(Conn.t(), Keyword.t()) :: Conn.t()
def put_no_cache_header(conn, _opts) do
conn
|> Conn.get_resp_header("cache-control")
|> case do
@default_cache_control_header -> Conn.put_resp_header(conn, "cache-control", @no_cache_control_header)
_any -> conn
end
end
end