Current section

Files

Jump to
doorman lib login session.ex
Raw

lib/login/session.ex

defmodule Doorman.Login.Session do
@moduledoc """
Provides functions for logging in users and finding the current user for use
in the Doorman plug.
## Example
The following example assumes you have a configured `MyApp.User` module with
using `Doorman.Auth.Bcrypt`.
```elixir
defmodule MyApp.Controller do
use MyApp.Web
import Doorman.Login.Session, only: [login: 2]
def create(conn, %{"email" => email, "password" => password}) do
if user = MyApp.Repo.get_by(MyApp.User, email: email) do
if MyApp.User.authenticate(user, password) do
conn
|> login(user) # Sets :user_id on conn's session
|> put_flash(:notice, "Successfully logged in")
|> redirect(to: "/")
else
conn
|> put_flash(:error, "Password was incorrect")
|> render "new.html"
end
else
conn
|> put_flash(:error, "No account for provided email found")
|> render "new.html"
end
end
end
```
"""
@behaviour Doorman.Login
@doc """
Returns a `Plug.Conn` with `:user_id` put into the session by using the `id`
field of `user`.
"""
@spec login(Plug.Conn.t, struct) :: Plug.Conn.t
def login(conn, user) do
conn
|> Plug.Conn.put_session(:user_id, user.id)
end
@doc """
Returns either an error, or a user based on passed in `conn`.
The configured `repo` and `user_module` options are used to find a user
if `:user_id` is present in the session of `conn`.
"""
@spec find_user(Plug.Conn.t) :: {:ok, struct} | {:error, String.t}
def find_user(conn) do
id = Plug.Conn.get_session(conn, :user_id)
repo = Application.get_env(:doorman, :repo)
user_module = Application.get_env(:doorman, :user_module)
if id == nil do
{:error, errors[:nil_user_id]}
else
case repo.get(user_module, id) do
nil -> {:error, errors[:no_user]}
user -> {:ok, user}
end
end
end
@doc """
Returns the errors that `find_user` can return.
Can be used to pattern match against errors for custom behavior. See source
for available errors.
"""
@spec errors :: %{nil_user_id: String.t, no_user: String.t}
def errors do
%{
nil_user_id: "Session's user_id can't be nil",
no_user: "Could not find user"
}
end
end