support for special chars in pack name

This commit is contained in:
Alexander Strizhakov 2020-06-27 13:43:25 +03:00
parent e02101e15c
commit 9b6d89ff8c
No known key found for this signature in database
GPG key ID: 022896A53AEF1381
7 changed files with 128 additions and 59 deletions

View file

@ -379,14 +379,18 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON, returns a list of Mastodon Conversation entities that were marked as read (200 - healthy, 503 unhealthy).
## `GET /api/pleroma/emoji/packs/import`
### Imports packs from filesystem
* Method `GET`
* Authentication: required
* Params: None
* Response: JSON, returns a list of imported packs.
## `GET /api/pleroma/emoji/packs/remote`
### Make request to another instance for packs list
* Method `GET`
* Authentication: required
* Params:
@ -394,7 +398,9 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON with the pack list, hashmap with pack name and pack contents
## `POST /api/pleroma/emoji/packs/download`
### Download pack from another instance
* Method `POST`
* Authentication: required
* Params:
@ -404,18 +410,24 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON, "ok" with 200 status if the pack was downloaded, or 500 if there were
errors downloading the pack
## `POST /api/pleroma/emoji/packs/:name`
## `POST /api/pleroma/emoji/packs/create?name=:name`
### Creates an empty pack
* Method `POST`
* Authentication: required
* Params: None
* Params:
* `name`: pack name
* Response: JSON, "ok" and 200 status or 409 if the pack with that name already exists
## `PATCH /api/pleroma/emoji/packs/:name`
## `PATCH /api/pleroma/emoji/packs/update?name=:name`
### Updates (replaces) pack metadata
* Method `PATCH`
* Authentication: required
* Params:
* `name`: pack name
* `metadata`: metadata to replace the old one
* `license`: Pack license
* `homepage`: Pack home page url
@ -426,39 +438,51 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Response: JSON, updated "metadata" section of the pack and 200 status or 400 if there was a
problem with the new metadata (the error is specified in the "error" part of the response JSON)
## `DELETE /api/pleroma/emoji/packs/:name`
## `DELETE /api/pleroma/emoji/packs/delete?name=:name`
### Delete a custom emoji pack
* Method `DELETE`
* Authentication: required
* Params: None
* Params:
* `name`: pack name
* Response: JSON, "ok" and 200 status or 500 if there was an error deleting the pack
## `POST /api/pleroma/emoji/packs/:name/files`
## `POST /api/pleroma/emoji/packs/files?name=:name`
### Add new file to the pack
* Method `POST`
* Authentication: required
* Params:
* `name`: pack name
* `file`: file needs to be uploaded with the multipart request or link to remote file.
* `shortcode`: (*optional*) shortcode for new emoji, must be unique for all emoji. If not sended, shortcode will be taken from original filename.
* `filename`: (*optional*) new emoji file name. If not specified will be taken from original filename.
* Response: JSON, list of files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
## `PATCH /api/pleroma/emoji/packs/:name/files`
## `PATCH /api/pleroma/emoji/packs/files?name=:name`
### Update emoji file from pack
* Method `PATCH`
* Authentication: required
* Params:
* `name`: pack name
* `shortcode`: emoji file shortcode
* `new_shortcode`: new emoji file shortcode
* `new_filename`: new filename for emoji file
* `force`: (*optional*) with true value to overwrite existing emoji with new shortcode
* Response: JSON, list with updated files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
## `DELETE /api/pleroma/emoji/packs/:name/files`
## `DELETE /api/pleroma/emoji/packs/files?name=:name`
### Delete emoji file from pack
* Method `DELETE`
* Authentication: required
* Params:
* `name`: pack name
* `shortcode`: emoji file shortcode
* Response: JSON, list with updated files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.
@ -483,7 +507,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
}
```
## `GET /api/pleroma/emoji/packs/:name`
## `GET /api/pleroma/emoji/packs/show?name=:name`
### Get pack.json for the pack
@ -502,11 +526,14 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
}
```
## `GET /api/pleroma/emoji/packs/:name/archive`
## `GET /api/pleroma/emoji/packs/archive?name=:name`
### Requests a local pack archive from the instance
* Method `GET`
* Authentication: not required
* Params: None
* Params:
* `name`: pack name
* Response: the archive of the pack with a 200 status code, 403 if the pack is not set as shared,
404 if the pack does not exist

