added api spec

This commit is contained in:
Maksim Pechnikov 2020-09-07 07:17:30 +03:00
parent 5ae56aafb2
commit 917d325972
5 changed files with 164 additions and 52 deletions

View file

@ -49,7 +49,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Method: `POST` * Method: `POST`
* Authentication: required * Authentication: required
* Params: * Params:
* `list`: STRING or FILE containing a whitespace-separated list of accounts to follow * `list`: STRING or FILE containing a whitespace-separated list of accounts to block
* Response: HTTP 200 on success, 500 on error * Response: HTTP 200 on success, 500 on error
## `/api/pleroma/mutes_import` ## `/api/pleroma/mutes_import`
@ -57,7 +57,7 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
* Method: `POST` * Method: `POST`
* Authentication: required * Authentication: required
* Params: * Params:
* `list`: STRING or FILE containing a whitespace-separated list of accounts to follow * `list`: STRING or FILE containing a whitespace-separated list of accounts to mute
* Response: HTTP 200 on success, 500 on error * Response: HTTP 200 on success, 500 on error

View file

@ -0,0 +1,80 @@
# 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.UserImportOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError
import Pleroma.Web.ApiSpec.Helpers
@spec open_api_operation(atom) :: Operation.t()
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def follow_operation do
%Operation{
tags: ["follow_import"],
summary: "Imports your follows.",
operationId: "UserImportController.follow",
requestBody: request_body("Parameters", import_request(), required: true),
responses: %{
200 => ok_response(),
500 => Operation.response("Error", "application/json", ApiError)
},
security: [%{"oAuth" => ["write:follow"]}]
}
end
def blocks_operation do
%Operation{
tags: ["blocks_import"],
summary: "Imports your blocks.",
operationId: "UserImportController.blocks",
requestBody: request_body("Parameters", import_request(), required: true),
responses: %{
200 => ok_response(),
500 => Operation.response("Error", "application/json", ApiError)
},
security: [%{"oAuth" => ["write:blocks"]}]
}
end
def mutes_operation do
%Operation{
tags: ["mutes_import"],
summary: "Imports your mutes.",
operationId: "UserImportController.mutes",
requestBody: request_body("Parameters", import_request(), required: true),
responses: %{
200 => ok_response(),
500 => Operation.response("Error", "application/json", ApiError)
},
security: [%{"oAuth" => ["write:mutes"]}]
}
end
defp import_request do
%Schema{
type: :object,
required: [:list],
properties: %{
list: %Schema{
description:
"STRING or FILE containing a whitespace-separated list of accounts to import.",
anyOf: [
%Schema{type: :string, format: :binary},
%Schema{type: :string}
]
}
}
}
end
defp ok_response do
Operation.response("Ok", "application/json", %Schema{type: :string, example: "ok"})
end
end

View file

