Packages
openmaize
2.1.4
3.0.1
retired
3.0.0
2.9.0
2.8.0
2.7.0
2.6.0
2.5.1
2.5.0
2.4.0
2.3.2
2.3.1
2.3.0
2.2.0
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
1.0.1
1.0.0
1.0.0-beta.5
1.0.0-beta.4
1.0.0-beta.3
1.0.0-beta.2
1.0.0-beta.1
1.0.0-beta.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.8.1
0.8.0
0.7.5
0.7.4
0.7.2
0.7.1
0.7.0
0.6.7
0.6.6
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
Authentication library for Elixir using Plug
Current section
Files
Jump to
Current section
Files
lib/openmaize/login.ex
defmodule Openmaize.Login do
@moduledoc """
Module to handle login.
There are two options:
* db_module - the module that is used to query the database
* the default is MyApp.OpenmaizeEcto - the name of the module generated by `mix openmaize.gen.ectodb`
* if you implement your own database module, it needs to implement the Openmaize.Database behaviour
* unique_id - the name which is used to identify the user (in the database)
* the default is `:username`
* this can also be a function which checks the user input and returns an atom
* see the Openmaize.Login.Name module for some example functions
## Examples with Phoenix
If you have used the `mix openmaize.gen.phoenixauth` command to generate
an Authorize module, the `login_user` function in the examples below
will simply call the `Authorize.handle_login` function.
In the `web/router.ex` file, add the following line (you can use
a different controller and route):
post "/login", PageController, :login_user
And then in the `page_controller.ex` file, add:
plug Openmaize.Login when action in [:login_user]
If you want to use `email` to identify the user:
plug Openmaize.Login, [unique_id: :email] when action in [:login_user]
If you want to use `email` or `username` to identify the user (allowing the
end user a choice):
plug Openmaize.Login, [unique_id: &Openmaize.Login.Name.email_username/1] when action in [:login_user]
"""
@behaviour Plug
import Plug.Conn
alias Openmaize.Config
def init(opts) do
{Keyword.get(opts, :db_module, Openmaize.Utils.default_db),
Keyword.get(opts, :unique_id, :username)}
end
@doc """
Handle the login POST request.
If the login is successful and `otp_required: true` is not in the
user model, the user will be added to the `conn.private.openmaize_user`
value. You can then use the information in the user model to add
the user to the session.
If the login is unsuccessful, an error message will be added to
`conn.private.openmaize_error`.
## Two factor authentication
If `otp_required: true` is in the user model and if the login is
successful, `conn.private.openmaize_otpdata` will be set to the
user id.
## User email confirmation
Before checking the password, the user struct will be checked for a
`confirmed_at` value. If it is set to nil, an error message will be
added to `conn.private.openmaize_error`.
"""
def call(%Plug.Conn{params: %{"session" => user_params}} = conn,
{db_module, uniq_id}) do
{uniq, user_id, password} = get_params(user_params, uniq_id)
db_module.find_user(user_id, uniq)
|> check_pass(password, Config.hash_name)
|> handle_auth(conn)
end
def call(%Plug.Conn{params: %{"user" => user_params}} = conn,
{db_module, uniq_id}) do
IO.puts :stderr, "warning: setting the login form parameters to 'user' is deprecated, " <>
"please use 'session' instead"
{uniq, user_id, password} = get_params(user_params, uniq_id)
db_module.find_user(user_id, uniq)
|> check_pass(password, Config.hash_name)
|> handle_auth(conn)
end
defp get_params(%{"password" => password} = user_params, uniq) when is_atom(uniq) do
{uniq, Map.get(user_params, to_string(uniq)), password}
end
defp get_params(user_params, uniq_func), do: uniq_func.(user_params)
defp check_pass(nil, _, _), do: Config.crypto_mod.dummy_checkpw
defp check_pass(%{confirmed_at: nil}, _, _),
do: {:error, "You have to confirm your email address before continuing."}
defp check_pass(user, password, hash_name) do
%{^hash_name => hash} = user
Config.crypto_mod.checkpw(password, hash) and {:ok, user}
end
defp handle_auth({:ok, %{id: id, otp_required: true}}, conn) do
put_private(conn, :openmaize_otpdata, id)
end
defp handle_auth({:ok, user}, conn) do
put_private(conn, :openmaize_user, user)
end
defp handle_auth({:error, message}, conn) do
put_private(conn, :openmaize_error, message)
end
defp handle_auth(_, conn) do
put_private(conn, :openmaize_error, "Invalid credentials")
end
end