diff options
Diffstat (limited to 'test')
22 files changed, 1390 insertions, 310 deletions
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index a000c0efd..255097ed0 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.NotificationTest do - use Pleroma.DataCase + use Pleroma.DataCase, async: false import Pleroma.Factory import Mock @@ -32,20 +32,26 @@ defmodule Pleroma.NotificationTest do refute {:ok, [nil]} == Notification.create_notifications(activity) end - test "creates a notification for a report" do + test "creates a report notification only for privileged users" do reporting_user = insert(:user) reported_user = insert(:user) - {:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true}) + moderator_user = insert(:user, is_moderator: true) - {:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id}) + clear_config([:instance, :moderator_privileges], []) + {:ok, activity1} = CommonAPI.report(reporting_user, %{account_id: reported_user.id}) + {:ok, []} = Notification.create_notifications(activity1) - {:ok, [notification]} = Notification.create_notifications(activity) + clear_config([:instance, :moderator_privileges], [:reports_manage_reports]) + {:ok, activity2} = CommonAPI.report(reporting_user, %{account_id: reported_user.id}) + {:ok, [notification]} = Notification.create_notifications(activity2) assert notification.user_id == moderator_user.id assert notification.type == "pleroma:report" end - test "suppresses notification to reporter if reporter is an admin" do + test "suppresses notifications for own reports" do + clear_config([:instance, :admin_privileges], [:reports_manage_reports]) + reporting_admin = insert(:user, is_admin: true) reported_user = insert(:user) other_admin = insert(:user, is_admin: true) @@ -542,25 +548,6 @@ defmodule Pleroma.NotificationTest do end end - describe "destroy_multiple_from_types/2" do - test "clears all notifications of a certain type for a given user" do - report_activity = insert(:report_activity) - user1 = insert(:user, is_moderator: true, is_admin: true) - user2 = insert(:user, is_moderator: true, is_admin: true) - {:ok, _} = Notification.create_notifications(report_activity) - - {:ok, _} = - CommonAPI.post(user2, %{ - status: "hey @#{user1.nickname} !" - }) - - Notification.destroy_multiple_from_types(user1, ["pleroma:report"]) - - assert [%Pleroma.Notification{type: "mention"}] = Notification.for_user(user1) - assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user2) - end - end - describe "set_read_up_to()" do test "it sets all notifications as read up to a specified notification ID" do user = insert(:user) diff --git a/test/pleroma/user/query_test.exs b/test/pleroma/user/query_test.exs index bd45d1bca..30a4637f2 100644 --- a/test/pleroma/user/query_test.exs +++ b/test/pleroma/user/query_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.User.QueryTest do - use Pleroma.DataCase, async: true + use Pleroma.DataCase, async: false alias Pleroma.Repo alias Pleroma.User @@ -44,4 +44,63 @@ defmodule Pleroma.User.QueryTest do |> User.Query.build() |> Repo.all() end + + describe "is_privileged param" do + setup do + %{ + user: insert(:user, local: true, is_admin: false, is_moderator: false), + moderator_user: insert(:user, local: true, is_admin: false, is_moderator: true), + admin_user: insert(:user, local: true, is_admin: true, is_moderator: false), + admin_moderator_user: insert(:user, local: true, is_admin: true, is_moderator: true), + remote_user: insert(:user, local: false, is_admin: true, is_moderator: true), + non_active_user: + insert(:user, local: true, is_admin: true, is_moderator: true, is_active: false) + } + end + + test "doesn't return any users when there are no privileged roles" do + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], []) + + assert [] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + end + + test "returns moderator users if they are privileged", %{ + moderator_user: moderator_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], [:cofe]) + + assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + end + + test "returns admin users if they are privileged", %{ + admin_user: admin_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], [:cofe]) + clear_config([:instance, :moderator_privileges], []) + + assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert admin_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + end + + test "returns admin and moderator users if they are both privileged", %{ + moderator_user: moderator_user, + admin_user: admin_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], [:cofe]) + clear_config([:instance, :moderator_privileges], [:cofe]) + + assert [_, _, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert admin_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + assert moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + assert admin_moderator_user in (User.Query.build(%{is_privileged: :cofe}) |> Repo.all()) + end + end end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index a58c8f68b..c16312a65 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -5,7 +5,6 @@ defmodule Pleroma.UserTest do alias Pleroma.Activity alias Pleroma.Builders.UserBuilder - alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo alias Pleroma.Tests.ObanHelpers @@ -13,7 +12,7 @@ defmodule Pleroma.UserTest do alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.CommonAPI - use Pleroma.DataCase + use Pleroma.DataCase, async: false use Oban.Testing, repo: Pleroma.Repo import Pleroma.Factory @@ -473,12 +472,7 @@ defmodule Pleroma.UserTest do reject_deletes: [] ) - setup do: - clear_config(:mrf, - policies: [ - Pleroma.Web.ActivityPub.MRF.SimplePolicy - ] - ) + setup do: clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) test "it sends a welcome chat message when Simple policy applied to local instance" do clear_config([:mrf_simple, :media_nsfw], [{"localhost", ""}]) @@ -2038,31 +2032,82 @@ defmodule Pleroma.UserTest do end end - describe "superuser?/1" do + describe "privileged?/1" do + setup do + clear_config([:instance, :admin_privileges], [:cofe, :suya]) + clear_config([:instance, :moderator_privileges], [:cofe, :suya]) + end + test "returns false for unprivileged users" do user = insert(:user, local: true) - refute User.superuser?(user) + refute User.privileged?(user, :cofe) end test "returns false for remote users" do user = insert(:user, local: false) remote_admin_user = insert(:user, local: false, is_admin: true) - refute User.superuser?(user) - refute User.superuser?(remote_admin_user) + refute User.privileged?(user, :cofe) + refute User.privileged?(remote_admin_user, :cofe) end - test "returns true for local moderators" do + test "returns true for local moderators if, and only if, they are privileged" do user = insert(:user, local: true, is_moderator: true) - assert User.superuser?(user) + assert User.privileged?(user, :cofe) + + clear_config([:instance, :moderator_privileges], []) + + refute User.privileged?(user, :cofe) end - test "returns true for local admins" do + test "returns true for local admins if, and only if, they are privileged" do user = insert(:user, local: true, is_admin: true) - assert User.superuser?(user) + assert User.privileged?(user, :cofe) + + clear_config([:instance, :admin_privileges], []) + + refute User.privileged?(user, :cofe) + 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 @@ -2105,13 +2150,77 @@ defmodule Pleroma.UserTest do assert User.visible_for(user, other_user) == :visible end - test "returns true when the account is unconfirmed and being viewed by a privileged account (confirmation required)" do + test "returns true when the account is unconfirmed and being viewed by a privileged account (privilege :users_manage_activation_state, confirmation required)" do clear_config([:instance, :account_activation_required], true) + clear_config([:instance, :admin_privileges], [:users_manage_activation_state]) user = insert(:user, local: true, is_confirmed: false) other_user = insert(:user, local: true, is_admin: true) assert User.visible_for(user, other_user) == :visible + + clear_config([:instance, :admin_privileges], []) + + refute User.visible_for(user, other_user) == :visible + end + end + + describe "all_users_with_privilege/1" do + setup do + %{ + user: insert(:user, local: true, is_admin: false, is_moderator: false), + moderator_user: insert(:user, local: true, is_admin: false, is_moderator: true), + admin_user: insert(:user, local: true, is_admin: true, is_moderator: false), + admin_moderator_user: insert(:user, local: true, is_admin: true, is_moderator: true), + remote_user: insert(:user, local: false, is_admin: true, is_moderator: true), + non_active_user: + insert(:user, local: true, is_admin: true, is_moderator: true, is_active: false) + } + end + + test "doesn't return any users when there are no privileged roles" do + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], []) + + assert [] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + end + + test "returns moderator users if they are privileged", %{ + moderator_user: moderator_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], [:cofe]) + + assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert moderator_user in User.all_users_with_privilege(:cofe) + assert admin_moderator_user in User.all_users_with_privilege(:cofe) + end + + test "returns admin users if they are privileged", %{ + admin_user: admin_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], [:cofe]) + clear_config([:instance, :moderator_privileges], []) + + assert [_, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert admin_user in User.all_users_with_privilege(:cofe) + assert admin_moderator_user in User.all_users_with_privilege(:cofe) + end + + test "returns admin and moderator users if they are both privileged", %{ + moderator_user: moderator_user, + admin_user: admin_user, + admin_moderator_user: admin_moderator_user + } do + clear_config([:instance, :admin_privileges], [:cofe]) + clear_config([:instance, :moderator_privileges], [:cofe]) + + assert [_, _, _] = User.Query.build(%{is_privileged: :cofe}) |> Repo.all() + assert admin_user in User.all_users_with_privilege(:cofe) + assert moderator_user in User.all_users_with_privilege(:cofe) + assert admin_moderator_user in User.all_users_with_privilege(:cofe) end end @@ -2351,26 +2460,6 @@ defmodule Pleroma.UserTest do assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}") assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id) end - - test "removes report notifs when user isn't superuser any more" do - report_activity = insert(:report_activity) - user = insert(:user, is_moderator: true, is_admin: true) - {:ok, _} = Notification.create_notifications(report_activity) - - assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user) - - {:ok, user} = user |> User.admin_api_update(%{is_moderator: false}) - # is still superuser because still admin - assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user) - - {:ok, user} = user |> User.admin_api_update(%{is_moderator: true, is_admin: false}) - # is still superuser because still moderator - assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user) - - {:ok, user} = user |> User.admin_api_update(%{is_moderator: false}) - # is not a superuser any more - assert [] = Notification.for_user(user) - end end describe "following/followers synchronization" do diff --git a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs index ea4664859..bbb31516c 100644 --- a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do - use Pleroma.DataCase, async: true + use Pleroma.DataCase, async: false alias Pleroma.Object alias Pleroma.Web.ActivityPub.Builder @@ -90,17 +90,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do assert {:actor, {"is not allowed to modify object", []}} in cng.errors end - test "it's valid if the actor of the object is a local superuser", + test "it's only valid if the actor of the object is a privileged local user", %{valid_post_delete: valid_post_delete} do + clear_config([:instance, :moderator_privileges], [:messages_delete]) + user = insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo") - valid_other_actor = + post_delete_with_moderator_actor = valid_post_delete |> Map.put("actor", user.ap_id) - {:ok, _, meta} = ObjectValidator.validate(valid_other_actor, []) + {:ok, _, meta} = ObjectValidator.validate(post_delete_with_moderator_actor, []) + assert meta[:do_not_federate] + + clear_config([:instance, :moderator_privileges], []) + + {:error, cng} = ObjectValidator.validate(post_delete_with_moderator_actor, []) + + assert {:actor, {"is not allowed to modify object", []}} in cng.errors end end end diff --git a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs index d83f7f011..e1ab50542 100644 --- a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false use Oban.Testing, repo: Pleroma.Repo import ExUnit.CaptureLog @@ -92,18 +92,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "PUT /api/pleroma/admin/users/tag" do setup %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_tags]) + user1 = insert(:user, %{tags: ["x"]}) user2 = insert(:user, %{tags: ["y"]}) user3 = insert(:user, %{tags: ["unchanged"]}) - conn = - conn - |> put_req_header("accept", "application/json") - |> put( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> - "#{user2.nickname}&tags[]=foo&tags[]=bar" - ) - %{conn: conn, user1: user1, user2: user2, user3: user3} end @@ -113,6 +107,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user1: user1, user2: user2 } do + conn = + conn + |> put_req_header("accept", "application/json") + |> put( + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=foo&tags[]=bar" + ) + assert empty_json_response(conn) assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"] assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"] @@ -130,26 +132,43 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} added tags: #{tags} to users: #{users}" end - test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do + test "it does not modify tags of not specified users", %{ + conn: conn, + user1: user1, + user2: user2, + user3: user3 + } do + conn = + conn + |> put_req_header("accept", "application/json") + |> put( + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=foo&tags[]=bar" + ) + assert empty_json_response(conn) assert User.get_cached_by_id(user3.id).tags == ["unchanged"] end + + test "it requires privileged role :users_manage_tags", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> put_req_header("accept", "application/json") + |> put("/api/pleroma/admin/users/tag?nicknames[]=nickname&tags[]=foo&tags[]=bar") + + assert json_response(response, :forbidden) + end end describe "DELETE /api/pleroma/admin/users/tag" do setup %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_tags]) user1 = insert(:user, %{tags: ["x"]}) user2 = insert(:user, %{tags: ["y", "z"]}) user3 = insert(:user, %{tags: ["unchanged"]}) - conn = - conn - |> put_req_header("accept", "application/json") - |> delete( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> - "#{user2.nickname}&tags[]=x&tags[]=z" - ) - %{conn: conn, user1: user1, user2: user2, user3: user3} end @@ -159,6 +178,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user1: user1, user2: user2 } do + conn = + conn + |> put_req_header("accept", "application/json") + |> delete( + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=x&tags[]=z" + ) + assert empty_json_response(conn) assert User.get_cached_by_id(user1.id).tags == [] assert User.get_cached_by_id(user2.id).tags == ["y"] @@ -176,10 +203,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} removed tags: #{tags} from users: #{users}" end - test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do + test "it does not modify tags of not specified users", %{ + conn: conn, + user1: user1, + user2: user2, + user3: user3 + } do + conn = + conn + |> put_req_header("accept", "application/json") + |> delete( + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=x&tags[]=z" + ) + assert empty_json_response(conn) assert User.get_cached_by_id(user3.id).tags == ["unchanged"] end + + test "it requires privileged role :users_manage_tags", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> put_req_header("accept", "application/json") + |> delete("/api/pleroma/admin/users/tag?nicknames[]=nickname&tags[]=foo&tags[]=bar") + + assert json_response(response, :forbidden) + end end describe "/api/pleroma/admin/users/:nickname/permission_group" do @@ -271,21 +322,38 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end - test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do - user = insert(:user) + describe "/api/pleroma/admin/users/:nickname/password_reset" do + test "it returns a password reset link", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) - conn = - conn - |> put_req_header("accept", "application/json") - |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset") + user = insert(:user) + + conn = + conn + |> put_req_header("accept", "application/json") + |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset") - resp = json_response(conn, 200) + resp = json_response(conn, 200) - assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"]) + assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"]) + end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> put_req_header("accept", "application/json") + |> get("/api/pleroma/admin/users/nickname/password_reset") + + assert json_response(response, :forbidden) + end end describe "PUT disable_mfa" do test "returns 200 and disable 2fa", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) + user = insert(:user, multi_factor_authentication_settings: %MFA.Settings{ @@ -307,6 +375,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end test "returns 404 if user not found", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) + response = conn |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"}) @@ -314,6 +384,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert response == %{"error" => "Not found"} end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"}) + + assert json_response(response, :forbidden) + end end describe "GET /api/pleroma/admin/restart" do @@ -344,6 +424,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "GET /api/pleroma/admin/users/:nickname/statuses" do setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + user = insert(:user) insert(:note_activity, user: user) @@ -360,6 +442,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert length(activities) == 3 end + test "it requires privileged role :messages_read", %{conn: conn, user: user} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses") + + assert json_response(conn, :forbidden) + end + test "renders user's statuses with pagination", %{conn: conn, user: user} do %{"total" => 3, "activities" => [activity1]} = conn @@ -421,20 +511,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "GET /api/pleroma/admin/users/:nickname/chats" do setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + user = insert(:user) + + %{user: user} + end + + test "renders user's chats", %{conn: conn, user: user} do recipients = insert_list(3, :user) Enum.each(recipients, fn recipient -> CommonAPI.post_chat_message(user, recipient, "yo") end) - %{user: user} + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats") + + assert json_response(conn, 200) |> length() == 3 end - test "renders user's chats", %{conn: conn, user: user} do + test "it requires privileged role :messages_read", %{conn: conn, user: user} do + clear_config([:instance, :admin_privileges], []) + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/chats") - assert json_response(conn, 200) |> length() == 3 + assert json_response(conn, :forbidden) end end @@ -471,6 +572,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "GET /api/pleroma/admin/moderation_log" do setup do + clear_config([:instance, :admin_privileges], [:moderation_log_read]) moderator = insert(:user, is_moderator: true) %{moderator: moderator} @@ -675,6 +777,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert get_in(first_entry, ["data", "message"]) == "@#{moderator.nickname} unfollowed relay: https://example.org/relay" end + + test "it requires privileged role :moderation_log_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "multipart/form-data") + |> get("/api/pleroma/admin/moderation_log") + |> json_response(:forbidden) + end end test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated", @@ -688,6 +799,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "GET /users/:nickname/credentials" do test "gets the user credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) user = insert(:user) conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials") @@ -696,6 +808,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end test "returns 403 if requested by a non-admin" do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) user = insert(:user) conn = @@ -705,6 +818,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, :forbidden) end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> get("/api/pleroma/admin/users/nickname/credentials") + + assert json_response(response, :forbidden) + end end describe "PATCH /users/:nickname/credentials" do @@ -714,6 +837,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end test "changes password and email", %{conn: conn, admin: admin, user: user} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) + assert user.password_reset_pending == false conn = @@ -756,6 +881,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, :forbidden) end + test "returns 403 if not privileged with :users_manage_credentials", %{conn: conn, user: user} do + clear_config([:instance, :admin_privileges], []) + + conn = + patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{ + "password" => "new_password", + "email" => "new_email@example.com", + "name" => "new_name" + }) + + assert json_response(conn, :forbidden) + end + test "changes actor type from permitted list", %{conn: conn, user: user} do assert user.actor_type == "Person" @@ -784,6 +922,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "PATCH /users/:nickname/force_password_reset" do test "sets password_reset_pending to true", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) user = insert(:user) assert user.password_reset_pending == false @@ -796,10 +935,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert User.get_by_id(user.id).password_reset_pending == true end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> patch("/api/pleroma/admin/users/force_password_reset", %{nickname: "nickname"}) + + assert json_response(response, :forbidden) + end end describe "PATCH /confirm_email" do test "it confirms emails of two users", %{conn: conn, admin: admin} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) [first_user, second_user] = insert_pair(:user, is_confirmed: false) refute first_user.is_confirmed @@ -826,10 +976,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert ModerationLog.get_log_entry_message(log_entry) == "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{second_user.nickname}" end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> patch("/api/pleroma/admin/users/confirm_email", %{nicknames: ["nickname"]}) + + assert json_response(response, :forbidden) + end end describe "PATCH /resend_confirmation_email" do test "it resend emails for two users", %{conn: conn, admin: admin} do + clear_config([:instance, :admin_privileges], [:users_manage_credentials]) [first_user, second_user] = insert_pair(:user, is_confirmed: false) ret_conn = @@ -855,9 +1016,23 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> Swoosh.Email.put_private(:hackney_options, ssl_options: [versions: [:"tlsv1.2"]]) |> assert_email_sent() end + + test "it requires privileged role :users_manage_credentials", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> patch("/api/pleroma/admin/users/resend_confirmation_email", %{nicknames: ["nickname"]}) + + assert json_response(response, :forbidden) + end end describe "/api/pleroma/admin/stats" do + setup do + clear_config([:instance, :admin_privileges], [:statistics_read]) + end + test "status visibility count", %{conn: conn} do user = insert(:user) CommonAPI.post(user, %{visibility: "public", status: "hey"}) @@ -890,6 +1065,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} = response["status_visibility"] end + + test "it requires privileged role :statistics_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> get("/api/pleroma/admin/stats", instance: "lain.wired") + |> json_response(:forbidden) + end end describe "/api/pleroma/backups" do @@ -958,6 +1141,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert Repo.aggregate(Pleroma.User.Backup, :count) == 2 end end + + describe "POST /api/v1/pleroma/admin/reload_emoji" do + setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) + + admin = insert(:user, is_admin: true) + token = insert(:oauth_admin_token, user: admin) + + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, token) + + {:ok, %{conn: conn, admin: admin}} + end + + test "it requires privileged role :emoji_manage_emoji", %{conn: conn} do + assert conn + |> post("/api/v1/pleroma/admin/reload_emoji") + |> json_response(200) + + clear_config([:instance, :admin_privileges], []) + + assert conn + |> post("/api/v1/pleroma/admin/reload_emoji") + |> json_response(:forbidden) + end + end end # Needed for testing diff --git a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs index 5b8148c05..cf60bcad5 100644 --- a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs @@ -3,11 +3,12 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory setup do + clear_config([:instance, :admin_privileges], [:announcements_manage_announcements]) admin = insert(:user, is_admin: true) token = insert(:oauth_admin_token, user: admin) @@ -31,6 +32,18 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do assert [%{"id" => ^id}] = response end + test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do + conn + |> get("/api/v1/pleroma/admin/announcements") + |> json_response_and_validate_schema(:ok) + + clear_config([:instance, :admin_privileges], []) + + conn + |> get("/api/v1/pleroma/admin/announcements") + |> json_response(:forbidden) + end + test "it paginates announcements", %{conn: conn} do _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end) @@ -92,6 +105,20 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do assert %{"id" => ^id} = response end + test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do + %{id: id} = insert(:announcement) + + conn + |> get("/api/v1/pleroma/admin/announcements/#{id}") + |> json_response_and_validate_schema(:ok) + + clear_config([:instance, :admin_privileges], []) + + conn + |> get("/api/v1/pleroma/admin/announcements/#{id}") + |> json_response(:forbidden) + end + test "it returns not found for non-existent id", %{conn: conn} do %{id: id} = insert(:announcement) @@ -112,6 +139,20 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do |> json_response_and_validate_schema(:ok) end + test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do + %{id: id} = insert(:announcement) + + conn + |> delete("/api/v1/pleroma/admin/announcements/#{id}") + |> json_response_and_validate_schema(:ok) + + clear_config([:instance, :admin_privileges], []) + + conn + |> delete("/api/v1/pleroma/admin/announcements/#{id}") + |> json_response(:forbidden) + end + test "it returns not found for non-existent id", %{conn: conn} do %{id: id} = insert(:announcement) @@ -156,6 +197,29 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do assert NaiveDateTime.compare(new.starts_at, starts_at) == :eq end + test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do + %{id: id} = insert(:announcement) + + now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) + starts_at = NaiveDateTime.add(now, -10, :second) + + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{ + starts_at: NaiveDateTime.to_iso8601(starts_at) + }) + |> json_response_and_validate_schema(:ok) + + clear_config([:instance, :admin_privileges], []) + + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{ + starts_at: NaiveDateTime.to_iso8601(starts_at) + }) + |> json_response(:forbidden) + end + test "it updates with time with utc timezone", %{conn: conn} do %{id: id} = insert(:announcement) @@ -250,6 +314,36 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do assert NaiveDateTime.compare(announcement.ends_at, ends_at) == :eq end + test "it requires privileged role :announcements_manage_announcements", %{conn: conn} do + content = "test post announcement api" + + now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) + starts_at = NaiveDateTime.add(now, -10, :second) + ends_at = NaiveDateTime.add(now, 10, :second) + + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/pleroma/admin/announcements", %{ + "content" => content, + "starts_at" => NaiveDateTime.to_iso8601(starts_at), + "ends_at" => NaiveDateTime.to_iso8601(ends_at), + "all_day" => true + }) + |> json_response_and_validate_schema(:ok) + + clear_config([:instance, :admin_privileges], []) + + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/pleroma/admin/announcements", %{ + "content" => content, + "starts_at" => NaiveDateTime.to_iso8601(starts_at), + "ends_at" => NaiveDateTime.to_iso8601(ends_at), + "all_day" => true + }) + |> json_response(:forbidden) + end + test "creating with time with utc timezones", %{conn: conn} do content = "test post announcement api" diff --git a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs index 0ef7c367b..1b5c31b7d 100644 --- a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.ChatControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory @@ -27,7 +27,10 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do end describe "DELETE /api/pleroma/admin/chats/:id/messages/:message_id" do - setup do: admin_setup() + setup do + clear_config([:instance, :admin_privileges], [:messages_delete]) + admin_setup() + end test "it deletes a message from the chat", %{conn: conn, admin: admin} do user = insert(:user) @@ -60,10 +63,22 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do refute MessageReference.get_by_id(recipient_cm_ref.id) assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id) end + + test "it requires privileged role :messages_delete", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/admin/chats/some_id/messages/some_ref_id") + |> json_response(:forbidden) + end end describe "GET /api/pleroma/admin/chats/:id/messages" do - setup do: admin_setup() + setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + admin_setup() + end test "it paginates", %{conn: conn} do user = insert(:user) @@ -114,10 +129,21 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do assert length(result) == 3 end + + test "it requires privileged role :messages_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/chats/some_id/messages") + + assert json_response(conn, :forbidden) + end end describe "GET /api/pleroma/admin/chats/:id" do - setup do: admin_setup() + setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + admin_setup() + end test "it returns a chat", %{conn: conn} do user = insert(:user) @@ -135,6 +161,14 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do assert %{} = result["receiver"] refute result["account"] end + + test "it requires privileged role :messages_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/chats/some_id") + + assert json_response(conn, :forbidden) + end end describe "unauthorized chat moderation" do diff --git a/test/pleroma/web/admin_api/controllers/instance_controller_test.exs b/test/pleroma/web/admin_api/controllers/instance_controller_test.exs index 72436cd83..6cca623f3 100644 --- a/test/pleroma/web/admin_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/instance_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false use Oban.Testing, repo: Pleroma.Repo import Pleroma.Factory @@ -31,6 +31,7 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do end test "GET /instances/:instance/statuses", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:messages_read]) user = insert(:user, local: false, ap_id: "https://archae.me/users/archaeme") user2 = insert(:user, local: false, ap_id: "https://test.com/users/test") insert_pair(:note_activity, user: user) @@ -60,9 +61,14 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do |> json_response(200) assert length(activities) == 3 + + clear_config([:instance, :admin_privileges], []) + + conn |> get("/api/pleroma/admin/instances/archae.me/statuses") |> json_response(:forbidden) end test "DELETE /instances/:instance", %{conn: conn} do + clear_config([:instance, :admin_privileges], [:instances_delete]) user = insert(:user, nickname: "lain@lain.com") post = insert(:note_activity, user: user) @@ -76,5 +82,11 @@ defmodule Pleroma.Web.AdminAPI.InstanceControllerTest do assert response == "lain.com" refute Repo.reload(user).is_active refute Repo.reload(post) + + clear_config([:instance, :admin_privileges], []) + + conn + |> delete("/api/pleroma/admin/instances/lain.com") + |> json_response(:forbidden) end end diff --git a/test/pleroma/web/admin_api/controllers/invite_controller_test.exs b/test/pleroma/web/admin_api/controllers/invite_controller_test.exs index b9d48a4b6..8051cb2e9 100644 --- a/test/pleroma/web/admin_api/controllers/invite_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/invite_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.InviteControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory @@ -23,8 +23,25 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do end describe "POST /api/pleroma/admin/users/email_invite, with valid config" do - setup do: clear_config([:instance, :registrations_open], false) - setup do: clear_config([:instance, :invites_enabled], true) + setup do + clear_config([:instance, :registrations_open], false) + clear_config([:instance, :invites_enabled], true) + clear_config([:instance, :admin_privileges], [:users_manage_invites]) + end + + test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json;charset=utf-8") + |> post("/api/pleroma/admin/users/email_invite", %{ + email: "foo@bar.com", + name: "J. D." + }) + + assert json_response(conn, :forbidden) + end test "sends invitation and returns 204", %{admin: admin, conn: conn} do recipient_email = "foo@bar.com" @@ -114,8 +131,11 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do end describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do - setup do: clear_config([:instance, :registrations_open]) - setup do: clear_config([:instance, :invites_enabled]) + setup do + clear_config([:instance, :registrations_open]) + clear_config([:instance, :invites_enabled]) + clear_config([:instance, :admin_privileges], [:users_manage_invites]) + end test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do clear_config([:instance, :registrations_open], false) @@ -157,6 +177,21 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do end describe "POST /api/pleroma/admin/users/invite_token" do + setup do + clear_config([:instance, :admin_privileges], [:users_manage_invites]) + end + + test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/pleroma/admin/users/invite_token") + + assert json_response(conn, :forbidden) + end + test "without options", %{conn: conn} do conn = conn @@ -221,6 +256,18 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do end describe "GET /api/pleroma/admin/users/invites" do + setup do + clear_config([:instance, :admin_privileges], [:users_manage_invites]) + end + + test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/users/invites") + + assert json_response(conn, :forbidden) + end + test "no invites", %{conn: conn} do conn = get(conn, "/api/pleroma/admin/users/invites") @@ -249,6 +296,21 @@ defmodule Pleroma.Web.AdminAPI.InviteControllerTest do end describe "POST /api/pleroma/admin/users/revoke_invite" do + setup do + clear_config([:instance, :admin_privileges], [:users_manage_invites]) + end + + test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"}) + + assert json_response(conn, :forbidden) + end + test "with token", %{conn: conn} do {:ok, invite} = UserInviteToken.create_invite() diff --git a/test/pleroma/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs index 6fd3fbe5a..aee26d80a 100644 --- a/test/pleroma/web/admin_api/controllers/report_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/report_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.ReportControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory @@ -26,6 +26,20 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do end describe "GET /api/pleroma/admin/reports/:id" do + setup do + clear_config([:instance, :admin_privileges], [:reports_manage_reports]) + end + + test "returns 403 if not privileged with :reports_manage_reports", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> get("/api/pleroma/admin/reports/report_id") + + assert json_response(conn, :forbidden) + end + test "returns report by its id", %{conn: conn} do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -89,6 +103,8 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do describe "PATCH /api/pleroma/admin/reports" do setup do + clear_config([:instance, :admin_privileges], [:reports_manage_reports]) + [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -112,6 +128,24 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do } end + test "returns 403 if not privileged with :reports_manage_reports", %{ + conn: conn, + id: id, + admin: admin + } do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> assign(:token, insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])) + |> put_req_header("content-type", "application/json") + |> patch("/api/pleroma/admin/reports", %{ + "reports" => [%{"state" => "resolved", "id" => id}] + }) + + assert json_response(conn, :forbidden) + end + test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"]) write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"]) @@ -235,6 +269,20 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do end describe "GET /api/pleroma/admin/reports" do + setup do + clear_config([:instance, :admin_privileges], [:reports_manage_reports]) + end + + test "returns 403 if not privileged with :reports_manage_reports", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> get(report_path(conn, :index)) + + assert json_response(conn, :forbidden) + end + test "returns empty response when no reports created", %{conn: conn} do response = conn @@ -343,6 +391,8 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do describe "POST /api/pleroma/admin/reports/:id/notes" do setup %{conn: conn, admin: admin} do + clear_config([:instance, :admin_privileges], [:reports_manage_reports]) + [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -371,6 +421,25 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do } end + test "returns 403 if not privileged with :reports_manage_reports", %{ + conn: conn, + report_id: report_id + } do + clear_config([:instance, :admin_privileges], []) + + post_conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/pleroma/admin/reports/#{report_id}/notes", %{ + content: "this is disgusting2!" + }) + + delete_conn = delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/note.id") + + assert json_response(post_conn, :forbidden) + assert json_response(delete_conn, :forbidden) + end + test "it creates report note", %{admin_id: admin_id, report_id: report_id} do assert [note, _] = Repo.all(ReportNote) diff --git a/test/pleroma/web/admin_api/controllers/status_controller_test.exs b/test/pleroma/web/admin_api/controllers/status_controller_test.exs index 8bb96ca87..8908a2812 100644 --- a/test/pleroma/web/admin_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/status_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.StatusControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory @@ -26,6 +26,10 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do end describe "GET /api/pleroma/admin/statuses/:id" do + setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + end + test "not found", %{conn: conn} do assert conn |> get("/api/pleroma/admin/statuses/not_found") @@ -50,10 +54,17 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do assert account["is_active"] == actor.is_active assert account["is_confirmed"] == actor.is_confirmed end + + test "denies reading activity when not privileged", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn |> get("/api/pleroma/admin/statuses/some_id") |> json_response(:forbidden) + end end describe "PUT /api/pleroma/admin/statuses/:id" do setup do + clear_config([:instance, :admin_privileges], [:messages_delete]) activity = insert(:note_activity) %{id: activity.id} @@ -122,10 +133,20 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do assert %{"error" => "test - Invalid value for enum."} = json_response_and_validate_schema(conn, :bad_request) end + + test "it requires privileged role :messages_delete", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "application/json") + |> put("/api/pleroma/admin/statuses/some_id", %{}) + |> json_response(:forbidden) + end end describe "DELETE /api/pleroma/admin/statuses/:id" do setup do + clear_config([:instance, :admin_privileges], [:messages_delete]) activity = insert(:note_activity) %{id: activity.id} @@ -149,9 +170,22 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"} end + + test "it requires privileged role :messages_delete", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "application/json") + |> delete("/api/pleroma/admin/statuses/some_id") + |> json_response(:forbidden) + end end describe "GET /api/pleroma/admin/statuses" do + setup do + clear_config([:instance, :admin_privileges], [:messages_read]) + end + test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do blocked = insert(:user) user = insert(:user) @@ -197,5 +231,13 @@ defmodule Pleroma.Web.AdminAPI.StatusControllerTest do conn = get(conn, "/api/pleroma/admin/statuses?godmode=true") assert json_response_and_validate_schema(conn, 200) |> length() == 3 end + + test "it requires privileged role :messages_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/statuses") + + assert json_response(conn, :forbidden) + end end end diff --git a/test/pleroma/web/admin_api/controllers/user_controller_test.exs b/test/pleroma/web/admin_api/controllers/user_controller_test.exs index 79971be06..bb9dcb4aa 100644 --- a/test/pleroma/web/admin_api/controllers/user_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/user_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.UserControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false use Oban.Testing, repo: Pleroma.Repo import Mock @@ -38,6 +38,7 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do end test "with valid `admin_token` query parameter, skips OAuth scopes check" do + clear_config([:instance, :admin_privileges], [:users_read]) clear_config([:admin_token], "password123") user = insert(:user) @@ -47,53 +48,10 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do assert json_response_and_validate_schema(conn, 200) end - test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope", - %{admin: admin} do - user = insert(:user) - url = "/api/pleroma/admin/users/#{user.nickname}" - - good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"]) - good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"]) - good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"]) - - bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"]) - bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"]) - bad_token3 = nil - - for good_token <- [good_token1, good_token2, good_token3] do - conn = - build_conn() - |> assign(:user, admin) - |> assign(:token, good_token) - |> get(url) - - assert json_response_and_validate_schema(conn, 200) - end - - for good_token <- [good_token1, good_token2, good_token3] do - conn = - build_conn() - |> assign(:user, nil) - |> assign(:token, good_token) - |> get(url) - - assert json_response(conn, :forbidden) - end - - for bad_token <- [bad_token1, bad_token2, bad_token3] do - conn = - build_conn() - |> assign(:user, admin) - |> assign(:token, bad_token) - |> get(url) - - assert json_response_and_validate_schema(conn, :forbidden) - end - end - describe "DELETE /api/pleroma/admin/users" do test "single user", %{admin: admin, conn: conn} do clear_config([:instance, :federating], true) + clear_config([:instance, :admin_privileges], [:users_delete]) user = insert(:user, @@ -149,6 +107,8 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do end test "multiple users", %{admin: admin, conn: conn} do + clear_config([:instance, :admin_privileges], [:users_delete]) + user_one = insert(:user) user_two = insert(:user) @@ -168,6 +128,17 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do assert response -- [user_one.nickname, user_two.nickname] == [] end + + test "Needs privileged role", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + response = + conn + |> put_req_header("accept", "application/json") + |> delete("/api/pleroma/admin/users?nickname=nickname") + + assert json_response(response, :forbidden) + end end describe "/api/pleroma/admin/users" do @@ -307,7 +278,19 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do end end - describe "/api/pleroma/admin/users/:nickname" do + describe "GET /api/pleroma/admin/users/:nickname" do + setup do + clear_config([:instance, :admin_privileges], [:users_read]) + end + + test "returns 403 if not privileged with :users_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/users/user.nickname") + + assert json_response(conn, :forbidden) + end + test "Show", %{conn: conn} do user = insert(:user) @@ -323,6 +306,50 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do assert %{"error" => "Not found"} == json_response_and_validate_schema(conn, 404) end + + test "requires admin:read:accounts or broader scope", + %{admin: admin} do + user = insert(:user) + url = "/api/pleroma/admin/users/#{user.nickname}" + + good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"]) + good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"]) + good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"]) + + bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"]) + bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"]) + bad_token3 = nil + + for good_token <- [good_token1, good_token2, good_token3] do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, good_token) + |> get(url) + + assert json_response_and_validate_schema(conn, 200) + end + + for good_token <- [good_token1, good_token2, good_token3] do + conn = + build_conn() + |> assign(:user, nil) + |> assign(:token, good_token) + |> get(url) + + assert json_response(conn, :forbidden) + end + + for bad_token <- [bad_token1, bad_token2, bad_token3] do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, bad_token) + |> get(url) + + assert json_response_and_validate_schema(conn, :forbidden) + end + end end describe "/api/pleroma/admin/users/follow" do @@ -378,6 +405,18 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do end describe "GET /api/pleroma/admin/users" do + setup do + clear_config([:instance, :admin_privileges], [:users_read]) + end + + test "returns 403 if not privileged with :users_read", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = get(conn, "/api/pleroma/admin/users?page=1") + + assert json_response(conn, :forbidden) + end + test "renders users array for the first page", %{conn: conn, admin: admin} do user = insert(:user, local: false, tags: ["foo", "bar"]) user2 = insert(:user, is_approved: false, registration_reason: "I'm a chill dude") @@ -810,67 +849,42 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do end end - test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do - user_one = insert(:user, is_active: false) - user_two = insert(:user, is_active: false) - - conn = - conn - |> put_req_header("content-type", "application/json") - |> patch( - "/api/pleroma/admin/users/activate", - %{nicknames: [user_one.nickname, user_two.nickname]} - ) - - response = json_response_and_validate_schema(conn, 200) - assert Enum.map(response["users"], & &1["is_active"]) == [true, true] - - log_entry = Repo.one(ModerationLog) - - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}" - end + test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_invites]) - test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do - user_one = insert(:user, is_active: true) - user_two = insert(:user, is_active: true) + user_one = insert(:user, is_approved: false) + user_two = insert(:user, is_approved: false) conn = conn |> put_req_header("content-type", "application/json") |> patch( - "/api/pleroma/admin/users/deactivate", + "/api/pleroma/admin/users/approve", %{nicknames: [user_one.nickname, user_two.nickname]} ) response = json_response_and_validate_schema(conn, 200) - assert Enum.map(response["users"], & &1["is_active"]) == [false, false] + assert Enum.map(response["users"], & &1["is_approved"]) == [true, true] log_entry = Repo.one(ModerationLog) assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}" + "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}" end - test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do - user_one = insert(:user, is_approved: false) - user_two = insert(:user, is_approved: false) + test "PATCH /api/pleroma/admin/users/approve returns 403 if not privileged with :users_manage_invites", + %{conn: conn} do + clear_config([:instance, :admin_privileges], []) conn = conn |> put_req_header("content-type", "application/json") |> patch( "/api/pleroma/admin/users/approve", - %{nicknames: [user_one.nickname, user_two.nickname]} + %{nicknames: ["user_one.nickname", "user_two.nickname"]} ) - response = json_response_and_validate_schema(conn, 200) - assert Enum.map(response["users"], & &1["is_approved"]) == [true, true] - - log_entry = Repo.one(ModerationLog) - - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}" + assert json_response(conn, :forbidden) end test "PATCH /api/pleroma/admin/users/suggest", %{admin: admin, conn: conn} do @@ -923,24 +937,113 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do "@#{admin.nickname} removed suggested users: @#{user1.nickname}, @#{user2.nickname}" end - test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do - user = insert(:user) + describe "user activation" do + test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_activation_state]) - conn = - conn - |> put_req_header("content-type", "application/json") - |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation") + user_one = insert(:user, is_active: false) + user_two = insert(:user, is_active: false) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch( + "/api/pleroma/admin/users/activate", + %{nicknames: [user_one.nickname, user_two.nickname]} + ) - assert json_response_and_validate_schema(conn, 200) == - user_response( - user, - %{"is_active" => !user.is_active} - ) + response = json_response_and_validate_schema(conn, 200) + assert Enum.map(response["users"], & &1["is_active"]) == [true, true] - log_entry = Repo.one(ModerationLog) + log_entry = Repo.one(ModerationLog) - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} deactivated users: @#{user.nickname}" + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}" + end + + test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_activation_state]) + + user_one = insert(:user, is_active: true) + user_two = insert(:user, is_active: true) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch( + "/api/pleroma/admin/users/deactivate", + %{nicknames: [user_one.nickname, user_two.nickname]} + ) + + response = json_response_and_validate_schema(conn, 200) + assert Enum.map(response["users"], & &1["is_active"]) == [false, false] + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}" + end + + test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do + clear_config([:instance, :admin_privileges], [:users_manage_activation_state]) + + user = insert(:user) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation") + + assert json_response_and_validate_schema(conn, 200) == + user_response( + user, + %{"is_active" => !user.is_active} + ) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deactivated users: @#{user.nickname}" + end + + test "it requires privileged role :statuses_activation to activate", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch( + "/api/pleroma/admin/users/activate", + %{nicknames: ["user_one.nickname", "user_two.nickname"]} + ) + + assert json_response(conn, :forbidden) + end + + test "it requires privileged role :statuses_activation to deactivate", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch( + "/api/pleroma/admin/users/deactivate", + %{nicknames: ["user_one.nickname", "user_two.nickname"]} + ) + + assert json_response(conn, :forbidden) + end + + test "it requires privileged role :statuses_activation to toggle activation", %{conn: conn} do + clear_config([:instance, :admin_privileges], []) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> patch("/api/pleroma/admin/users/user.nickname/toggle_activation") + + assert json_response(conn, :forbidden) + end end defp user_response(user, attrs \\ %{}) do diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 9d52bd93e..44355c26d 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Web.CommonAPITest do use Oban.Testing, repo: Pleroma.Repo - use Pleroma.DataCase + use Pleroma.DataCase, async: false alias Pleroma.Activity alias Pleroma.Chat @@ -331,7 +331,7 @@ defmodule Pleroma.Web.CommonAPITest do refute Activity.get_by_id(post.id) end - test "it does not allow a user to delete their posts" do + test "it does not allow a user to delete posts from another user" do user = insert(:user) other_user = insert(:user) @@ -341,7 +341,8 @@ defmodule Pleroma.Web.CommonAPITest do assert Activity.get_by_id(post.id) end - test "it allows moderators to delete other user's posts" do + test "it allows privileged users to delete other user's posts" do + clear_config([:instance, :moderator_privileges], [:messages_delete]) user = insert(:user) moderator = insert(:user, is_moderator: true) @@ -353,19 +354,20 @@ defmodule Pleroma.Web.CommonAPITest do refute Activity.get_by_id(post.id) end - test "it allows admins to delete other user's posts" do + test "it doesn't allow unprivileged mods or admins to delete other user's posts" do + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], []) user = insert(:user) - moderator = insert(:user, is_admin: true) + moderator = insert(:user, is_moderator: true, is_admin: true) {:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"}) - assert {:ok, delete} = CommonAPI.delete(post.id, moderator) - assert delete.local - - refute Activity.get_by_id(post.id) + assert {:error, "Could not delete"} = CommonAPI.delete(post.id, moderator) + assert Activity.get_by_id(post.id) end - test "superusers deleting non-local posts won't federate the delete" do + test "privileged users deleting non-local posts won't federate the delete" do + clear_config([:instance, :admin_privileges], [:messages_delete]) # This is the user of the ingested activity _user = insert(:user, @@ -374,7 +376,7 @@ defmodule Pleroma.Web.CommonAPITest do last_refreshed_at: NaiveDateTime.utc_now() ) - moderator = insert(:user, is_admin: true) + admin = insert(:user, is_admin: true) data = File.read!("test/fixtures/mastodon-post-activity.json") @@ -384,7 +386,7 @@ defmodule Pleroma.Web.CommonAPITest do with_mock Pleroma.Web.Federator, publish: fn _ -> nil end do - assert {:ok, delete} = CommonAPI.delete(post.id, moderator) + assert {:ok, delete} = CommonAPI.delete(post.id, admin) assert delete.local refute called(Pleroma.Web.Federator.publish(:_)) end diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs index 403628488..1524df98f 100644 --- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false alias Pleroma.Notification alias Pleroma.Repo @@ -74,12 +74,15 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do end test "by default, does not contain pleroma:report" do - %{user: user, conn: conn} = oauth_access(["read:notifications"]) + clear_config([:instance, :moderator_privileges], [:reports_manage_reports]) + + user = insert(:user) other_user = insert(:user) third_user = insert(:user) - user - |> User.admin_api_update(%{is_moderator: true}) + {:ok, user} = user |> User.admin_api_update(%{is_moderator: true}) + + %{conn: conn} = oauth_access(["read:notifications"], user: user) {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"}) @@ -101,6 +104,39 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert [_] = result end + test "Pleroma:report is hidden for non-privileged users" do + clear_config([:instance, :moderator_privileges], [:reports_manage_reports]) + + user = insert(:user) + other_user = insert(:user) + third_user = insert(:user) + + {:ok, user} = user |> User.admin_api_update(%{is_moderator: true}) + + %{conn: conn} = oauth_access(["read:notifications"], user: user) + + {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"}) + + {:ok, _report} = + CommonAPI.report(third_user, %{account_id: other_user.id, status_ids: [activity.id]}) + + result = + conn + |> get("/api/v1/notifications?include_types[]=pleroma:report") + |> json_response_and_validate_schema(200) + + assert [_] = result + + clear_config([:instance, :moderator_privileges], []) + + result = + conn + |> get("/api/v1/notifications?include_types[]=pleroma:report") + |> json_response_and_validate_schema(200) + + assert [] == result + end + test "excludes mentions from blockers when blockers_visible is false" do clear_config([:activitypub, :blockers_visible], false) diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index dbb840574..5bae2cd00 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false use Oban.Testing, repo: Pleroma.Repo alias Pleroma.Activity @@ -971,25 +971,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert Activity.get_by_id(activity.id) == activity end - test "when you're an admin", %{conn: conn} do - activity = insert(:note_activity) - user = insert(:user, is_admin: true) - - res_conn = - conn - |> assign(:user, user) - |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"])) - |> delete("/api/v1/statuses/#{activity.id}") - - assert %{} = json_response_and_validate_schema(res_conn, 200) - - assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() == - "@#{user.nickname} deleted status ##{activity.id}" - - refute Activity.get_by_id(activity.id) - end - - test "when you're a moderator", %{conn: conn} do + test "when you're privileged to", %{conn: conn} do + clear_config([:instance, :moderator_privileges], [:messages_delete]) activity = insert(:note_activity) user = insert(:user, is_moderator: 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 692ec8c92..3bb4970ca 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AccountViewTest do - use Pleroma.DataCase + use Pleroma.DataCase, async: false alias Pleroma.User alias Pleroma.UserRelationship @@ -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, @@ -214,8 +357,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions" end - test "Represent a deactivated user for an admin" do - admin = insert(:user, is_admin: true) + test "Represent a deactivated user for a privileged user" do + clear_config([:instance, :moderator_privileges], [:users_manage_activation_state]) + + admin = insert(:user, is_moderator: true) deactivated_user = insert(:user, is_active: false) represented = AccountView.render("show.json", %{user: deactivated_user, for: admin}) assert represented[:pleroma][:deactivated] == true diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs index d3d74f5cd..6ea894691 100644 --- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do - use Pleroma.DataCase + use Pleroma.DataCase, async: false alias Pleroma.Activity alias Pleroma.Chat @@ -218,9 +218,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do end test "Report notification" do + clear_config([:instance, :moderator_privileges], [:reports_manage_reports]) + reporting_user = insert(:user) reported_user = insert(:user) - {:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true}) + moderator_user = insert(:user, is_moderator: true) {:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id}) {:ok, [notification]} = Notification.create_notifications(activity) diff --git a/test/pleroma/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs index 247ad7501..f474220be 100644 --- a/test/pleroma/web/node_info_test.exs +++ b/test/pleroma/web/node_info_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.NodeInfoTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false import Pleroma.Factory @@ -40,6 +40,19 @@ defmodule Pleroma.Web.NodeInfoTest do assert admin.ap_id in result["metadata"]["staffAccounts"] end + test "nodeinfo shows roles and privileges", %{conn: conn} do + clear_config([:instance, :moderator_privileges], [:cofe]) + clear_config([:instance, :admin_privileges], [:suya, :cofe]) + + conn = + conn + |> get("/nodeinfo/2.1.json") + + assert result = json_response(conn, 200) + + assert %{"admin" => ["suya", "cofe"], "moderator" => ["cofe"]} == result["metadata"]["roles"] + end + test "nodeinfo shows restricted nicknames", %{conn: conn} do conn = conn diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_file_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_file_controller_test.exs index 200ce3b68..540b452c7 100644 --- a/test/pleroma/web/pleroma_api/controllers/emoji_file_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/emoji_file_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do - use Pleroma.Web.ConnCase + use Pleroma.Web.ConnCase, async: false import Mock import Tesla.Mock @@ -30,6 +30,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/files?name=:name" do setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) pack_file = "#{@emoji_path}/test_pack/pack.json" original_content = File.read!(pack_file) @@ -377,5 +378,32 @@ defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do }) |> json_response_and_validate_schema(:bad_request) end + + test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do + clear_config([:instance, :admin_privileges], []) + + assert admin_conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/emoji/packs/files?name=test_pack", %{ + file: %Plug.Upload{ + filename: "shortcode.png", + path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png" + } + }) + |> json_response(:forbidden) + + assert admin_conn + |> put_req_header("content-type", "multipart/form-data") + |> patch("/api/pleroma/emoji/packs/files?name=test_pack", %{ + shortcode: "blank", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(:forbidden) + + assert admin_conn + |> put_req_header("content-type", "multipart/form-data") + |> delete("/api/pleroma/emoji/packs/files?name=test_pack&shortcode=blank3") + |> json_response(:forbidden) + end end end diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs index d1fd1cbb0..1d5240639 100644 --- a/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs @@ -99,6 +99,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do end describe "GET /api/pleroma/emoji/packs/remote" do + setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) + end + test "shareable instance", %{admin_conn: admin_conn, conn: conn} do resp = conn @@ -136,6 +140,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do "error" => "The requested instance does not support sharing emoji packs" } end + + test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do + clear_config([:instance, :admin_privileges], []) + + assert admin_conn + |> get("/api/pleroma/emoji/packs/remote?url=https://example.com") + |> json_response(:forbidden) + end end describe "GET /api/pleroma/emoji/packs/archive?name=:name" do @@ -170,6 +182,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do end describe "POST /api/pleroma/emoji/packs/download" do + setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) + end + test "shared pack from remote and non shared from fallback-src", %{ admin_conn: admin_conn, conn: conn @@ -344,10 +360,24 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do "The pack was not set as shared and there is no fallback src to download from" } end + + test "it requires privileged role :emoji_manage_emoji", %{admin_conn: conn} do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/pleroma/emoji/packs/download", %{ + url: "https://example.com", + name: "test_pack", + as: "test_pack2" + }) + |> json_response(:forbidden) + end end describe "PATCH/update /api/pleroma/emoji/pack?name=:name" do setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) pack_file = "#{@emoji_path}/test_pack/pack.json" original_content = File.read!(pack_file) @@ -435,9 +465,25 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do "error" => "The fallback archive does not have all files specified in pack.json" } end + + test "it requires privileged role :emoji_manage_emoji", %{ + admin_conn: conn, + new_data: new_data + } do + clear_config([:instance, :admin_privileges], []) + + assert conn + |> put_req_header("content-type", "multipart/form-data") + |> patch("/api/pleroma/emoji/pack?name=test_pack", %{metadata: new_data}) + |> json_response(:forbidden) + end end describe "POST/DELETE /api/pleroma/emoji/pack?name=:name" do + setup do + clear_config([:instance, :admin_privileges], [:emoji_manage_emoji]) + end + test "returns an error on creates pack when file system not writable", %{ admin_conn: admin_conn } do @@ -520,6 +566,18 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do "error" => "pack name cannot be empty" } end + + test "it requires privileged role :emoji_manage_emoji", %{admin_conn: admin_conn} do + clear_config([:instance, :admin_privileges], []) + + assert admin_conn + |> post("/api/pleroma/emoji/pack?name= ") + |> json_response(:forbidden) + + assert admin_conn + |> delete("/api/pleroma/emoji/pack?name= ") + |> json_response(:forbidden) + end end test "deleting nonexisting pack", %{admin_conn: admin_conn} do @@ -578,6 +636,12 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do "blank2" => "blank.png", "foo" => "blank.png" } + + clear_config([:instance, :admin_privileges], []) + + assert admin_conn + |> get("/api/pleroma/emoji/packs/import") + |> json_response(:forbidden) end describe "GET /api/pleroma/emoji/pack?name=:name" do diff --git a/test/pleroma/web/plugs/ensure_privileged_plug_test.exs b/test/pleroma/web/plugs/ensure_privileged_plug_test.exs new file mode 100644 index 000000000..4b6679b66 --- /dev/null +++ b/test/pleroma/web/plugs/ensure_privileged_plug_test.exs @@ -0,0 +1,96 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Plugs.EnsurePrivilegedPlugTest do + use Pleroma.Web.ConnCase, async: true + + alias Pleroma.Web.Plugs.EnsurePrivilegedPlug + import Pleroma.Factory + + test "denies a user that isn't moderator or admin" do + clear_config([:instance, :admin_privileges], []) + user = insert(:user) + + conn = + build_conn() + |> assign(:user, user) + |> EnsurePrivilegedPlug.call(:cofe) + + assert conn.status == 403 + end + + test "accepts an admin that is privileged" do + clear_config([:instance, :admin_privileges], [:cofe]) + user = insert(:user, is_admin: true) + conn = assign(build_conn(), :user, user) + + ret_conn = EnsurePrivilegedPlug.call(conn, :cofe) + + assert conn == ret_conn + end + + test "denies an admin that isn't privileged" do + clear_config([:instance, :admin_privileges], [:suya]) + user = insert(:user, is_admin: true) + + conn = + build_conn() + |> assign(:user, user) + |> EnsurePrivilegedPlug.call(:cofe) + + assert conn.status == 403 + end + + test "accepts a moderator that is privileged" do + clear_config([:instance, :moderator_privileges], [:cofe]) + user = insert(:user, is_moderator: true) + conn = assign(build_conn(), :user, user) + + ret_conn = EnsurePrivilegedPlug.call(conn, :cofe) + + assert conn == ret_conn + end + + test "denies a moderator that isn't privileged" do + clear_config([:instance, :moderator_privileges], [:suya]) + user = insert(:user, is_moderator: true) + + conn = + build_conn() + |> assign(:user, user) + |> EnsurePrivilegedPlug.call(:cofe) + + assert conn.status == 403 + end + + test "accepts for a privileged role even if other role isn't privileged" do + clear_config([:instance, :admin_privileges], [:cofe]) + clear_config([:instance, :moderator_privileges], []) + user = insert(:user, is_admin: true, is_moderator: true) + conn = assign(build_conn(), :user, user) + + ret_conn = EnsurePrivilegedPlug.call(conn, :cofe) + + # privileged through admin role + assert conn == ret_conn + + clear_config([:instance, :admin_privileges], []) + clear_config([:instance, :moderator_privileges], [:cofe]) + user = insert(:user, is_admin: true, is_moderator: true) + conn = assign(build_conn(), :user, user) + + ret_conn = EnsurePrivilegedPlug.call(conn, :cofe) + + # privileged through moderator role + assert conn == ret_conn + end + + test "denies when no user is set" do + conn = + build_conn() + |> EnsurePrivilegedPlug.call(:cofe) + + assert conn.status == 403 + end +end diff --git a/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs b/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs deleted file mode 100644 index c684714b8..000000000 --- a/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs +++ /dev/null @@ -1,60 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlugTest do - use Pleroma.Web.ConnCase, async: true - - alias Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug - import Pleroma.Factory - - test "accepts a user that is an admin" do - user = insert(:user, is_admin: true) - - conn = assign(build_conn(), :user, user) - - ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{}) - - assert conn == ret_conn - end - - test "accepts a user that is a moderator when :privileged_staff is enabled" do - clear_config([:instance, :privileged_staff], true) - user = insert(:user, is_moderator: true) - - conn = assign(build_conn(), :user, user) - - ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{}) - - assert conn == ret_conn - end - - test "denies a user that is a moderator when :privileged_staff is disabled" do - clear_config([:instance, :privileged_staff], false) - user = insert(:user, is_moderator: true) - - conn = - build_conn() - |> assign(:user, user) - |> EnsureStaffPrivilegedPlug.call(%{}) - - assert conn.status == 403 - end - - test "denies a user that isn't a staff member" do - user = insert(:user) - - conn = - build_conn() - |> assign(:user, user) - |> EnsureStaffPrivilegedPlug.call(%{}) - - assert conn.status == 403 - end - - test "denies when a user isn't set" do - conn = EnsureStaffPrivilegedPlug.call(build_conn(), %{}) - - assert conn.status == 403 - end -end |