559c889f1b
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
149 lines
4.4 KiB
Elixir
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
|