diff options
Diffstat (limited to 'lib/pleroma')
| -rw-r--r-- | lib/pleroma/upload.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/api_spec/helpers.ex | 4 | ||||
| -rw-r--r-- | lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex | 185 | ||||
| -rw-r--r-- | lib/pleroma/web/api_spec/operations/status_operation.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/pleroma_api/controllers/account_controller.ex | 26 | 
5 files changed, 209 insertions, 10 deletions
| diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 762d813d9..1be1a3a5b 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -134,7 +134,7 @@ defmodule Pleroma.Upload do      end    end -  defp prepare_upload(%{"img" => "data:image/" <> image_data}, opts) do +  defp prepare_upload(%{img: "data:image/" <> image_data}, opts) do      parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)      data = Base.decode64!(parsed["data"], ignore: :whitespace)      hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data))) diff --git a/lib/pleroma/web/api_spec/helpers.ex b/lib/pleroma/web/api_spec/helpers.ex index 183df43ee..f0b558aa5 100644 --- a/lib/pleroma/web/api_spec/helpers.ex +++ b/lib/pleroma/web/api_spec/helpers.ex @@ -54,4 +54,8 @@ defmodule Pleroma.Web.ApiSpec.Helpers do    def empty_array_response do      Operation.response("Empty array", "application/json", %Schema{type: :array, example: []})    end + +  def no_content_response do +    Operation.response("No Content", "application/json", %Schema{type: :string, example: ""}) +  end  end diff --git a/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex new file mode 100644 index 000000000..435991037 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex @@ -0,0 +1,185 @@ +# 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.PleromaAccountOperation do +  alias OpenApiSpex.Operation +  alias OpenApiSpex.Schema +  alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship +  alias Pleroma.Web.ApiSpec.Schemas.ApiError +  alias Pleroma.Web.ApiSpec.Schemas.FlakeID +  alias Pleroma.Web.ApiSpec.StatusOperation + +  import Pleroma.Web.ApiSpec.Helpers + +  def open_api_operation(action) do +    operation = String.to_existing_atom("#{action}_operation") +    apply(__MODULE__, operation, []) +  end + +  def confirmation_resend_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Resend confirmation email. Expects `email` or `nickname`", +      operationId: "PleromaAPI.AccountController.confirmation_resend", +      parameters: [ +        Operation.parameter(:email, :query, :string, "Email of that needs to be verified", +          example: "cofe@cofe.io" +        ), +        Operation.parameter( +          :nickname, +          :query, +          :string, +          "Nickname of user that needs to be verified", +          example: "cofefe" +        ) +      ], +      responses: %{ +        204 => no_content_response() +      } +    } +  end + +  def update_avatar_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Set/clear user avatar image", +      operationId: "PleromaAPI.AccountController.update_avatar", +      requestBody: +        request_body("Parameters", update_avatar_or_background_request(), required: true), +      security: [%{"oAuth" => ["write:accounts"]}], +      responses: %{ +        200 => update_response(), +        403 => Operation.response("Forbidden", "application/json", ApiError) +      } +    } +  end + +  def update_banner_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Set/clear user banner image", +      operationId: "PleromaAPI.AccountController.update_banner", +      requestBody: request_body("Parameters", update_banner_request(), required: true), +      security: [%{"oAuth" => ["write:accounts"]}], +      responses: %{ +        200 => update_response() +      } +    } +  end + +  def update_background_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Set/clear user background image", +      operationId: "PleromaAPI.AccountController.update_background", +      security: [%{"oAuth" => ["write:accounts"]}], +      requestBody: +        request_body("Parameters", update_avatar_or_background_request(), required: true), +      responses: %{ +        200 => update_response() +      } +    } +  end + +  def favourites_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Returns favorites timeline of any user", +      operationId: "PleromaAPI.AccountController.favourites", +      parameters: [id_param() | pagination_params()], +      security: [%{"oAuth" => ["read:favourites"]}], +      responses: %{ +        200 => +          Operation.response( +            "Array of Statuses", +            "application/json", +            StatusOperation.array_of_statuses() +          ), +        403 => Operation.response("Forbidden", "application/json", ApiError), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  def subscribe_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Subscribe to receive notifications for all statuses posted by a user", +      operationId: "PleromaAPI.AccountController.subscribe", +      parameters: [id_param()], +      security: [%{"oAuth" => ["follow", "write:follows"]}], +      responses: %{ +        200 => Operation.response("Relationship", "application/json", AccountRelationship), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  def unsubscribe_operation do +    %Operation{ +      tags: ["Accounts"], +      summary: "Unsubscribe to stop receiving notifications from user statuses", +      operationId: "PleromaAPI.AccountController.unsubscribe", +      parameters: [id_param()], +      security: [%{"oAuth" => ["follow", "write:follows"]}], +      responses: %{ +        200 => Operation.response("Relationship", "application/json", AccountRelationship), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  defp id_param do +    Operation.parameter(:id, :path, FlakeID, "Account ID", +      example: "9umDrYheeY451cQnEe", +      required: true +    ) +  end + +  defp update_avatar_or_background_request do +    %Schema{ +      title: "PleromaAccountUpdateAvatarOrBackgroundRequest", +      type: :object, +      properties: %{ +        img: %Schema{ +          type: :string, +          format: :binary, +          description: "Image encoded using `multipart/form-data` or an empty string to clear" +        } +      } +    } +  end + +  defp update_banner_request do +    %Schema{ +      title: "PleromaAccountUpdateBannerRequest", +      type: :object, +      properties: %{ +        banner: %Schema{ +          type: :string, +          format: :binary, +          description: "Image encoded using `multipart/form-data` or an empty string to clear" +        } +      } +    } +  end + +  defp update_response do +    Operation.response("PleromaAccountUpdateResponse", "application/json", %Schema{ +      type: :object, +      properties: %{ +        url: %Schema{ +          type: :string, +          format: :uri, +          nullable: true, +          description: "Image URL" +        } +      }, +      example: %{ +        "url" => +          "https://cofe.party/media/9d0add56-bcb6-4c0f-8225-cbbd0b6dd773/13eadb6972c9ccd3f4ffa3b8196f0e0d38b4d2f27594457c52e52946c054cd9a.gif" +      } +    }) +  end +end diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex index a6bb87560..561db3bce 100644 --- a/lib/pleroma/web/api_spec/operations/status_operation.ex +++ b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -360,7 +360,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do      }    end -  defp array_of_statuses do +  def array_of_statuses do      %Schema{type: :array, items: Status, example: [Status.schema().example]}    end diff --git a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex index be7477867..07078d415 100644 --- a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex @@ -19,6 +19,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    require Pleroma.Constants    plug( +    OpenApiSpex.Plug.PutApiSpec, +    [module: Pleroma.Web.ApiSpec] when action == :confirmation_resend +  ) + +  plug(Pleroma.Web.ApiSpec.CastAndValidate) + +  plug(      :skip_plug,      [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirmation_resend    ) @@ -49,9 +56,11 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])    plug(:put_view, Pleroma.Web.MastodonAPI.AccountView) +  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation +    @doc "POST /api/v1/pleroma/accounts/confirmation_resend"    def confirmation_resend(conn, params) do -    nickname_or_email = params["email"] || params["nickname"] +    nickname_or_email = params[:email] || params[:nickname]      with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),           {:ok, _} <- User.try_send_confirmation_email(user) do @@ -60,7 +69,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    end    @doc "PATCH /api/v1/pleroma/accounts/update_avatar" -  def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do +  def update_avatar(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do      {:ok, _user} =        user        |> Changeset.change(%{avatar: nil}) @@ -69,7 +78,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do      json(conn, %{url: nil})    end -  def update_avatar(%{assigns: %{user: user}} = conn, params) do +  def update_avatar(%{assigns: %{user: user}, body_params: params} = conn, _params) do      {:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)      {:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()      %{"url" => [%{"href" => href} | _]} = data @@ -78,14 +87,14 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    end    @doc "PATCH /api/v1/pleroma/accounts/update_banner" -  def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do +  def update_banner(%{assigns: %{user: user}, body_params: %{banner: ""}} = conn, _) do      with {:ok, _user} <- User.update_banner(user, %{}) do        json(conn, %{url: nil})      end    end -  def update_banner(%{assigns: %{user: user}} = conn, params) do -    with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner), +  def update_banner(%{assigns: %{user: user}, body_params: params} = conn, _) do +    with {:ok, object} <- ActivityPub.upload(%{img: params[:banner]}, type: :banner),           {:ok, _user} <- User.update_banner(user, object.data) do        %{"url" => [%{"href" => href} | _]} = object.data @@ -94,13 +103,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    end    @doc "PATCH /api/v1/pleroma/accounts/update_background" -  def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do +  def update_background(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do      with {:ok, _user} <- User.update_background(user, %{}) do        json(conn, %{url: nil})      end    end -  def update_background(%{assigns: %{user: user}} = conn, params) do +  def update_background(%{assigns: %{user: user}, body_params: params} = conn, _) do      with {:ok, object} <- ActivityPub.upload(params, type: :background),           {:ok, _user} <- User.update_background(user, object.data) do        %{"url" => [%{"href" => href} | _]} = object.data @@ -117,6 +126,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do    def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do      params =        params +      |> Map.new(fn {key, value} -> {to_string(key), value} end)        |> Map.put("type", "Create")        |> Map.put("favorited_by", user.ap_id)        |> Map.put("blocking_user", for_user) | 
