aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMaksim Pechnikov <parallel588@gmail.com>2020-05-06 05:55:39 +0300
committerMaksim Pechnikov <parallel588@gmail.com>2020-05-06 05:55:39 +0300
commitfb38b7339ccb6c3d7a3a07b74a6471a0f38622fe (patch)
treea6dc7761d53a37be6a1c46af1c3cbc8873ce50d8 /lib
parentfe7a0d660e357a03558be3a95ddbb8b409ef9a9e (diff)
parent7612d9403dbaa6741b28dcf427ecad8fd0f70c30 (diff)
downloadpleroma-fb38b7339ccb6c3d7a3a07b74a6471a0f38622fe.tar.gz
Merge branch 'develop' into issue/1276-2
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/user.ex2
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex27
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/like_validator.ex48
-rw-r--r--lib/pleroma/web/activity_pub/pipeline.ex23
-rw-r--r--lib/pleroma/web/activity_pub/side_effects.ex13
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex55
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex12
-rw-r--r--lib/pleroma/web/api_spec/cast_and_validate.ex139
-rw-r--r--lib/pleroma/web/api_spec/operations/scheduled_activity_operation.ex96
-rw-r--r--lib/pleroma/web/api_spec/render_error.ex3
-rw-r--r--lib/pleroma/web/api_spec/schemas/attachment.ex68
-rw-r--r--lib/pleroma/web/api_spec/schemas/scheduled_status.ex54
-rw-r--r--lib/pleroma/web/api_spec/schemas/status.ex18
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/app_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/notification_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/report_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex12
-rw-r--r--lib/pleroma/web/router.ex1
-rw-r--r--lib/pleroma/web/web_finger/web_finger.ex61
22 files changed, 493 insertions, 151 deletions
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 99358ddaf..2c343eb22 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -113,7 +113,6 @@ defmodule Pleroma.User do
field(:is_admin, :boolean, default: false)
field(:show_role, :boolean, default: true)
field(:settings, :map, default: nil)
- field(:magic_key, :string, default: nil)
field(:uri, Types.Uri, default: nil)
field(:hide_followers_count, :boolean, default: false)
field(:hide_follows_count, :boolean, default: false)
@@ -387,7 +386,6 @@ defmodule Pleroma.User do
:banner,
:locked,
:last_refreshed_at,
- :magic_key,
:uri,
:follower_address,
:following_address,
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 1f4a09370..1c21d78af 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -1530,21 +1530,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp normalize_counter(counter) when is_integer(counter), do: counter
defp normalize_counter(_), do: 0
- defp maybe_update_follow_information(data) do
+ def maybe_update_follow_information(user_data) do
with {:enabled, true} <- {:enabled, Config.get([:instance, :external_user_synchronization])},
- {:ok, info} <- fetch_follow_information_for_user(data) do
- info = Map.merge(data[:info] || %{}, info)
- Map.put(data, :info, info)
+ {_, true} <- {:user_type_check, user_data[:type] in ["Person", "Service"]},
+ {_, true} <-
+ {:collections_available,
+ !!(user_data[:following_address] && user_data[:follower_address])},
+ {:ok, info} <-
+ fetch_follow_information_for_user(user_data) do
+ info = Map.merge(user_data[:info] || %{}, info)
+
+ user_data
+ |> Map.put(:info, info)
else
+ {:user_type_check, false} ->
+ user_data
+
+ {:collections_available, false} ->
+ user_data
+
{:enabled, false} ->
- data
+ user_data
e ->
Logger.error(
- "Follower/Following counter update for #{data.ap_id} failed.\n" <> inspect(e)
+ "Follower/Following counter update for #{user_data.ap_id} failed.\n" <> inspect(e)
)
- data
+ user_data
end
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/like_validator.ex b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex
index 49546ceaa..1bce739bd 100644
--- a/lib/pleroma/web/activity_pub/object_validators/like_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
use Ecto.Schema
+ alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectValidators.Types
alias Pleroma.Web.ActivityPub.Utils
@@ -19,8 +20,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
field(:object, Types.ObjectID)
field(:actor, Types.ObjectID)
field(:context, :string)
- field(:to, {:array, :string})
- field(:cc, {:array, :string})
+ field(:to, {:array, :string}, default: [])
+ field(:cc, {:array, :string}, default: [])
end
def cast_and_validate(data) do
@@ -31,7 +32,48 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
def cast_data(data) do
%__MODULE__{}
- |> cast(data, [:id, :type, :object, :actor, :context, :to, :cc])
+ |> changeset(data)
+ end
+
+ def changeset(struct, data) do
+ struct
+ |> cast(data, __schema__(:fields))
+ |> fix_after_cast()
+ end
+
+ def fix_after_cast(cng) do
+ cng
+ |> fix_recipients()
+ |> fix_context()
+ end
+
+ def fix_context(cng) do
+ object = get_field(cng, :object)
+
+ with nil <- get_field(cng, :context),
+ %Object{data: %{"context" => context}} <- Object.get_cached_by_ap_id(object) do
+ cng
+ |> put_change(:context, context)
+ else
+ _ ->
+ cng
+ end
+ end
+
+ def fix_recipients(cng) do
+ to = get_field(cng, :to)
+ cc = get_field(cng, :cc)
+ object = get_field(cng, :object)
+
+ with {[], []} <- {to, cc},
+ %Object{data: %{"actor" => actor}} <- Object.get_cached_by_ap_id(object),
+ {:ok, actor} <- Types.ObjectID.cast(actor) do
+ cng
+ |> put_change(:to, [actor])
+ else
+ _ ->
+ cng
+ end
end
def validate_data(data_cng) do
diff --git a/lib/pleroma/web/activity_pub/pipeline.ex b/lib/pleroma/web/activity_pub/pipeline.ex
index 7ccee54c9..d5abb7567 100644
--- a/lib/pleroma/web/activity_pub/pipeline.ex
+++ b/lib/pleroma/web/activity_pub/pipeline.ex
@@ -4,20 +4,33 @@
defmodule Pleroma.Web.ActivityPub.Pipeline do
alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.Repo
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.ActivityPub.ObjectValidator
alias Pleroma.Web.ActivityPub.SideEffects
alias Pleroma.Web.Federator
- @spec common_pipeline(map(), keyword()) :: {:ok, Activity.t(), keyword()} | {:error, any()}
+ @spec common_pipeline(map(), keyword()) ::
+ {:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
def common_pipeline(object, meta) do
+ case Repo.transaction(fn -> do_common_pipeline(object, meta) end) do
+ {:ok, value} ->
+ value
+
+ {:error, e} ->
+ {:error, e}
+ end
+ end
+
+ def do_common_pipeline(object, meta) do
with {_, {:ok, validated_object, meta}} <-
{:validate_object, ObjectValidator.validate(object, meta)},
{_, {:ok, mrfd_object}} <- {:mrf_object, MRF.filter(validated_object)},
- {_, {:ok, %Activity{} = activity, meta}} <-
+ {_, {:ok, activity, meta}} <-
{:persist_object, ActivityPub.persist(mrfd_object, meta)},
- {_, {:ok, %Activity{} = activity, meta}} <-
+ {_, {:ok, activity, meta}} <-
{:execute_side_effects, SideEffects.handle(activity, meta)},
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
{:ok, activity, meta}
@@ -27,7 +40,9 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
end
end
- defp maybe_federate(activity, meta) do
+ defp maybe_federate(%Object{}, _), do: {:ok, :not_federated}
+
+ defp maybe_federate(%Activity{} = activity, meta) do
with {:ok, local} <- Keyword.fetch(meta, :local) do
if local do
Federator.publish(activity)
diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex
index 5981e7545..6a8f1af96 100644
--- a/lib/pleroma/web/activity_pub/side_effects.ex
+++ b/lib/pleroma/web/activity_pub/side_effects.ex
@@ -15,17 +15,12 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
# - Add like to object
# - Set up notification
def handle(%{data: %{"type" => "Like"}} = object, meta) do
- {:ok, result} =
- Pleroma.Repo.transaction(fn ->
- liked_object = Object.get_by_ap_id(object.data["object"])
- Utils.add_like_to_object(object, liked_object)
+ liked_object = Object.get_by_ap_id(object.data["object"])
+ Utils.add_like_to_object(object, liked_object)
- Notification.create_notifications(object)
+ Notification.create_notifications(object)
- {:ok, object, meta}
- end)
-
- result
+ {:ok, object, meta}
end
# Nothing to do
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index c966ec960..581e7040b 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -15,7 +15,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.ObjectValidator
- alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
alias Pleroma.Web.ActivityPub.Pipeline
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
@@ -658,16 +657,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def handle_incoming(%{"type" => "Like"} = data, _options) do
- with {_, {:ok, cast_data_sym}} <-
- {:casting_data,
- data |> LikeValidator.cast_data() |> Ecto.Changeset.apply_action(:insert)},
- cast_data = ObjectValidator.stringify_keys(Map.from_struct(cast_data_sym)),
- :ok <- ObjectValidator.fetch_actor_and_object(cast_data),
- {_, {:ok, cast_data}} <- {:ensure_context_presence, ensure_context_presence(cast_data)},
- {_, {:ok, cast_data}} <-
- {:ensure_recipients_presence, ensure_recipients_presence(cast_data)},
- {_, {:ok, activity, _meta}} <-
- {:common_pipeline, Pipeline.common_pipeline(cast_data, local: false)} do
+ with :ok <- ObjectValidator.fetch_actor_and_object(data),
+ {:ok, activity, _meta} <-
+ Pipeline.common_pipeline(data, local: false) do
{:ok, activity}
else
e -> {:error, e}
@@ -1296,45 +1288,4 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def maybe_fix_user_url(data), do: data
def maybe_fix_user_object(data), do: maybe_fix_user_url(data)
-
- defp ensure_context_presence(%{"context" => context} = data) when is_binary(context),
- do: {:ok, data}
-
- defp ensure_context_presence(%{"object" => object} = data) when is_binary(object) do
- with %{data: %{"context" => context}} when is_binary(context) <- Object.normalize(object) do
- {:ok, Map.put(data, "context", context)}
- else
- _ ->
- {:error, :no_context}
- end
- end
-
- defp ensure_context_presence(_) do
- {:error, :no_context}
- end
-
- defp ensure_recipients_presence(%{"to" => [_ | _], "cc" => [_ | _]} = data),
- do: {:ok, data}
-
- defp ensure_recipients_presence(%{"object" => object} = data) do
- case Object.normalize(object) do
- %{data: %{"actor" => actor}} ->
- data =
- data
- |> Map.put("to", [actor])
- |> Map.put("cc", data["cc"] || [])
-
- {:ok, data}
-
- nil ->
- {:error, :no_object}
-
- _ ->
- {:error, :no_actor}
- end
- end
-
- defp ensure_recipients_presence(_) do
- {:error, :no_object}
- end
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 816c11e01..ac661e515 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -93,7 +93,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]
+ when action in [:list_statuses, :list_user_statuses, :list_instance_statuses, :status_show]
)
plug(
@@ -837,6 +837,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
end
+ def status_show(conn, %{"id" => id}) do
+ with %Activity{} = activity <- Activity.get_by_id(id) do
+ conn
+ |> put_view(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
with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
{:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
diff --git a/lib/pleroma/web/api_spec/cast_and_validate.ex b/lib/pleroma/web/api_spec/cast_and_validate.ex
new file mode 100644
index 000000000..bd9026237
--- /dev/null
+++ b/lib/pleroma/web/api_spec/cast_and_validate.ex
@@ -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
diff --git a/lib/pleroma/web/api_spec/operations/scheduled_activity_operation.ex b/lib/pleroma/web/api_spec/operations/scheduled_activity_operation.ex
new file mode 100644
index 000000000..fe675a923
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/scheduled_activity_operation.ex
@@ -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
diff --git a/lib/pleroma/web/api_spec/render_error.ex b/lib/pleroma/web/api_spec/render_error.ex
index b5877ca9c..d476b8ef3 100644
--- a/lib/pleroma/web/api_spec/render_error.ex
+++ b/lib/pleroma/web/api_spec/render_error.ex
@@ -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)}
diff --git a/lib/pleroma/web/api_spec/schemas/attachment.ex b/lib/pleroma/web/api_spec/schemas/attachment.ex
new file mode 100644
index 000000000..c146c416e
--- /dev/null
+++ b/lib/pleroma/web/api_spec/schemas/attachment.ex
@@ -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
diff --git a/lib/pleroma/web/api_spec/schemas/scheduled_status.ex b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex
new file mode 100644
index 000000000..0520d0848
--- /dev/null
+++ b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex
@@ -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
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index aef0588d4..d44636a48 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -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,
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index 61b0e2f63..8458cbdd5 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.TwitterAPI.TwitterAPI
- plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :create)
diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
index 408e11474..a516b6c20 100644
--- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
- plug(OpenApiSpex.Plug.CastAndValidate)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
@local_mastodon_name "Mastodon-Local"
diff --git a/lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex b/lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex
index 000ad743f..c5f47c5df 100644
--- a/lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex
@@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.CustomEmojiController do
use Pleroma.Web, :controller
- plug(OpenApiSpex.Plug.CastAndValidate)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(
:skip_plug,
diff --git a/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex b/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex
index c4fa383f2..825b231ab 100644
--- a/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockController do
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
- plug(OpenApiSpex.Plug.CastAndValidate)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.DomainBlockOperation
plug(
diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
index a14c86893..596b85617 100644
--- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
@@ -13,7 +13,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
@oauth_read_actions [:show, :index]
- plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(
OAuthScopesPlug,
diff --git a/lib/pleroma/web/mastodon_api/controllers/report_controller.ex b/lib/pleroma/web/mastodon_api/controllers/report_controller.ex
index f65c5c62b..405167108 100644
--- a/lib/pleroma/web/mastodon_api/controllers/report_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/report_controller.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.ReportController do
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
- plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["write:reports"]} when action == :create)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ReportOperation
diff --git a/lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex b/lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex
index 899b78873..1719c67ea 100644
--- a/lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex
@@ -11,17 +11,21 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
alias Pleroma.ScheduledActivity
alias Pleroma.Web.MastodonAPI.MastodonAPI
- plug(:assign_scheduled_activity when action != :index)
-
@oauth_read_actions [:show, :index]
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in @oauth_read_actions)
plug(OAuthScopesPlug, %{scopes: ["write:statuses"]} when action not in @oauth_read_actions)
+ plug(:assign_scheduled_activity when action != :index)
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ScheduledActivityOperation
+
@doc "GET /api/v1/scheduled_statuses"
def index(%{assigns: %{user: user}} = conn, params) do
+ params = Map.new(params, fn {key, value} -> {to_string(key), value} end)
+
with scheduled_activities <- MastodonAPI.get_scheduled_activities(user, params) do
conn
|> add_link_headers(scheduled_activities)
@@ -35,7 +39,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
end
@doc "PUT /api/v1/scheduled_statuses/:id"
- def update(%{assigns: %{scheduled_activity: scheduled_activity}} = conn, params) do
+ def update(%{assigns: %{scheduled_activity: scheduled_activity}, body_params: params} = conn, _) do
with {:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
render(conn, "show.json", scheduled_activity: scheduled_activity)
end
@@ -48,7 +52,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
end
end
- defp assign_scheduled_activity(%{assigns: %{user: user}, params: %{"id" => id}} = conn, _) do
+ defp assign_scheduled_activity(%{assigns: %{user: user}, params: %{id: id}} = conn, _) do
case ScheduledActivity.get(user, id) do
%ScheduledActivity{} = activity -> assign(conn, :scheduled_activity, activity)
nil -> Pleroma.Web.MastodonAPI.FallbackController.call(conn, {:error, :not_found}) |> halt()
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 5b00243e9..ef2239d59 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -188,6 +188,7 @@ 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)
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 7ffd0e51b..84ece1be2 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -86,54 +86,24 @@ defmodule Pleroma.Web.WebFinger do
|> XmlBuilder.to_doc()
end
- defp get_magic_key("data:application/magic-public-key," <> magic_key) do
- {:ok, magic_key}
- end
-
- defp get_magic_key(nil) do
- Logger.debug("Undefined magic key.")
- {:ok, nil}
- end
+ defp webfinger_from_xml(doc) do
+ subject = XML.string_from_xpath("//Subject", doc)
- defp get_magic_key(_) do
- {:error, "Missing magic key data."}
- end
+ subscribe_address =
+ ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}
+ |> XML.string_from_xpath(doc)
- defp webfinger_from_xml(doc) do
- with magic_key <- XML.string_from_xpath(~s{//Link[@rel="magic-public-key"]/@href}, doc),
- {:ok, magic_key} <- get_magic_key(magic_key),
- topic <-
- XML.string_from_xpath(
- ~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href},
- doc
- ),
- subject <- XML.string_from_xpath("//Subject", doc),
- subscribe_address <-
- XML.string_from_xpath(
- ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template},
- doc
- ),
- ap_id <-
- XML.string_from_xpath(
- ~s{//Link[@rel="self" and @type="application/activity+json"]/@href},
- doc
- ) do
- data = %{
- "magic_key" => magic_key,
- "topic" => topic,
- "subject" => subject,
- "subscribe_address" => subscribe_address,
- "ap_id" => ap_id
- }
+ ap_id =
+ ~s{//Link[@rel="self" and @type="application/activity+json"]/@href}
+ |> XML.string_from_xpath(doc)
- {:ok, data}
- else
- {:error, e} ->
- {:error, e}
+ data = %{
+ "subject" => subject,
+ "subscribe_address" => subscribe_address,
+ "ap_id" => ap_id
+ }
- e ->
- {:error, e}
- end
+ {:ok, data}
end
defp webfinger_from_json(doc) do
@@ -146,9 +116,6 @@ defmodule Pleroma.Web.WebFinger do
{"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", "self"} ->
Map.put(data, "ap_id", link["href"])
- {_, "http://ostatus.org/schema/1.0/subscribe"} ->
- Map.put(data, "subscribe_address", link["template"])
-
_ ->
Logger.debug("Unhandled type: #{inspect(link["type"])}")
data