View file

@ -244,7 +244,8 @@ def download(name, url, as) do
uri = url |> String.trim() |> URI.parse()
with :ok <- validate_shareable_packs_available(uri),
{:ok, remote_pack} <- uri |> URI.merge("/api/pleroma/emoji/packs/#{name}") |> http_get(),
{:ok, remote_pack} <-
uri |> URI.merge("/api/pleroma/emoji/packs/show?name=#{name}") |> http_get(),
{:ok, %{sha: sha, url: url} = pack_info} <- fetch_pack_info(remote_pack, uri, name),
{:ok, archive} <- download_archive(url, sha),
pack <- copy_as(remote_pack, as || name),
@ -572,7 +573,7 @@ defp fetch_pack_info(remote_pack, uri, name) do
{:ok,
%{
sha: sha,
url: URI.merge(uri, "/api/pleroma/emoji/packs/#{name}/archive") |> to_string()
url: URI.merge(uri, "/api/pleroma/emoji/packs/archive?name=#{name}") |> to_string()
}}
%{"fallback-src" => src, "fallback-src-sha256" => sha} when is_binary(src) ->

View file

@ -192,7 +192,7 @@ def import_from_filesystem_operation do
end
defp name_param do
Operation.parameter(:name, :path, :string, "Pack Name", example: "cofe", required: true)
Operation.parameter(:name, :query, :string, "Pack Name", example: "cofe", required: true)
end
defp url_param do

View file

@ -234,21 +234,21 @@ defmodule Pleroma.Web.Router do
get("/remote", EmojiPackController, :remote)
post("/download", EmojiPackController, :download)
post("/:name", EmojiPackController, :create)
patch("/:name", EmojiPackController, :update)
delete("/:name", EmojiPackController, :delete)
post("/create", EmojiPackController, :create)
patch("/update", EmojiPackController, :update)
delete("/delete", EmojiPackController, :delete)
post("/:name/files", EmojiFileController, :create)
patch("/:name/files", EmojiFileController, :update)
delete("/:name/files", EmojiFileController, :delete)
post("/files", EmojiFileController, :add_file)
patch("/files", EmojiFileController, :update_file)
delete("/files", EmojiFileController, :delete_file)
end
# Pack info / downloading
scope "/packs" do
pipe_through(:api)
get("/", EmojiPackController, :index)
get("/:name", EmojiPackController, :show)
get("/:name/archive", EmojiPackController, :archive)
get("/show", EmojiPackController, :show)
get("/archive", EmojiPackController, :archive)
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

View file

@ -0,0 +1,11 @@
{
"files": {
"blank": "blank.png"
},
"pack": {
"description": "Test description",
"homepage": "https://pleroma.social",
"license": "Test license",
"share-files": true
}
}

View file

