forked from potsda.mn/mobilizon
Extract User from Actors context
Mobilizon.Actors.User -> Mobilizon.Users.User Also Mobilizon.Actors.Service now become Mobilizon.User.Service And Mobilizon.Users and Mobilizon.UsersTest is introduced. Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
625d0d37d5
commit
c689406114
|
@ -5,15 +5,16 @@ defmodule Mix.Tasks.Mobilizon.CreateBot do
|
||||||
|
|
||||||
use Mix.Task
|
use Mix.Task
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
|
alias Mobilizon.Users
|
||||||
alias Mobilizon.Actors.Bot
|
alias Mobilizon.Actors.Bot
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Users.User
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@shortdoc "Register user"
|
@shortdoc "Register user"
|
||||||
def run([email, name, summary, type, url]) do
|
def run([email, name, summary, type, url]) do
|
||||||
Mix.Task.run("app.start")
|
Mix.Task.run("app.start")
|
||||||
|
|
||||||
with {:ok, %User{} = user} <- Actors.get_user_by_email(email, true),
|
with {:ok, %User{} = user} <- Users.get_user_by_email(email, true),
|
||||||
actor <- Actors.register_bot_account(%{name: name, summary: summary}),
|
actor <- Actors.register_bot_account(%{name: name, summary: summary}),
|
||||||
{:ok, %Bot{} = bot} <-
|
{:ok, %Bot{} = bot} <-
|
||||||
Actors.create_bot(%{
|
Actors.create_bot(%{
|
||||||
|
|
|
@ -22,7 +22,8 @@ defmodule Mobilizon.Actors.Actor do
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.{Actor, User, Follower, Member}
|
alias Mobilizon.Users.User
|
||||||
|
alias Mobilizon.Actors.{Actor, Follower, Member}
|
||||||
alias Mobilizon.Events.Event
|
alias Mobilizon.Events.Event
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
|
@ -8,7 +8,8 @@ defmodule Mobilizon.Actors do
|
||||||
|
|
||||||
alias Mobilizon.Repo
|
alias Mobilizon.Repo
|
||||||
|
|
||||||
alias Mobilizon.Actors.{Actor, Bot, Member, Follower, User}
|
alias Mobilizon.Actors.{Actor, Bot, Member, Follower}
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
alias Mobilizon.Service.ActivityPub
|
alias Mobilizon.Service.ActivityPub
|
||||||
# import Exgravatar
|
# import Exgravatar
|
||||||
|
@ -56,33 +57,6 @@ defmodule Mobilizon.Actors do
|
||||||
Repo.get!(Actor, id)
|
Repo.get!(Actor, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Returns the associated actor for an user, either the default set one or the first found
|
|
||||||
"""
|
|
||||||
@spec get_actor_for_user(Mobilizon.Actors.User.t()) :: Mobilizon.Actors.Actor.t()
|
|
||||||
def get_actor_for_user(%Mobilizon.Actors.User{} = user) do
|
|
||||||
case Repo.one(
|
|
||||||
from(a in Actor,
|
|
||||||
join: u in User,
|
|
||||||
on: u.default_actor_id == a.id,
|
|
||||||
where: u.id == ^user.id
|
|
||||||
)
|
|
||||||
) do
|
|
||||||
nil ->
|
|
||||||
case user |> get_actors_for_user() do
|
|
||||||
[] -> nil
|
|
||||||
actors -> hd(actors)
|
|
||||||
end
|
|
||||||
|
|
||||||
actor ->
|
|
||||||
actor
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_actors_for_user(%User{id: user_id}) do
|
|
||||||
Repo.all(from(a in Actor, where: a.user_id == ^user_id))
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec get_actor_with_everything(integer()) :: Ecto.Query
|
@spec get_actor_with_everything(integer()) :: Ecto.Query
|
||||||
defp do_get_actor_with_everything(id) do
|
defp do_get_actor_with_everything(id) do
|
||||||
from(a in Actor, where: a.id == ^id, preload: [:organized_events, :followers, :followings])
|
from(a in Actor, where: a.id == ^id, preload: [:organized_events, :followers, :followings])
|
||||||
|
@ -145,13 +119,6 @@ defmodule Mobilizon.Actors do
|
||||||
|> Repo.update()
|
|> Repo.update()
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_user_default_actor(user_id, actor_id) do
|
|
||||||
with from(u in User, where: u.id == ^user_id, update: [set: [default_actor_id: ^actor_id]])
|
|
||||||
|> Repo.update_all([]) do
|
|
||||||
Repo.get!(User, user_id) |> Repo.preload([:default_actor])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Deletes a Actor.
|
Deletes a Actor.
|
||||||
|
|
||||||
|
@ -255,34 +222,6 @@ defmodule Mobilizon.Actors do
|
||||||
Repo.delete!(group)
|
Repo.delete!(group)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias Mobilizon.Actors.User
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Returns the list of users.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> list_users()
|
|
||||||
[%Mobilizon.Actors.User{}]
|
|
||||||
|
|
||||||
"""
|
|
||||||
def list_users(page \\ nil, limit \\ nil, sort \\ nil, direction \\ nil) do
|
|
||||||
Repo.all(
|
|
||||||
User
|
|
||||||
|> paginate(page, limit)
|
|
||||||
|> sort(sort, direction)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def count_users() do
|
|
||||||
Repo.one(
|
|
||||||
from(
|
|
||||||
u in User,
|
|
||||||
select: count(u.id)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def insert_or_update_actor(data, preload \\ false) do
|
def insert_or_update_actor(data, preload \\ false) do
|
||||||
cs = Actor.remote_actor_creation(data)
|
cs = Actor.remote_actor_creation(data)
|
||||||
|
|
||||||
|
@ -313,52 +252,6 @@ defmodule Mobilizon.Actors do
|
||||||
# update_and_set_cache(cs)
|
# update_and_set_cache(cs)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Gets a single user.
|
|
||||||
|
|
||||||
Raises `Ecto.NoResultsError` if the User does not exist.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> get_user!(123)
|
|
||||||
%Mobilizon.Actors.User{}
|
|
||||||
|
|
||||||
iex> get_user!(456)
|
|
||||||
** (Ecto.NoResultsError)
|
|
||||||
|
|
||||||
"""
|
|
||||||
def get_user!(id), do: Repo.get!(User, id)
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Get an user with it's actors
|
|
||||||
|
|
||||||
Raises `Ecto.NoResultsError` if the User does not exist.
|
|
||||||
"""
|
|
||||||
@spec get_user_with_actors!(integer()) :: User.t()
|
|
||||||
def get_user_with_actors!(id) do
|
|
||||||
user = Repo.get!(User, id)
|
|
||||||
Repo.preload(user, [:actors, :default_actor])
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Get user with it's actors by ID
|
|
||||||
"""
|
|
||||||
@spec get_user_with_actors(integer()) :: User.t()
|
|
||||||
def get_user_with_actors(id) do
|
|
||||||
case Repo.get(User, id) do
|
|
||||||
nil ->
|
|
||||||
{:error, "User with ID #{id} not found"}
|
|
||||||
|
|
||||||
user ->
|
|
||||||
user =
|
|
||||||
user
|
|
||||||
|> Repo.preload([:actors, :default_actor])
|
|
||||||
|> Map.put(:actors, get_actors_for_user(user))
|
|
||||||
|
|
||||||
{:ok, user}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get an actor by it's URL (ActivityPub ID). The `:preload` option allows preloading the Followers relation.
|
Get an actor by it's URL (ActivityPub ID). The `:preload` option allows preloading the Followers relation.
|
||||||
|
|
||||||
|
@ -596,22 +489,6 @@ defmodule Mobilizon.Actors do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Authenticate user
|
|
||||||
"""
|
|
||||||
def authenticate(%{user: user, password: password}) do
|
|
||||||
# Does password match the one stored in the database?
|
|
||||||
case Argon2.verify_pass(password, user.password_hash) do
|
|
||||||
true ->
|
|
||||||
# Yes, create and return the token
|
|
||||||
MobilizonWeb.Guardian.encode_and_sign(user)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
# No, return an error
|
|
||||||
{:error, :unauthorized}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Create a new RSA key
|
Create a new RSA key
|
||||||
"""
|
"""
|
||||||
|
@ -668,136 +545,6 @@ defmodule Mobilizon.Actors do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Creates a user.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> create_user(%{email: "test@test.tld"})
|
|
||||||
{:ok, %Mobilizon.Actors.User{}}
|
|
||||||
|
|
||||||
iex> create_user(%{email: "not an email"})
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def create_user(attrs \\ %{}) do
|
|
||||||
%User{}
|
|
||||||
|> User.registration_changeset(attrs)
|
|
||||||
|> Repo.insert()
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Gets an user by it's email
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> get_user_by_email("test@test.tld", true)
|
|
||||||
{:ok, %Mobilizon.Actors.User{}}
|
|
||||||
|
|
||||||
iex> get_user_by_email("test@notfound.tld", false)
|
|
||||||
{:error, :user_not_found}
|
|
||||||
"""
|
|
||||||
def get_user_by_email(email, activated \\ nil) do
|
|
||||||
query =
|
|
||||||
case activated do
|
|
||||||
nil ->
|
|
||||||
from(u in User, where: u.email == ^email, preload: :default_actor)
|
|
||||||
|
|
||||||
true ->
|
|
||||||
from(u in User,
|
|
||||||
where: u.email == ^email and not is_nil(u.confirmed_at),
|
|
||||||
preload: :default_actor
|
|
||||||
)
|
|
||||||
|
|
||||||
false ->
|
|
||||||
from(u in User,
|
|
||||||
where: u.email == ^email and is_nil(u.confirmed_at),
|
|
||||||
preload: :default_actor
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
case Repo.one(query) do
|
|
||||||
nil -> {:error, :user_not_found}
|
|
||||||
user -> {:ok, user}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Get an user by it's activation token
|
|
||||||
"""
|
|
||||||
@spec get_user_by_activation_token(String.t()) :: Actor.t()
|
|
||||||
def get_user_by_activation_token(token) do
|
|
||||||
Repo.one(
|
|
||||||
from(u in User,
|
|
||||||
where: u.confirmation_token == ^token,
|
|
||||||
preload: [:default_actor]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Get an user by it's reset password token
|
|
||||||
"""
|
|
||||||
@spec get_user_by_reset_password_token(String.t()) :: Actor.t()
|
|
||||||
def get_user_by_reset_password_token(token) do
|
|
||||||
Repo.one(
|
|
||||||
from(u in User,
|
|
||||||
where: u.reset_password_token == ^token,
|
|
||||||
preload: [:default_actor]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Updates a user.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> update_user(User{}, %{password: "coucou"})
|
|
||||||
{:ok, %Mobilizon.Actors.User{}}
|
|
||||||
|
|
||||||
iex> update_user(User{}, %{password: nil})
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def update_user(%User{} = user, attrs) do
|
|
||||||
with {:ok, %User{} = user} <-
|
|
||||||
user
|
|
||||||
|> User.changeset(attrs)
|
|
||||||
|> Repo.update() do
|
|
||||||
{:ok, Repo.preload(user, [:default_actor])}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Deletes a User.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> delete_user(%User{email: "test@test.tld"})
|
|
||||||
{:ok, %Mobilizon.Actors.User{}}
|
|
||||||
|
|
||||||
iex> delete_user(%User{})
|
|
||||||
{:error, %Ecto.Changeset{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def delete_user(%User{} = user) do
|
|
||||||
Repo.delete(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
# @doc """
|
|
||||||
# Returns an `%Ecto.Changeset{}` for tracking user changes.
|
|
||||||
|
|
||||||
# ## Examples
|
|
||||||
|
|
||||||
# iex> change_user(%Mobilizon.Actors.User{})
|
|
||||||
# %Ecto.Changeset{data: %Mobilizon.Actors.User{}}
|
|
||||||
|
|
||||||
# """
|
|
||||||
# def change_user(%User{} = user) do
|
|
||||||
# User.changeset(user, %{})
|
|
||||||
# end
|
|
||||||
|
|
||||||
alias Mobilizon.Actors.Member
|
alias Mobilizon.Actors.Member
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -4,7 +4,8 @@ defmodule Mobilizon.Actors.Bot do
|
||||||
"""
|
"""
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Mobilizon.Actors.{Actor, User}
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
schema "bots" do
|
schema "bots" do
|
||||||
field(:source, :string)
|
field(:source, :string)
|
||||||
|
|
|
@ -2,7 +2,7 @@ defmodule Mobilizon.Email.User do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Handles emails sent to users
|
Handles emails sent to users
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
import Bamboo.Email
|
import Bamboo.Email
|
||||||
import Bamboo.Phoenix
|
import Bamboo.Phoenix
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
defmodule Mobilizon.Actors.Service.Activation do
|
defmodule Mobilizon.Users.Service.Activation do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
alias Mobilizon.{Mailer, Actors.User, Actors}
|
alias Mobilizon.{Mailer, Users}
|
||||||
|
alias Mobilizon.Users.User
|
||||||
alias Mobilizon.Email.User, as: UserEmail
|
alias Mobilizon.Email.User, as: UserEmail
|
||||||
alias Mobilizon.Actors.Service.Tools
|
alias Mobilizon.Users.Service.Tools
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def check_confirmation_token(token) when is_binary(token) do
|
def check_confirmation_token(token) when is_binary(token) do
|
||||||
with %User{} = user <- Actors.get_user_by_activation_token(token),
|
with %User{} = user <- Users.get_user_by_activation_token(token),
|
||||||
{:ok, %User{} = user} <-
|
{:ok, %User{} = user} <-
|
||||||
Actors.update_user(user, %{
|
Users.update_user(user, %{
|
||||||
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
"confirmation_sent_at" => nil,
|
"confirmation_sent_at" => nil,
|
||||||
"confirmation_token" => nil
|
"confirmation_token" => nil
|
||||||
|
@ -27,7 +28,7 @@ defmodule Mobilizon.Actors.Service.Activation do
|
||||||
def resend_confirmation_email(%User{} = user, locale \\ "en") do
|
def resend_confirmation_email(%User{} = user, locale \\ "en") do
|
||||||
with :ok <- Tools.we_can_send_email(user, :confirmation_sent_at),
|
with :ok <- Tools.we_can_send_email(user, :confirmation_sent_at),
|
||||||
{:ok, user} <-
|
{:ok, user} <-
|
||||||
Actors.update_user(user, %{
|
Users.update_user(user, %{
|
||||||
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
|
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
|
||||||
}) do
|
}) do
|
||||||
send_confirmation_email(user, locale)
|
send_confirmation_email(user, locale)
|
|
@ -1,18 +1,19 @@
|
||||||
defmodule Mobilizon.Actors.Service.ResetPassword do
|
defmodule Mobilizon.Users.Service.ResetPassword do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias Mobilizon.{Mailer, Repo, Actors.User, Actors}
|
alias Mobilizon.Users.User
|
||||||
|
alias Mobilizon.{Mailer, Repo, Users}
|
||||||
alias Mobilizon.Email.User, as: UserEmail
|
alias Mobilizon.Email.User, as: UserEmail
|
||||||
alias Mobilizon.Actors.Service.Tools
|
alias Mobilizon.Users.Service.Tools
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Check that the provided token is correct and update provided password
|
Check that the provided token is correct and update provided password
|
||||||
"""
|
"""
|
||||||
@spec check_reset_password_token(String.t(), String.t()) :: tuple
|
@spec check_reset_password_token(String.t(), String.t()) :: tuple
|
||||||
def check_reset_password_token(password, token) do
|
def check_reset_password_token(password, token) do
|
||||||
with %User{} = user <- Actors.get_user_by_reset_password_token(token),
|
with %User{} = user <- Users.get_user_by_reset_password_token(token),
|
||||||
{:ok, %User{} = user} <-
|
{:ok, %User{} = user} <-
|
||||||
Repo.update(
|
Repo.update(
|
||||||
User.password_reset_changeset(user, %{
|
User.password_reset_changeset(user, %{
|
|
@ -1,8 +1,8 @@
|
||||||
defmodule Mobilizon.Actors.Service.Tools do
|
defmodule Mobilizon.Users.Service.Tools do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Common functions for actors services
|
Common functions for actors services
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
@spec we_can_send_email(User.t(), atom()) :: :ok | {:error, :email_too_soon}
|
@spec we_can_send_email(User.t(), atom()) :: :ok | {:error, :email_too_soon}
|
||||||
def we_can_send_email(%User{} = user, key \\ :reset_password_sent_at) do
|
def we_can_send_email(%User{} = user, key \\ :reset_password_sent_at) do
|
|
@ -1,10 +1,11 @@
|
||||||
defmodule Mobilizon.Actors.User do
|
defmodule Mobilizon.Users.User do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Represents a local user
|
Represents a local user
|
||||||
"""
|
"""
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Mobilizon.Actors.{Actor, User}
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
alias Mobilizon.Service.EmailChecker
|
alias Mobilizon.Service.EmailChecker
|
||||||
|
|
||||||
schema "users" do
|
schema "users" do
|
257
lib/mobilizon/users/users.ex
Normal file
257
lib/mobilizon/users/users.ex
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
defmodule Mobilizon.Users do
|
||||||
|
@moduledoc """
|
||||||
|
The Users context.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import Ecto.Query, warn: false
|
||||||
|
|
||||||
|
alias Mobilizon.Repo
|
||||||
|
import Mobilizon.Ecto
|
||||||
|
|
||||||
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def data() do
|
||||||
|
Dataloader.Ecto.new(Repo, query: &query/2)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def query(queryable, _params) do
|
||||||
|
queryable
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets an user by it's email
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> get_user_by_email("test@test.tld", true)
|
||||||
|
{:ok, %Mobilizon.Users.User{}}
|
||||||
|
|
||||||
|
iex> get_user_by_email("test@notfound.tld", false)
|
||||||
|
{:error, :user_not_found}
|
||||||
|
"""
|
||||||
|
def get_user_by_email(email, activated \\ nil) do
|
||||||
|
query =
|
||||||
|
case activated do
|
||||||
|
nil ->
|
||||||
|
from(u in User, where: u.email == ^email, preload: :default_actor)
|
||||||
|
|
||||||
|
true ->
|
||||||
|
from(u in User,
|
||||||
|
where: u.email == ^email and not is_nil(u.confirmed_at),
|
||||||
|
preload: :default_actor
|
||||||
|
)
|
||||||
|
|
||||||
|
false ->
|
||||||
|
from(u in User,
|
||||||
|
where: u.email == ^email and is_nil(u.confirmed_at),
|
||||||
|
preload: :default_actor
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
case Repo.one(query) do
|
||||||
|
nil -> {:error, :user_not_found}
|
||||||
|
user -> {:ok, user}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get an user by it's activation token
|
||||||
|
"""
|
||||||
|
@spec get_user_by_activation_token(String.t()) :: Actor.t()
|
||||||
|
def get_user_by_activation_token(token) do
|
||||||
|
Repo.one(
|
||||||
|
from(u in User,
|
||||||
|
where: u.confirmation_token == ^token,
|
||||||
|
preload: [:default_actor]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get an user by it's reset password token
|
||||||
|
"""
|
||||||
|
@spec get_user_by_reset_password_token(String.t()) :: Actor.t()
|
||||||
|
def get_user_by_reset_password_token(token) do
|
||||||
|
Repo.one(
|
||||||
|
from(u in User,
|
||||||
|
where: u.reset_password_token == ^token,
|
||||||
|
preload: [:default_actor]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates a user.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> update_user(User{}, %{password: "coucou"})
|
||||||
|
{:ok, %Mobilizon.Users.User{}}
|
||||||
|
|
||||||
|
iex> update_user(User{}, %{password: nil})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def update_user(%User{} = user, attrs) do
|
||||||
|
with {:ok, %User{} = user} <-
|
||||||
|
user
|
||||||
|
|> User.changeset(attrs)
|
||||||
|
|> Repo.update() do
|
||||||
|
{:ok, Repo.preload(user, [:default_actor])}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Deletes a User.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> delete_user(%User{email: "test@test.tld"})
|
||||||
|
{:ok, %Mobilizon.Users.User{}}
|
||||||
|
|
||||||
|
iex> delete_user(%User{})
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def delete_user(%User{} = user) do
|
||||||
|
Repo.delete(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @doc """
|
||||||
|
# Returns an `%Ecto.Changeset{}` for tracking user changes.
|
||||||
|
|
||||||
|
# ## Examples
|
||||||
|
|
||||||
|
# iex> change_user(%Mobilizon.Users.User{})
|
||||||
|
# %Ecto.Changeset{data: %Mobilizon.Users.User{}}
|
||||||
|
|
||||||
|
# """
|
||||||
|
# def change_user(%User{} = user) do
|
||||||
|
# User.changeset(user, %{})
|
||||||
|
# end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Gets a single user.
|
||||||
|
|
||||||
|
Raises `Ecto.NoResultsError` if the User does not exist.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> get_user!(123)
|
||||||
|
%Mobilizon.Users.User{}
|
||||||
|
|
||||||
|
iex> get_user!(456)
|
||||||
|
** (Ecto.NoResultsError)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def get_user!(id), do: Repo.get!(User, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get an user with it's actors
|
||||||
|
|
||||||
|
Raises `Ecto.NoResultsError` if the User does not exist.
|
||||||
|
"""
|
||||||
|
@spec get_user_with_actors!(integer()) :: User.t()
|
||||||
|
def get_user_with_actors!(id) do
|
||||||
|
user = Repo.get!(User, id)
|
||||||
|
Repo.preload(user, [:actors, :default_actor])
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get user with it's actors by ID
|
||||||
|
"""
|
||||||
|
@spec get_user_with_actors(integer()) :: User.t()
|
||||||
|
def get_user_with_actors(id) do
|
||||||
|
case Repo.get(User, id) do
|
||||||
|
nil ->
|
||||||
|
{:error, "User with ID #{id} not found"}
|
||||||
|
|
||||||
|
user ->
|
||||||
|
user =
|
||||||
|
user
|
||||||
|
|> Repo.preload([:actors, :default_actor])
|
||||||
|
|> Map.put(:actors, get_actors_for_user(user))
|
||||||
|
|
||||||
|
{:ok, user}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the associated actor for an user, either the default set one or the first found
|
||||||
|
"""
|
||||||
|
@spec get_actor_for_user(Mobilizon.Users.User.t()) :: Mobilizon.Actors.Actor.t()
|
||||||
|
def get_actor_for_user(%Mobilizon.Users.User{} = user) do
|
||||||
|
case Repo.one(
|
||||||
|
from(a in Actor,
|
||||||
|
join: u in User,
|
||||||
|
on: u.default_actor_id == a.id,
|
||||||
|
where: u.id == ^user.id
|
||||||
|
)
|
||||||
|
) do
|
||||||
|
nil ->
|
||||||
|
case user |> get_actors_for_user() do
|
||||||
|
[] -> nil
|
||||||
|
actors -> hd(actors)
|
||||||
|
end
|
||||||
|
|
||||||
|
actor ->
|
||||||
|
actor
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_actors_for_user(%User{id: user_id}) do
|
||||||
|
Repo.all(from(a in Actor, where: a.user_id == ^user_id))
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Authenticate user
|
||||||
|
"""
|
||||||
|
def authenticate(%{user: user, password: password}) do
|
||||||
|
# Does password match the one stored in the database?
|
||||||
|
case Argon2.verify_pass(password, user.password_hash) do
|
||||||
|
true ->
|
||||||
|
# Yes, create and return the token
|
||||||
|
MobilizonWeb.Guardian.encode_and_sign(user)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
# No, return an error
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user_default_actor(user_id, actor_id) do
|
||||||
|
with from(u in User, where: u.id == ^user_id, update: [set: [default_actor_id: ^actor_id]])
|
||||||
|
|> Repo.update_all([]) do
|
||||||
|
Repo.get!(User, user_id) |> Repo.preload([:default_actor])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the list of users.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> list_users()
|
||||||
|
[%Mobilizon.Users.User{}]
|
||||||
|
|
||||||
|
"""
|
||||||
|
def list_users(page \\ nil, limit \\ nil, sort \\ nil, direction \\ nil) do
|
||||||
|
Repo.all(
|
||||||
|
User
|
||||||
|
|> paginate(page, limit)
|
||||||
|
|> sort(sort, direction)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_users() do
|
||||||
|
Repo.one(
|
||||||
|
from(
|
||||||
|
u in User,
|
||||||
|
select: count(u.id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,7 +6,7 @@
|
||||||
defmodule MobilizonWeb.NodeInfoController do
|
defmodule MobilizonWeb.NodeInfoController do
|
||||||
use MobilizonWeb, :controller
|
use MobilizonWeb, :controller
|
||||||
|
|
||||||
alias Mobilizon.{Actors, Events}
|
alias Mobilizon.{Events, Users}
|
||||||
|
|
||||||
@instance Application.get_env(:mobilizon, :instance)
|
@instance Application.get_env(:mobilizon, :instance)
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ defmodule MobilizonWeb.NodeInfoController do
|
||||||
openRegistrations: Keyword.get(@instance, :registrations_open),
|
openRegistrations: Keyword.get(@instance, :registrations_open),
|
||||||
usage: %{
|
usage: %{
|
||||||
users: %{
|
users: %{
|
||||||
total: Actors.count_users()
|
total: Users.count_users()
|
||||||
},
|
},
|
||||||
localPosts: Events.count_local_events(),
|
localPosts: Events.count_local_events(),
|
||||||
localComments: Events.count_local_comments()
|
localComments: Events.count_local_comments()
|
||||||
|
|
|
@ -9,8 +9,8 @@ defmodule MobilizonWeb.Guardian do
|
||||||
user: [:base]
|
user: [:base]
|
||||||
}
|
}
|
||||||
|
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Users
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
def subject_for_token(%User{} = user, _claims) do
|
def subject_for_token(%User{} = user, _claims) do
|
||||||
{:ok, "User:" <> to_string(user.id)}
|
{:ok, "User:" <> to_string(user.id)}
|
||||||
|
@ -24,7 +24,7 @@ defmodule MobilizonWeb.Guardian do
|
||||||
try do
|
try do
|
||||||
case Integer.parse(uid_str) do
|
case Integer.parse(uid_str) do
|
||||||
{uid, ""} ->
|
{uid, ""} ->
|
||||||
{:ok, Actors.get_user_with_actors!(uid)}
|
{:ok, Users.get_user_with_actors!(uid)}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{:error, :invalid_id}
|
{:error, :invalid_id}
|
||||||
|
|
|
@ -5,7 +5,7 @@ defmodule MobilizonWeb.Resolvers.Comment do
|
||||||
require Logger
|
require Logger
|
||||||
alias Mobilizon.Events.Comment
|
alias Mobilizon.Events.Comment
|
||||||
alias Mobilizon.Activity
|
alias Mobilizon.Activity
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Users.User
|
||||||
alias MobilizonWeb.API.Comments
|
alias MobilizonWeb.API.Comments
|
||||||
|
|
||||||
def create_comment(_parent, %{text: comment, actor_username: username}, %{
|
def create_comment(_parent, %{text: comment, actor_username: username}, %{
|
||||||
|
|
|
@ -4,7 +4,8 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Activity
|
alias Mobilizon.Activity
|
||||||
alias Mobilizon.Events.{Event, Participant}
|
alias Mobilizon.Events.{Event, Participant}
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
# We limit the max number of events that can be retrieved
|
# We limit the max number of events that can be retrieved
|
||||||
@event_max_limit 100
|
@event_max_limit 100
|
||||||
|
|
|
@ -3,7 +3,8 @@ defmodule MobilizonWeb.Resolvers.Group do
|
||||||
Handles the group-related GraphQL calls
|
Handles the group-related GraphQL calls
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.{Actor, User, Member}
|
alias Mobilizon.Actors.{Actor, Member}
|
||||||
|
alias Mobilizon.Users.User
|
||||||
alias Mobilizon.Service.ActivityPub
|
alias Mobilizon.Service.ActivityPub
|
||||||
alias Mobilizon.Activity
|
alias Mobilizon.Activity
|
||||||
require Logger
|
require Logger
|
||||||
|
|
|
@ -3,7 +3,9 @@ defmodule MobilizonWeb.Resolvers.Person do
|
||||||
Handles the person-related GraphQL calls
|
Handles the person-related GraphQL calls
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.{Actor, User}
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
alias Mobilizon.Users
|
||||||
alias Mobilizon.Service.ActivityPub
|
alias Mobilizon.Service.ActivityPub
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -23,7 +25,7 @@ defmodule MobilizonWeb.Resolvers.Person do
|
||||||
Returns the current actor for the currently logged-in user
|
Returns the current actor for the currently logged-in user
|
||||||
"""
|
"""
|
||||||
def get_current_person(_parent, _args, %{context: %{current_user: user}}) do
|
def get_current_person(_parent, _args, %{context: %{current_user: user}}) do
|
||||||
{:ok, Actors.get_actor_for_user(user)}
|
{:ok, Users.get_actor_for_user(user)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_current_person(_parent, _args, _resolution) do
|
def get_current_person(_parent, _args, _resolution) do
|
||||||
|
@ -34,7 +36,7 @@ defmodule MobilizonWeb.Resolvers.Person do
|
||||||
Returns the list of identities for the logged-in user
|
Returns the list of identities for the logged-in user
|
||||||
"""
|
"""
|
||||||
def identities(_parent, _args, %{context: %{current_user: user}}) do
|
def identities(_parent, _args, %{context: %{current_user: user}}) do
|
||||||
{:ok, Actors.get_actors_for_user(user)}
|
{:ok, Users.get_actors_for_user(user)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def identities(_parent, _args, _resolution) do
|
def identities(_parent, _args, _resolution) do
|
||||||
|
@ -65,8 +67,8 @@ defmodule MobilizonWeb.Resolvers.Person do
|
||||||
This function is used to register a person afterwards the user has been created (but not activated)
|
This function is used to register a person afterwards the user has been created (but not activated)
|
||||||
"""
|
"""
|
||||||
def register_person(_parent, args, _resolution) do
|
def register_person(_parent, args, _resolution) do
|
||||||
with {:ok, %User{} = user} <- Actors.get_user_by_email(args.email),
|
with {:ok, %User{} = user} <- Users.get_user_by_email(args.email),
|
||||||
{:no_actor, nil} <- {:no_actor, Actors.get_actor_for_user(user)},
|
{:no_actor, nil} <- {:no_actor, Users.get_actor_for_user(user)},
|
||||||
args <- Map.put(args, :user_id, user.id),
|
args <- Map.put(args, :user_id, user.id),
|
||||||
{:ok, %Actor{} = new_person} <- Actors.new_person(args) do
|
{:ok, %Actor{} = new_person} <- Actors.new_person(args) do
|
||||||
{:ok, new_person}
|
{:ok, new_person}
|
||||||
|
|
|
@ -2,15 +2,17 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Handles the user-related GraphQL calls
|
Handles the user-related GraphQL calls
|
||||||
"""
|
"""
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Users.User
|
||||||
|
alias Mobilizon.{Actors, Users}
|
||||||
|
alias Mobilizon.Users.Service.{ResetPassword, Activation}
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Find an user by it's ID
|
Find an user by it's ID
|
||||||
"""
|
"""
|
||||||
def find_user(_parent, %{id: id}, _resolution) do
|
def find_user(_parent, %{id: id}, _resolution) do
|
||||||
Actors.get_user_with_actors(id)
|
Users.get_user_with_actors(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -32,8 +34,8 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
%{page: page, limit: limit, sort: sort, direction: direction},
|
%{page: page, limit: limit, sort: sort, direction: direction},
|
||||||
_resolution
|
_resolution
|
||||||
) do
|
) do
|
||||||
total = Task.async(&Actors.count_users/0)
|
total = Task.async(&Users.count_users/0)
|
||||||
elements = Task.async(fn -> Actors.list_users(page, limit, sort, direction) end)
|
elements = Task.async(fn -> Users.list_users(page, limit, sort, direction) end)
|
||||||
|
|
||||||
{:ok, %{total: Task.await(total), elements: Task.await(elements)}}
|
{:ok, %{total: Task.await(total), elements: Task.await(elements)}}
|
||||||
end
|
end
|
||||||
|
@ -42,8 +44,8 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
Login an user. Returns a token and the user
|
Login an user. Returns a token and the user
|
||||||
"""
|
"""
|
||||||
def login_user(_parent, %{email: email, password: password}, _resolution) do
|
def login_user(_parent, %{email: email, password: password}, _resolution) do
|
||||||
with {:ok, %User{} = user} <- Actors.get_user_by_email(email, true),
|
with {:ok, %User{} = user} <- Users.get_user_by_email(email, true),
|
||||||
{:ok, token, _} <- Actors.authenticate(%{user: user, password: password}) do
|
{:ok, token, _} <- Users.authenticate(%{user: user, password: password}) do
|
||||||
{:ok, %{token: token, user: user}}
|
{:ok, %{token: token, user: user}}
|
||||||
else
|
else
|
||||||
{:error, :user_not_found} ->
|
{:error, :user_not_found} ->
|
||||||
|
@ -62,7 +64,7 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
@spec create_user(any(), map(), any()) :: tuple()
|
@spec create_user(any(), map(), any()) :: tuple()
|
||||||
def create_user(_parent, args, _resolution) do
|
def create_user(_parent, args, _resolution) do
|
||||||
with {:ok, %User{} = user} <- Actors.register(args) do
|
with {:ok, %User{} = user} <- Actors.register(args) do
|
||||||
Mobilizon.Actors.Service.Activation.send_confirmation_email(user)
|
Activation.send_confirmation_email(user)
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -72,9 +74,8 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
"""
|
"""
|
||||||
def validate_user(_parent, %{token: token}, _resolution) do
|
def validate_user(_parent, %{token: token}, _resolution) do
|
||||||
with {:check_confirmation_token, {:ok, %User{} = user}} <-
|
with {:check_confirmation_token, {:ok, %User{} = user}} <-
|
||||||
{:check_confirmation_token,
|
{:check_confirmation_token, Activation.check_confirmation_token(token)},
|
||||||
Mobilizon.Actors.Service.Activation.check_confirmation_token(token)},
|
{:get_actor, actor} <- {:get_actor, Users.get_actor_for_user(user)},
|
||||||
{:get_actor, actor} <- {:get_actor, Actors.get_actor_for_user(user)},
|
|
||||||
{:guardian_encode_and_sign, {:ok, token, _}} <-
|
{:guardian_encode_and_sign, {:ok, token, _}} <-
|
||||||
{:guardian_encode_and_sign, MobilizonWeb.Guardian.encode_and_sign(user)} do
|
{:guardian_encode_and_sign, MobilizonWeb.Guardian.encode_and_sign(user)} do
|
||||||
{:ok, %{token: token, user: Map.put(user, :default_actor, actor)}}
|
{:ok, %{token: token, user: Map.put(user, :default_actor, actor)}}
|
||||||
|
@ -91,9 +92,9 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
We only do this to accounts unconfirmed
|
We only do this to accounts unconfirmed
|
||||||
"""
|
"""
|
||||||
def resend_confirmation_email(_parent, %{email: email, locale: locale}, _resolution) do
|
def resend_confirmation_email(_parent, %{email: email, locale: locale}, _resolution) do
|
||||||
with {:ok, user} <- Actors.get_user_by_email(email, false),
|
with {:ok, user} <- Users.get_user_by_email(email, false),
|
||||||
{:ok, email} <-
|
{:ok, email} <-
|
||||||
Mobilizon.Actors.Service.Activation.resend_confirmation_email(user, locale) do
|
Activation.resend_confirmation_email(user, locale) do
|
||||||
{:ok, email}
|
{:ok, email}
|
||||||
else
|
else
|
||||||
{:error, :user_not_found} ->
|
{:error, :user_not_found} ->
|
||||||
|
@ -108,9 +109,9 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
Send an email to reset the password from an user
|
Send an email to reset the password from an user
|
||||||
"""
|
"""
|
||||||
def send_reset_password(_parent, %{email: email, locale: locale}, _resolution) do
|
def send_reset_password(_parent, %{email: email, locale: locale}, _resolution) do
|
||||||
with {:ok, user} <- Actors.get_user_by_email(email, true),
|
with {:ok, user} <- Users.get_user_by_email(email, true),
|
||||||
{:ok, %Bamboo.Email{} = _email_html} <-
|
{:ok, %Bamboo.Email{} = _email_html} <-
|
||||||
Mobilizon.Actors.Service.ResetPassword.send_password_reset_email(user, locale) do
|
ResetPassword.send_password_reset_email(user, locale) do
|
||||||
{:ok, email}
|
{:ok, email}
|
||||||
else
|
else
|
||||||
{:error, :user_not_found} ->
|
{:error, :user_not_found} ->
|
||||||
|
@ -127,7 +128,7 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
"""
|
"""
|
||||||
def reset_password(_parent, %{password: password, token: token}, _resolution) do
|
def reset_password(_parent, %{password: password, token: token}, _resolution) do
|
||||||
with {:ok, %User{} = user} <-
|
with {:ok, %User{} = user} <-
|
||||||
Mobilizon.Actors.Service.ResetPassword.check_reset_password_token(password, token),
|
ResetPassword.check_reset_password_token(password, token),
|
||||||
{:ok, token, _} <- MobilizonWeb.Guardian.encode_and_sign(user) do
|
{:ok, token, _} <- MobilizonWeb.Guardian.encode_and_sign(user) do
|
||||||
{:ok, %{token: token, user: user}}
|
{:ok, %{token: token, user: user}}
|
||||||
end
|
end
|
||||||
|
@ -139,8 +140,8 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
}) do
|
}) do
|
||||||
with %Actor{id: actor_id} <- Actors.get_local_actor_by_name(username),
|
with %Actor{id: actor_id} <- Actors.get_local_actor_by_name(username),
|
||||||
{:user_actor, true} <-
|
{:user_actor, true} <-
|
||||||
{:user_actor, actor_id in Enum.map(Actors.get_actors_for_user(user), & &1.id)},
|
{:user_actor, actor_id in Enum.map(Users.get_actors_for_user(user), & &1.id)},
|
||||||
%User{} = user <- Actors.update_user_default_actor(user.id, actor_id) do
|
%User{} = user <- Users.update_user_default_actor(user.id, actor_id) do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
else
|
else
|
||||||
{:user_actor, _} ->
|
{:user_actor, _} ->
|
||||||
|
|
|
@ -2,7 +2,8 @@ defmodule Mobilizon.ActorsTest do
|
||||||
use Mobilizon.DataCase
|
use Mobilizon.DataCase
|
||||||
|
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.{Actor, Member, Follower, User, Bot}
|
alias Mobilizon.Actors.{Actor, Member, Follower, Bot}
|
||||||
|
alias Mobilizon.Users
|
||||||
import Mobilizon.Factory
|
import Mobilizon.Factory
|
||||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||||
|
|
||||||
|
@ -60,13 +61,13 @@ defmodule Mobilizon.ActorsTest do
|
||||||
test "get_actor_for_user/1 returns the actor for an user", %{
|
test "get_actor_for_user/1 returns the actor for an user", %{
|
||||||
actor: %{user: user, id: actor_id} = _actor
|
actor: %{user: user, id: actor_id} = _actor
|
||||||
} do
|
} do
|
||||||
assert actor_id == Actors.get_actor_for_user(user).id
|
assert actor_id == Users.get_actor_for_user(user).id
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_actor_for_user/1 returns the actor for an user with no default actor defined" do
|
test "get_actor_for_user/1 returns the actor for an user with no default actor defined" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
actor_id = insert(:actor, user: user).id
|
actor_id = insert(:actor, user: user).id
|
||||||
assert actor_id == Actors.get_actor_for_user(user).id
|
assert actor_id == Users.get_actor_for_user(user).id
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_actor_with_everything/1 returns the actor with it's organized events", %{
|
test "get_actor_with_everything/1 returns the actor with it's organized events", %{
|
||||||
|
@ -265,104 +266,6 @@ defmodule Mobilizon.ActorsTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "users" do
|
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
|
||||||
|
|
||||||
@valid_attrs %{email: "foo@bar.tld", password: "some password"}
|
|
||||||
@update_attrs %{email: "foo@fighters.tld", password: "some updated password"}
|
|
||||||
@invalid_attrs %{email: nil, password: nil}
|
|
||||||
|
|
||||||
test "list_users/0 returns all users" do
|
|
||||||
user = insert(:user)
|
|
||||||
users = Actors.list_users(nil, nil, :id, :desc)
|
|
||||||
assert [user.id] == users |> Enum.map(& &1.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get_user!/1 returns the user with given id" do
|
|
||||||
user = insert(:user)
|
|
||||||
assert user = Actors.get_user!(user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
# There's no create_user/1, just register/1
|
|
||||||
test "register/1 with valid data creates a user" do
|
|
||||||
assert {:ok, %User{email: email} = user} = Actors.register(@valid_attrs)
|
|
||||||
|
|
||||||
assert email == @valid_attrs.email
|
|
||||||
end
|
|
||||||
|
|
||||||
test "create_user/1 with invalid data returns error changeset" do
|
|
||||||
assert {:error,
|
|
||||||
%Ecto.Changeset{
|
|
||||||
errors: [
|
|
||||||
password: {"can't be blank", [validation: :required]},
|
|
||||||
email: {"can't be blank", [validation: :required]}
|
|
||||||
],
|
|
||||||
valid?: false
|
|
||||||
}} = Actors.register(@invalid_attrs)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "update_user/2 with valid data updates the user" do
|
|
||||||
user = insert(:user)
|
|
||||||
assert {:ok, %User{email: email}} = Actors.update_user(user, @update_attrs)
|
|
||||||
assert email == "foo@fighters.tld"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "update_user/2 with invalid data returns error changeset" do
|
|
||||||
user = insert(:user)
|
|
||||||
assert {:error, %Ecto.Changeset{}} = Actors.update_user(user, @invalid_attrs)
|
|
||||||
assert user = Actors.get_user!(user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "delete_user/1 deletes the user" do
|
|
||||||
user = insert(:user)
|
|
||||||
assert {:ok, %User{}} = Actors.delete_user(user)
|
|
||||||
assert_raise Ecto.NoResultsError, fn -> Actors.get_user!(user.id) end
|
|
||||||
end
|
|
||||||
|
|
||||||
# test "change_user/1 returns a user changeset" do
|
|
||||||
# user = insert(:user)
|
|
||||||
# assert %Ecto.Changeset{} = Actors.change_user(user)
|
|
||||||
# end
|
|
||||||
|
|
||||||
@email "email@domain.tld"
|
|
||||||
@password "password"
|
|
||||||
test "authenticate/1 checks the user's password" do
|
|
||||||
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
|
|
||||||
|
|
||||||
assert {:ok, _, _} = Actors.authenticate(%{user: user, password: @password})
|
|
||||||
|
|
||||||
assert {:error, :unauthorized} ==
|
|
||||||
Actors.authenticate(%{user: user, password: "bad password"})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get_user_by_email/1 finds an user by it's email" do
|
|
||||||
{:ok, %User{email: email} = user} = Actors.register(%{email: @email, password: @password})
|
|
||||||
|
|
||||||
assert email == @email
|
|
||||||
{:ok, %User{id: id}} = Actors.get_user_by_email(@email)
|
|
||||||
assert id == user.id
|
|
||||||
assert {:error, :user_not_found} = Actors.get_user_by_email("no email")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get_user_by_email/1 finds an activated user by it's email" do
|
|
||||||
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
|
|
||||||
|
|
||||||
{:ok, %User{id: id}} = Actors.get_user_by_email(@email, false)
|
|
||||||
assert id == user.id
|
|
||||||
assert {:error, :user_not_found} = Actors.get_user_by_email(@email, true)
|
|
||||||
|
|
||||||
Actors.update_user(user, %{
|
|
||||||
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
|
||||||
"confirmation_sent_at" => nil,
|
|
||||||
"confirmation_token" => nil
|
|
||||||
})
|
|
||||||
|
|
||||||
assert {:error, :user_not_found} = Actors.get_user_by_email(@email, false)
|
|
||||||
{:ok, %User{id: id}} = Actors.get_user_by_email(@email, true)
|
|
||||||
assert id == user.id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "groups" do
|
describe "groups" do
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
|
|
105
test/mobilizon/users/users_test.exs
Normal file
105
test/mobilizon/users/users_test.exs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
defmodule Mobilizon.UsersTest do
|
||||||
|
use Mobilizon.DataCase
|
||||||
|
|
||||||
|
alias Mobilizon.Actors
|
||||||
|
alias Mobilizon.Users
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
import Mobilizon.Factory
|
||||||
|
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||||
|
|
||||||
|
describe "users" do
|
||||||
|
@valid_attrs %{email: "foo@bar.tld", password: "some password"}
|
||||||
|
@update_attrs %{email: "foo@fighters.tld", password: "some updated password"}
|
||||||
|
@invalid_attrs %{email: nil, password: nil}
|
||||||
|
|
||||||
|
test "list_users/0 returns all users" do
|
||||||
|
user = insert(:user)
|
||||||
|
users = Users.list_users(nil, nil, :id, :desc)
|
||||||
|
assert [user.id] == users |> Enum.map(& &1.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_user!/1 returns the user with given id" do
|
||||||
|
user = insert(:user)
|
||||||
|
assert user = Users.get_user!(user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# There's no create_user/1, just register/1
|
||||||
|
test "register/1 with valid data creates a user" do
|
||||||
|
assert {:ok, %User{email: email} = user} = Actors.register(@valid_attrs)
|
||||||
|
|
||||||
|
assert email == @valid_attrs.email
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create_user/1 with invalid data returns error changeset" do
|
||||||
|
assert {:error,
|
||||||
|
%Ecto.Changeset{
|
||||||
|
errors: [
|
||||||
|
password: {"can't be blank", [validation: :required]},
|
||||||
|
email: {"can't be blank", [validation: :required]}
|
||||||
|
],
|
||||||
|
valid?: false
|
||||||
|
}} = Actors.register(@invalid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_user/2 with valid data updates the user" do
|
||||||
|
user = insert(:user)
|
||||||
|
assert {:ok, %User{email: email}} = Users.update_user(user, @update_attrs)
|
||||||
|
assert email == "foo@fighters.tld"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update_user/2 with invalid data returns error changeset" do
|
||||||
|
user = insert(:user)
|
||||||
|
assert {:error, %Ecto.Changeset{}} = Users.update_user(user, @invalid_attrs)
|
||||||
|
assert user = Users.get_user!(user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "delete_user/1 deletes the user" do
|
||||||
|
user = insert(:user)
|
||||||
|
assert {:ok, %User{}} = Users.delete_user(user)
|
||||||
|
assert_raise Ecto.NoResultsError, fn -> Users.get_user!(user.id) end
|
||||||
|
end
|
||||||
|
|
||||||
|
# test "change_user/1 returns a user changeset" do
|
||||||
|
# user = insert(:user)
|
||||||
|
# assert %Ecto.Changeset{} = Users.change_user(user)
|
||||||
|
# end
|
||||||
|
|
||||||
|
@email "email@domain.tld"
|
||||||
|
@password "password"
|
||||||
|
test "authenticate/1 checks the user's password" do
|
||||||
|
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
|
||||||
|
|
||||||
|
assert {:ok, _, _} = Users.authenticate(%{user: user, password: @password})
|
||||||
|
|
||||||
|
assert {:error, :unauthorized} ==
|
||||||
|
Users.authenticate(%{user: user, password: "bad password"})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_user_by_email/1 finds an user by it's email" do
|
||||||
|
{:ok, %User{email: email} = user} = Actors.register(%{email: @email, password: @password})
|
||||||
|
|
||||||
|
assert email == @email
|
||||||
|
{:ok, %User{id: id}} = Users.get_user_by_email(@email)
|
||||||
|
assert id == user.id
|
||||||
|
assert {:error, :user_not_found} = Users.get_user_by_email("no email")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_user_by_email/1 finds an activated user by it's email" do
|
||||||
|
{:ok, %User{} = user} = Actors.register(%{email: @email, password: @password})
|
||||||
|
|
||||||
|
{:ok, %User{id: id}} = Users.get_user_by_email(@email, false)
|
||||||
|
assert id == user.id
|
||||||
|
assert {:error, :user_not_found} = Users.get_user_by_email(@email, true)
|
||||||
|
|
||||||
|
Users.update_user(user, %{
|
||||||
|
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
|
"confirmation_sent_at" => nil,
|
||||||
|
"confirmation_token" => nil
|
||||||
|
})
|
||||||
|
|
||||||
|
assert {:error, :user_not_found} = Users.get_user_by_email(@email, false)
|
||||||
|
{:ok, %User{id: id}} = Users.get_user_by_email(@email, true)
|
||||||
|
assert id == user.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,10 @@
|
||||||
defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
use MobilizonWeb.ConnCase
|
use MobilizonWeb.ConnCase
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.{Actors, Users}
|
||||||
alias Mobilizon.Actors.{User, Actor}
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Users.User
|
||||||
alias MobilizonWeb.AbsintheHelpers
|
alias MobilizonWeb.AbsintheHelpers
|
||||||
|
alias Mobilizon.Users.Service.ResetPassword
|
||||||
import Mobilizon.Factory
|
import Mobilizon.Factory
|
||||||
use Bamboo.Test
|
use Bamboo.Test
|
||||||
|
|
||||||
|
@ -431,7 +433,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
"You requested again a confirmation email too soon"
|
"You requested again a confirmation email too soon"
|
||||||
|
|
||||||
# Hammer time !
|
# Hammer time !
|
||||||
Mobilizon.Actors.update_user(user, %{
|
Mobilizon.Users.update_user(user, %{
|
||||||
confirmation_sent_at: Timex.shift(user.confirmation_sent_at, hours: -3)
|
confirmation_sent_at: Timex.shift(user.confirmation_sent_at, hours: -3)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -503,8 +505,8 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
test "test reset_password/3 with valid email", context do
|
test "test reset_password/3 with valid email", context do
|
||||||
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
||||||
%Actor{} = insert(:actor, user: user)
|
%Actor{} = insert(:actor, user: user)
|
||||||
{:ok, _email_sent} = Mobilizon.Actors.Service.ResetPassword.send_password_reset_email(user)
|
{:ok, _email_sent} = ResetPassword.send_password_reset_email(user)
|
||||||
%User{reset_password_token: reset_password_token} = Mobilizon.Actors.get_user!(user.id)
|
%User{reset_password_token: reset_password_token} = Mobilizon.Users.get_user!(user.id)
|
||||||
|
|
||||||
mutation = """
|
mutation = """
|
||||||
mutation {
|
mutation {
|
||||||
|
@ -528,8 +530,8 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
|
|
||||||
test "test reset_password/3 with a password too short", context do
|
test "test reset_password/3 with a password too short", context do
|
||||||
%User{} = user = insert(:user)
|
%User{} = user = insert(:user)
|
||||||
{:ok, _email_sent} = Mobilizon.Actors.Service.ResetPassword.send_password_reset_email(user)
|
{:ok, _email_sent} = ResetPassword.send_password_reset_email(user)
|
||||||
%User{reset_password_token: reset_password_token} = Mobilizon.Actors.get_user!(user.id)
|
%User{reset_password_token: reset_password_token} = Mobilizon.Users.get_user!(user.id)
|
||||||
|
|
||||||
mutation = """
|
mutation = """
|
||||||
mutation {
|
mutation {
|
||||||
|
@ -554,8 +556,8 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
|
|
||||||
test "test reset_password/3 with an invalid token", context do
|
test "test reset_password/3 with an invalid token", context do
|
||||||
%User{} = user = insert(:user)
|
%User{} = user = insert(:user)
|
||||||
{:ok, _email_sent} = Mobilizon.Actors.Service.ResetPassword.send_password_reset_email(user)
|
{:ok, _email_sent} = ResetPassword.send_password_reset_email(user)
|
||||||
%User{} = Mobilizon.Actors.get_user!(user.id)
|
%User{} = Mobilizon.Users.get_user!(user.id)
|
||||||
|
|
||||||
mutation = """
|
mutation = """
|
||||||
mutation {
|
mutation {
|
||||||
|
@ -584,7 +586,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
||||||
|
|
||||||
{:ok, %User{} = _user} =
|
{:ok, %User{} = _user} =
|
||||||
Actors.update_user(user, %{
|
Users.update_user(user, %{
|
||||||
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
"confirmation_sent_at" => nil,
|
"confirmation_sent_at" => nil,
|
||||||
"confirmation_token" => nil
|
"confirmation_token" => nil
|
||||||
|
@ -616,7 +618,7 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
{:ok, %User{} = user} = Actors.register(%{email: "toto@tata.tld", password: "p4ssw0rd"})
|
||||||
|
|
||||||
{:ok, %User{} = _user} =
|
{:ok, %User{} = _user} =
|
||||||
Actors.update_user(user, %{
|
Users.update_user(user, %{
|
||||||
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
|
||||||
"confirmation_sent_at" => nil,
|
"confirmation_sent_at" => nil,
|
||||||
"confirmation_token" => nil
|
"confirmation_token" => nil
|
||||||
|
@ -677,12 +679,12 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
insert(:actor, user: user)
|
insert(:actor, user: user)
|
||||||
|
|
||||||
assert {:ok, %User{actors: actors}} = Actors.get_user_with_actors(user.id)
|
assert {:ok, %User{actors: actors}} = Users.get_user_with_actors(user.id)
|
||||||
|
|
||||||
actor_params = @valid_single_actor_params |> Map.put(:user_id, user.id)
|
actor_params = @valid_single_actor_params |> Map.put(:user_id, user.id)
|
||||||
assert {:ok, %Actor{} = actor2} = Actors.create_actor(actor_params)
|
assert {:ok, %Actor{} = actor2} = Actors.create_actor(actor_params)
|
||||||
|
|
||||||
assert {:ok, %User{actors: actors}} = Actors.get_user_with_actors(user.id)
|
assert {:ok, %User{actors: actors}} = Users.get_user_with_actors(user.id)
|
||||||
assert length(actors) == 2
|
assert length(actors) == 2
|
||||||
|
|
||||||
mutation = """
|
mutation = """
|
||||||
|
|
|
@ -24,7 +24,7 @@ defmodule MobilizonWeb.ConnCase do
|
||||||
# The default endpoint for testing
|
# The default endpoint for testing
|
||||||
@endpoint MobilizonWeb.Endpoint
|
@endpoint MobilizonWeb.Endpoint
|
||||||
|
|
||||||
def auth_conn(%Plug.Conn{} = conn, %Mobilizon.Actors.User{} = user) do
|
def auth_conn(%Plug.Conn{} = conn, %Mobilizon.Users.User{} = user) do
|
||||||
{:ok, token, _claims} = MobilizonWeb.Guardian.encode_and_sign(user)
|
{:ok, token, _claims} = MobilizonWeb.Guardian.encode_and_sign(user)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -6,7 +6,7 @@ defmodule Mobilizon.Factory do
|
||||||
use ExMachina.Ecto, repo: Mobilizon.Repo
|
use ExMachina.Ecto, repo: Mobilizon.Repo
|
||||||
|
|
||||||
def user_factory do
|
def user_factory do
|
||||||
%Mobilizon.Actors.User{
|
%Mobilizon.Users.User{
|
||||||
password_hash: "Jane Smith",
|
password_hash: "Jane Smith",
|
||||||
email: sequence(:email, &"email-#{&1}@example.com"),
|
email: sequence(:email, &"email-#{&1}@example.com"),
|
||||||
role: 0,
|
role: 0,
|
||||||
|
|
Loading…
Reference in a new issue