defmodule PowLockout.Plug do @moduledoc """ Plug helper methods. """ alias Plug.Conn alias Pow.Plug alias PowLockout.Ecto.Context require IEx @doc """ Check if the current user is locked out. """ @spec locked_out?(Conn.t()) :: boolean() def locked_out?(conn) do config = Plug.fetch_config(conn) conn |> Plug.current_user() |> Context.locked_out?(config) end @doc """ Get the user belonging to the id field. """ @spec user_for_attempts(Conn.t()) :: map() | nil def user_for_attempts(conn) do config = Plug.fetch_config(conn) id_field = Pow.Ecto.Schema.user_id_field(config) id_value = to_string(conn.params["user"][to_string(id_field)]) Pow.Ecto.Context.get_by([{id_field, id_value}], config) end @doc """ Unlocks the user found by the provided unlock token. """ @spec unlock_account(Conn.t(), binary()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} def unlock_account(conn, token) do config = Plug.fetch_config(conn) token |> Context.get_by_unlock_token(config) |> maybe_unlock_account(conn, config) end defp maybe_unlock_account(nil, conn, _config) do {:error, nil, conn} end defp maybe_unlock_account(user, conn, config) do user |> Context.unlock_account(config) |> case do {:error, changeset} -> {:error, changeset, conn} {:ok, user} -> {:ok, user, conn} end end @doc """ Increments the failed attempts counter and possibly locks the user out. """ @spec fail_attempt(Conn.t(), map()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} def fail_attempt(conn, user) do config = Plug.fetch_config(conn) Context.fail_attempt(user, config) |> case do {:error, changeset} -> {:error, changeset, conn} {:ok, user} -> {:ok, user, conn} end end @doc """ Resets the failed attempts counter to 0. """ @spec succeed_attempt(Conn.t(), map()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} def succeed_attempt(conn, user) do config = Plug.fetch_config(conn) Context.succeed_attempt(user, config) |> case do {:error, changeset} -> {:error, changeset, conn} {:ok, user} -> {:ok, user, conn} end end end