@ -37,11 +37,11 @@ test "GET /api/pleroma/emoji/packs when :public: false", %{conn: conn} do
test "GET /api/pleroma/emoji/packs", %{conn: conn} do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
assert resp["count"] == 3
assert resp["count"] == 4
assert resp["packs"]
|> Map.keys()
|> length() == 3
|> length() == 4
shared = resp["packs"]["test_pack"]
assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}
@ -58,7 +58,7 @@ test "GET /api/pleroma/emoji/packs", %{conn: conn} do
|> get("/api/pleroma/emoji/packs?page_size=1")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
assert resp["count"] == 4
packs = Map.keys(resp["packs"])
@ -71,7 +71,7 @@ test "GET /api/pleroma/emoji/packs", %{conn: conn} do
|> get("/api/pleroma/emoji/packs?page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
assert resp["count"] == 4
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack2] = packs
@ -81,11 +81,21 @@ test "GET /api/pleroma/emoji/packs", %{conn: conn} do
|> get("/api/pleroma/emoji/packs?page_size=1&page=3")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
assert resp["count"] == 4
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack3] = packs
assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1&page=4")
|> json_response_and_validate_schema(200)
assert resp["count"] == 4
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack4] = packs
assert [pack1, pack2, pack3, pack4] |> Enum.uniq() |> length() == 4
end
describe "GET /api/pleroma/emoji/packs/remote" do
@ -128,11 +138,11 @@ test "non shareable instance", %{admin_conn: admin_conn} do
end
end
describe "GET /api/pleroma/emoji/packs/:name/archive" do
describe "GET /api/pleroma/emoji/packs/archive?name=:name" do
test "download shared pack", %{conn: conn} do
resp =
conn
|> get("/api/pleroma/emoji/packs/test_pack/archive")
|> get("/api/pleroma/emoji/packs/archive?name=test_pack")
|> response(200)
{:ok, arch} = :zip.unzip(resp, [:memory])
@ -143,7 +153,7 @@ test "download shared pack", %{conn: conn} do
test "non existing pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/test_pack_for_import/archive")
|> get("/api/pleroma/emoji/packs/archive?name=test_pack_for_import")
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack test_pack_for_import does not exist"
}
@ -151,7 +161,7 @@ test "non existing pack", %{conn: conn} do
test "non downloadable pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive")
|> get("/api/pleroma/emoji/packs/archive?name=test_pack_nonshared")
|> json_response_and_validate_schema(:forbidden) == %{
"error" =>
"Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
@ -173,28 +183,28 @@ test "shared pack from remote and non shared from fallback-src", %{
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack"
url: "https://example.com/api/pleroma/emoji/packs/show?name=test_pack"
} ->
conn
|> get("/api/pleroma/emoji/packs/test_pack")
|> get("/api/pleroma/emoji/packs/show?name=test_pack")
|> json_response_and_validate_schema(200)
|> json()
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack/archive"
url: "https://example.com/api/pleroma/emoji/packs/archive?name=test_pack"
} ->
conn
|> get("/api/pleroma/emoji/packs/test_pack/archive")
|> get("/api/pleroma/emoji/packs/archive?name=test_pack")
|> response(200)
|> text()
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack_nonshared"
url: "https://example.com/api/pleroma/emoji/packs/show?name=test_pack_nonshared"
} ->
conn
|> get("/api/pleroma/emoji/packs/test_pack_nonshared")
|> get("/api/pleroma/emoji/packs/show?name=test_pack_nonshared")
|> json_response_and_validate_schema(200)
|> json()
@ -218,7 +228,7 @@ test "shared pack from remote and non shared from fallback-src", %{
assert File.exists?("#{@emoji_path}/test_pack2/blank.png")
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack2")
|> delete("/api/pleroma/emoji/packs/delete?name=test_pack2")
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_pack2")
@ -239,7 +249,7 @@ test "shared pack from remote and non shared from fallback-src", %{
assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack_nonshared2")
|> delete("/api/pleroma/emoji/packs/delete?name=test_pack_nonshared2")
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_pack_nonshared2")
@ -279,14 +289,14 @@ test "checksum fail", %{admin_conn: admin_conn} do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"
url: "https://example.com/api/pleroma/emoji/packs/show?name=pack_bad_sha"
} ->
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/archive"
url: "https://example.com/api/pleroma/emoji/packs/archive?name=pack_bad_sha"
} ->
%Tesla.Env{
status: 200,
@ -316,7 +326,7 @@ test "other error", %{admin_conn: admin_conn} do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack"
url: "https://example.com/api/pleroma/emoji/packs/show?name=test_pack"
} ->
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
@ -336,7 +346,7 @@ test "other error", %{admin_conn: admin_conn} do
end
end
describe "PATCH /api/pleroma/emoji/packs/:name" do
describe "PATCH /api/pleroma/emoji/packs/update?name=:name" do
setup do
pack_file = "#{@emoji_path}/test_pack/pack.json"
original_content = File.read!(pack_file)
@ -358,7 +368,9 @@ test "other error", %{admin_conn: admin_conn} do
test "for a pack without a fallback source", ctx do
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]})
|> patch("/api/pleroma/emoji/packs/update?name=test_pack", %{
"metadata" => ctx[:new_data]
})
|> json_response_and_validate_schema(200) == ctx[:new_data]
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
@ -384,7 +396,7 @@ test "for a pack with a fallback source", ctx do
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
|> patch("/api/pleroma/emoji/packs/update?name=test_pack", %{metadata: new_data})
|> json_response_and_validate_schema(200) == new_data_with_sha
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
@ -404,17 +416,17 @@ test "when the fallback source doesn't have all the files", ctx do
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
|> patch("/api/pleroma/emoji/packs/update?name=test_pack", %{metadata: new_data})
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "The fallback archive does not have all files specified in pack.json"
}
end
end
describe "POST/DELETE /api/pleroma/emoji/packs/:name" do
describe "POST/DELETE /api/pleroma/emoji/packs/?name=:name" do
test "creating and deleting a pack", %{admin_conn: admin_conn} do
assert admin_conn
|> post("/api/pleroma/emoji/packs/test_created")
|> post("/api/pleroma/emoji/packs/create?name=test_created")
|> json_response_and_validate_schema(200) == "ok"
assert File.exists?("#{@emoji_path}/test_created/pack.json")
@ -426,7 +438,7 @@ test "creating and deleting a pack", %{admin_conn: admin_conn} do
}
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_created")
|> delete("/api/pleroma/emoji/packs/delete?name=test_created")
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_created/pack.json")
@ -439,7 +451,7 @@ test "if pack exists", %{admin_conn: admin_conn} do
File.write!(Path.join(path, "pack.json"), pack_file)
assert admin_conn
|> post("/api/pleroma/emoji/packs/test_created")
|> post("/api/pleroma/emoji/packs/create?name=test_created")
|> json_response_and_validate_schema(:conflict) == %{
"error" => "A pack named \"test_created\" already exists"
}
@ -449,7 +461,7 @@ test "if pack exists", %{admin_conn: admin_conn} do
test "with empty name", %{admin_conn: admin_conn} do
assert admin_conn
|> post("/api/pleroma/emoji/packs/ ")
|> post("/api/pleroma/emoji/packs/create?name= ")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}
@ -458,7 +470,7 @@ test "with empty name", %{admin_conn: admin_conn} do
test "deleting nonexisting pack", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/non_existing")
|> delete("/api/pleroma/emoji/packs/delete?name=non_existing")
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack non_existing does not exist"
}
@ -466,7 +478,7 @@ test "deleting nonexisting pack", %{admin_conn: admin_conn} do
test "deleting with empty name", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/ ")
|> delete("/api/pleroma/emoji/packs/delete?name= ")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}
@ -529,7 +541,7 @@ test "shows pack.json", %{conn: conn} do
}
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack")
|> get("/api/pleroma/emoji/packs/show?name=test_pack")
|> json_response_and_validate_schema(200)
assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
@ -539,7 +551,7 @@ test "shows pack.json", %{conn: conn} do
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1")
|> get("/api/pleroma/emoji/packs/show?name=test_pack&page_size=1")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
@ -549,15 +561,33 @@ test "shows pack.json", %{conn: conn} do
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2")
|> get("/api/pleroma/emoji/packs/show?name=test_pack&page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
end
test "for pack name with special chars", %{conn: conn} do
assert %{
"files" => files,
"files_count" => 1,
"pack" => %{
"can-download" => true,
"description" => "Test description",
"download-sha256" => _,
"homepage" => "https://pleroma.social",
"license" => "Test license",
"share-files" => true
}
} =
conn
|> get("/api/pleroma/emoji/packs/show?name=blobs.gg")
|> json_response_and_validate_schema(200)
end
test "non existing pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/non_existing")
|> get("/api/pleroma/emoji/packs/show?name=non_existing")
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack non_existing does not exist"
}
@ -565,7 +595,7 @@ test "non existing pack", %{conn: conn} do
test "error name", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/ ")
|> get("/api/pleroma/emoji/packs/show?name= ")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}