diff options
| -rw-r--r-- | lib/pleroma/web/admin_api/controllers/admin_api_controller.ex (renamed from lib/pleroma/web/admin_api/admin_api_controller.ex) | 124 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/controllers/fallback_controller.ex | 31 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/controllers/status_controller.ex | 79 | ||||
| -rw-r--r-- | lib/pleroma/web/api_spec/operations/admin/status_operation.ex | 165 | ||||
| -rw-r--r-- | lib/pleroma/web/api_spec/operations/status_operation.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 8 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/steal_emoji_policy_test.exs | 6 | ||||
| -rw-r--r-- | test/web/admin_api/controllers/admin_api_controller_test.exs (renamed from test/web/admin_api/admin_api_controller_test.exs) | 181 | ||||
| -rw-r--r-- | test/web/admin_api/controllers/status_controller_test.exs | 194 | 
9 files changed, 506 insertions, 284 deletions
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex index 647ceb3ba..6b1d64a2e 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex @@ -98,13 +98,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    plug(      OAuthScopesPlug,      %{scopes: ["read:statuses"], admin: true} -    when action in [:list_statuses, :list_user_statuses, :list_instance_statuses, :status_show] -  ) - -  plug( -    OAuthScopesPlug, -    %{scopes: ["write:statuses"], admin: true} -    when action in [:status_update, :status_delete] +    when action in [:list_user_statuses, :list_instance_statuses]    )    plug( @@ -136,7 +130,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do           ]    ) -  action_fallback(:errors) +  action_fallback(AdminAPI.FallbackController)    def user_delete(conn, %{"nickname" => nickname}) do      user_delete(conn, %{"nicknames" => [nickname]}) @@ -597,16 +591,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do        json_response(conn, :no_content, "")      else        {:registrations_open, _} -> -        errors( -          conn, -          {:error, "To send invites you need to set the `registrations_open` option to false."} -        ) +        {:error, "To send invites you need to set the `registrations_open` option to false."}        {:invites_enabled, _} -> -        errors( -          conn, -          {:error, "To send invites you need to set the `invites_enabled` option to true."} -        ) +        {:error, "To send invites you need to set the `invites_enabled` option to true."}      end    end @@ -814,71 +802,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do      end    end -  def list_statuses(%{assigns: %{user: _admin}} = conn, params) do -    godmode = params["godmode"] == "true" || params["godmode"] == true -    local_only = params["local_only"] == "true" || params["local_only"] == true -    with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true -    {page, page_size} = page_params(params) - -    activities = -      ActivityPub.fetch_statuses(nil, %{ -        "godmode" => godmode, -        "local_only" => local_only, -        "limit" => page_size, -        "offset" => (page - 1) * page_size, -        "exclude_reblogs" => !with_reblogs && "true" -      }) - -    conn -    |> put_view(AdminAPI.StatusView) -    |> render("index.json", %{activities: activities, as: :activity}) -  end - -  def status_show(conn, %{"id" => id}) do -    with %Activity{} = activity <- Activity.get_by_id(id) do -      conn -      |> put_view(MastodonAPI.StatusView) -      |> render("show.json", %{activity: activity}) -    else -      _ -> errors(conn, {:error, :not_found}) -    end -  end - -  def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do -    params = -      params -      |> Map.take(["sensitive", "visibility"]) -      |> Map.new(fn {key, value} -> {String.to_existing_atom(key), value} end) - -    with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do -      {:ok, sensitive} = Ecto.Type.cast(:boolean, params[:sensitive]) - -      ModerationLog.insert_log(%{ -        action: "status_update", -        actor: admin, -        subject: activity, -        sensitive: sensitive, -        visibility: params[:visibility] -      }) - -      conn -      |> put_view(MastodonAPI.StatusView) -      |> render("show.json", %{activity: activity}) -    end -  end - -  def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do -    with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do -      ModerationLog.insert_log(%{ -        action: "status_delete", -        actor: user, -        subject_id: id -      }) - -      json(conn, %{}) -    end -  end -    def list_log(conn, params) do      {page, page_size} = page_params(params) @@ -904,7 +827,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def config_show(conn, %{"only_db" => true}) do -    with :ok <- configurable_from_database(conn) do +    with :ok <- configurable_from_database() do        configs = Pleroma.Repo.all(ConfigDB)        conn @@ -914,7 +837,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def config_show(conn, _params) do -    with :ok <- configurable_from_database(conn) do +    with :ok <- configurable_from_database() do        configs = ConfigDB.get_all_as_keyword()        merged = @@ -953,7 +876,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def config_update(conn, %{"configs" => configs}) do -    with :ok <- configurable_from_database(conn) do +    with :ok <- configurable_from_database() do        {_errors, results} =          configs          |> Enum.filter(&whitelisted_config?/1) @@ -997,7 +920,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def restart(conn, _params) do -    with :ok <- configurable_from_database(conn) do +    with :ok <- configurable_from_database() do        Restarter.Pleroma.restart(Config.get(:env), 50)        json(conn, %{}) @@ -1008,14 +931,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do      json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})    end -  defp configurable_from_database(conn) do +  defp configurable_from_database do      if Config.get(:configurable_from_database) do        :ok      else -      errors( -        conn, -        {:error, "To use this endpoint you need to enable configuration from database."} -      ) +      {:error, "To use this endpoint you need to enable configuration from database."}      end    end @@ -1159,30 +1079,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do      |> json(%{"status_visibility" => count})    end -  defp errors(conn, {:error, :not_found}) do -    conn -    |> put_status(:not_found) -    |> json(dgettext("errors", "Not found")) -  end - -  defp errors(conn, {:error, reason}) do -    conn -    |> put_status(:bad_request) -    |> json(reason) -  end - -  defp errors(conn, {:param_cast, _}) do -    conn -    |> put_status(:bad_request) -    |> json(dgettext("errors", "Invalid parameters")) -  end - -  defp errors(conn, _) do -    conn -    |> put_status(:internal_server_error) -    |> json(dgettext("errors", "Something went wrong")) -  end -    defp page_params(params) do      {get_page(params["page"]), get_page_size(params["page_size"])}    end diff --git a/lib/pleroma/web/admin_api/controllers/fallback_controller.ex b/lib/pleroma/web/admin_api/controllers/fallback_controller.ex new file mode 100644 index 000000000..82965936d --- /dev/null +++ b/lib/pleroma/web/admin_api/controllers/fallback_controller.ex @@ -0,0 +1,31 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.AdminAPI.FallbackController do +  use Pleroma.Web, :controller + +  def call(conn, {:error, :not_found}) do +    conn +    |> put_status(:not_found) +    |> json(%{error: dgettext("errors", "Not found")}) +  end + +  def call(conn, {:error, reason}) do +    conn +    |> put_status(:bad_request) +    |> json(%{error: reason}) +  end + +  def call(conn, {:param_cast, _}) do +    conn +    |> put_status(:bad_request) +    |> json(dgettext("errors", "Invalid parameters")) +  end + +  def call(conn, _) do +    conn +    |> put_status(:internal_server_error) +    |> json(%{error: dgettext("errors", "Something went wrong")}) +  end +end diff --git a/lib/pleroma/web/admin_api/controllers/status_controller.ex b/lib/pleroma/web/admin_api/controllers/status_controller.ex new file mode 100644 index 000000000..08cb9c10b --- /dev/null +++ b/lib/pleroma/web/admin_api/controllers/status_controller.ex @@ -0,0 +1,79 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.AdminAPI.StatusController do +  use Pleroma.Web, :controller + +  alias Pleroma.Activity +  alias Pleroma.ModerationLog +  alias Pleroma.Plugs.OAuthScopesPlug +  alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.CommonAPI +  alias Pleroma.Web.MastodonAPI + +  require Logger + +  plug(Pleroma.Web.ApiSpec.CastAndValidate) +  plug(OAuthScopesPlug, %{scopes: ["read:statuses"], admin: true} when action in [:index, :show]) + +  plug( +    OAuthScopesPlug, +    %{scopes: ["write:statuses"], admin: true} when action in [:update, :delete] +  ) + +  action_fallback(Pleroma.Web.AdminAPI.FallbackController) + +  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.StatusOperation + +  def index(%{assigns: %{user: _admin}} = conn, params) do +    activities = +      ActivityPub.fetch_statuses(nil, %{ +        "godmode" => params.godmode, +        "local_only" => params.local_only, +        "limit" => params.page_size, +        "offset" => (params.page - 1) * params.page_size, +        "exclude_reblogs" => not params.with_reblogs +      }) + +    render(conn, "index.json", activities: activities, as: :activity) +  end + +  def show(conn, %{id: id}) do +    with %Activity{} = activity <- Activity.get_by_id(id) do +      conn +      |> put_view(MastodonAPI.StatusView) +      |> render("show.json", %{activity: activity}) +    else +      nil -> {:error, :not_found} +    end +  end + +  def update(%{assigns: %{user: admin}, body_params: params} = conn, %{id: id}) do +    with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do +      ModerationLog.insert_log(%{ +        action: "status_update", +        actor: admin, +        subject: activity, +        sensitive: params[:sensitive], +        visibility: params[:visibility] +      }) + +      conn +      |> put_view(MastodonAPI.StatusView) +      |> render("show.json", %{activity: activity}) +    end +  end + +  def delete(%{assigns: %{user: user}} = conn, %{id: id}) do +    with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do +      ModerationLog.insert_log(%{ +        action: "status_delete", +        actor: user, +        subject_id: id +      }) + +      json(conn, %{}) +    end +  end +end diff --git a/lib/pleroma/web/api_spec/operations/admin/status_operation.ex b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex new file mode 100644 index 000000000..0b138dc79 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex @@ -0,0 +1,165 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do +  alias OpenApiSpex.Operation +  alias OpenApiSpex.Schema +  alias Pleroma.Web.ApiSpec.Schemas.Account +  alias Pleroma.Web.ApiSpec.Schemas.ApiError +  alias Pleroma.Web.ApiSpec.Schemas.FlakeID +  alias Pleroma.Web.ApiSpec.Schemas.Status +  alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope + +  import Pleroma.Web.ApiSpec.Helpers +  import Pleroma.Web.ApiSpec.StatusOperation, only: [id_param: 0] + +  def open_api_operation(action) do +    operation = String.to_existing_atom("#{action}_operation") +    apply(__MODULE__, operation, []) +  end + +  def index_operation do +    %Operation{ +      tags: ["Admin", "Statuses"], +      operationId: "AdminAPI.StatusController.index", +      security: [%{"oAuth" => ["read:statuses"]}], +      parameters: [ +        Operation.parameter( +          :godmode, +          :query, +          %Schema{type: :boolean, default: false}, +          "Allows to see private statuses" +        ), +        Operation.parameter( +          :local_only, +          :query, +          %Schema{type: :boolean, default: false}, +          "Excludes remote statuses" +        ), +        Operation.parameter( +          :with_reblogs, +          :query, +          %Schema{type: :boolean, default: false}, +          "Allows to see reblogs" +        ), +        Operation.parameter( +          :page, +          :query, +          %Schema{type: :integer, default: 1}, +          "Page" +        ), +        Operation.parameter( +          :page_size, +          :query, +          %Schema{type: :integer, default: 50}, +          "Number of statuses to return" +        ) +      ], +      responses: %{ +        200 => +          Operation.response("Array of statuses", "application/json", %Schema{ +            type: :array, +            items: status() +          }) +      } +    } +  end + +  def show_operation do +    %Operation{ +      tags: ["Admin", "Statuses"], +      summary: "Show Status", +      operationId: "AdminAPI.StatusController.show", +      parameters: [id_param()], +      security: [%{"oAuth" => ["read:statuses"]}], +      responses: %{ +        200 => Operation.response("Status", "application/json", Status), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  def update_operation do +    %Operation{ +      tags: ["Admin", "Statuses"], +      summary: "Change the scope of an individual reported status", +      operationId: "AdminAPI.StatusController.update", +      parameters: [id_param()], +      security: [%{"oAuth" => ["write:statuses"]}], +      requestBody: request_body("Parameters", update_request(), required: true), +      responses: %{ +        200 => Operation.response("Status", "application/json", Status), +        400 => Operation.response("Error", "application/json", ApiError) +      } +    } +  end + +  def delete_operation do +    %Operation{ +      tags: ["Admin", "Statuses"], +      summary: "Delete an individual reported status", +      operationId: "AdminAPI.StatusController.delete", +      parameters: [id_param()], +      security: [%{"oAuth" => ["write:statuses"]}], +      responses: %{ +        200 => empty_object_response(), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  defp status do +    %Schema{ +      anyOf: [ +        Status, +        %Schema{ +          type: :object, +          properties: %{ +            account: %Schema{allOf: [Account, admin_account()]} +          } +        } +      ] +    } +  end + +  defp admin_account do +    %Schema{ +      type: :object, +      properties: %{ +        id: FlakeID, +        avatar: %Schema{type: :string}, +        nickname: %Schema{type: :string}, +        display_name: %Schema{type: :string}, +        deactivated: %Schema{type: :boolean}, +        local: %Schema{type: :boolean}, +        roles: %Schema{ +          type: :object, +          properties: %{ +            admin: %Schema{type: :boolean}, +            moderator: %Schema{type: :boolean} +          } +        }, +        tags: %Schema{type: :string}, +        confirmation_pending: %Schema{type: :string} +      } +    } +  end + +  defp update_request do +    %Schema{ +      type: :object, +      properties: %{ +        sensitive: %Schema{ +          type: :boolean, +          description: "Mark status and attached media as sensitive?" +        }, +        visibility: VisibilityScope +      }, +      example: %{ +        "visibility" => "private", +        "sensitive" => "false" +      } +    } +  end +end diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex index 0682ca6e5..ca9db01e5 100644 --- a/lib/pleroma/web/api_spec/operations/status_operation.ex +++ b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -487,7 +487,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do      }    end -  defp id_param do +  def id_param do      Operation.parameter(:id, :path, FlakeID, "Status ID",        example: "9umDrYheeY451cQnEe",        required: true diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 08ab3c8bb..e493a4153 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -189,10 +189,10 @@ defmodule Pleroma.Web.Router do      post("/reports/:id/notes", AdminAPIController, :report_notes_create)      delete("/reports/:report_id/notes/:id", AdminAPIController, :report_notes_delete) -    get("/statuses/:id", AdminAPIController, :status_show) -    put("/statuses/:id", AdminAPIController, :status_update) -    delete("/statuses/:id", AdminAPIController, :status_delete) -    get("/statuses", AdminAPIController, :list_statuses) +    get("/statuses/:id", StatusController, :show) +    put("/statuses/:id", StatusController, :update) +    delete("/statuses/:id", StatusController, :delete) +    get("/statuses", StatusController, :index)      get("/config", AdminAPIController, :config_show)      post("/config", AdminAPIController, :config_update) diff --git a/test/web/activity_pub/mrf/steal_emoji_policy_test.exs b/test/web/activity_pub/mrf/steal_emoji_policy_test.exs index 0e7e57c77..3f8222736 100644 --- a/test/web/activity_pub/mrf/steal_emoji_policy_test.exs +++ b/test/web/activity_pub/mrf/steal_emoji_policy_test.exs @@ -19,6 +19,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do      File.mkdir!(emoji_path)      Pleroma.Emoji.reload() + +    on_exit(fn -> +      File.rm_rf!(emoji_path) +    end) + +    :ok    end    test "does nothing by default" do diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs index 12cb1afd9..321840a8c 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/controllers/admin_api_controller_test.exs @@ -351,7 +351,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}") -      assert "Not found" == json_response(conn, 404) +      assert %{"error" => "Not found"} == json_response(conn, 404)      end    end @@ -684,7 +684,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = post(conn, "/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")        assert json_response(conn, :bad_request) == -               "To send invites you need to set the `invites_enabled` option to true." +               %{ +                 "error" => +                   "To send invites you need to set the `invites_enabled` option to true." +               }      end      test "it returns 500 if `registrations_open` is enabled", %{conn: conn} do @@ -694,7 +697,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = post(conn, "/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")        assert json_response(conn, :bad_request) == -               "To send invites you need to set the `registrations_open` option to false." +               %{ +                 "error" => +                   "To send invites you need to set the `registrations_open` option to false." +               }      end    end @@ -1308,7 +1314,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do          |> put("/api/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})          |> json_response(404) -      assert response == "Not found" +      assert response == %{"error" => "Not found"}      end    end @@ -1414,7 +1420,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      test "with invalid token", %{conn: conn} do        conn = post(conn, "/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"}) -      assert json_response(conn, :not_found) == "Not found" +      assert json_response(conn, :not_found) == %{"error" => "Not found"}      end    end @@ -1441,7 +1447,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      test "returns 404 when report id is invalid", %{conn: conn} do        conn = get(conn, "/api/pleroma/admin/reports/test") -      assert json_response(conn, :not_found) == "Not found" +      assert json_response(conn, :not_found) == %{"error" => "Not found"}      end    end @@ -1698,115 +1704,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      end    end -  describe "GET /api/pleroma/admin/statuses/:id" do -    test "not found", %{conn: conn} do -      assert conn -             |> get("/api/pleroma/admin/statuses/not_found") -             |> json_response(:not_found) -    end - -    test "shows activity", %{conn: conn} do -      activity = insert(:note_activity) - -      response = -        conn -        |> get("/api/pleroma/admin/statuses/#{activity.id}") -        |> json_response(200) - -      assert response["id"] == activity.id -    end -  end - -  describe "PUT /api/pleroma/admin/statuses/:id" do -    setup do -      activity = insert(:note_activity) - -      %{id: activity.id} -    end - -    test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do -      response = -        conn -        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"}) -        |> json_response(:ok) - -      assert response["sensitive"] - -      log_entry = Repo.one(ModerationLog) - -      assert ModerationLog.get_log_entry_message(log_entry) == -               "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'" - -      response = -        conn -        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"}) -        |> json_response(:ok) - -      refute response["sensitive"] -    end - -    test "change visibility flag", %{conn: conn, id: id, admin: admin} do -      response = -        conn -        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "public"}) -        |> json_response(:ok) - -      assert response["visibility"] == "public" - -      log_entry = Repo.one(ModerationLog) - -      assert ModerationLog.get_log_entry_message(log_entry) == -               "@#{admin.nickname} updated status ##{id}, set visibility: 'public'" - -      response = -        conn -        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "private"}) -        |> json_response(:ok) - -      assert response["visibility"] == "private" - -      response = -        conn -        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "unlisted"}) -        |> json_response(:ok) - -      assert response["visibility"] == "unlisted" -    end - -    test "returns 400 when visibility is unknown", %{conn: conn, id: id} do -      conn = put(conn, "/api/pleroma/admin/statuses/#{id}", %{visibility: "test"}) - -      assert json_response(conn, :bad_request) == "Unsupported visibility" -    end -  end - -  describe "DELETE /api/pleroma/admin/statuses/:id" do -    setup do -      activity = insert(:note_activity) - -      %{id: activity.id} -    end - -    test "deletes status", %{conn: conn, id: id, admin: admin} do -      conn -      |> delete("/api/pleroma/admin/statuses/#{id}") -      |> json_response(:ok) - -      refute Activity.get_by_id(id) - -      log_entry = Repo.one(ModerationLog) - -      assert ModerationLog.get_log_entry_message(log_entry) == -               "@#{admin.nickname} deleted status ##{id}" -    end - -    test "returns 404 when the status does not exist", %{conn: conn} do -      conn = delete(conn, "/api/pleroma/admin/statuses/test") - -      assert json_response(conn, :not_found) == "Not found" -    end -  end -    describe "GET /api/pleroma/admin/config" do      setup do: clear_config(:configurable_from_database, true) @@ -1815,7 +1712,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = get(conn, "/api/pleroma/admin/config")        assert json_response(conn, 400) == -               "To use this endpoint you need to enable configuration from database." +               %{ +                 "error" => "To use this endpoint you need to enable configuration from database." +               }      end      test "with settings only in db", %{conn: conn} do @@ -1937,7 +1836,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      conn = post(conn, "/api/pleroma/admin/config", %{"configs" => []})      assert json_response(conn, 400) == -             "To use this endpoint you need to enable configuration from database." +             %{"error" => "To use this endpoint you need to enable configuration from database."}    end    describe "POST /api/pleroma/admin/config" do @@ -3000,54 +2899,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      on_exit(fn -> Restarter.Pleroma.refresh() end)    end -  describe "GET /api/pleroma/admin/statuses" do -    test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do -      blocked = insert(:user) -      user = insert(:user) -      User.block(admin, blocked) - -      {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"}) - -      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"}) -      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"}) -      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"}) -      {:ok, _} = CommonAPI.post(blocked, %{status: ".", visibility: "public"}) - -      response = -        conn -        |> get("/api/pleroma/admin/statuses") -        |> json_response(200) - -      refute "private" in Enum.map(response, & &1["visibility"]) -      assert length(response) == 3 -    end - -    test "returns only local statuses with local_only on", %{conn: conn} do -      user = insert(:user) -      remote_user = insert(:user, local: false, nickname: "archaeme@archae.me") -      insert(:note_activity, user: user, local: true) -      insert(:note_activity, user: remote_user, local: false) - -      response = -        conn -        |> get("/api/pleroma/admin/statuses?local_only=true") -        |> json_response(200) - -      assert length(response) == 1 -    end - -    test "returns private and direct statuses with godmode on", %{conn: conn, admin: admin} do -      user = insert(:user) - -      {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"}) - -      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"}) -      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"}) -      conn = get(conn, "/api/pleroma/admin/statuses?godmode=true") -      assert json_response(conn, 200) |> length() == 3 -    end -  end -    describe "GET /api/pleroma/admin/users/:nickname/statuses" do      setup do        user = insert(:user) diff --git a/test/web/admin_api/controllers/status_controller_test.exs b/test/web/admin_api/controllers/status_controller_test.exs new file mode 100644 index 000000000..124d8dc2e --- /dev/null +++ b/test/web/admin_api/controllers/status_controller_test.exs @@ -0,0 +1,194 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.AdminAPI.StatusControllerTest do +  use Pleroma.Web.ConnCase + +  import Pleroma.Factory + +  alias Pleroma.Activity +  alias Pleroma.Config +  alias Pleroma.ModerationLog +  alias Pleroma.Repo +  alias Pleroma.User +  alias Pleroma.Web.CommonAPI + +  setup do +    admin = insert(:user, is_admin: true) +    token = insert(:oauth_admin_token, user: admin) + +    conn = +      build_conn() +      |> assign(:user, admin) +      |> assign(:token, token) + +    {:ok, %{admin: admin, token: token, conn: conn}} +  end + +  describe "GET /api/pleroma/admin/statuses/:id" do +    test "not found", %{conn: conn} do +      assert conn +             |> get("/api/pleroma/admin/statuses/not_found") +             |> json_response_and_validate_schema(:not_found) +    end + +    test "shows activity", %{conn: conn} do +      activity = insert(:note_activity) + +      response = +        conn +        |> get("/api/pleroma/admin/statuses/#{activity.id}") +        |> json_response_and_validate_schema(200) + +      assert response["id"] == activity.id +    end +  end + +  describe "PUT /api/pleroma/admin/statuses/:id" do +    setup do +      activity = insert(:note_activity) + +      %{id: activity.id} +    end + +    test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"}) +        |> json_response_and_validate_schema(:ok) + +      assert response["sensitive"] + +      log_entry = Repo.one(ModerationLog) + +      assert ModerationLog.get_log_entry_message(log_entry) == +               "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'" + +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"}) +        |> json_response_and_validate_schema(:ok) + +      refute response["sensitive"] +    end + +    test "change visibility flag", %{conn: conn, id: id, admin: admin} do +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "public"}) +        |> json_response_and_validate_schema(:ok) + +      assert response["visibility"] == "public" + +      log_entry = Repo.one(ModerationLog) + +      assert ModerationLog.get_log_entry_message(log_entry) == +               "@#{admin.nickname} updated status ##{id}, set visibility: 'public'" + +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "private"}) +        |> json_response_and_validate_schema(:ok) + +      assert response["visibility"] == "private" + +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "unlisted"}) +        |> json_response_and_validate_schema(:ok) + +      assert response["visibility"] == "unlisted" +    end + +    test "returns 400 when visibility is unknown", %{conn: conn, id: id} do +      conn = +        conn +        |> put_req_header("content-type", "application/json") +        |> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "test"}) + +      assert %{"error" => "test - Invalid value for enum."} = +               json_response_and_validate_schema(conn, :bad_request) +    end +  end + +  describe "DELETE /api/pleroma/admin/statuses/:id" do +    setup do +      activity = insert(:note_activity) + +      %{id: activity.id} +    end + +    test "deletes status", %{conn: conn, id: id, admin: admin} do +      conn +      |> delete("/api/pleroma/admin/statuses/#{id}") +      |> json_response_and_validate_schema(:ok) + +      refute Activity.get_by_id(id) + +      log_entry = Repo.one(ModerationLog) + +      assert ModerationLog.get_log_entry_message(log_entry) == +               "@#{admin.nickname} deleted status ##{id}" +    end + +    test "returns 404 when the status does not exist", %{conn: conn} do +      conn = delete(conn, "/api/pleroma/admin/statuses/test") + +      assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"} +    end +  end + +  describe "GET /api/pleroma/admin/statuses" do +    test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do +      blocked = insert(:user) +      user = insert(:user) +      User.block(admin, blocked) + +      {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"}) + +      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"}) +      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"}) +      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"}) +      {:ok, _} = CommonAPI.post(blocked, %{status: ".", visibility: "public"}) + +      response = +        conn +        |> get("/api/pleroma/admin/statuses") +        |> json_response_and_validate_schema(200) + +      refute "private" in Enum.map(response, & &1["visibility"]) +      assert length(response) == 3 +    end + +    test "returns only local statuses with local_only on", %{conn: conn} do +      user = insert(:user) +      remote_user = insert(:user, local: false, nickname: "archaeme@archae.me") +      insert(:note_activity, user: user, local: true) +      insert(:note_activity, user: remote_user, local: false) + +      response = +        conn +        |> get("/api/pleroma/admin/statuses?local_only=true") +        |> json_response_and_validate_schema(200) + +      assert length(response) == 1 +    end + +    test "returns private and direct statuses with godmode on", %{conn: conn, admin: admin} do +      user = insert(:user) + +      {:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"}) + +      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"}) +      {:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"}) +      conn = get(conn, "/api/pleroma/admin/statuses?godmode=true") +      assert json_response_and_validate_schema(conn, 200) |> length() == 3 +    end +  end +end  | 
