MastoAPI: Unify pin/bookmark/mute/fav not visible responses to 404

Also adds more tests for these interactions.
This commit is contained in:
Phantasm 2025-12-11 22:37:51 +01:00
commit fe7108cbc2
No known key found for this signature in database
GPG key ID: 2669E588BCC634C8
5 changed files with 88 additions and 14 deletions

View file

@ -8,6 +8,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
alias Pleroma.Web.ApiSpec.AccountOperation
alias Pleroma.Web.ApiSpec.Schemas.Account
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.ApiNotFoundError
alias Pleroma.Web.ApiSpec.Schemas.Attachment
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.Emoji
@ -289,7 +290,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
}
}),
responses: %{
200 => status_response()
200 => status_response(),
404 => Operation.response("Not found", "application/json", ApiNotFoundError)
}
}
end
@ -303,7 +305,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
operationId: "StatusController.unbookmark",
parameters: [id_param()],
responses: %{
200 => status_response()
200 => status_response(),
404 => Operation.response("Not found", "application/json", ApiNotFoundError)
}
}
end
@ -339,16 +342,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
responses: %{
200 => status_response(),
400 => Operation.response("Error", "application/json", ApiError),
404 =>
Operation.response(
"Not Found",
"application/json",
%Schema{
allOf: [ApiError],
title: "Error",
example: %{"error" => "Record not found"}
}
)
404 => Operation.response("Not found", "application/json", ApiError)
}
}
end

View file

@ -300,6 +300,7 @@ defmodule Pleroma.Web.CommonAPI do
with {_, %Activity{data: %{"type" => "Create"}} = activity} <-
{:find_activity, Activity.get_by_id(id)},
%Object{} = note <- Object.normalize(activity, fetch: false),
{_, true} <- {:visibility, activity_visible_to_actor(note, user)},
%Activity{} = like <- Utils.get_existing_like(user.ap_id, note),
{_, {:ok, _}} <- {:cancel_jobs, maybe_cancel_jobs(like)},
{:ok, undo, _} <- Builder.undo(user, like),
@ -307,6 +308,7 @@ defmodule Pleroma.Web.CommonAPI do
{:ok, activity}
else
{:find_activity, _} -> {:error, :not_found}
{:visibility, _} -> {:error, :not_found}
_ -> {:error, dgettext("errors", "Could not unfavorite")}
end
end
@ -514,6 +516,7 @@ defmodule Pleroma.Web.CommonAPI do
@spec pin(String.t(), User.t()) :: {:ok, Activity.t()} | Pipeline.errors()
def pin(id, %User{} = user) do
with %Activity{} = activity <- create_activity_by_id(id),
true <- activity_visible_to_actor(activity, user),
true <- activity_belongs_to_actor(activity, user.ap_id),
true <- object_type_is_allowed_for_pin(activity.object),
true <- activity_is_public(activity),
@ -555,7 +558,7 @@ defmodule Pleroma.Web.CommonAPI do
defp activity_is_public(activity) do
with false <- Visibility.public?(activity) do
{:error, :visibility_error}
{:error, :non_public_error}
end
end

View file

@ -393,6 +393,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
with {:ok, activity} <- CommonAPI.pin(ap_id_or_id, user) do
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
else
# Order matters, if status is not owned by user and is not visible to user
# return 404 just like other endpoints
{:error, :pinned_statuses_limit_reached} ->
{:error, "You have already pinned the maximum number of statuses"}
@ -400,6 +402,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
{:error, :unprocessable_entity, "Someone else's status cannot be pinned"}
{:error, :visibility_error} ->
{:error, :not_found, "Record not found"}
{:error, :non_public_error} ->
{:error, :unprocessable_entity, "Non-public status cannot be pinned"}
error ->
@ -449,6 +454,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
),
{:ok, _bookmark} <- Bookmark.create(user.id, activity.id, folder_id) do
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
else
false ->
{:error, :not_found, "Record not found"}
error ->
error
end
end
@ -462,6 +473,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
true <- Visibility.visible_for_user?(activity, user),
{:ok, _bookmark} <- Bookmark.destroy(user.id, activity.id) do
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
else
false ->
{:error, :not_found, "Record not found"}
error ->
error
end
end