Add an API endpoint for listing remote packs

This commit is contained in:
Ekaterina Vaartis 2019-09-24 19:18:07 +03:00
parent a6e85215e1
commit ba9d35a904
3 changed files with 61 additions and 14 deletions

View File

@ -10,6 +10,27 @@ def emoji_dir_path do
) )
end end
@doc """
Lists packs from the remote instance.
Since JS cannot ask remote instances for their packs due to CPS, it has to
be done by the server
"""
def list_from(conn, %{"instance_address" => address}) do
address = String.trim(address)
if shareable_packs_available(address) do
list_resp =
"#{address}/api/pleroma/emoji/packs" |> Tesla.get!() |> Map.get(:body) |> Jason.decode!()
json(conn, list_resp)
else
conn
|> put_status(:internal_server_error)
|> json(%{error: "The requested instance does not support sharing emoji packs"})
end
end
@doc """ @doc """
Lists the packs available on the instance as JSON. Lists the packs available on the instance as JSON.
@ -156,6 +177,21 @@ def download_shared(conn, %{"name" => name}) do
end end
end end
defp shareable_packs_available(address) do
"#{address}/.well-known/nodeinfo"
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> List.last()
|> Map.get("href")
# Get the actual nodeinfo address and fetch it
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> get_in(["metadata", "features"])
|> Enum.member?("shareable_emoji_packs")
end
@doc """ @doc """
An admin endpoint to request downloading a pack named `pack_name` from the instance An admin endpoint to request downloading a pack named `pack_name` from the instance
`instance_address`. `instance_address`.
@ -164,21 +200,9 @@ def download_shared(conn, %{"name" => name}) do
from that instance, otherwise it will be downloaded from the fallback source, if there is one. from that instance, otherwise it will be downloaded from the fallback source, if there is one.
""" """
def download_from(conn, %{"instance_address" => address, "pack_name" => name} = data) do def download_from(conn, %{"instance_address" => address, "pack_name" => name} = data) do
shareable_packs_available = address = String.trim(address)
"#{address}/.well-known/nodeinfo"
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> List.last()
|> Map.get("href")
# Get the actual nodeinfo address and fetch it
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> get_in(["metadata", "features"])
|> Enum.member?("shareable_emoji_packs")
if shareable_packs_available do if shareable_packs_available(address) do
full_pack = full_pack =
"#{address}/api/pleroma/emoji/packs/list" "#{address}/api/pleroma/emoji/packs/list"
|> Tesla.get!() |> Tesla.get!()

View File

@ -222,6 +222,7 @@ defmodule Pleroma.Web.Router do
put("/:name", EmojiAPIController, :create) put("/:name", EmojiAPIController, :create)
delete("/:name", EmojiAPIController, :delete) delete("/:name", EmojiAPIController, :delete)
post("/download_from", EmojiAPIController, :download_from) post("/download_from", EmojiAPIController, :download_from)
post("/list_from", EmojiAPIController, :list_from)
end end
scope "/packs" do scope "/packs" do

View File

@ -33,6 +33,28 @@ test "shared & non-shared pack information in list_packs is ok" do
refute pack["pack"]["can-download"] refute pack["pack"]["can-download"]
end end
test "listing remote packs" do
admin = insert(:user, info: %{is_admin: true})
conn = build_conn() |> assign(:user, admin)
resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
mock(fn
%{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
json([%{href: "https://example.com/nodeinfo/2.1.json"}])
%{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
json(%{metadata: %{features: ["shareable_emoji_packs"]}})
%{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} ->
json(resp)
end)
assert conn
|> post(emoji_api_path(conn, :list_from), %{instance_address: "https://example.com"})
|> json_response(200) == resp
end
test "downloading a shared pack from download_shared" do test "downloading a shared pack from download_shared" do
conn = build_conn() conn = build_conn()