From 211e561e2ad862c75a1b34f783d3210523dc211e Mon Sep 17 00:00:00 2001 From: Ilja Date: Tue, 21 Jun 2022 11:13:32 +0200 Subject: [PATCH] Show privileges to FE I added an extra key We already had is_admin and is_moderator, now we have an extra privileges key --- lib/pleroma/user.ex | 22 +++ .../web/mastodon_api/views/account_view.ex | 15 +- test/pleroma/user_test.exs | 38 +++++ .../mastodon_api/views/account_view_test.exs | 143 ++++++++++++++++++ 4 files changed, 212 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 16438e524..fb2fade42 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -371,6 +371,28 @@ defp privileged_for?(privilege_tag, true, config_role_key), 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 index d3f2245e2..a28ad9d85 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -369,19 +369,22 @@ defp maybe_put_chat_token(data, %User{id: id}, %User{id: id}, %{ 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 - 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, _, _), 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_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 index 0262470b2..477553fe5 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -1918,6 +1918,44 @@ test "returns true for local admins if, and only if, they are privileged" 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 index d9d3866e7..ce94ec7e4 100644 --- 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 @@ test "Represent a user account" do tags: [], is_admin: false, is_moderator: false, + privileges: [], is_suggested: false, hide_favorites: true, hide_followers: false, @@ -99,6 +100,147 @@ test "Represent a user account" 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 @@ test "Represent a Service(bot) account" do tags: [], is_admin: false, is_moderator: false, + privileges: [], is_suggested: false, hide_favorites: true, hide_followers: false,