Skip to content

Instantly share code, notes, and snippets.

@ruevaughn
Created January 9, 2017 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruevaughn/17895cad012be369768ded5c6adbe88e to your computer and use it in GitHub Desktop.
Save ruevaughn/17895cad012be369768ded5c6adbe88e to your computer and use it in GitHub Desktop.
defmodule Rumbl.Auth do
import Plug.Conn
import Comeonin.Bcrypt, only: [checkpw: 2, dummy_checkpw: 0]
def init(opts) do
Keyword.fetch!(opts, :repo)
end
def call(conn, repo) do
user_id = get_session(conn, :user_id)
cond do
user = conn.assigns[:current_user] ->
conn
user = user_id && repo.get(Rumbl.User, user_id)
assign(conn, :current_user, user)
true ->
assign(conn, :current_user, nil)
end
end
def login(conn, user) do
conn
|> assign(:current_user, user)
|> put_session(:user_id, user.id)
|> configure_session(renew: true)
end
def login_by_username_and_pass(conn, username, given_pass, opts) do
repo = Keyword.fetch!(opts, :repo)
user = repo.get_by(Rumbl.User, username: username)
cond do
user && checkpw(given_pass, user.password_hash) ->
{:ok, login(conn, user)}
user ->
{:error, :unauthorized, conn}
true ->
# When a user isn’t found, we use comeonin’s dummy_checkpw() function to simulate a password check with variable timing. This hardens our authentication layer against timing attacks
dummy_checkpw()
{:error, :not_found, conn}
end
end
def logout(conn) do
configure_session(conn, drop: true)
end
import Phoenix.Controller
alias Rumbl.Router.Helpers
def authenticate_user(conn, _opts) do
if conn.assigns.current_user do
conn
else
conn
|> put_flash(:error, "You must be logged in to access that page")
|> redirect(to: Helpers.page_path(conn, :index))
|> halt()
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment