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 | 
