Merge pull request 'Remove unused AP C2S endpoints' (#749) from who-wants-to-yeet-c2s-i-want-to-yeet-c2s into develop
Reviewed-on: #749
This commit is contained in:
commit
1e48a37545
4 changed files with 8 additions and 462 deletions
|
@ -12,9 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||||
alias Pleroma.Web.ActivityPub.ObjectView
|
alias Pleroma.Web.ActivityPub.ObjectView
|
||||||
alias Pleroma.Web.ActivityPub.Pipeline
|
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
|
||||||
alias Pleroma.Web.ActivityPub.UserView
|
alias Pleroma.Web.ActivityPub.UserView
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
|
@ -40,11 +38,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
# Note: :following and :followers must be served even without authentication (as via :api)
|
# Note: :following and :followers must be served even without authentication (as via :api)
|
||||||
plug(
|
plug(
|
||||||
EnsureAuthenticatedPlug
|
EnsureAuthenticatedPlug
|
||||||
when action in [:read_inbox, :update_outbox, :whoami, :upload_media]
|
when action in [:read_inbox]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(Majic.Plug, [pool: Pleroma.MajicPool] when action in [:upload_media])
|
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Pleroma.Web.Plugs.Cache,
|
Pleroma.Web.Plugs.Cache,
|
||||||
[query_params: false, tracking_fun: &__MODULE__.track_object_fetch/2]
|
[query_params: false, tracking_fun: &__MODULE__.track_object_fetch/2]
|
||||||
|
@ -160,7 +156,9 @@ def maybe_skip_cache(conn, user) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /relay/following
|
@doc """
|
||||||
|
GET /relay/following
|
||||||
|
"""
|
||||||
def relay_following(conn, _params) do
|
def relay_following(conn, _params) do
|
||||||
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
||||||
conn
|
conn
|
||||||
|
@ -197,7 +195,9 @@ def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /relay/followers
|
@doc """
|
||||||
|
GET /relay/followers
|
||||||
|
"""
|
||||||
def relay_followers(conn, _params) do
|
def relay_followers(conn, _params) do
|
||||||
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
with %{halted: false} = conn <- FederatingPlug.call(conn, []) do
|
||||||
conn
|
conn
|
||||||
|
@ -317,14 +317,6 @@ def internal_fetch(conn, _params) do
|
||||||
|> represent_service_actor(conn)
|
|> represent_service_actor(conn)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Returns the authenticated user's ActivityPub User object or a 404 Not Found if non-authenticated"
|
|
||||||
def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do
|
|
||||||
conn
|
|
||||||
|> put_resp_content_type("application/activity+json")
|
|
||||||
|> put_view(UserView)
|
|
||||||
|> render("user.json", %{user: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def read_inbox(
|
def read_inbox(
|
||||||
%{assigns: %{user: %User{nickname: nickname} = user}} = conn,
|
%{assigns: %{user: %User{nickname: nickname} = user}} = conn,
|
||||||
%{"nickname" => nickname, "page" => page?} = params
|
%{"nickname" => nickname, "page" => page?} = params
|
||||||
|
@ -375,105 +367,6 @@ def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{
|
||||||
|> json(err)
|
|> json(err)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fix_user_message(%User{ap_id: actor}, %{"type" => "Create", "object" => object} = activity)
|
|
||||||
when is_map(object) do
|
|
||||||
length =
|
|
||||||
[object["content"], object["summary"], object["name"]]
|
|
||||||
|> Enum.filter(&is_binary(&1))
|
|
||||||
|> Enum.join("")
|
|
||||||
|> String.length()
|
|
||||||
|
|
||||||
limit = Pleroma.Config.get([:instance, :limit])
|
|
||||||
|
|
||||||
if length < limit do
|
|
||||||
object =
|
|
||||||
object
|
|
||||||
|> Transmogrifier.strip_internal_fields()
|
|
||||||
|> Map.put("attributedTo", actor)
|
|
||||||
|> Map.put("actor", actor)
|
|
||||||
|> Map.put("id", Utils.generate_object_id())
|
|
||||||
|
|
||||||
{:ok, Map.put(activity, "object", object)}
|
|
||||||
else
|
|
||||||
{:error,
|
|
||||||
dgettext(
|
|
||||||
"errors",
|
|
||||||
"Character limit (%{limit} characters) exceeded, contains %{length} characters",
|
|
||||||
limit: limit,
|
|
||||||
length: length
|
|
||||||
)}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp fix_user_message(
|
|
||||||
%User{ap_id: actor} = user,
|
|
||||||
%{"type" => "Delete", "object" => object} = activity
|
|
||||||
) do
|
|
||||||
with {_, %Object{data: object_data}} <- {:normalize, Object.normalize(object, fetch: false)},
|
|
||||||
{_, true} <- {:permission, user.is_moderator || actor == object_data["actor"]} do
|
|
||||||
{:ok, activity}
|
|
||||||
else
|
|
||||||
{:normalize, _} ->
|
|
||||||
{:error, "No such object found"}
|
|
||||||
|
|
||||||
{:permission, _} ->
|
|
||||||
{:forbidden, "You can't delete this object"}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp fix_user_message(%User{}, activity) do
|
|
||||||
{:ok, activity}
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_outbox(
|
|
||||||
%{assigns: %{user: %User{nickname: nickname, ap_id: actor} = user}} = conn,
|
|
||||||
%{"nickname" => nickname} = params
|
|
||||||
) do
|
|
||||||
params =
|
|
||||||
params
|
|
||||||
|> Map.drop(["nickname"])
|
|
||||||
|> Map.put("id", Utils.generate_activity_id())
|
|
||||||
|> Map.put("actor", actor)
|
|
||||||
|
|
||||||
with {:ok, params} <- fix_user_message(user, params),
|
|
||||||
{:ok, activity, _} <- Pipeline.common_pipeline(params, local: true),
|
|
||||||
%Activity{data: activity_data} <- Activity.normalize(activity) do
|
|
||||||
conn
|
|
||||||
|> put_status(:created)
|
|
||||||
|> put_resp_header("location", activity_data["id"])
|
|
||||||
|> json(activity_data)
|
|
||||||
else
|
|
||||||
{:forbidden, message} ->
|
|
||||||
conn
|
|
||||||
|> put_status(:forbidden)
|
|
||||||
|> json(message)
|
|
||||||
|
|
||||||
{:error, message} ->
|
|
||||||
conn
|
|
||||||
|> put_status(:bad_request)
|
|
||||||
|> json(message)
|
|
||||||
|
|
||||||
e ->
|
|
||||||
Logger.warning(fn -> "AP C2S: #{inspect(e)}" end)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> put_status(:bad_request)
|
|
||||||
|> json("Bad Request")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_outbox(%{assigns: %{user: %User{} = user}} = conn, %{"nickname" => nickname}) do
|
|
||||||
err =
|
|
||||||
dgettext("errors", "can't update outbox of %{nickname} as %{as_nickname}",
|
|
||||||
nickname: nickname,
|
|
||||||
as_nickname: user.nickname
|
|
||||||
)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> put_status(:forbidden)
|
|
||||||
|> json(err)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp errors(conn, {:error, :not_found}) do
|
defp errors(conn, {:error, :not_found}) do
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|
@ -495,21 +388,6 @@ defp set_requester_reachable(%Plug.Conn{} = conn, _) do
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do
|
|
||||||
with {:ok, object} <-
|
|
||||||
ActivityPub.upload(
|
|
||||||
file,
|
|
||||||
actor: User.ap_id(user),
|
|
||||||
description: Map.get(data, "description")
|
|
||||||
) do
|
|
||||||
Logger.debug(inspect(object))
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> put_status(:created)
|
|
||||||
|> json(object.data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pinned(conn, %{"nickname" => nickname}) do
|
def pinned(conn, %{"nickname" => nickname}) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -26,8 +26,7 @@ def render("endpoints.json", %{user: %User{local: true} = _user}) do
|
||||||
"oauthAuthorizationEndpoint" => url(~p"/oauth/authorize"),
|
"oauthAuthorizationEndpoint" => url(~p"/oauth/authorize"),
|
||||||
"oauthRegistrationEndpoint" => url(~p"/api/v1/apps"),
|
"oauthRegistrationEndpoint" => url(~p"/api/v1/apps"),
|
||||||
"oauthTokenEndpoint" => url(~p"/oauth/token"),
|
"oauthTokenEndpoint" => url(~p"/oauth/token"),
|
||||||
"sharedInbox" => url(~p"/inbox"),
|
"sharedInbox" => url(~p"/inbox")
|
||||||
"uploadMedia" => url(~p"/api/ap/upload_media")
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -800,13 +800,9 @@ defmodule Pleroma.Web.Router do
|
||||||
scope "/", Pleroma.Web.ActivityPub do
|
scope "/", Pleroma.Web.ActivityPub do
|
||||||
pipe_through([:activitypub_client])
|
pipe_through([:activitypub_client])
|
||||||
|
|
||||||
get("/api/ap/whoami", ActivityPubController, :whoami)
|
|
||||||
get("/users/:nickname/inbox", ActivityPubController, :read_inbox)
|
get("/users/:nickname/inbox", ActivityPubController, :read_inbox)
|
||||||
|
|
||||||
get("/users/:nickname/outbox", ActivityPubController, :outbox)
|
get("/users/:nickname/outbox", ActivityPubController, :outbox)
|
||||||
post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
|
|
||||||
post("/api/ap/upload_media", ActivityPubController, :upload_media)
|
|
||||||
|
|
||||||
get("/users/:nickname/collections/featured", ActivityPubController, :pinned)
|
get("/users/:nickname/collections/featured", ActivityPubController, :pinned)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1418,244 +1418,6 @@ test "It returns poll Answers when authenticated", %{conn: conn} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /users/:nickname/outbox (C2S)" do
|
|
||||||
setup do: clear_config([:instance, :limit])
|
|
||||||
|
|
||||||
setup do
|
|
||||||
[
|
|
||||||
activity: %{
|
|
||||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
||||||
"type" => "Create",
|
|
||||||
"object" => %{
|
|
||||||
"type" => "Note",
|
|
||||||
"content" => "AP C2S test",
|
|
||||||
"to" => "https://www.w3.org/ns/activitystreams#Public",
|
|
||||||
"cc" => []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it rejects posts from other users / unauthenticated users", %{
|
|
||||||
conn: conn,
|
|
||||||
activity: activity
|
|
||||||
} do
|
|
||||||
user = insert(:user)
|
|
||||||
other_user = insert(:user)
|
|
||||||
conn = put_req_header(conn, "content-type", "application/activity+json")
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(403)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> assign(:user, other_user)
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(403)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it inserts an incoming create activity into the database", %{
|
|
||||||
conn: conn,
|
|
||||||
activity: activity
|
|
||||||
} do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(201)
|
|
||||||
|
|
||||||
assert Activity.get_by_ap_id(result["id"])
|
|
||||||
assert result["object"]
|
|
||||||
assert %Object{data: object} = Object.normalize(result["object"], fetch: false)
|
|
||||||
assert object["content"] == activity["object"]["content"]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it rejects anything beyond 'Note' creations", %{conn: conn, activity: activity} do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
activity =
|
|
||||||
activity
|
|
||||||
|> put_in(["object", "type"], "Benis")
|
|
||||||
|
|
||||||
_result =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(400)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it inserts an incoming sensitive activity into the database", %{
|
|
||||||
conn: conn,
|
|
||||||
activity: activity
|
|
||||||
} do
|
|
||||||
user = insert(:user)
|
|
||||||
conn = assign(conn, :user, user)
|
|
||||||
object = Map.put(activity["object"], "sensitive", true)
|
|
||||||
activity = Map.put(activity, "object", object)
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(201)
|
|
||||||
|
|
||||||
assert Activity.get_by_ap_id(response["id"])
|
|
||||||
assert response["object"]
|
|
||||||
assert %Object{data: response_object} = Object.normalize(response["object"], fetch: false)
|
|
||||||
assert response_object["sensitive"] == true
|
|
||||||
assert response_object["content"] == activity["object"]["content"]
|
|
||||||
|
|
||||||
representation =
|
|
||||||
conn
|
|
||||||
|> put_req_header("accept", "application/activity+json")
|
|
||||||
|> get(response["id"])
|
|
||||||
|> json_response(200)
|
|
||||||
|
|
||||||
assert representation["object"]["sensitive"] == true
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it rejects an incoming activity with bogus type", %{conn: conn, activity: activity} do
|
|
||||||
user = insert(:user)
|
|
||||||
activity = Map.put(activity, "type", "BadType")
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|
|
||||||
assert json_response(conn, 400)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
note_object = Object.normalize(note_activity, fetch: false)
|
|
||||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
|
||||||
|
|
||||||
data = %{
|
|
||||||
"type" => "Delete",
|
|
||||||
"object" => %{
|
|
||||||
"id" => note_object.data["id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", data)
|
|
||||||
|> json_response(201)
|
|
||||||
|
|
||||||
assert Activity.get_by_ap_id(result["id"])
|
|
||||||
|
|
||||||
assert object = Object.get_by_ap_id(note_object.data["id"])
|
|
||||||
assert object.data["type"] == "Tombstone"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it rejects delete activity of object from other actor", %{conn: conn} do
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
note_object = Object.normalize(note_activity, fetch: false)
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
data = %{
|
|
||||||
type: "Delete",
|
|
||||||
object: %{
|
|
||||||
id: note_object.data["id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", data)
|
|
||||||
|
|
||||||
assert json_response(conn, 403)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it increases like count when receiving a like action", %{conn: conn} do
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
note_object = Object.normalize(note_activity, fetch: false)
|
|
||||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
|
||||||
|
|
||||||
data = %{
|
|
||||||
type: "Like",
|
|
||||||
object: %{
|
|
||||||
id: note_object.data["id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", data)
|
|
||||||
|
|
||||||
result = json_response(conn, 201)
|
|
||||||
assert Activity.get_by_ap_id(result["id"])
|
|
||||||
|
|
||||||
assert object = Object.get_by_ap_id(note_object.data["id"])
|
|
||||||
assert object.data["like_count"] == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it doesn't spreads faulty attributedTo or actor fields", %{
|
|
||||||
conn: conn,
|
|
||||||
activity: activity
|
|
||||||
} do
|
|
||||||
reimu = insert(:user, nickname: "reimu")
|
|
||||||
cirno = insert(:user, nickname: "cirno")
|
|
||||||
|
|
||||||
assert reimu.ap_id
|
|
||||||
assert cirno.ap_id
|
|
||||||
|
|
||||||
activity =
|
|
||||||
activity
|
|
||||||
|> put_in(["object", "actor"], reimu.ap_id)
|
|
||||||
|> put_in(["object", "attributedTo"], reimu.ap_id)
|
|
||||||
|> put_in(["actor"], reimu.ap_id)
|
|
||||||
|> put_in(["attributedTo"], reimu.ap_id)
|
|
||||||
|
|
||||||
_reimu_outbox =
|
|
||||||
conn
|
|
||||||
|> assign(:user, cirno)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{reimu.nickname}/outbox", activity)
|
|
||||||
|> json_response(403)
|
|
||||||
|
|
||||||
cirno_outbox =
|
|
||||||
conn
|
|
||||||
|> assign(:user, cirno)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{cirno.nickname}/outbox", activity)
|
|
||||||
|> json_response(201)
|
|
||||||
|
|
||||||
assert cirno_outbox["attributedTo"] == nil
|
|
||||||
assert cirno_outbox["actor"] == cirno.ap_id
|
|
||||||
|
|
||||||
assert cirno_object = Object.normalize(cirno_outbox["object"], fetch: false)
|
|
||||||
assert cirno_object.data["actor"] == cirno.ap_id
|
|
||||||
assert cirno_object.data["attributedTo"] == cirno.ap_id
|
|
||||||
end
|
|
||||||
|
|
||||||
test "Character limitation", %{conn: conn, activity: activity} do
|
|
||||||
clear_config([:instance, :limit], 5)
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
result =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> put_req_header("content-type", "application/activity+json")
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity)
|
|
||||||
|> json_response(400)
|
|
||||||
|
|
||||||
assert result == "Character limit (5 characters) exceeded, contains 11 characters"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "/relay/followers" do
|
describe "/relay/followers" do
|
||||||
test "it returns relay followers", %{conn: conn} do
|
test "it returns relay followers", %{conn: conn} do
|
||||||
relay_actor = Relay.get_actor()
|
relay_actor = Relay.get_actor()
|
||||||
|
@ -1977,95 +1739,6 @@ test "it tracks a signed activity fetch when the json is cached", %{conn: conn}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Additional ActivityPub C2S endpoints" do
|
|
||||||
test "GET /api/ap/whoami", %{conn: conn} do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> get("/api/ap/whoami")
|
|
||||||
|
|
||||||
user = User.get_cached_by_id(user.id)
|
|
||||||
|
|
||||||
assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> get("/api/ap/whoami")
|
|
||||||
|> json_response(403)
|
|
||||||
end
|
|
||||||
|
|
||||||
setup do: clear_config([:media_proxy])
|
|
||||||
setup do: clear_config([Pleroma.Upload])
|
|
||||||
|
|
||||||
test "POST /api/ap/upload_media", %{conn: conn} do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
desc = "Description of the image"
|
|
||||||
|
|
||||||
image = %Plug.Upload{
|
|
||||||
content_type: "image/jpeg",
|
|
||||||
path: Path.absname("test/fixtures/image.jpg"),
|
|
||||||
filename: "an_image.jpg"
|
|
||||||
}
|
|
||||||
|
|
||||||
object =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
|
|
||||||
|> json_response(:created)
|
|
||||||
|
|
||||||
assert object["name"] == desc
|
|
||||||
assert object["type"] == "Document"
|
|
||||||
assert object["actor"] == user.ap_id
|
|
||||||
assert [%{"href" => object_href, "mediaType" => object_mediatype}] = object["url"]
|
|
||||||
assert is_binary(object_href)
|
|
||||||
assert object_mediatype == "image/jpeg"
|
|
||||||
assert String.ends_with?(object_href, ".jpg")
|
|
||||||
|
|
||||||
activity_request = %{
|
|
||||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
||||||
"type" => "Create",
|
|
||||||
"object" => %{
|
|
||||||
"type" => "Note",
|
|
||||||
"content" => "AP C2S test, attachment",
|
|
||||||
"attachment" => [object],
|
|
||||||
"to" => "https://www.w3.org/ns/activitystreams#Public",
|
|
||||||
"cc" => []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
activity_response =
|
|
||||||
conn
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> post("/users/#{user.nickname}/outbox", activity_request)
|
|
||||||
|> json_response(:created)
|
|
||||||
|
|
||||||
assert activity_response["id"]
|
|
||||||
assert activity_response["object"]
|
|
||||||
assert activity_response["actor"] == user.ap_id
|
|
||||||
|
|
||||||
assert %Object{data: %{"attachment" => [attachment]}} =
|
|
||||||
Object.normalize(activity_response["object"], fetch: false)
|
|
||||||
|
|
||||||
assert attachment["type"] == "Document"
|
|
||||||
assert attachment["name"] == desc
|
|
||||||
|
|
||||||
assert [
|
|
||||||
%{
|
|
||||||
"href" => ^object_href,
|
|
||||||
"type" => "Link",
|
|
||||||
"mediaType" => ^object_mediatype
|
|
||||||
}
|
|
||||||
] = attachment["url"]
|
|
||||||
|
|
||||||
# Fails if unauthenticated
|
|
||||||
conn
|
|
||||||
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
|
|
||||||
|> json_response(403)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "pinned collection", %{conn: conn} do
|
test "pinned collection", %{conn: conn} do
|
||||||
clear_config([:instance, :max_pinned_statuses], 2)
|
clear_config([:instance, :max_pinned_statuses], 2)
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
Loading…
Reference in a new issue