Introduce admin and moderator role, check role on list_users action
Signed-off-by: Thomas Citharel <tcit@tcit.fr> Add test for guards
This commit is contained in:
@@ -31,3 +31,13 @@ defmodule Mobilizon.Users.Service.Tools do
|
||||
|> Base.url_encode64()
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Mobilizon.Users.Guards do
|
||||
@moduledoc """
|
||||
Guards for users
|
||||
"""
|
||||
|
||||
defguard is_admin(role) when is_atom(role) and role == :administrator
|
||||
|
||||
defguard is_moderator(role) when is_atom(role) and role in [:administrator, :moderator]
|
||||
end
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import EctoEnum
|
||||
|
||||
defenum(Mobilizon.Users.UserRoleEnum, :user_role_type, [
|
||||
:administrator,
|
||||
:moderator,
|
||||
:user
|
||||
])
|
||||
|
||||
defmodule Mobilizon.Users.User do
|
||||
@moduledoc """
|
||||
Represents a local user
|
||||
@@ -12,7 +20,7 @@ defmodule Mobilizon.Users.User do
|
||||
field(:email, :string)
|
||||
field(:password_hash, :string)
|
||||
field(:password, :string, virtual: true)
|
||||
field(:role, :integer, default: 0)
|
||||
field(:role, Mobilizon.Users.UserRoleEnum, default: :user)
|
||||
has_many(:actors, Actor)
|
||||
belongs_to(:default_actor, Actor)
|
||||
field(:confirmed_at, :utc_datetime)
|
||||
|
||||
@@ -5,19 +5,18 @@ defmodule MobilizonWeb.Context do
|
||||
@behaviour Plug
|
||||
|
||||
import Plug.Conn
|
||||
require Logger
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
def init(opts) do
|
||||
opts
|
||||
end
|
||||
|
||||
def call(conn, _) do
|
||||
case Guardian.Plug.current_resource(conn) do
|
||||
with %User{} = user <- Guardian.Plug.current_resource(conn) do
|
||||
put_private(conn, :absinthe, %{context: %{current_user: user}})
|
||||
else
|
||||
nil ->
|
||||
conn
|
||||
|
||||
user ->
|
||||
put_private(conn, :absinthe, %{context: %{current_user: user}})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@ defmodule MobilizonWeb.Guardian do
|
||||
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
require Logger
|
||||
|
||||
def subject_for_token(%User{} = user, _claims) do
|
||||
{:ok, "User:" <> to_string(user.id)}
|
||||
@@ -21,6 +22,8 @@ defmodule MobilizonWeb.Guardian do
|
||||
end
|
||||
|
||||
def resource_from_claims(%{"sub" => "User:" <> uid_str}) do
|
||||
Logger.debug(fn -> "Receiving claim for user #{uid_str}" end)
|
||||
|
||||
try do
|
||||
case Integer.parse(uid_str) do
|
||||
{uid, ""} ->
|
||||
@@ -39,6 +42,8 @@ defmodule MobilizonWeb.Guardian do
|
||||
end
|
||||
|
||||
def after_encode_and_sign(resource, claims, token, _options) do
|
||||
Logger.debug(fn -> "after_encode_and_sign #{inspect(claims)}" end)
|
||||
|
||||
with {:ok, _} <- Guardian.DB.after_encode_and_sign(resource, claims["typ"], claims, token) do
|
||||
{:ok, token}
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.{Actors, Users}
|
||||
alias Mobilizon.Users.Service.{ResetPassword, Activation}
|
||||
import Mobilizon.Users.Guards
|
||||
require Logger
|
||||
|
||||
@doc """
|
||||
@@ -32,14 +33,20 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||
def list_and_count_users(
|
||||
_parent,
|
||||
%{page: page, limit: limit, sort: sort, direction: direction},
|
||||
_resolution
|
||||
) do
|
||||
%{
|
||||
context: %{current_user: %User{role: role}}
|
||||
}
|
||||
)
|
||||
when is_moderator(role) do
|
||||
total = Task.async(&Users.count_users/0)
|
||||
elements = Task.async(fn -> Users.list_users(page, limit, sort, direction) end)
|
||||
|
||||
{:ok, %{total: Task.await(total), elements: Task.await(elements)}}
|
||||
end
|
||||
|
||||
def list_and_count_users(_parent, _args, _resolution),
|
||||
do: {:error, "You need to have admin access to list users"}
|
||||
|
||||
@doc """
|
||||
Login an user. Returns a token and the user
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user