Current section

Files

Jump to
guard lib doorman controller registration.ex
Raw

lib/doorman/controller/registration.ex

defmodule Doorman.Controller.Registration do
require Logger
use Phoenix.Controller
alias Doorman.{Repo, User, Authenticator, Device, Mailer, Users}
import Doorman.Controller, only: [send_error: 2, send_error: 3]
def call(conn, opts) do
try do
super(conn, opts)
rescue
error -> send_error(conn, error, :internal_server_error)
end
end
defp check_user(conn, user) do
case user do
nil ->
conn
|> put_status(:not_found)
|> json(%{ok: false})
_ ->
conn
|> put_status(:ok)
|> json(%{ok: true})
end
end
def check_account(conn, %{"username" => username}) do
check_user(conn, Users.get_by_username(username))
end
def check_account(conn, %{"email" => email}) do
check_user(conn, Users.get_by(email: String.downcase(email)))
end
def check_account(conn, %{"mobile" => mobile}) do
check_user(conn, Users.get_by(mobile: mobile))
end
def list_all_users(conn, _params) do
users = Doorman.Repo.all(Doorman.User)
conn
|> json(%{data: users})
end
def create(conn, %{"user" => user}) do
case Authenticator.create_and_confirm_user(user) do
{:ok, user, jwt, extra} ->
conn
|> put_status(:created)
|> json(%{user: user, jwt: jwt, extra: extra})
{:error, error, _} ->
send_error(conn, error)
end
end
def confirm(conn, %{"confirmation_token" => token, "user_id" => user_id}) do
user = Users.get!(user_id)
case Authenticator.confirm_email(user, token) do
{:ok, user} ->
json conn, %{user: user}
{:error, error, _} ->
send_error(conn, error)
end
end
def send_password_reset(conn, %{"username" => username}) do
send_password_reset(conn, Users.get_by_username(username), username)
end
def send_password_reset(conn, %{"email" => email}) do
send_password_reset(conn, Users.get_by_email(email), email)
end
def send_password_reset(conn, user, name) do
case user do
nil ->
Logger.debug "Failed to send link to unknown user #{name}"
json conn, %{ok: true} #Do not allow people to probe which users are on the system
user ->
case Authenticator.generate_password_reset_claim(user) do
{:ok, token, _} ->
{:ok, pin, user} = Authenticator.generate_pin(user)
Mailer.send_reset_password_link(user, token, pin)
json conn, %{ok: true}
_ ->
Logger.debug "Failed to generate claim for #{name}"
json conn, %{ok: true} #Do not allow people to probe which users are on the system
end
end
end
def send_login_link(conn, %{"username" => username}) do
send_login_link(conn, Users.get_by_username(username), username)
end
def send_login_link(conn, user=%{"email" => email}) do
existing_user = Users.get_by_email(email)
if existing_user do
send_login_link(conn, existing_user, email)
else
create(conn, %{"user" => user})
end
end
def send_login_link(conn, user, name) do
case user do
nil ->
Logger.debug "Failed to send link to unknown user #{name}"
json conn, %{ok: true} #Do not allow people to probe which users are on the system
user ->
case Authenticator.generate_login_claim(user) do
{:ok, token, _} ->
{:ok, pin, user} = Authenticator.generate_pin(user)
Mailer.send_login_link(user, token, pin)
json conn, %{ok: true, user: user}
_ ->
Logger.debug "Failed to generate claim for #{name}"
json conn, %{ok: true} #Do not allow people to probe which users are on the system
end
end
end
def update_password(conn, %{"username" => username, "pin" => pin, "new_password" => new_password, "new_password_confirmation" => new_password_confirmation}) do
user = Users.get_by_username(username)
case User.check_pin(user, pin) do
true ->
case Users.update_user(user, %{"password" => new_password, "password_confirmation" => new_password_confirmation}) do
{:ok, _user} ->
Authenticator.clear_pin(user)
json(conn, %{ok: true})
{:error, error, _changeset} ->
send_error(conn, error)
end
false ->
conn
|> put_status(:precondition_failed)
|> json(%{ok: false})
end
end
defp find_device(token, platform) do
Repo.get_by(Device, token: token, platform: platform)
end
def register_device(conn, %{"device" => %{"platform" => platform, "token" => token} = device}) do
user = Authenticator.current_user conn
Logger.debug "Registering '#{token}'"
existing = find_device(token, platform)
model = if existing == nil do
%Device{}
else
existing
end
device = if user != nil do
Map.put(device, "user_id", user.id)
else
device
end
changeset = Device.changeset(model, device)
res = if existing == nil do
Repo.insert(changeset)
else
Repo.update(changeset)
end
case res do
{:ok, updated_device} ->
conn
|> put_status(:created)
|> json(%{device: updated_device})
{:error, changeset} ->
send_error(conn, Repo.changeset_errors(changeset))
end
end
def unregister_device(conn, %{"platform" => platform, "token" => token}) do
user = Authenticator.current_user conn
existing = find_device(token, platform)
if (existing == nil) do
conn
|> put_status(:not_found)
|> json(%{device: nil})
else
if existing.user_id == nil || existing.user_id == user.id do
case Repo.delete(existing) do
{:ok, model} ->
json conn, %{ok: true, device: model}
{:error, changeset} ->
send_error(conn, Repo.changeset_errors(changeset))
end
else
conn
|> put_status(:not_found)
|> json(%{device: nil})
end
end
end
end