aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/api_spec/operations/poll_operation.ex76
-rw-r--r--lib/pleroma/web/api_spec/schemas/poll.ex62
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/poll_controller.ex8
3 files changed, 136 insertions, 10 deletions
diff --git a/lib/pleroma/web/api_spec/operations/poll_operation.ex b/lib/pleroma/web/api_spec/operations/poll_operation.ex
new file mode 100644
index 000000000..b953323e9
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/poll_operation.ex
@@ -0,0 +1,76 @@
+# 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.PollOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+ alias Pleroma.Web.ApiSpec.Schemas.FlakeID
+ alias Pleroma.Web.ApiSpec.Schemas.Poll
+
+ import Pleroma.Web.ApiSpec.Helpers
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def show_operation do
+ %Operation{
+ tags: ["Polls"],
+ summary: "View a poll",
+ security: [%{"oAuth" => ["read:statuses"]}],
+ parameters: [id_param()],
+ operationId: "PollController.show",
+ responses: %{
+ 200 => Operation.response("Poll", "application/json", Poll),
+ 404 => Operation.response("Error", "application/json", ApiError)
+ }
+ }
+ end
+
+ def vote_operation do
+ %Operation{
+ tags: ["Polls"],
+ summary: "Block a domain",
+ parameters: [id_param()],
+ operationId: "PollController.vote",
+ requestBody: vote_request(),
+ security: [%{"oAuth" => ["write:statuses"]}],
+ responses: %{
+ 200 => Operation.response("Poll", "application/json", Poll),
+ 422 => Operation.response("Error", "application/json", ApiError),
+ 404 => Operation.response("Error", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp id_param do
+ Operation.parameter(:id, :path, FlakeID, "Poll ID",
+ example: "123",
+ required: true
+ )
+ end
+
+ defp vote_request do
+ request_body(
+ "Parameters",
+ %Schema{
+ type: :object,
+ properties: %{
+ choices: %Schema{
+ type: :array,
+ items: %Schema{type: :integer},
+ description: "Array of own votes containing index for each option (starting from 0)"
+ }
+ },
+ required: [:choices]
+ },
+ required: true,
+ example: %{
+ "choices" => [0, 1, 2]
+ }
+ )
+ end
+end
diff --git a/lib/pleroma/web/api_spec/schemas/poll.ex b/lib/pleroma/web/api_spec/schemas/poll.ex
index 0474b550b..c62096db0 100644
--- a/lib/pleroma/web/api_spec/schemas/poll.ex
+++ b/lib/pleroma/web/api_spec/schemas/poll.ex
@@ -11,26 +11,72 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Poll do
OpenApiSpex.schema(%{
title: "Poll",
- description: "Response schema for account custom fields",
+ description: "Represents a poll attached to a status",
type: :object,
properties: %{
id: FlakeID,
- expires_at: %Schema{type: :string, format: "date-time"},
- expired: %Schema{type: :boolean},
- multiple: %Schema{type: :boolean},
- votes_count: %Schema{type: :integer},
- voted: %Schema{type: :boolean},
- emojis: %Schema{type: :array, items: Emoji},
+ expires_at: %Schema{
+ type: :string,
+ format: :"date-time",
+ nullable: true,
+ description: "When the poll ends"
+ },
+ expired: %Schema{type: :boolean, description: "Is the poll currently expired?"},
+ multiple: %Schema{
+ type: :boolean,
+ description: "Does the poll allow multiple-choice answers?"
+ },
+ votes_count: %Schema{
+ type: :integer,
+ nullable: true,
+ description: "How many votes have been received. Number, or null if `multiple` is false."
+ },
+ voted: %Schema{
+ type: :boolean,
+ nullable: true,
+ description:
+ "When called with a user token, has the authorized user voted? Boolean, or null if no current user."
+ },
+ emojis: %Schema{
+ type: :array,
+ items: Emoji,
+ description: "Custom emoji to be used for rendering poll options."
+ },
options: %Schema{
type: :array,
items: %Schema{
+ title: "PollOption",
type: :object,
properties: %{
title: %Schema{type: :string},
votes_count: %Schema{type: :integer}
}
- }
+ },
+ description: "Possible answers for the poll."
}
+ },
+ example: %{
+ id: "34830",
+ expires_at: "2019-12-05T04:05:08.302Z",
+ expired: true,
+ multiple: false,
+ votes_count: 10,
+ voters_count: nil,
+ voted: true,
+ own_votes: [
+ 1
+ ],
+ options: [
+ %{
+ title: "accept",
+ votes_count: 6
+ },
+ %{
+ title: "deny",
+ votes_count: 4
+ }
+ ],
+ emojis: []
}
})
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex b/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
index af9b66eff..db46ffcfc 100644
--- a/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
@@ -15,6 +15,8 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
plug(
OAuthScopesPlug,
%{scopes: ["read:statuses"], fallback: :proceed_unauthenticated} when action == :show
@@ -22,8 +24,10 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
plug(OAuthScopesPlug, %{scopes: ["write:statuses"]} when action == :vote)
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PollOperation
+
@doc "GET /api/v1/polls/:id"
- def show(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+ def show(%{assigns: %{user: user}} = conn, %{id: id}) do
with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
true <- Visibility.visible_for_user?(activity, user) do
@@ -35,7 +39,7 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
end
@doc "POST /api/v1/polls/:id/votes"
- def vote(%{assigns: %{user: user}} = conn, %{"id" => id, "choices" => choices}) do
+ def vote(%{assigns: %{user: user}, body_params: %{choices: choices}} = conn, %{id: id}) do
with %Object{data: %{"type" => "Question"}} = object <- Object.get_by_id(id),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
true <- Visibility.visible_for_user?(activity, user),