@@ -0,0 +1,79 @@ | |||||
# Pleroma: A lightweight social networking server | |||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> | |||||
# SPDX-License-Identifier: AGPL-3.0-only | |||||
defmodule Pleroma.Web.ApiSpec.PleromaMascotOperation do | |||||
alias OpenApiSpex.Operation | |||||
alias OpenApiSpex.Schema | |||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError | |||||
import Pleroma.Web.ApiSpec.Helpers | |||||
def open_api_operation(action) do | |||||
operation = String.to_existing_atom("#{action}_operation") | |||||
apply(__MODULE__, operation, []) | |||||
end | |||||
def show_operation do | |||||
%Operation{ | |||||
tags: ["Mascot"], | |||||
summary: "Gets user mascot image", | |||||
security: [%{"oAuth" => ["read:accounts"]}], | |||||
operationId: "PleromaAPI.MascotController.show", | |||||
responses: %{ | |||||
200 => Operation.response("Mascot", "application/json", mascot()) | |||||
} | |||||
} | |||||
end | |||||
def update_operation do | |||||
%Operation{ | |||||
tags: ["Mascot"], | |||||
summary: "Set/clear user avatar image", | |||||
description: | |||||
"Behaves exactly the same as `POST /api/v1/upload`. Can only accept images - any attempt to upload non-image files will be met with `HTTP 415 Unsupported Media Type`.", | |||||
operationId: "PleromaAPI.MascotController.update", | |||||
requestBody: | |||||
request_body( | |||||
"Parameters", | |||||
%Schema{ | |||||
type: :object, | |||||
properties: %{ | |||||
file: %Schema{type: :string, format: :binary} | |||||
} | |||||
}, | |||||
required: true | |||||
), | |||||
security: [%{"oAuth" => ["write:accounts"]}], | |||||
responses: %{ | |||||
200 => Operation.response("Mascot", "application/json", mascot()), | |||||
415 => Operation.response("Unsupported Media Type", "application/json", ApiError) | |||||
} | |||||
} | |||||
end | |||||
defp mascot do | |||||
%Schema{ | |||||
type: :object, | |||||
properties: %{ | |||||
id: %Schema{type: :string}, | |||||
url: %Schema{type: :string, format: :uri}, | |||||
type: %Schema{type: :string}, | |||||
pleroma: %Schema{ | |||||
type: :object, | |||||
properties: %{ | |||||
mime_type: %Schema{type: :string} | |||||
} | |||||
} | |||||
}, | |||||
example: %{ | |||||
"id" => "abcdefg", | |||||
"url" => "https://pleroma.example.org/media/abcdefg.png", | |||||
"type" => "image", | |||||
"pleroma" => %{ | |||||
"mime_type" => "image/png" | |||||
} | |||||
} | |||||
} | |||||
end | |||||
end |
@@ -9,16 +9,19 @@ defmodule Pleroma.Web.PleromaAPI.MascotController do | |||||
alias Pleroma.User | alias Pleroma.User | ||||
alias Pleroma.Web.ActivityPub.ActivityPub | alias Pleroma.Web.ActivityPub.ActivityPub | ||||
plug(Pleroma.Web.ApiSpec.CastAndValidate) | |||||
plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action == :show) | plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action == :show) | ||||
plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action != :show) | plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action != :show) | ||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaMascotOperation | |||||
@doc "GET /api/v1/pleroma/mascot" | @doc "GET /api/v1/pleroma/mascot" | ||||
def show(%{assigns: %{user: user}} = conn, _params) do | def show(%{assigns: %{user: user}} = conn, _params) do | ||||
json(conn, User.get_mascot(user)) | json(conn, User.get_mascot(user)) | ||||
end | end | ||||
@doc "PUT /api/v1/pleroma/mascot" | @doc "PUT /api/v1/pleroma/mascot" | ||||
def update(%{assigns: %{user: user}} = conn, %{"file" => file}) do | |||||
def update(%{assigns: %{user: user}, body_params: %{file: file}} = conn, _) do | |||||
with {:ok, object} <- ActivityPub.upload(file, actor: User.ap_id(user)), | with {:ok, object} <- ActivityPub.upload(file, actor: User.ap_id(user)), | ||||
# Reject if not an image | # Reject if not an image | ||||
%{type: "image"} = attachment <- render_attachment(object) do | %{type: "image"} = attachment <- render_attachment(object) do | ||||
@@ -16,9 +16,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do | |||||
filename: "sound.mp3" | filename: "sound.mp3" | ||||
} | } | ||||
ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => non_image_file}) | |||||
ret_conn = | |||||
conn | |||||
|> put_req_header("content-type", "multipart/form-data") | |||||
|> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) | |||||
assert json_response(ret_conn, 415) | |||||
assert json_response_and_validate_schema(ret_conn, 415) | |||||
file = %Plug.Upload{ | file = %Plug.Upload{ | ||||
content_type: "image/jpg", | content_type: "image/jpg", | ||||
@@ -26,9 +29,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do | |||||
filename: "an_image.jpg" | filename: "an_image.jpg" | ||||
} | } | ||||
conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) | |||||
conn = | |||||
conn | |||||
|> put_req_header("content-type", "multipart/form-data") | |||||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||||
assert %{"id" => _, "type" => image} = json_response(conn, 200) | |||||
assert %{"id" => _, "type" => image} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
test "mascot retrieving" do | test "mascot retrieving" do | ||||
@@ -37,7 +43,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do | |||||
# When user hasn't set a mascot, we should just get pleroma tan back | # When user hasn't set a mascot, we should just get pleroma tan back | ||||
ret_conn = get(conn, "/api/v1/pleroma/mascot") | ret_conn = get(conn, "/api/v1/pleroma/mascot") | ||||
assert %{"url" => url} = json_response(ret_conn, 200) | |||||
assert %{"url" => url} = json_response_and_validate_schema(ret_conn, 200) | |||||
assert url =~ "pleroma-fox-tan-smol" | assert url =~ "pleroma-fox-tan-smol" | ||||
# When a user sets their mascot, we should get that back | # When a user sets their mascot, we should get that back | ||||
@@ -47,9 +53,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do | |||||
filename: "an_image.jpg" | filename: "an_image.jpg" | ||||
} | } | ||||
ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) | |||||
ret_conn = | |||||
conn | |||||
|> put_req_header("content-type", "multipart/form-data") | |||||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||||
assert json_response(ret_conn, 200) | |||||
assert json_response_and_validate_schema(ret_conn, 200) | |||||
user = User.get_cached_by_id(user.id) | user = User.get_cached_by_id(user.id) | ||||
@@ -58,7 +67,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do | |||||
|> assign(:user, user) | |> assign(:user, user) | ||||
|> get("/api/v1/pleroma/mascot") | |> get("/api/v1/pleroma/mascot") | ||||
assert %{"url" => url, "type" => "image"} = json_response(conn, 200) | |||||
assert %{"url" => url, "type" => "image"} = json_response_and_validate_schema(conn, 200) | |||||
assert url =~ "an_image" | assert url =~ "an_image" | ||||
end | end | ||||
end | end |