@ -9,16 +9,20 @@ defmodule Pleroma.Web.PleromaAPI.UserImportController do
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ApiSpec
plug(OAuthScopesPlug, %{scopes: ["follow", "write:follows"]} when action == :follow) plug(OAuthScopesPlug, %{scopes: ["follow", "write:follows"]} when action == :follow)
plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks) plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks)
plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action == :mutes) plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action == :mutes)
def follow(conn, %{"list" => %Plug.Upload{path: path}}) do plug(OpenApiSpex.Plug.CastAndValidate)
follow(conn, %{"list" => File.read!(path)}) defdelegate open_api_operation(action), to: ApiSpec.UserImportOperation
def follow(%{body_params: %{list: %Plug.Upload{path: path}}} = conn, _) do
follow(%Plug.Conn{conn | body_params: %{list: File.read!(path)}}, %{})
end end
def follow(%{assigns: %{user: follower}} = conn, %{"list" => list}) do def follow(%{assigns: %{user: follower}, body_params: %{list: list}} = conn, _) do
identifiers = identifiers =
list list
|> String.split("\n") |> String.split("\n")
@ -31,20 +35,20 @@ def follow(%{assigns: %{user: follower}} = conn, %{"list" => list}) do
json(conn, "job started") json(conn, "job started")
end end
def blocks(conn, %{"list" => %Plug.Upload{path: path}}) do def blocks(%{body_params: %{list: %Plug.Upload{path: path}}} = conn, _) do
blocks(conn, %{"list" => File.read!(path)}) blocks(%Plug.Conn{conn | body_params: %{list: File.read!(path)}}, %{})
end end
def blocks(%{assigns: %{user: blocker}} = conn, %{"list" => list}) do def blocks(%{assigns: %{user: blocker}, body_params: %{list: list}} = conn, _) do
User.Import.blocks_import(blocker, prepare_user_identifiers(list)) User.Import.blocks_import(blocker, prepare_user_identifiers(list))
json(conn, "job started") json(conn, "job started")
end end
def mutes(conn, %{"list" => %Plug.Upload{path: path}}) do def mutes(%{body_params: %{list: %Plug.Upload{path: path}}} = conn, _) do
mutes(conn, %{"list" => File.read!(path)}) mutes(%Plug.Conn{conn | body_params: %{list: File.read!(path)}}, %{})
end end
def mutes(%{assigns: %{user: user}} = conn, %{"list" => list}) do def mutes(%{assigns: %{user: user}, body_params: %{list: list}} = conn, _) do
User.Import.mutes_import(user, prepare_user_identifiers(list)) User.Import.mutes_import(user, prepare_user_identifiers(list))
json(conn, "job started") json(conn, "job started")
end end

View file

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.ImportTest do defmodule Pleroma.User.ImportTest do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers alias Pleroma.Tests.ObanHelpers
alias Pleroma.User alias Pleroma.User
@ -37,7 +36,6 @@ test "it imports user followings from list" do
end end
end end
describe "blocks_import" do describe "blocks_import" do
test "it imports user blocks from list" do test "it imports user blocks from list" do
[user1, user2, user3] = insert_list(3, :user) [user1, user2, user3] = insert_list(3, :user)

View file

