Introduce basic user and profile management

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2020-06-11 19:13:21 +02:00
parent da4ea84baf
commit beb35a09c6
51 changed files with 1808 additions and 254 deletions

View File

@@ -25,6 +25,7 @@ defmodule Mobilizon.Users.User do
reset_password_token: String.t(),
locale: String.t(),
default_actor: Actor.t(),
disabled: boolean(),
actors: [Actor.t()],
feed_tokens: [FeedToken.t()]
}
@@ -40,7 +41,8 @@ defmodule Mobilizon.Users.User do
:reset_password_sent_at,
:reset_password_token,
:locale,
:unconfirmed_email
:unconfirmed_email,
:disabled
]
@attrs @required_attrs ++ @optional_attrs
@@ -64,6 +66,7 @@ defmodule Mobilizon.Users.User do
field(:reset_password_token, :string)
field(:unconfirmed_email, :string)
field(:locale, :string, default: "en")
field(:disabled, :boolean, default: false)
belongs_to(:default_actor, Actor)
has_many(:actors, Actor)
@@ -91,6 +94,13 @@ defmodule Mobilizon.Users.User do
end
end
def delete_changeset(%__MODULE__{} = user) do
user
|> change()
|> put_change(:disabled, true)
|> put_change(:default_actor_id, nil)
end
@doc false
@spec registration_changeset(t, map) :: Ecto.Changeset.t()
def registration_changeset(%__MODULE__{} = user, attrs) do

View File

@@ -8,8 +8,10 @@ defmodule Mobilizon.Users do
import Mobilizon.Storage.Ecto
alias Ecto.Multi
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.FeedToken
alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.{Setting, User}
@@ -46,7 +48,8 @@ defmodule Mobilizon.Users do
@spec get_user!(integer | String.t()) :: User.t()
def get_user!(id), do: Repo.get!(User, id)
@spec get_user(integer | String.t()) :: User.t() | nil
@spec get_user(integer | String.t() | nil) :: User.t() | nil
def get_user(nil), do: nil
def get_user(id), do: Repo.get(User, id)
def get_user_with_settings!(id) do
@@ -105,11 +108,35 @@ defmodule Mobilizon.Users do
end
end
@delete_user_default_options [reserve_email: true]
@doc """
Deletes an user.
"""
@spec delete_user(User.t()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def delete_user(%User{} = user), do: Repo.delete(user)
def delete_user(%User{id: user_id} = user, options \\ @delete_user_default_options) do
delete_user_options = Keyword.merge(@delete_user_default_options, options)
multi =
Multi.new()
|> Multi.delete_all(:settings, from(s in Setting, where: s.user_id == ^user_id))
|> Multi.delete_all(:feed_tokens, from(f in FeedToken, where: f.user_id == ^user_id))
multi =
if Keyword.get(delete_user_options, :reserve_email, true) do
Multi.update(multi, :user, User.delete_changeset(user))
else
Multi.delete(multi, :user, user)
end
case Repo.transaction(multi) do
{:ok, %{user: %User{} = user}} ->
{:ok, user}
{:error, remove, error, _} when remove in [:settings, :feed_tokens] ->
{:error, error}
end
end
@doc """
Get an user with its actors
@@ -196,12 +223,22 @@ defmodule Mobilizon.Users do
@doc """
Returns the list of users.
"""
@spec list_users(integer | nil, integer | nil, atom | nil, atom | nil) :: [User.t()]
def list_users(page \\ nil, limit \\ nil, sort \\ nil, direction \\ nil) do
@spec list_users(String.t(), integer | nil, integer | nil, atom | nil, atom | nil) :: Page.t()
def list_users(email \\ "", page \\ nil, limit \\ nil, sort \\ nil, direction \\ nil)
def list_users("", page, limit, sort, direction) do
User
|> Page.paginate(page, limit)
|> sort(sort, direction)
|> Repo.all()
|> preload([u], [:actors, :feed_tokens, :settings, :default_actor])
|> Page.build_page(page, limit)
end
def list_users(email, page, limit, sort, direction) do
User
|> where([u], ilike(u.email, ^"%#{email}%"))
|> sort(sort, direction)
|> preload([u], [:actors, :feed_tokens, :settings, :default_actor])
|> Page.build_page(page, limit)
end
@doc """