Packages
openmaize
1.0.0-beta.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/onetime_pass.ex
defmodule Openmaize.OnetimePass do
@moduledoc """
Module to handle one-time passwords for use in two factor authentication.
There are two options:
* db_module - the module that is used to query the database
* in most cases, this will be generated by `mix openmaize.gen.ectodb` and will be called MyApp.OpenmaizeEcto
* if you implement your own database module, it needs to implement the Openmaize.Database behaviour
* add_jwt - the function used to add the JSON Web Token to the response
* the default is `&OpenmaizeJWT.Plug.add_token/5`
"""
import Plug.Conn
alias Comeonin.Otp
@behaviour Plug
def init(opts) do
{Keyword.get(opts, :db_module),
Keyword.pop(opts, :add_jwt, &OpenmaizeJWT.Plug.add_token/5)}
end
@doc """
Handle the one-time password POST request.
If the one-time password check is successful, a JSON Web Token will be added
to the conn, either in a cookie or in the body of the response. The conn
is then returned.
"""
def call(_, {nil, _}) do
raise ArgumentError, "You need to set the db_module value for Openmaize.OnetimePass"
end
def call(%Plug.Conn{params: %{"user" => user_params}} = conn, {db_module, {add_jwt, opts}}) do
{storage, uniq, id, override_exp} = get_params(user_params)
db_module.find_user_byid(id)
|> check_key(user_params, opts)
|> handle_auth(conn, {storage, uniq, add_jwt, override_exp})
end
defp get_params(%{"storage" => storage, "uniq" => uniq, "id" => id} = user_params) do
override_exp = Map.get user_params, "override_exp"
{String.to_atom(storage), String.to_atom(uniq), id,
override_exp && String.to_integer(override_exp)}
end
defp check_key(user, %{"hotp" => hotp}, opts) do
{user, Otp.check_hotp(hotp, user.otp_secret, opts)}
end
defp check_key(user, %{"totp" => totp}, opts) do
{user, Otp.check_totp(totp, user.otp_secret, opts)}
end
defp handle_auth({_, false}, conn, _opts) do
put_private(conn, :openmaize_error, "Invalid credentials")
end
defp handle_auth({user, last}, conn, {storage, uniq, add_jwt, override_exp}) do
conn
|> put_private(:openmaize_info, last)
|> add_jwt.(user, storage, uniq, override_exp)
end
end