defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
use Pleroma.Web, :controller
+ alias Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug
+ alias Pleroma.Plugs.OAuthScopesPlug
+
require Logger
- def emoji_dir_path do
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["write"], admin: true}
+ when action in [
+ :create,
+ :delete,
+ :save_from,
+ :import_from_fs,
+ :update_file,
+ :update_metadata
+ ]
+ )
+
+ plug(
+ :skip_plug,
+ [OAuthScopesPlug, ExpectPublicOrAuthenticatedCheckPlug]
+ when action in [:download_shared, :list_packs, :list_from]
+ )
+
+ defp emoji_dir_path do
Path.join(
Pleroma.Config.get!([:instance, :static_dir]),
"emoji"
@doc """
Lists the packs available on the instance as JSON.
- The information is public and does not require authentification. The format is
+ The information is public and does not require authentication. The format is
a map of "pack directory name" to pack.json contents.
"""
def list_packs(conn, _params) do
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
+ |> Map.get("links")
|> List.last()
|> Map.get("href")
# Get the actual nodeinfo address and fetch it
end
@doc """
- An admin endpoint to request downloading a pack named `pack_name` from the instance
+ An admin endpoint to request downloading and storing a pack named `pack_name` from the instance
`instance_address`.
If the requested instance's admin chose to share the pack, it will be downloaded
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 save_from(conn, %{"instance_address" => address, "pack_name" => name} = data) do
address = String.trim(address)
if shareable_packs_available(address) do
{:ok, _} ->
conn |> json("ok")
- {:error, _} ->
+ {:error, _, _} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "Couldn't delete the pack #{name}"})
assumed to be emojis and stored in the new `pack.json` file.
"""
def import_from_fs(conn, _params) do
- with {:ok, results} <- File.ls(emoji_dir_path()) do
+ emoji_path = emoji_dir_path()
+
+ with {:ok, %{access: :read_write}} <- File.stat(emoji_path),
+ {:ok, results} <- File.ls(emoji_path) do
imported_pack_names =
results
|> Enum.filter(fn file ->
- dir_path = Path.join(emoji_dir_path(), file)
+ dir_path = Path.join(emoji_path, file)
# Find the directories that do NOT have pack.json
File.dir?(dir_path) and not File.exists?(Path.join(dir_path, "pack.json"))
end)
json(conn, imported_pack_names)
else
+ {:ok, %{access: _}} ->
+ conn
+ |> put_status(:internal_server_error)
+ |> json(%{error: "Error: emoji pack directory must be writable"})
+
{:error, _} ->
conn
|> put_status(:internal_server_error)