From 1bbbc15925d3cb3a967993a8bd85a1316050af61 Mon Sep 17 00:00:00 2001 From: Sergey Suprunenko Date: Tue, 6 Oct 2020 20:58:32 +0200 Subject: Allow updating the media filename --- CHANGELOG.md | 4 +- .../web/api_spec/operations/media_operation.ex | 6 +++ .../mastodon_api/controllers/media_controller.ex | 33 ++++++++++-- .../controllers/media_controller_test.exs | 60 +++++++++++++++++++--- 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0776e85b0..49c08c8a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,6 +110,8 @@ switched to a new configuration mechanism, however it was not officially removed - Admin API: Importing emoji from a zip file - Pleroma API: Importing the mutes users from CSV files. - Pleroma API: Pagination for remote/local packs and emoji. +- Mastodon API: Add `filename` parameter to `POST /api/v1/media`, `POST /api/v2/media` and `PUT /api/v1/media/:id` +- Mastodon API: Add account setting for providing filename to post attachments @@ -272,8 +274,6 @@ switched to a new configuration mechanism, however it was not officially removed - Mastodon API: Support for `bot` field in `/api/v1/accounts/update_credentials`. - Mastodon API: Support irreversible property for filters. - Mastodon API: Add pleroma.favicon field to accounts. -- Mastodon API: Add `filename` parameter to `POST /api/v1/media` and `POST /api/v2/media`. -- Mastodon API: Add account setting for providing filename to post attachments - Admin API: endpoints for create/update/delete OAuth Apps. - Admin API: endpoint for status view. - OTP: Add command to reload emoji packs diff --git a/lib/pleroma/web/api_spec/operations/media_operation.ex b/lib/pleroma/web/api_spec/operations/media_operation.ex index 4c1496dd7..72234591a 100644 --- a/lib/pleroma/web/api_spec/operations/media_operation.ex +++ b/lib/pleroma/web/api_spec/operations/media_operation.ex @@ -90,8 +90,14 @@ defp update_request do }, description: %Schema{ type: :string, + nullable: true, description: "A plain-text description of the media, for accessibility purposes." }, + filename: %Schema{ + type: :string, + nullable: true, + description: "Filename of the media." + }, focus: %Schema{ type: :string, description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0." diff --git a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex index b003a2de6..175254837 100644 --- a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex @@ -57,18 +57,21 @@ def create2(%{assigns: %{user: user}, body_params: %{file: file} = data} = conn, def create2(_conn, _data), do: {:error, :bad_request} @doc "PUT /api/v1/media/:id" - def update(%{assigns: %{user: user}, body_params: %{description: description}} = conn, %{id: id}) do + def update( + %{assigns: %{user: user}, body_params: body_params} = conn, + %{id: id} + ) do with %Object{} = object <- Object.get_by_id(id), :ok <- Object.authorize_access(object, user), - {:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do + params <- prepare_update_params(body_params), + :ok <- validate_filename(params["filename"], hd(object.data["url"])), + {:ok, %Object{data: data}} <- Object.update_data(object, params) do attachment_data = Map.put(data, "id", object.id) render(conn, "attachment.json", %{attachment: attachment_data}) end end - def update(conn, data), do: show(conn, data) - @doc "GET /api/v1/media/:id" def show(%{assigns: %{user: user}} = conn, %{id: id}) do with %Object{data: data, id: object_id} = object <- Object.get_by_id(id), @@ -80,4 +83,26 @@ def show(%{assigns: %{user: user}} = conn, %{id: id}) do end def show(_conn, _data), do: {:error, :bad_request} + + defp prepare_update_params(body_params) do + body_params + |> Map.take([:description, :filename]) + |> Enum.into(%{}, fn + {:description, description} -> + {"name", description} + + {:filename, filename} -> + {"filename", filename} + end) + end + + defp validate_filename(nil, _), do: :ok + + defp validate_filename(filename, %{"href" => href}) do + if Path.extname(filename) == Path.extname(href) do + :ok + else + {:error, :invalid_filename_extension} + end + end end diff --git a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs index c471c0366..d99bf3694 100644 --- a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs @@ -99,7 +99,7 @@ test "returns error when custom filename has different extension than original o end end - describe "Update media description" do + describe "Update media" do setup do: oauth_access(["write:media"]) setup %{user: actor} do @@ -113,21 +113,69 @@ test "returns error when custom filename has different extension than original o ActivityPub.upload( file, actor: User.ap_id(actor), - description: "test-m" + description: "test-m", + filename: "test_image.jpg" ) [object: object] end - test "/api/v1/media/:id good request", %{conn: conn, object: object} do + test "/api/v1/media/:id update description", %{conn: conn, object: object} do + new_description = "test-media" + media = conn |> put_req_header("content-type", "multipart/form-data") - |> put("/api/v1/media/#{object.id}", %{"description" => "test-media"}) + |> put("/api/v1/media/#{object.id}", %{"description" => new_description}) |> json_response_and_validate_schema(:ok) - assert media["description"] == "test-media" - assert refresh_record(object).data["name"] == "test-media" + assert media["description"] == new_description + assert refresh_record(object).data["name"] == new_description + end + + test "/api/v1/media/:id update filename", %{conn: conn, object: object} do + new_filename = "media.jpg" + + media = + conn + |> put_req_header("content-type", "multipart/form-data") + |> put("/api/v1/media/#{object.id}", %{"filename" => new_filename}) + |> json_response_and_validate_schema(:ok) + + assert media["pleroma"]["filename"] == new_filename + assert refresh_record(object).data["filename"] == new_filename + end + + test "/api/v1/media/:id update description and filename", %{conn: conn, object: object} do + new_description = "test-media" + new_filename = "media.jpg" + + media = + conn + |> put_req_header("content-type", "multipart/form-data") + |> put("/api/v1/media/#{object.id}", %{ + "description" => new_description, + "filename" => new_filename, + "foo" => "bar" + }) + |> json_response_and_validate_schema(:ok) + + assert media["description"] == new_description + assert media["pleroma"]["filename"] == new_filename + assert refresh_record(object).data["name"] == new_description + assert refresh_record(object).data["filename"] == new_filename + end + + test "/api/v1/media/:id filename with a wrong extension", %{conn: conn, object: object} do + new_filename = "media.exe" + + response = + conn + |> put_req_header("content-type", "multipart/form-data") + |> put("/api/v1/media/#{object.id}", %{"filename" => new_filename}) + |> json_response(400) + + assert response["error"] == "invalid_filename_extension" end end -- cgit v1.2.3