mobilizon/lib/mobilizon_web/controllers/user_controller.ex

149 lines
4.4 KiB
Elixir

defmodule MobilizonWeb.UserController do
@moduledoc """
Controller for Users
"""
use MobilizonWeb, :controller
alias Mobilizon.Actors
alias Mobilizon.Actors.User
alias Mobilizon.Repo
alias Mobilizon.Actors.Service.{Activation, ResetPassword}
action_fallback(MobilizonWeb.FallbackController)
def index(conn, _params) do
users = Actors.list_users_with_actors()
render(conn, "index.json", users: users)
end
def register(conn, %{"username" => username, "email" => email, "password" => password}) do
with {:ok, %User{} = user} <-
Actors.register(%{email: email, password: password, username: username}) do
Activation.send_confirmation_email(user, "locale")
conn
|> put_status(:created)
|> render("confirmation.json", %{user: user})
end
end
def validate(conn, %{"token" => token}) do
with {:ok, %User{} = user} <- Activation.check_confirmation_token(token) do
{:ok, token, _claims} = MobilizonWeb.Guardian.encode_and_sign(user)
conn
|> put_resp_header("location", user_path(conn, :show_current_actor))
|> render("show_with_token.json", %{user: user, token: token})
else
{:error, msg} ->
conn
|> put_status(:not_found)
|> json(%{"error" => msg})
end
end
@time_before_resend 3600
def resend_confirmation(conn, %{"email" => email}) do
with {:ok, %User{} = user} <- Actors.find_by_email(email),
false <- is_nil(user.confirmation_token),
true <-
Timex.before?(
Timex.shift(user.confirmation_sent_at, seconds: @time_before_resend),
DateTime.utc_now()
) do
Activation.resend_confirmation_email(user)
render(conn, "confirmation.json", %{user: user})
else
{:error, :not_found} ->
conn
|> put_status(:not_found)
|> json(%{"error" => "Unable to find an user with this email"})
_ ->
conn
|> put_status(:not_found)
|> json(%{
"error" =>
"Unable to resend the validation token. Please wait a while before you can ask for resending token"
})
end
end
def send_reset_password(conn, %{"email" => email}) do
with {:ok, %User{} = user} <- Actors.find_by_email(email),
{:ok, _} <- ResetPassword.send_password_reset_email(user) do
render(conn, "password_reset.json", %{user: user})
else
{:error, nil} ->
conn
|> put_status(:not_found)
|> json(%{"errors" => "Unable to find an user with this email"})
{:error, :email_too_soon} ->
conn
|> put_status(:not_found)
|> json(%{"errors" => "You requested a new reset password too early"})
end
end
def reset_password(conn, %{"password" => password, "token" => token}) do
with {:ok, %User{} = user} <- ResetPassword.check_reset_password_token(password, token) do
{:ok, token, _claims} = MobilizonWeb.Guardian.encode_and_sign(user)
render(conn, "show_with_token.json", %{user: user, token: token})
else
{:error, :invalid_token} ->
conn
|> put_status(:not_found)
|> json(%{"errors" => %{"token" => ["Wrong token for password reset"]}})
{:error, %Ecto.Changeset{} = changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MobilizonWeb.ChangesetView, "error.json", changeset: changeset)
end
end
def show_current_actor(conn, _params) do
user =
conn
|> Guardian.Plug.current_resource()
|> Repo.preload(:actors)
render(conn, "show_simple.json", user: user)
end
# defp handle_changeset_errors(errors) do
# errors
# |> Enum.map(fn {field, detail} ->
# "#{field} " <> render_detail(detail)
# end)
# |> Enum.join()
# end
# defp render_detail({message, values}) do
# Enum.reduce(values, message, fn {k, v}, acc ->
# String.replace(acc, "%{#{k}}", to_string(v))
# end)
# end
# defp render_detail(message) do
# message
# end
def update(conn, %{"id" => id, "user" => user_params}) do
user = Actors.get_user!(id)
with {:ok, %User{} = user} <- Actors.update_user(user, user_params) do
render(conn, "show.json", user: user)
end
end
def delete(conn, %{"id" => id}) do
user = Actors.get_user!(id)
with {:ok, %User{}} <- Actors.delete_user(user) do
send_resp(conn, :no_content, "")
end
end
end