Packages
openmaize
2.3.0
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 three options:
* repo - the name of the repo
* the default is MyApp.Repo - using the name of the project
* user_model - the name of the user model
* the default is MyApp.User - using the name of the project
* 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
The easiest way to use this plug is to run the
`mix openmaize.gen.phoenixauth` command, which will create
all the files you need.
If you do not want to run the above command, you need to create the
following files:
* controllers/session_controller.ex
* views/session_view.ex
* templates/session/new.html.eex
In the `new.html.eex` file, make sure that the form uses `session` to
identify the user.
You also need to add the following command to the `web/router.ex` file:
resources "/sessions", SessionController, only: [:new, :create, :delete]
Add the following command to the `session_controller.ex` file:
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, :repo, Openmaize.Utils.default_repo),
Keyword.get(opts, :user_model, Openmaize.Utils.default_user_model),
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,
{repo, user_model, uniq_id}) do
{uniq, user_id, password} = get_params(user_params, uniq_id)
repo.get_by(user_model, [{uniq, user_id}])
|> 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