commit: 211e561e2ad862c75a1b34f783d3210523dc211e
parent 143ea7b80a228d9bd23a77354fe214553ca2b8cc
Author: Ilja <ilja@ilja.space>
Date: Tue, 21 Jun 2022 11:13:32 +0200
Show privileges to FE
I added an extra key
We already had is_admin and is_moderator, now we have an extra privileges key
Diffstat:
4 files changed, 211 insertions(+), 5 deletions(-)
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
@@ -371,6 +371,28 @@ defmodule Pleroma.User do
defp privileged_for?(_, _, _), do: false
+ @spec privileges(User.t()) :: [atom()]
+ def privileges(%User{local: false}) do
+ []
+ end
+
+ def privileges(%User{is_moderator: false, is_admin: false}) do
+ []
+ end
+
+ def privileges(%User{local: true, is_moderator: true, is_admin: true}) do
+ (Config.get([:instance, :moderator_privileges]) ++ Config.get([:instance, :admin_privileges]))
+ |> Enum.uniq()
+ end
+
+ def privileges(%User{local: true, is_moderator: true, is_admin: false}) do
+ Config.get([:instance, :moderator_privileges])
+ end
+
+ def privileges(%User{local: true, is_moderator: false, is_admin: true}) do
+ Config.get([:instance, :admin_privileges])
+ end
+
@spec invisible?(User.t()) :: boolean()
def invisible?(%User{invisible: true}), do: true
def invisible?(_), do: false
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -369,19 +369,22 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
defp maybe_put_chat_token(data, _, _, _), do: data
defp maybe_put_role(data, %User{show_role: true} = user, _) do
- data
- |> Kernel.put_in([:pleroma, :is_admin], user.is_admin)
- |> Kernel.put_in([:pleroma, :is_moderator], user.is_moderator)
+ put_role(data, user)
end
defp maybe_put_role(data, %User{id: user_id} = user, %User{id: user_id}) do
+ put_role(data, user)
+ end
+
+ defp maybe_put_role(data, _, _), do: data
+
+ defp put_role(data, user) do
data
|> Kernel.put_in([:pleroma, :is_admin], user.is_admin)
|> Kernel.put_in([:pleroma, :is_moderator], user.is_moderator)
+ |> Kernel.put_in([:pleroma, :privileges], User.privileges(user))
end
- defp maybe_put_role(data, _, _), do: data
-
defp maybe_put_notification_settings(data, %User{id: user_id} = user, %User{id: user_id}) do
Kernel.put_in(
data,
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
@@ -1918,6 +1918,44 @@ defmodule Pleroma.UserTest do
end
end
+ describe "privileges/1" do
+ setup do
+ clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])
+ clear_config([:instance, :admin_privileges], [:cofe, :only_admin])
+ end
+
+ test "returns empty list for users without roles" do
+ user = insert(:user, local: true)
+
+ assert [] == User.privileges(user)
+ end
+
+ test "returns list of privileges for moderators" do
+ moderator = insert(:user, is_moderator: true, local: true)
+
+ assert [:cofe, :only_moderator] == User.privileges(moderator) |> Enum.sort()
+ end
+
+ test "returns list of privileges for admins" do
+ admin = insert(:user, is_admin: true, local: true)
+
+ assert [:cofe, :only_admin] == User.privileges(admin) |> Enum.sort()
+ end
+
+ test "returns list of unique privileges for users who are both moderator and admin" do
+ moderator_admin = insert(:user, is_moderator: true, is_admin: true, local: true)
+
+ assert [:cofe, :only_admin, :only_moderator] ==
+ User.privileges(moderator_admin) |> Enum.sort()
+ end
+
+ test "returns empty list for remote users" do
+ remote_moderator_admin = insert(:user, is_moderator: true, is_admin: true, local: false)
+
+ assert [] == User.privileges(remote_moderator_admin)
+ end
+ end
+
describe "invisible?/1" do
test "returns true for an invisible user" do
user = insert(:user, local: true, invisible: true)
diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs
@@ -84,6 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
tags: [],
is_admin: false,
is_moderator: false,
+ privileges: [],
is_suggested: false,
hide_favorites: true,
hide_followers: false,
@@ -99,6 +100,147 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
+ describe "roles and privileges" do
+ setup do
+ clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])
+ clear_config([:instance, :admin_privileges], [:cofe, :only_admin])
+
+ %{
+ user: insert(:user),
+ moderator: insert(:user, is_moderator: true),
+ admin: insert(:user, is_admin: true),
+ moderator_admin: insert(:user, is_moderator: true, is_admin: true),
+ user_no_show_roles: insert(:user, show_role: false),
+ moderator_admin_no_show_roles:
+ insert(:user, is_moderator: true, is_admin: true, show_role: false)
+ }
+ end
+
+ test "shows roles and privileges when show_role: true", %{
+ user: user,
+ moderator: moderator,
+ admin: admin,
+ moderator_admin: moderator_admin,
+ user_no_show_roles: user_no_show_roles,
+ moderator_admin_no_show_roles: moderator_admin_no_show_roles
+ } do
+ assert %{pleroma: %{is_moderator: false, is_admin: false}} =
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})
+
+ assert [] ==
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})[
+ :pleroma
+ ][:privileges]
+ |> Enum.sort()
+
+ assert %{pleroma: %{is_moderator: true, is_admin: false}} =
+ AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})
+
+ assert [:cofe, :only_moderator] ==
+ AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})[
+ :pleroma
+ ][:privileges]
+ |> Enum.sort()
+
+ assert %{pleroma: %{is_moderator: false, is_admin: true}} =
+ AccountView.render("show.json", %{user: admin, skip_visibility_check: true})
+
+ assert [:cofe, :only_admin] ==
+ AccountView.render("show.json", %{user: admin, skip_visibility_check: true})[
+ :pleroma
+ ][:privileges]
+ |> Enum.sort()
+
+ assert %{pleroma: %{is_moderator: true, is_admin: true}} =
+ AccountView.render("show.json", %{
+ user: moderator_admin,
+ skip_visibility_check: true
+ })
+
+ assert [:cofe, :only_admin, :only_moderator] ==
+ AccountView.render("show.json", %{
+ user: moderator_admin,
+ skip_visibility_check: true
+ })[:pleroma][:privileges]
+ |> Enum.sort()
+
+ refute match?(
+ %{pleroma: %{is_moderator: _}},
+ AccountView.render("show.json", %{
+ user: user_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+
+ refute match?(
+ %{pleroma: %{is_admin: _}},
+ AccountView.render("show.json", %{
+ user: user_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+
+ refute match?(
+ %{pleroma: %{privileges: _}},
+ AccountView.render("show.json", %{
+ user: user_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+
+ refute match?(
+ %{pleroma: %{is_moderator: _}},
+ AccountView.render("show.json", %{
+ user: moderator_admin_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+
+ refute match?(
+ %{pleroma: %{is_admin: _}},
+ AccountView.render("show.json", %{
+ user: moderator_admin_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+
+ refute match?(
+ %{pleroma: %{privileges: _}},
+ AccountView.render("show.json", %{
+ user: moderator_admin_no_show_roles,
+ skip_visibility_check: true
+ })
+ )
+ end
+
+ test "shows roles and privileges when viewing own account, even when show_role: false", %{
+ user_no_show_roles: user_no_show_roles,
+ moderator_admin_no_show_roles: moderator_admin_no_show_roles
+ } do
+ assert %{pleroma: %{is_moderator: false, is_admin: false, privileges: []}} =
+ AccountView.render("show.json", %{
+ user: user_no_show_roles,
+ skip_visibility_check: true,
+ for: user_no_show_roles
+ })
+
+ assert %{
+ pleroma: %{
+ is_moderator: true,
+ is_admin: true,
+ privileges: privileges
+ }
+ } =
+ AccountView.render("show.json", %{
+ user: moderator_admin_no_show_roles,
+ skip_visibility_check: true,
+ for: moderator_admin_no_show_roles
+ })
+
+ assert [:cofe, :only_admin, :only_moderator] == privileges |> Enum.sort()
+ end
+ end
+
describe "favicon" do
setup do
[user: insert(:user)]
@@ -186,6 +328,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
tags: [],
is_admin: false,
is_moderator: false,
+ privileges: [],
is_suggested: false,
hide_favorites: true,
hide_followers: false,