Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-dms
This commit is contained in:
commit
205313e541
80 changed files with 2138 additions and 337 deletions
139
lib/pleroma/web/api_spec/cast_and_validate.ex
Normal file
139
lib/pleroma/web/api_spec/cast_and_validate.ex
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019-2020 Moxley Stratton, Mike Buhot <https://github.com/open-api-spex/open_api_spex>, MPL-2.0
|
||||
# Copyright © 2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
||||
@moduledoc """
|
||||
This plug is based on [`OpenApiSpex.Plug.CastAndValidate`]
|
||||
(https://github.com/open-api-spex/open_api_spex/blob/master/lib/open_api_spex/plug/cast_and_validate.ex).
|
||||
The main difference is ignoring unexpected query params instead of throwing
|
||||
an error and a config option (`[Pleroma.Web.ApiSpec.CastAndValidate, :strict]`)
|
||||
to disable this behavior. Also, the default rendering error module
|
||||
is `Pleroma.Web.ApiSpec.RenderError`.
|
||||
"""
|
||||
|
||||
@behaviour Plug
|
||||
|
||||
alias Plug.Conn
|
||||
|
||||
@impl Plug
|
||||
def init(opts) do
|
||||
opts
|
||||
|> Map.new()
|
||||
|> Map.put_new(:render_error, Pleroma.Web.ApiSpec.RenderError)
|
||||
end
|
||||
|
||||
@impl Plug
|
||||
def call(%{private: %{open_api_spex: private_data}} = conn, %{
|
||||
operation_id: operation_id,
|
||||
render_error: render_error
|
||||
}) do
|
||||
spec = private_data.spec
|
||||
operation = private_data.operation_lookup[operation_id]
|
||||
|
||||
content_type =
|
||||
case Conn.get_req_header(conn, "content-type") do
|
||||
[header_value | _] ->
|
||||
header_value
|
||||
|> String.split(";")
|
||||
|> List.first()
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
|
||||
private_data = Map.put(private_data, :operation_id, operation_id)
|
||||
conn = Conn.put_private(conn, :open_api_spex, private_data)
|
||||
|
||||
case cast_and_validate(spec, operation, conn, content_type, strict?()) do
|
||||
{:ok, conn} ->
|
||||
conn
|
||||
|
||||
{:error, reason} ->
|
||||
opts = render_error.init(reason)
|
||||
|
||||
conn
|
||||
|> render_error.call(opts)
|
||||
|> Plug.Conn.halt()
|
||||
end
|
||||
end
|
||||
|
||||
def call(
|
||||
%{
|
||||
private: %{
|
||||
phoenix_controller: controller,
|
||||
phoenix_action: action,
|
||||
open_api_spex: private_data
|
||||
}
|
||||
} = conn,
|
||||
opts
|
||||
) do
|
||||
operation =
|
||||
case private_data.operation_lookup[{controller, action}] do
|
||||
nil ->
|
||||
operation_id = controller.open_api_operation(action).operationId
|
||||
operation = private_data.operation_lookup[operation_id]
|
||||
|
||||
operation_lookup =
|
||||
private_data.operation_lookup
|
||||
|> Map.put({controller, action}, operation)
|
||||
|
||||
OpenApiSpex.Plug.Cache.adapter().put(
|
||||
private_data.spec_module,
|
||||
{private_data.spec, operation_lookup}
|
||||
)
|
||||
|
||||
operation
|
||||
|
||||
operation ->
|
||||
operation
|
||||
end
|
||||
|
||||
if operation.operationId do
|
||||
call(conn, Map.put(opts, :operation_id, operation.operationId))
|
||||
else
|
||||
raise "operationId was not found in action API spec"
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, opts), do: OpenApiSpex.Plug.CastAndValidate.call(conn, opts)
|
||||
|
||||
defp cast_and_validate(spec, operation, conn, content_type, true = _strict) do
|
||||
OpenApiSpex.cast_and_validate(spec, operation, conn, content_type)
|
||||
end
|
||||
|
||||
defp cast_and_validate(spec, operation, conn, content_type, false = _strict) do
|
||||
case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) do
|
||||
{:ok, conn} ->
|
||||
{:ok, conn}
|
||||
|
||||
# Remove unexpected query params and cast/validate again
|
||||
{:error, errors} ->
|
||||
query_params =
|
||||
Enum.reduce(errors, conn.query_params, fn
|
||||
%{reason: :unexpected_field, name: name, path: [name]}, params ->
|
||||
Map.delete(params, name)
|
||||
|
||||
%{reason: :invalid_enum, name: nil, path: path, value: value}, params ->
|
||||
path = path |> Enum.reverse() |> tl() |> Enum.reverse() |> list_items_to_string()
|
||||
update_in(params, path, &List.delete(&1, value))
|
||||
|
||||
_, params ->
|
||||
params
|
||||
end)
|
||||
|
||||
conn = %Conn{conn | query_params: query_params}
|
||||
OpenApiSpex.cast_and_validate(spec, operation, conn, content_type)
|
||||
end
|
||||
end
|
||||
|
||||
defp list_items_to_string(list) do
|
||||
Enum.map(list, fn
|
||||
i when is_atom(i) -> to_string(i)
|
||||
i -> i
|
||||
end)
|
||||
end
|
||||
|
||||
defp strict?, do: Pleroma.Config.get([__MODULE__, :strict], false)
|
||||
end
|
||||
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
alias Pleroma.Web.ApiSpec.Schemas.ActorType
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
|
||||
alias Pleroma.Web.ApiSpec.Schemas.List
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Status
|
||||
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
||||
|
||||
|
|
@ -646,28 +647,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
}
|
||||
end
|
||||
|
||||
defp list do
|
||||
%Schema{
|
||||
title: "List",
|
||||
description: "Response schema for a list",
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
title: %Schema{type: :string}
|
||||
},
|
||||
example: %{
|
||||
"id" => "123",
|
||||
"title" => "my list"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_lists do
|
||||
%Schema{
|
||||
title: "ArrayOfLists",
|
||||
description: "Response schema for lists",
|
||||
type: :array,
|
||||
items: list(),
|
||||
items: List,
|
||||
example: [
|
||||
%{"id" => "123", "title" => "my list"},
|
||||
%{"id" => "1337", "title" => "anotehr list"}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
# 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.ConversationOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Conversation
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Conversations"],
|
||||
summary: "Show conversation",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
operationId: "ConversationController.index",
|
||||
parameters: [
|
||||
Operation.parameter(
|
||||
:recipients,
|
||||
:query,
|
||||
%Schema{type: :array, items: FlakeID},
|
||||
"Only return conversations with the given recipients (a list of user ids)"
|
||||
)
|
||||
| pagination_params()
|
||||
],
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of Conversation", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: Conversation,
|
||||
example: [Conversation.schema().example]
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def mark_as_read_operation do
|
||||
%Operation{
|
||||
tags: ["Conversations"],
|
||||
summary: "Mark as read",
|
||||
operationId: "ConversationController.mark_as_read",
|
||||
parameters: [
|
||||
Operation.parameter(:id, :path, :string, "Conversation ID",
|
||||
example: "123",
|
||||
required: true
|
||||
)
|
||||
],
|
||||
security: [%{"oAuth" => ["write:conversations"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Conversation", "application/json", Conversation)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
227
lib/pleroma/web/api_spec/operations/filter_operation.ex
Normal file
227
lib/pleroma/web/api_spec/operations/filter_operation.ex
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
# 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.FilterOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["apps"],
|
||||
summary: "View all filters",
|
||||
operationId: "FilterController.index",
|
||||
security: [%{"oAuth" => ["read:filters"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Filters", "application/json", array_of_filters())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["apps"],
|
||||
summary: "Create a filter",
|
||||
operationId: "FilterController.create",
|
||||
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
|
||||
security: [%{"oAuth" => ["write:filters"]}],
|
||||
responses: %{200 => Operation.response("Filter", "application/json", filter())}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["apps"],
|
||||
summary: "View all filters",
|
||||
parameters: [id_param()],
|
||||
operationId: "FilterController.show",
|
||||
security: [%{"oAuth" => ["read:filters"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Filter", "application/json", filter())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["apps"],
|
||||
summary: "Update a filter",
|
||||
parameters: [id_param()],
|
||||
operationId: "FilterController.update",
|
||||
requestBody: Helpers.request_body("Parameters", update_request(), required: true),
|
||||
security: [%{"oAuth" => ["write:filters"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Filter", "application/json", filter())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["apps"],
|
||||
summary: "Remove a filter",
|
||||
parameters: [id_param()],
|
||||
operationId: "FilterController.delete",
|
||||
security: [%{"oAuth" => ["write:filters"]}],
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Filter", "application/json", %Schema{
|
||||
type: :object,
|
||||
description: "Empty object"
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, :string, "Filter ID", example: "123", required: true)
|
||||
end
|
||||
|
||||
defp filter do
|
||||
%Schema{
|
||||
title: "Filter",
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
phrase: %Schema{type: :string, description: "The text to be filtered"},
|
||||
context: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string, enum: ["home", "notifications", "public", "thread"]},
|
||||
description: "The contexts in which the filter should be applied."
|
||||
},
|
||||
expires_at: %Schema{
|
||||
type: :string,
|
||||
format: :"date-time",
|
||||
description:
|
||||
"When the filter should no longer be applied. String (ISO 8601 Datetime), or null if the filter does not expire.",
|
||||
nullable: true
|
||||
},
|
||||
irreversible: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"Should matching entities in home and notifications be dropped by the server?"
|
||||
},
|
||||
whole_word: %Schema{
|
||||
type: :boolean,
|
||||
description: "Should the filter consider word boundaries?"
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"id" => "5580",
|
||||
"phrase" => "@twitter.com",
|
||||
"context" => [
|
||||
"home",
|
||||
"notifications",
|
||||
"public",
|
||||
"thread"
|
||||
],
|
||||
"whole_word" => false,
|
||||
"expires_at" => nil,
|
||||
"irreversible" => true
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_filters do
|
||||
%Schema{
|
||||
title: "ArrayOfFilters",
|
||||
description: "Array of Filters",
|
||||
type: :array,
|
||||
items: filter(),
|
||||
example: [
|
||||
%{
|
||||
"id" => "5580",
|
||||
"phrase" => "@twitter.com",
|
||||
"context" => [
|
||||
"home",
|
||||
"notifications",
|
||||
"public",
|
||||
"thread"
|
||||
],
|
||||
"whole_word" => false,
|
||||
"expires_at" => nil,
|
||||
"irreversible" => true
|
||||
},
|
||||
%{
|
||||
"id" => "6191",
|
||||
"phrase" => ":eurovision2019:",
|
||||
"context" => [
|
||||
"home"
|
||||
],
|
||||
"whole_word" => true,
|
||||
"expires_at" => "2019-05-21T13:47:31.333Z",
|
||||
"irreversible" => false
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
defp create_request do
|
||||
%Schema{
|
||||
title: "FilterCreateRequest",
|
||||
allOf: [
|
||||
update_request(),
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
irreversible: %Schema{
|
||||
type: :bolean,
|
||||
description:
|
||||
"Should the server irreversibly drop matching entities from home and notifications?",
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
example: %{
|
||||
"phrase" => "knights",
|
||||
"context" => ["home"]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_request do
|
||||
%Schema{
|
||||
title: "FilterUpdateRequest",
|
||||
type: :object,
|
||||
properties: %{
|
||||
phrase: %Schema{type: :string, description: "The text to be filtered"},
|
||||
context: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string, enum: ["home", "notifications", "public", "thread"]},
|
||||
description:
|
||||
"Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified."
|
||||
},
|
||||
irreversible: %Schema{
|
||||
type: :bolean,
|
||||
description:
|
||||
"Should the server irreversibly drop matching entities from home and notifications?"
|
||||
},
|
||||
whole_word: %Schema{
|
||||
type: :bolean,
|
||||
description: "Consider word boundaries?",
|
||||
default: true
|
||||
}
|
||||
# TODO: probably should implement filter expiration
|
||||
# expires_in: %Schema{
|
||||
# type: :string,
|
||||
# format: :"date-time",
|
||||
# description:
|
||||
# "ISO 8601 Datetime for when the filter expires. Otherwise,
|
||||
# null for a filter that doesn't expire."
|
||||
# }
|
||||
},
|
||||
required: [:phrase, :context],
|
||||
example: %{
|
||||
"phrase" => "knights",
|
||||
"context" => ["home"]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# 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.FollowRequestOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Follow Requests"],
|
||||
summary: "Pending Follows",
|
||||
security: [%{"oAuth" => ["read:follows", "follow"]}],
|
||||
operationId: "FollowRequestController.index",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of Account", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: Account,
|
||||
example: [Account.schema().example]
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def authorize_operation do
|
||||
%Operation{
|
||||
tags: ["Follow Requests"],
|
||||
summary: "Accept Follow",
|
||||
operationId: "FollowRequestController.authorize",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["follow", "write:follows"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Relationship", "application/json", AccountRelationship)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def reject_operation do
|
||||
%Operation{
|
||||
tags: ["Follow Requests"],
|
||||
summary: "Reject Follow",
|
||||
operationId: "FollowRequestController.reject",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["follow", "write:follows"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Relationship", "application/json", AccountRelationship)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, :string, "Conversation ID",
|
||||
example: "123",
|
||||
required: true
|
||||
)
|
||||
end
|
||||
end
|
||||
169
lib/pleroma/web/api_spec/operations/instance_operation.ex
Normal file
169
lib/pleroma/web/api_spec/operations/instance_operation.ex
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# 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.InstanceOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
summary: "Fetch instance",
|
||||
description: "Information about the server",
|
||||
operationId: "InstanceController.show",
|
||||
responses: %{
|
||||
200 => Operation.response("Instance", "application/json", instance())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def peers_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
summary: "List of known hosts",
|
||||
operationId: "InstanceController.peers",
|
||||
responses: %{
|
||||
200 => Operation.response("Array of domains", "application/json", array_of_domains())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp instance do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
uri: %Schema{type: :string, description: "The domain name of the instance"},
|
||||
title: %Schema{type: :string, description: "The title of the website"},
|
||||
description: %Schema{
|
||||
type: :string,
|
||||
description: "Admin-defined description of the Pleroma site"
|
||||
},
|
||||
version: %Schema{
|
||||
type: :string,
|
||||
description: "The version of Pleroma installed on the instance"
|
||||
},
|
||||
email: %Schema{
|
||||
type: :string,
|
||||
description: "An email that may be contacted for any inquiries",
|
||||
format: :email
|
||||
},
|
||||
urls: %Schema{
|
||||
type: :object,
|
||||
description: "URLs of interest for clients apps",
|
||||
properties: %{
|
||||
streaming_api: %Schema{
|
||||
type: :string,
|
||||
description: "Websockets address for push streaming"
|
||||
}
|
||||
}
|
||||
},
|
||||
stats: %Schema{
|
||||
type: :object,
|
||||
description: "Statistics about how much information the instance contains",
|
||||
properties: %{
|
||||
user_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Users registered on this instance"
|
||||
},
|
||||
status_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Statuses authored by users on instance"
|
||||
},
|
||||
domain_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Domains federated with this instance"
|
||||
}
|
||||
}
|
||||
},
|
||||
thumbnail: %Schema{
|
||||
type: :string,
|
||||
description: "Banner image for the website",
|
||||
nullable: true
|
||||
},
|
||||
languages: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
description: "Primary langauges of the website and its staff"
|
||||
},
|
||||
registrations: %Schema{type: :boolean, description: "Whether registrations are enabled"},
|
||||
# Extra (not present in Mastodon):
|
||||
max_toot_chars: %Schema{
|
||||
type: :integer,
|
||||
description: ": Posts character limit (CW/Subject included in the counter)"
|
||||
},
|
||||
poll_limits: %Schema{
|
||||
type: :object,
|
||||
description: "A map with poll limits for local polls",
|
||||
properties: %{
|
||||
max_options: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum number of options."
|
||||
},
|
||||
max_option_chars: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum number of characters per option."
|
||||
},
|
||||
min_expiration: %Schema{
|
||||
type: :integer,
|
||||
description: "Minimum expiration time (in seconds)."
|
||||
},
|
||||
max_expiration: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum expiration time (in seconds)."
|
||||
}
|
||||
}
|
||||
},
|
||||
upload_limit: %Schema{
|
||||
type: :integer,
|
||||
description: "File size limit of uploads (except for avatar, background, banner)"
|
||||
},
|
||||
avatar_upload_limit: %Schema{type: :integer, description: "The title of the website"},
|
||||
background_upload_limit: %Schema{type: :integer, description: "The title of the website"},
|
||||
banner_upload_limit: %Schema{type: :integer, description: "The title of the website"}
|
||||
},
|
||||
example: %{
|
||||
"avatar_upload_limit" => 2_000_000,
|
||||
"background_upload_limit" => 4_000_000,
|
||||
"banner_upload_limit" => 4_000_000,
|
||||
"description" => "A Pleroma instance, an alternative fediverse server",
|
||||
"email" => "lain@lain.com",
|
||||
"languages" => ["en"],
|
||||
"max_toot_chars" => 5000,
|
||||
"poll_limits" => %{
|
||||
"max_expiration" => 31_536_000,
|
||||
"max_option_chars" => 200,
|
||||
"max_options" => 20,
|
||||
"min_expiration" => 0
|
||||
},
|
||||
"registrations" => false,
|
||||
"stats" => %{
|
||||
"domain_count" => 2996,
|
||||
"status_count" => 15_802,
|
||||
"user_count" => 5
|
||||
},
|
||||
"thumbnail" => "https://lain.com/instance/thumbnail.jpeg",
|
||||
"title" => "lain.com",
|
||||
"upload_limit" => 16_000_000,
|
||||
"uri" => "https://lain.com",
|
||||
"urls" => %{
|
||||
"streaming_api" => "wss://lain.com"
|
||||
},
|
||||
"version" => "2.7.2 (compatible; Pleroma 2.0.50-536-g25eec6d7-develop)"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_domains do
|
||||
%Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
example: ["pleroma.site", "lain.com", "bikeshed.party"]
|
||||
}
|
||||
end
|
||||
end
|
||||
188
lib/pleroma/web/api_spec/operations/list_operation.ex
Normal file
188
lib/pleroma/web/api_spec/operations/list_operation.ex
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
# 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.ListOperation 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.List
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Show user's lists",
|
||||
description: "Fetch all lists that the user owns",
|
||||
security: [%{"oAuth" => ["read:lists"]}],
|
||||
operationId: "ListController.index",
|
||||
responses: %{
|
||||
200 => Operation.response("Array of List", "application/json", array_of_lists())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Create a list",
|
||||
description: "Fetch the list with the given ID. Used for verifying the title of a list.",
|
||||
operationId: "ListController.create",
|
||||
requestBody: create_update_request(),
|
||||
security: [%{"oAuth" => ["write:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("List", "application/json", List),
|
||||
400 => Operation.response("Error", "application/json", ApiError),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Show a single list",
|
||||
description: "Fetch the list with the given ID. Used for verifying the title of a list.",
|
||||
operationId: "ListController.show",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["read:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("List", "application/json", List),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Update a list",
|
||||
description: "Change the title of a list",
|
||||
operationId: "ListController.update",
|
||||
parameters: [id_param()],
|
||||
requestBody: create_update_request(),
|
||||
security: [%{"oAuth" => ["write:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("List", "application/json", List),
|
||||
422 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Delete a list",
|
||||
operationId: "ListController.delete",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["write:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def list_accounts_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "View accounts in list",
|
||||
operationId: "ListController.list_accounts",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["read:lists"]}],
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of Account", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: Account
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def add_to_list_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Add accounts to list",
|
||||
description: "Add accounts to the given list.",
|
||||
operationId: "ListController.add_to_list",
|
||||
parameters: [id_param()],
|
||||
requestBody: add_remove_accounts_request(),
|
||||
security: [%{"oAuth" => ["write:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def remove_from_list_operation do
|
||||
%Operation{
|
||||
tags: ["Lists"],
|
||||
summary: "Remove accounts from list",
|
||||
operationId: "ListController.remove_from_list",
|
||||
parameters: [id_param()],
|
||||
requestBody: add_remove_accounts_request(),
|
||||
security: [%{"oAuth" => ["write:lists"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_lists do
|
||||
%Schema{
|
||||
title: "ArrayOfLists",
|
||||
description: "Response schema for lists",
|
||||
type: :array,
|
||||
items: List,
|
||||
example: [
|
||||
%{"id" => "123", "title" => "my list"},
|
||||
%{"id" => "1337", "title" => "another list"}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, :string, "List ID",
|
||||
example: "123",
|
||||
required: true
|
||||
)
|
||||
end
|
||||
|
||||
defp create_update_request do
|
||||
request_body(
|
||||
"Parameters",
|
||||
%Schema{
|
||||
description: "POST body for creating or updating a List",
|
||||
type: :object,
|
||||
properties: %{
|
||||
title: %Schema{type: :string, description: "List title"}
|
||||
},
|
||||
required: [:title]
|
||||
},
|
||||
required: true
|
||||
)
|
||||
end
|
||||
|
||||
defp add_remove_accounts_request do
|
||||
request_body(
|
||||
"Parameters",
|
||||
%Schema{
|
||||
description: "POST body for adding/removing accounts to/from a List",
|
||||
type: :object,
|
||||
properties: %{
|
||||
account_ids: %Schema{type: :array, description: "Array of account IDs", items: FlakeID}
|
||||
},
|
||||
required: [:account_ids]
|
||||
},
|
||||
required: true
|
||||
)
|
||||
end
|
||||
end
|
||||
140
lib/pleroma/web/api_spec/operations/marker_operation.ex
Normal file
140
lib/pleroma/web/api_spec/operations/marker_operation.ex
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# 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.MarkerOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Markers"],
|
||||
summary: "Get saved timeline position",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
operationId: "MarkerController.index",
|
||||
parameters: [
|
||||
Operation.parameter(
|
||||
:timeline,
|
||||
:query,
|
||||
%Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string, enum: ["home", "notifications"]}
|
||||
},
|
||||
"Array of markers to fetch. If not provided, an empty object will be returned."
|
||||
)
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("Marker", "application/json", response()),
|
||||
403 => Operation.response("Error", "application/json", api_error())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def upsert_operation do
|
||||
%Operation{
|
||||
tags: ["Markers"],
|
||||
summary: "Save position in timeline",
|
||||
operationId: "MarkerController.upsert",
|
||||
requestBody: Helpers.request_body("Parameters", upsert_request(), required: true),
|
||||
security: [%{"oAuth" => ["follow", "write:blocks"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Marker", "application/json", response()),
|
||||
403 => Operation.response("Error", "application/json", api_error())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp marker do
|
||||
%Schema{
|
||||
title: "Marker",
|
||||
description: "Schema for a marker",
|
||||
type: :object,
|
||||
properties: %{
|
||||
last_read_id: %Schema{type: :string},
|
||||
version: %Schema{type: :integer},
|
||||
updated_at: %Schema{type: :string},
|
||||
pleroma: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
unread_count: %Schema{type: :integer}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"last_read_id" => "35098814",
|
||||
"version" => 361,
|
||||
"updated_at" => "2019-11-26T22:37:25.239Z",
|
||||
"pleroma" => %{"unread_count" => 5}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp response do
|
||||
%Schema{
|
||||
title: "MarkersResponse",
|
||||
description: "Response schema for markers",
|
||||
type: :object,
|
||||
properties: %{
|
||||
notifications: %Schema{allOf: [marker()], nullable: true},
|
||||
home: %Schema{allOf: [marker()], nullable: true}
|
||||
},
|
||||
items: %Schema{type: :string},
|
||||
example: %{
|
||||
"notifications" => %{
|
||||
"last_read_id" => "35098814",
|
||||
"version" => 361,
|
||||
"updated_at" => "2019-11-26T22:37:25.239Z",
|
||||
"pleroma" => %{"unread_count" => 0}
|
||||
},
|
||||
"home" => %{
|
||||
"last_read_id" => "103206604258487607",
|
||||
"version" => 468,
|
||||
"updated_at" => "2019-11-26T22:37:25.235Z",
|
||||
"pleroma" => %{"unread_count" => 10}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp upsert_request do
|
||||
%Schema{
|
||||
title: "MarkersUpsertRequest",
|
||||
description: "Request schema for marker upsert",
|
||||
type: :object,
|
||||
properties: %{
|
||||
notifications: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
last_read_id: %Schema{type: :string}
|
||||
}
|
||||
},
|
||||
home: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
last_read_id: %Schema{type: :string}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"home" => %{
|
||||
"last_read_id" => "103194548672408537",
|
||||
"version" => 462,
|
||||
"updated_at" => "2019-11-24T19:39:39.337Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp api_error do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{error: %Schema{type: :string}}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
# 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.ScheduledActivityOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "View scheduled statuses",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
parameters: pagination_params(),
|
||||
operationId: "ScheduledActivity.index",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of ScheduledStatus", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: ScheduledStatus
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "View a single scheduled status",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
operationId: "ScheduledActivity.show",
|
||||
responses: %{
|
||||
200 => Operation.response("Scheduled Status", "application/json", ScheduledStatus),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "Schedule a status",
|
||||
operationId: "ScheduledActivity.update",
|
||||
security: [%{"oAuth" => ["write:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
requestBody:
|
||||
request_body("Parameters", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
scheduled_at: %Schema{
|
||||
type: :string,
|
||||
format: :"date-time",
|
||||
description:
|
||||
"ISO 8601 Datetime at which the status will be published. Must be at least 5 minutes into the future."
|
||||
}
|
||||
}
|
||||
}),
|
||||
responses: %{
|
||||
200 => Operation.response("Scheduled Status", "application/json", ScheduledStatus),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "Cancel a scheduled status",
|
||||
security: [%{"oAuth" => ["write:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
operationId: "ScheduledActivity.delete",
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object}),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, FlakeID, "Poll ID",
|
||||
example: "123",
|
||||
required: true
|
||||
)
|
||||
end
|
||||
end
|
||||
188
lib/pleroma/web/api_spec/operations/subscription_operation.ex
Normal file
188
lib/pleroma/web/api_spec/operations/subscription_operation.ex
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
# 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.SubscriptionOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Helpers
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.PushSubscription
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["Push Subscriptions"],
|
||||
summary: "Subscribe to push notifications",
|
||||
description:
|
||||
"Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.",
|
||||
operationId: "SubscriptionController.create",
|
||||
security: [%{"oAuth" => ["push"]}],
|
||||
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
|
||||
responses: %{
|
||||
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
|
||||
400 => Operation.response("Error", "application/json", ApiError),
|
||||
403 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Push Subscriptions"],
|
||||
summary: "Get current subscription",
|
||||
description: "View the PushSubscription currently associated with this access token.",
|
||||
operationId: "SubscriptionController.show",
|
||||
security: [%{"oAuth" => ["push"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
|
||||
403 => Operation.response("Error", "application/json", ApiError),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Push Subscriptions"],
|
||||
summary: "Change types of notifications",
|
||||
description:
|
||||
"Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead.",
|
||||
operationId: "SubscriptionController.update",
|
||||
security: [%{"oAuth" => ["push"]}],
|
||||
requestBody: Helpers.request_body("Parameters", update_request(), required: true),
|
||||
responses: %{
|
||||
200 => Operation.response("Push Subscription", "application/json", PushSubscription),
|
||||
403 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Push Subscriptions"],
|
||||
summary: "Remove current subscription",
|
||||
description: "Removes the current Web Push API subscription.",
|
||||
operationId: "SubscriptionController.delete",
|
||||
security: [%{"oAuth" => ["push"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object}),
|
||||
403 => Operation.response("Error", "application/json", ApiError),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp create_request do
|
||||
%Schema{
|
||||
title: "SubscriptionCreateRequest",
|
||||
description: "POST body for creating a push subscription",
|
||||
type: :object,
|
||||
properties: %{
|
||||
subscription: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
endpoint: %Schema{
|
||||
type: :string,
|
||||
description: "Endpoint URL that is called when a notification event occurs."
|
||||
},
|
||||
keys: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
p256dh: %Schema{
|
||||
type: :string,
|
||||
description:
|
||||
"User agent public key. Base64 encoded string of public key of ECDH key using `prime256v1` curve."
|
||||
},
|
||||
auth: %Schema{
|
||||
type: :string,
|
||||
description: "Auth secret. Base64 encoded string of 16 bytes of random data."
|
||||
}
|
||||
},
|
||||
required: [:p256dh, :auth]
|
||||
}
|
||||
},
|
||||
required: [:endpoint, :keys]
|
||||
},
|
||||
data: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
alerts: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
|
||||
favourite: %Schema{
|
||||
type: :boolean,
|
||||
description: "Receive favourite notifications?"
|
||||
},
|
||||
reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
|
||||
mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
|
||||
poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
required: [:subscription],
|
||||
example: %{
|
||||
"subscription" => %{
|
||||
"endpoint" => "https://example.com/example/1234",
|
||||
"keys" => %{
|
||||
"auth" => "8eDyX_uCN0XRhSbY5hs7Hg==",
|
||||
"p256dh" =>
|
||||
"BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
|
||||
}
|
||||
},
|
||||
"data" => %{
|
||||
"alerts" => %{
|
||||
"follow" => true,
|
||||
"mention" => true,
|
||||
"poll" => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_request do
|
||||
%Schema{
|
||||
title: "SubscriptionUpdateRequest",
|
||||
type: :object,
|
||||
properties: %{
|
||||
data: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
alerts: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
|
||||
favourite: %Schema{
|
||||
type: :boolean,
|
||||
description: "Receive favourite notifications?"
|
||||
},
|
||||
reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
|
||||
mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
|
||||
poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"data" => %{
|
||||
"alerts" => %{
|
||||
"follow" => true,
|
||||
"favourite" => true,
|
||||
"reblog" => true,
|
||||
"mention" => true,
|
||||
"poll" => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -17,6 +17,9 @@ defmodule Pleroma.Web.ApiSpec.RenderError do
|
|||
def call(conn, errors) do
|
||||
errors =
|
||||
Enum.map(errors, fn
|
||||
%{name: nil, reason: :invalid_enum} = err ->
|
||||
%OpenApiSpex.Cast.Error{err | name: err.value}
|
||||
|
||||
%{name: nil} = err ->
|
||||
%OpenApiSpex.Cast.Error{err | name: List.last(err.path)}
|
||||
|
||||
|
|
|
|||
68
lib/pleroma/web/api_spec/schemas/attachment.ex
Normal file
68
lib/pleroma/web/api_spec/schemas/attachment.ex
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# 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.Schemas.Attachment do
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "Attachment",
|
||||
description: "Represents a file or media attachment that can be added to a status.",
|
||||
type: :object,
|
||||
requried: [:id, :url, :preview_url],
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description: "The location of the original full-size attachment"
|
||||
},
|
||||
remote_url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description:
|
||||
"The location of the full-size original attachment on the remote website. String (URL), or null if the attachment is local",
|
||||
nullable: true
|
||||
},
|
||||
preview_url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description: "The location of a scaled-down preview of the attachment"
|
||||
},
|
||||
text_url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description: "A shorter URL for the attachment"
|
||||
},
|
||||
description: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"Alternate text that describes what is in the media attachment, to be used for the visually impaired or when media attachments do not load"
|
||||
},
|
||||
type: %Schema{
|
||||
type: :string,
|
||||
enum: ["image", "video", "audio", "unknown"],
|
||||
description: "The type of the attachment"
|
||||
},
|
||||
pleroma: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
mime_type: %Schema{type: :string, description: "mime type of the attachment"}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
id: "1638338801",
|
||||
type: "image",
|
||||
url: "someurl",
|
||||
remote_url: "someurl",
|
||||
preview_url: "someurl",
|
||||
text_url: "someurl",
|
||||
description: nil,
|
||||
pleroma: %{mime_type: "image/png"}
|
||||
}
|
||||
})
|
||||
end
|
||||
41
lib/pleroma/web/api_spec/schemas/conversation.ex
Normal file
41
lib/pleroma/web/api_spec/schemas/conversation.ex
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# 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.Schemas.Conversation do
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Status
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "Conversation",
|
||||
description: "Represents a conversation with \"direct message\" visibility.",
|
||||
type: :object,
|
||||
required: [:id, :accounts, :unread],
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
accounts: %Schema{
|
||||
type: :array,
|
||||
items: Account,
|
||||
description: "Participants in the conversation"
|
||||
},
|
||||
unread: %Schema{
|
||||
type: :boolean,
|
||||
description: "Is the conversation currently marked as unread?"
|
||||
},
|
||||
# last_status: Status
|
||||
last_status: %Schema{
|
||||
allOf: [Status],
|
||||
description: "The last status in the conversation, to be used for optional display"
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"id" => "418450",
|
||||
"unread" => true,
|
||||
"accounts" => [Account.schema().example],
|
||||
"last_status" => Status.schema().example
|
||||
}
|
||||
})
|
||||
end
|
||||
23
lib/pleroma/web/api_spec/schemas/list.ex
Normal file
23
lib/pleroma/web/api_spec/schemas/list.ex
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# 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.Schemas.List do
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "List",
|
||||
description: "Represents a list of users",
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string, description: "The internal database ID of the list"},
|
||||
title: %Schema{type: :string, description: "The user-defined title of the list"}
|
||||
},
|
||||
example: %{
|
||||
"id" => "12249",
|
||||
"title" => "Friends"
|
||||
}
|
||||
})
|
||||
end
|
||||
66
lib/pleroma/web/api_spec/schemas/push_subscription.ex
Normal file
66
lib/pleroma/web/api_spec/schemas/push_subscription.ex
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# 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.Schemas.PushSubscription do
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "PushSubscription",
|
||||
description: "Response schema for a push subscription",
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{
|
||||
anyOf: [%Schema{type: :string}, %Schema{type: :integer}],
|
||||
description: "The id of the push subscription in the database."
|
||||
},
|
||||
endpoint: %Schema{type: :string, description: "Where push alerts will be sent to."},
|
||||
server_key: %Schema{type: :string, description: "The streaming server's VAPID key."},
|
||||
alerts: %Schema{
|
||||
type: :object,
|
||||
description: "Which alerts should be delivered to the endpoint.",
|
||||
properties: %{
|
||||
follow: %Schema{
|
||||
type: :boolean,
|
||||
description: "Receive a push notification when someone has followed you?"
|
||||
},
|
||||
favourite: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"Receive a push notification when a status you created has been favourited by someone else?"
|
||||
},
|
||||
reblog: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"Receive a push notification when a status you created has been boosted by someone else?"
|
||||
},
|
||||
mention: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"Receive a push notification when someone else has mentioned you in a status?"
|
||||
},
|
||||
poll: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"Receive a push notification when a poll you voted in or created has ended? "
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"id" => "328_183",
|
||||
"endpoint" => "https://yourdomain.example/listener",
|
||||
"alerts" => %{
|
||||
"follow" => true,
|
||||
"favourite" => true,
|
||||
"reblog" => true,
|
||||
"mention" => true,
|
||||
"poll" => true
|
||||
},
|
||||
"server_key" =>
|
||||
"BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M="
|
||||
}
|
||||
})
|
||||
end
|
||||
54
lib/pleroma/web/api_spec/schemas/scheduled_status.ex
Normal file
54
lib/pleroma/web/api_spec/schemas/scheduled_status.ex
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# 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.Schemas.ScheduledStatus do
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Attachment
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Poll
|
||||
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "ScheduledStatus",
|
||||
description: "Represents a status that will be published at a future scheduled date.",
|
||||
type: :object,
|
||||
required: [:id, :scheduled_at, :params],
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
scheduled_at: %Schema{type: :string, format: :"date-time"},
|
||||
media_attachments: %Schema{type: :array, items: Attachment},
|
||||
params: %Schema{
|
||||
type: :object,
|
||||
required: [:text, :visibility],
|
||||
properties: %{
|
||||
text: %Schema{type: :string, nullable: true},
|
||||
media_ids: %Schema{type: :array, nullable: true, items: %Schema{type: :string}},
|
||||
sensitive: %Schema{type: :boolean, nullable: true},
|
||||
spoiler_text: %Schema{type: :string, nullable: true},
|
||||
visibility: %Schema{type: VisibilityScope, nullable: true},
|
||||
scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true},
|
||||
poll: %Schema{type: Poll, nullable: true},
|
||||
in_reply_to_id: %Schema{type: :string, nullable: true}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
id: "3221",
|
||||
scheduled_at: "2019-12-05T12:33:01.000Z",
|
||||
params: %{
|
||||
text: "test content",
|
||||
media_ids: nil,
|
||||
sensitive: nil,
|
||||
spoiler_text: nil,
|
||||
visibility: nil,
|
||||
scheduled_at: nil,
|
||||
poll: nil,
|
||||
idempotency: nil,
|
||||
in_reply_to_id: nil
|
||||
},
|
||||
media_attachments: [Attachment.schema().example]
|
||||
}
|
||||
})
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Attachment
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Emoji
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Poll
|
||||
|
|
@ -50,22 +51,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
language: %Schema{type: :string, nullable: true},
|
||||
media_attachments: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
url: %Schema{type: :string, format: :uri},
|
||||
remote_url: %Schema{type: :string, format: :uri},
|
||||
preview_url: %Schema{type: :string, format: :uri},
|
||||
text_url: %Schema{type: :string, format: :uri},
|
||||
description: %Schema{type: :string},
|
||||
type: %Schema{type: :string, enum: ["image", "video", "audio", "unknown"]},
|
||||
pleroma: %Schema{
|
||||
type: :object,
|
||||
properties: %{mime_type: %Schema{type: :string}}
|
||||
}
|
||||
}
|
||||
}
|
||||
items: Attachment
|
||||
},
|
||||
mentions: %Schema{
|
||||
type: :array,
|
||||
|
|
@ -86,7 +72,12 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
properties: %{
|
||||
content: %Schema{type: :object, additionalProperties: %Schema{type: :string}},
|
||||
conversation_id: %Schema{type: :integer},
|
||||
direct_conversation_id: %Schema{type: :string, nullable: true},
|
||||
direct_conversation_id: %Schema{
|
||||
type: :integer,
|
||||
nullable: true,
|
||||
description:
|
||||
"The ID of the Mastodon direct message conversation the status is associated with (if any)"
|
||||
},
|
||||
emoji_reactions: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue