Packages
pow
0.1.0-alpha.1
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/ecto/context.ex
defmodule Pow.Ecto.Context do
@moduledoc """
Handles pow users context for user.
## Usage
This module will be used by pow by default. If you
wish to have control over context methods, you can
do configure `lib/my_project/users/users.ex`
the following way:
defmodule MyApp.Users do
use Pow.Ecto.Context,
repo: MyApp.Repo,
user: MyApp.Users.User
def create(params) do
pow_create(params)
end
end
Remember to update configuration with `users_context: MyApp.Users`.
The following Pow methods can be accessed:
* `pow_authenticate/1`
* `pow_create/1`
* `pow_update/2`
* `pow_delete/1`
* `pow_get_by/1`
## Configuration options
* `:repo` the ecto repo module
* `:user` the user schema module
"""
alias Ecto.Changeset
alias Pow.Config
alias Pow.Ecto.Schema
@type user :: map()
@callback authenticate(map()) :: user() | nil
@callback create(map()) :: {:ok, user()} | {:error, Changeset.t()}
@callback update(user(), map()) :: {:ok, user()} | {:error, Changeset.t()}
@callback delete(user()) :: {:ok, user()} | {:error, Changeset.t()}
@callback get_by(Keyword.t() | map()) :: user() | nil
defmacro __using__(config) do
quote do
@behaviour unquote(__MODULE__)
@pow_config unquote(config)
def authenticate(params), do: pow_authenticate(params)
def create(params), do: pow_create(params)
def update(user, params), do: pow_update(user, params)
def delete(user), do: pow_delete(user)
def get_by(clauses), do: pow_get_by(clauses)
def pow_authenticate(params) do
unquote(__MODULE__).authenticate(@pow_config, params)
end
def pow_create(params) do
unquote(__MODULE__).create(@pow_config, params)
end
def pow_update(user, params) do
unquote(__MODULE__).update(@pow_config, user, params)
end
def pow_delete(user) do
unquote(__MODULE__).delete(@pow_config, user)
end
def pow_get_by(clauses) do
unquote(__MODULE__).get_by(@pow_config, clauses)
end
defoverridable unquote(__MODULE__)
end
end
@spec authenticate(Config.t(), map()) :: user() | nil
def authenticate(config, params) do
user_mod = user_schema_mod(config)
user_id_field = Schema.user_id_field(user_mod)
login_value = params[Atom.to_string(user_id_field)]
password = params["password"]
config
|> get_by([{user_id_field, login_value}])
|> maybe_verify_password(password)
end
defp maybe_verify_password(nil, _password),
do: nil
defp maybe_verify_password(user, password) do
case user.__struct__.verify_password(user, password) do
true -> user
_ -> nil
end
end
@spec create(Config.t(), map()) :: {:ok, user()} | {:error, Changeset.t()}
def create(config, params) do
user_mod = user_schema_mod(config)
user_mod
|> struct()
|> user_mod.changeset(params)
|> repo(config).insert()
end
@spec update(Config.t(), user(), map()) :: {:ok, user()} | {:error, Changeset.t()}
def update(config, user, params) do
user
|> user.__struct__.changeset(params)
|> repo(config).update()
end
@spec delete(Config.t(), user()) :: {:ok, user()} | {:error, Changeset.t()}
def delete(config, user) do
repo(config).delete(user)
end
@spec get_by(Config.t(), Keyword.t() | map()) :: user() | nil
def get_by(config, clauses) do
user_mod = user_schema_mod(config)
clauses = normalize_user_id_field_value(user_mod, clauses)
repo(config).get_by(user_mod, clauses)
end
defp normalize_user_id_field_value(user_mod, clauses) do
user_id_field = Schema.user_id_field(user_mod)
Enum.map clauses, fn
{^user_id_field, value} -> {user_id_field, Schema.normalize_user_id_field_value(value)}
any -> any
end
end
@spec repo(Config.t()) :: atom() | no_return
def repo(config) do
Config.get(config, :repo, nil) || raise_no_repo_error()
end
@spec user_schema_mod(Config.t()) :: atom() | no_return
def user_schema_mod(config) do
Config.get(config, :user, nil) || raise_no_user_error()
end
@spec raise_no_repo_error :: no_return
defp raise_no_repo_error do
Config.raise_error("No :repo configuration option found for users context module.")
end
@spec raise_no_user_error :: no_return
defp raise_no_user_error do
Config.raise_error("No :user configuration option found for user schema module.")
end
end