From 125ba74fbf88d3ccd82b61a253a5a1f3deba759d Mon Sep 17 00:00:00 2001 From: Dan Schultzer Date: Sat, 4 Aug 2018 23:09:16 -0700 Subject: [PATCH] Update docs --- .../persistent_session/plug/base.ex | 3 +- lib/pow/config.ex | 5 --- lib/pow/ecto/context.ex | 33 ++++++++++++++- lib/pow/ecto/schema.ex | 9 ++-- lib/pow/extension/ecto/context/base.ex | 1 + lib/pow/extension/ecto/schema.ex | 4 +- lib/pow/extension/phoenix/router.ex | 3 ++ lib/pow/operations.ex | 2 +- lib/pow/phoenix/mailer/template.ex | 5 +++ lib/pow/phoenix/template.ex | 5 +++ lib/pow/plug.ex | 41 ++++++++++++++++++- lib/pow/uuid.ex | 4 ++ test/pow/operations_test.exs | 4 ++ test/pow/plug_test.exs | 2 +- test/pow/uuid_test.exs | 4 ++ 15 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 test/pow/operations_test.exs create mode 100644 test/pow/uuid_test.exs diff --git a/lib/extensions/persistent_session/plug/base.ex b/lib/extensions/persistent_session/plug/base.ex index 7aa68ce6..550b0d9d 100644 --- a/lib/extensions/persistent_session/plug/base.ex +++ b/lib/extensions/persistent_session/plug/base.ex @@ -2,7 +2,7 @@ defmodule PowPersistentSession.Plug.Base do @moduledoc """ Base module for setting up persistent session plugs. - See PowPersistentSession.Plug.Cookie for an implementation example. + See `PowPersistentSession.Plug.Cookie` for an implementation example. ## Configuration options @@ -21,6 +21,7 @@ defmodule PowPersistentSession.Plug.Base do @callback authenticate(Conn.t(), Config.t()) :: Conn.t() @callback create(Conn.t(), map(), Config.t()) :: Conn.t() + @doc false defmacro __using__(_opts) do quote do @behaviour unquote(__MODULE__) diff --git a/lib/pow/config.ex b/lib/pow/config.ex index c9e9cf22..94693b4b 100644 --- a/lib/pow/config.ex +++ b/lib/pow/config.ex @@ -7,11 +7,6 @@ defmodule Pow.Config do defexception [:message] end - @spec current_user_assigns_key(t()) :: atom() - def current_user_assigns_key(config) do - get(config, :current_user_assigns_key, :current_user) - end - @spec user_module(t()) :: atom() def user_module(config) do get(config, :user, nil) || raise_no_user_error() diff --git a/lib/pow/ecto/context.ex b/lib/pow/ecto/context.ex index bc1c7bfc..b4e2474e 100644 --- a/lib/pow/ecto/context.ex +++ b/lib/pow/ecto/context.ex @@ -46,6 +46,7 @@ defmodule Pow.Ecto.Context do @callback delete(user()) :: {:ok, user()} | {:error, Changeset.t()} @callback get_by(Keyword.t() | map()) :: user() | nil + @doc false defmacro __using__(config) do quote do @behaviour unquote(__MODULE__) @@ -82,6 +83,11 @@ defmodule Pow.Ecto.Context do end end + @doc """ + Finds a user based on the user id, and verifies the password on the user. + User schema module and repo module will be fetched from the config. The + user id field is fetched from the user schema module. + """ @spec authenticate(Config.t(), map()) :: user() | nil def authenticate(config, params) do user_mod = user_schema_mod(config) @@ -104,7 +110,8 @@ defmodule Pow.Ecto.Context do end @doc """ - Creates a new user. User struct will be fetched from repo. + Creates a new user. User schema module and repo module will be fetched from + config. """ @spec create(Config.t(), map()) :: {:ok, user()} | {:error, Changeset.t()} def create(config, params) do @@ -116,7 +123,8 @@ defmodule Pow.Ecto.Context do end @doc """ - updates a new user. User struct will be fetched from repo. + Updates the user. User schema module will be fetched from provided user and + repo will be fetched from the config. """ @spec update(Config.t(), user(), map()) :: {:ok, user()} | {:error, Changeset.t()} def update(config, user, params) do @@ -125,11 +133,18 @@ defmodule Pow.Ecto.Context do |> do_update(config) end + @doc """ + Deletes the user. Repo module will be fetched from the config. + """ @spec delete(Config.t(), user()) :: {:ok, user()} | {:error, Changeset.t()} def delete(config, user) do repo(config).delete(user) end + @doc """ + Retrieves an user by the provided clauses. User schema module and repo module + will be fetched from the config. + """ @spec get_by(Config.t(), Keyword.t() | map()) :: user() | nil def get_by(config, clauses) do user_mod = user_schema_mod(config) @@ -147,6 +162,10 @@ defmodule Pow.Ecto.Context do end end + @doc """ + Inserts a changeset to the database. If succesful, the returned row will be + reloaded from the database. + """ @spec do_insert(Changeset.t(), Config.t()) :: {:ok, user()} | {:error, Changeset.t()} def do_insert(changeset, config) do changeset @@ -154,6 +173,10 @@ defmodule Pow.Ecto.Context do |> reload_after_write(config) end + @doc """ + Updates a changeset in the database. If succesful, the returned row will be + reloaded from the database. + """ @spec do_update(Changeset.t(), Config.t()) :: {:ok, user()} | {:error, Changeset.t()} def do_update(changeset, config) do changeset @@ -170,11 +193,17 @@ defmodule Pow.Ecto.Context do {:ok, user} end + @doc """ + Retrieves the repo module from the config, or raises an exception. + """ @spec repo(Config.t()) :: atom() | no_return def repo(config) do Config.get(config, :repo, nil) || raise_no_repo_error() end + @doc """ + Retrieves the user schema module from the config, or raises an exception. + """ @spec user_schema_mod(Config.t()) :: atom() | no_return def user_schema_mod(config) do Config.get(config, :user, nil) || raise_no_user_error() diff --git a/lib/pow/ecto/schema.ex b/lib/pow/ecto/schema.ex index e1c0eb99..9787a8b1 100644 --- a/lib/pow/ecto/schema.ex +++ b/lib/pow/ecto/schema.ex @@ -41,6 +41,7 @@ defmodule Pow.Ecto.Schema do @callback changeset(Ecto.Schema.t() | Changeset.t(), map()) :: Changeset.t() @callback verify_password(Ecto.Schema.t(), binary()) :: boolean() + @doc false defmacro __using__(config) do quote do @behaviour unquote(__MODULE__) @@ -62,7 +63,6 @@ defmodule Pow.Ecto.Schema do @changeset_methods [:user_id_field_changeset, :password_changeset, :current_password_changeset] - @spec __pow_methods__() :: Macro.t() defmacro __pow_methods__ do quoted_changeset_methods = for method <- @changeset_methods do pow_method_name = String.to_atom("pow_#{method}") @@ -95,7 +95,10 @@ defmodule Pow.Ecto.Schema do end end - @spec pow_user_fields :: Macro.t() + @doc """ + A macro to add fields from the `@pow_fields` module attribute generated in + `__using__/1`. + """ defmacro pow_user_fields do quote do Enum.each(@pow_fields, fn @@ -108,7 +111,6 @@ defmodule Pow.Ecto.Schema do end end - @spec __register_fields__() :: Macro.t() defmacro __register_fields__ do quote do Module.register_attribute(__MODULE__, :pow_fields, accumulate: true) @@ -118,7 +120,6 @@ defmodule Pow.Ecto.Schema do end end - @spec __register_user_id_field__() :: Macro.t() defmacro __register_user_id_field__ do quote do @user_id_field unquote(__MODULE__).user_id_field(@pow_config) diff --git a/lib/pow/extension/ecto/context/base.ex b/lib/pow/extension/ecto/context/base.ex index 2f172400..ee4f8b71 100644 --- a/lib/pow/extension/ecto/context/base.ex +++ b/lib/pow/extension/ecto/context/base.ex @@ -17,6 +17,7 @@ defmodule Pow.Extension.Ecto.Context.Base do """ alias Pow.Ecto.Context + @doc false defmacro __using__(_opts) do quote do def user_schema_mod(config), do: Context.user_schema_mod(config) diff --git a/lib/pow/extension/ecto/schema.ex b/lib/pow/extension/ecto/schema.ex index a3d7196e..e4034773 100644 --- a/lib/pow/extension/ecto/schema.ex +++ b/lib/pow/extension/ecto/schema.ex @@ -32,6 +32,7 @@ defmodule Pow.Extension.Ecto.Schema do defexception [:message] end + @doc false defmacro __using__(config) do quote do @pow_extension_config Config.merge(@pow_config, unquote(config)) @@ -42,7 +43,6 @@ defmodule Pow.Extension.Ecto.Schema do end end - @spec __register_extension_fields__() :: Macro.t() defmacro __register_extension_fields__ do quote do config = Module.get_attribute(__MODULE__, :pow_extension_config) @@ -54,7 +54,6 @@ defmodule Pow.Extension.Ecto.Schema do end end - @spec __pow_extension_methods__() :: Macro.t() defmacro __pow_extension_methods__ do quote do @spec pow_extension_changeset(Changeset.t(), map()) :: Changeset.t() @@ -64,7 +63,6 @@ defmodule Pow.Extension.Ecto.Schema do end end - @spec __register_after_compile_validation__() :: Macro.t() defmacro __register_after_compile_validation__ do quote do def validate_after_compilation!(env, _bytecode) do diff --git a/lib/pow/extension/phoenix/router.ex b/lib/pow/extension/phoenix/router.ex index 85e7c125..6b3dc18f 100644 --- a/lib/pow/extension/phoenix/router.ex +++ b/lib/pow/extension/phoenix/router.ex @@ -40,6 +40,9 @@ defmodule Pow.Extension.Phoenix.Router do end end + @doc """ + A macro that will call the router method in all extension router modules. + """ defmacro pow_extension_routes do router_methods = Module.concat(__CALLER__.module, RouterMethods).methods() diff --git a/lib/pow/operations.ex b/lib/pow/operations.ex index f30fd41d..26ec9463 100644 --- a/lib/pow/operations.ex +++ b/lib/pow/operations.ex @@ -11,7 +11,7 @@ defmodule Pow.Operations do |> Config.user_module() |> struct() - changeset(config, user, params) + changeset(config, user, params) end @spec changeset(Config.t(), map(), map()) :: map() diff --git a/lib/pow/phoenix/mailer/template.ex b/lib/pow/phoenix/mailer/template.ex index ffe0f5ae..d81aa862 100644 --- a/lib/pow/phoenix/mailer/template.ex +++ b/lib/pow/phoenix/mailer/template.ex @@ -18,6 +18,11 @@ defmodule Pow.Phoenix.Mailer.Template do end end + @doc """ + A macro that will compile a mailer template from the provided binaries, and + add the compiled versions to `render/2` methods. The `text/1` and `html/1` + outputs the binaries. + """ @spec template(atom(), binary(), binary(), binary()) :: Macro.t() defmacro template(action, subject, text, html) do quoted_text = EEx.compile_string(text) diff --git a/lib/pow/phoenix/template.ex b/lib/pow/phoenix/template.ex index 32ac0bf5..67243850 100644 --- a/lib/pow/phoenix/template.ex +++ b/lib/pow/phoenix/template.ex @@ -24,6 +24,11 @@ defmodule Pow.Phoenix.Template do end end + @doc """ + A macro that will compile a phoenix view template from the provided binary, + and add the compiled version to a `render/2` method. The `html/1` method + outputs the binary. + """ @spec template(atom(), atom(), binary() | {atom(), any()}) :: Macro.t() defmacro template(action, :html, content) do content = EEx.eval_string(content) diff --git a/lib/pow/plug.ex b/lib/pow/plug.ex index 03a3221f..8b3a5934 100644 --- a/lib/pow/plug.ex +++ b/lib/pow/plug.ex @@ -12,30 +12,50 @@ defmodule Pow.Plug do current_user(conn, fetch_config(conn)) end + @doc """ + Get the current authenticated user. + """ @spec current_user(Conn.t(), Config.t()) :: map() | nil def current_user(%{assigns: assigns}, config) do - key = Config.current_user_assigns_key(config) + key = current_user_assigns_key(config) Map.get(assigns, key, nil) end + @doc """ + Assign an authenticated user to the connection. + """ @spec assign_current_user(Conn.t(), any(), Config.t()) :: Conn.t() def assign_current_user(conn, user, config) do - key = Config.current_user_assigns_key(config) + key = current_user_assigns_key(config) Conn.assign(conn, key, user) end + defp current_user_assigns_key(config) do + Config.get(config, :current_user_assigns_key, :current_user) + end + + @doc """ + Put the provided config as a private key in the connection. + """ @spec put_config(Conn.t(), Config.t()) :: Conn.t() def put_config(conn, config) do Conn.put_private(conn, @private_config_key, config) end + @doc """ + Fetch config from the connection. It'll raise an error if configuration + hasn't been set as a private key. + """ @spec fetch_config(Conn.t()) :: Config.t() | no_return def fetch_config(%{private: private}) do private[@private_config_key] || no_config_error() end + @doc """ + Authenticates a user. If successful, a new session will be created. + """ @spec authenticate_user(Conn.t(), map()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} | no_return def authenticate_user(conn, params) do config = fetch_config(conn) @@ -49,6 +69,9 @@ defmodule Pow.Plug do |> maybe_create_auth(conn, config) end + @doc """ + Clears the user authentication from the session. + """ @spec clear_authenticated_user(Conn.t()) :: {:ok, Conn.t()} | no_return def clear_authenticated_user(conn) do config = fetch_config(conn) @@ -56,6 +79,9 @@ defmodule Pow.Plug do {:ok, get_mod(config).do_delete(conn)} end + @doc """ + Creates a changeset from the current authenticated user. + """ @spec change_user(Conn.t(), map()) :: map() def change_user(conn, params \\ %{}) do config = fetch_config(conn) @@ -66,6 +92,9 @@ defmodule Pow.Plug do end end + @doc """ + Creates a new user. If successful, a new session will be created. + """ @spec create_user(Conn.t(), map()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} | no_return def create_user(conn, params) do config = fetch_config(conn) @@ -75,6 +104,10 @@ defmodule Pow.Plug do |> maybe_create_auth(conn, config) end + @doc """ + Updates the current authenticated user. If successful, a new session will be + created. + """ @spec update_user(Conn.t(), map()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} | no_return def update_user(conn, params) do config = fetch_config(conn) @@ -85,6 +118,10 @@ defmodule Pow.Plug do |> maybe_create_auth(conn, config) end + @doc """ + Deletes the current authenticated user. If successful, the user + authentication will be cleared from the session. + """ @spec delete_user(Conn.t()) :: {:ok, map(), Conn.t()} | {:error, map(), Conn.t()} | no_return def delete_user(conn) do config = fetch_config(conn) diff --git a/lib/pow/uuid.ex b/lib/pow/uuid.ex index 1cb08e6e..8d8c4382 100644 --- a/lib/pow/uuid.ex +++ b/lib/pow/uuid.ex @@ -6,6 +6,10 @@ defmodule Pow.UUID do https://github.com/elixir-ecto/ecto/blob/v2.2.10/lib/ecto/uuid.ex#L1, and is under Apache 2 license. """ + + @doc """ + Generates a UUID binary. + """ @spec generate :: binary() def generate, do: encode(bingenerate()) diff --git a/test/pow/operations_test.exs b/test/pow/operations_test.exs new file mode 100644 index 00000000..3cc51fff --- /dev/null +++ b/test/pow/operations_test.exs @@ -0,0 +1,4 @@ +defmodule Pow.OperationsTest do + use ExUnit.Case + doctest Pow.Operations +end diff --git a/test/pow/plug_test.exs b/test/pow/plug_test.exs index a7239588..2ff1d4f1 100644 --- a/test/pow/plug_test.exs +++ b/test/pow/plug_test.exs @@ -40,7 +40,7 @@ defmodule Pow.PlugTest do assert is_nil(Plug.current_user(conn, @admin_config)) end - test "assign_current_user/2" do + test "assign_current_user/3" do user = %{id: 1} conn = %Conn{assigns: %{}} assert Plug.assign_current_user(conn, %{id: 1}, @default_config) == %Conn{assigns: %{current_user: user}} diff --git a/test/pow/uuid_test.exs b/test/pow/uuid_test.exs new file mode 100644 index 00000000..1b5374b9 --- /dev/null +++ b/test/pow/uuid_test.exs @@ -0,0 +1,4 @@ +defmodule Pow.UUIDTest do + use ExUnit.Case + doctest Pow.UUID +end