@ -23,9 +23,11 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do
test "it returns HTTP 200", %{conn: conn} do test "it returns HTTP 200", %{conn: conn} do
user2 = insert(:user) user2 = insert(:user)
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"}) |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"})
|> json_response(:ok) |> json_response_and_validate_schema(200)
end end
test "it imports follow lists from file", %{conn: conn} do test "it imports follow lists from file", %{conn: conn} do
@ -37,9 +39,13 @@ test "it imports follow lists from file", %{conn: conn} do
"Account address,Show boosts\n#{user2.ap_id},true" "Account address,Show boosts\n#{user2.ap_id},true"
end} end}
]) do ]) do
assert "job started" == conn assert "job started" ==
|> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}}) conn
|> json_response(:ok) |> put_req_header("content-type", "application/json")
|> post("/api/pleroma/follow_import", %{
"list" => %Plug.Upload{path: "follow_list.txt"}
})
|> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == [user2] assert job_result == [user2]
@ -49,11 +55,13 @@ test "it imports follow lists from file", %{conn: conn} do
test "it imports new-style mastodon follow lists", %{conn: conn} do test "it imports new-style mastodon follow lists", %{conn: conn} do
user2 = insert(:user) user2 = insert(:user)
response = conn response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/follow_import", %{ |> post("/api/pleroma/follow_import", %{
"list" => "Account address,Show boosts\n#{user2.ap_id},true"} "list" => "Account address,Show boosts\n#{user2.ap_id},true"
) })
|> json_response(:ok) |> json_response_and_validate_schema(200)
assert response == "job started" assert response == "job started"
end end
@ -68,6 +76,7 @@ test "requires 'follow' or 'write:follows' permissions" do
conn = conn =
build_conn() build_conn()
|> put_req_header("authorization", "Bearer #{token.token}") |> put_req_header("authorization", "Bearer #{token.token}")
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"}) |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
if token == token3 do if token == token3 do
@ -93,9 +102,11 @@ test "it imports follows with different nickname variations", %{conn: conn} do
] ]
|> Enum.join("\n") |> Enum.join("\n")
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/follow_import", %{"list" => identifiers}) |> post("/api/pleroma/follow_import", %{"list" => identifiers})
|> json_response(:ok) |> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == users assert job_result == users
@ -109,9 +120,11 @@ test "it imports follows with different nickname variations", %{conn: conn} do
test "it returns HTTP 200", %{conn: conn} do test "it returns HTTP 200", %{conn: conn} do
user2 = insert(:user) user2 = insert(:user)
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"}) |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"})
|> json_response(:ok) |> json_response_and_validate_schema(200)
end end
test "it imports blocks users from file", %{conn: conn} do test "it imports blocks users from file", %{conn: conn} do
@ -120,10 +133,13 @@ test "it imports blocks users from file", %{conn: conn} do
with_mocks([ with_mocks([
{File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end} {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
]) do ]) do
assert "job started" ==
assert "job started" == conn conn
|> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}}) |> put_req_header("content-type", "application/json")
|> json_response(:ok) |> post("/api/pleroma/blocks_import", %{
"list" => %Plug.Upload{path: "blocks_list.txt"}
})
|> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == users assert job_result == users
@ -143,9 +159,11 @@ test "it imports blocks with different nickname variations", %{conn: conn} do
] ]
|> Enum.join(" ") |> Enum.join(" ")
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/blocks_import", %{"list" => identifiers}) |> post("/api/pleroma/blocks_import", %{"list" => identifiers})
|> json_response(:ok) |> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == users assert job_result == users
@ -159,25 +177,30 @@ test "it imports blocks with different nickname variations", %{conn: conn} do
test "it returns HTTP 200", %{user: user, conn: conn} do test "it returns HTTP 200", %{user: user, conn: conn} do
user2 = insert(:user) user2 = insert(:user)
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/mutes_import", %{"list" => "#{user2.ap_id}"}) |> post("/api/pleroma/mutes_import", %{"list" => "#{user2.ap_id}"})
|> json_response(:ok) |> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == [user2] assert job_result == [user2]
assert Pleroma.User.mutes?(user, user2) assert Pleroma.User.mutes?(user, user2)
end end
test "it imports mutes users from file", %{user: user, conn: conn} do test "it imports mutes users from file", %{user: user, conn: conn} do
users = [user2, user3] = insert_list(2, :user) users = [user2, user3] = insert_list(2, :user)
with_mocks([ with_mocks([
{File, [], read!: fn "mutes_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end} {File, [], read!: fn "mutes_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
]) do ]) do
assert "job started" == conn assert "job started" ==
|> post("/api/pleroma/mutes_import", %{"list" => %Plug.Upload{path: "mutes_list.txt"}}) conn
|> json_response(:ok) |> put_req_header("content-type", "application/json")
|> post("/api/pleroma/mutes_import", %{
"list" => %Plug.Upload{path: "mutes_list.txt"}
})
|> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == users assert job_result == users
@ -188,15 +211,22 @@ test "it imports mutes users from file", %{user: user, conn: conn} do
test "it imports mutes with different nickname variations", %{user: user, conn: conn} do test "it imports mutes with different nickname variations", %{user: user, conn: conn} do
users = [user2, user3, user4, user5, user6] = insert_list(5, :user) users = [user2, user3, user4, user5, user6] = insert_list(5, :user)
identifiers = [ identifiers =
user2.ap_id, user3.nickname, "@" <> user4.nickname, [
user5.nickname <> "@localhost", "@" <> user6.nickname <> "@localhost" user2.ap_id,
user3.nickname,
"@" <> user4.nickname,
user5.nickname <> "@localhost",
"@" <> user6.nickname <> "@localhost"
] ]
|> Enum.join(" ") |> Enum.join(" ")
assert "job started" == conn assert "job started" ==
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/mutes_import", %{"list" => identifiers}) |> post("/api/pleroma/mutes_import", %{"list" => identifiers})
|> json_response(:ok) |> json_response_and_validate_schema(200)
assert [{:ok, job_result}] = ObanHelpers.perform_all() assert [{:ok, job_result}] = ObanHelpers.perform_all()
assert job_result == users assert job_result == users
assert Enum.all?(users, &Pleroma.User.mutes?(user, &1)) assert Enum.all?(users, &Pleroma.User.mutes?(user, &1))