Merge branch 'develop' into 'remove-twitter-api'
[akkoma] / lib / pleroma / web / mastodon_api / controllers / account_controller.ex
index 93df7964523307a65a18a7cd710e0da636f6a1ae..b9ed2d7b27e3ef34160c26503277b46f898e2d66 100644 (file)
@@ -14,6 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       skip_relationships?: 1
     ]
 
+  alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
   alias Pleroma.Plugs.OAuthScopesPlug
   alias Pleroma.Plugs.RateLimiter
   alias Pleroma.User
@@ -26,18 +27,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   alias Pleroma.Web.OAuth.Token
   alias Pleroma.Web.TwitterAPI.TwitterAPI
 
-  plug(:skip_plug, OAuthScopesPlug when action == :identity_proofs)
+  plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
+  plug(:skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :create)
+
+  plug(:skip_plug, EnsurePublicOrAuthenticatedPlug when action in [:show, :statuses])
 
   plug(
     OAuthScopesPlug,
     %{fallback: :proceed_unauthenticated, scopes: ["read:accounts"]}
-    when action == :show
+    when action in [:show, :followers, :following]
+  )
+
+  plug(
+    OAuthScopesPlug,
+    %{fallback: :proceed_unauthenticated, scopes: ["read:statuses"]}
+    when action == :statuses
   )
 
   plug(
     OAuthScopesPlug,
     %{scopes: ["read:accounts"]}
-    when action in [:endorsements, :verify_credentials, :followers, :following]
+    when action in [:verify_credentials, :endorsements, :identity_proofs]
   )
 
   plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action == :update_credentials)
@@ -56,21 +67,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
   plug(OAuthScopesPlug, %{scopes: ["read:follows"]} when action == :relationships)
 
-  # Note: :follows (POST /api/v1/follows) is the same as :follow, consider removing :follows
   plug(
     OAuthScopesPlug,
-    %{scopes: ["follow", "write:follows"]} when action in [:follows, :follow, :unfollow]
+    %{scopes: ["follow", "write:follows"]} when action in [:follow_by_uri, :follow, :unfollow]
   )
 
   plug(OAuthScopesPlug, %{scopes: ["follow", "read:mutes"]} when action == :mutes)
 
   plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action in [:mute, :unmute])
 
-  plug(
-    Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
-    when action not in [:create, :show, :statuses]
-  )
-
   @relationship_actions [:follow, :unfollow]
   @needs_account ~W(followers following lists follow unfollow mute unmute block unblock)a
 
@@ -83,33 +88,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   plug(RateLimiter, [name: :app_account_creation] when action == :create)
   plug(:assign_account_by_id when action in @needs_account)
 
-  plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
-
   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 
   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AccountOperation
 
   @doc "POST /api/v1/accounts"
   def create(%{assigns: %{app: app}, body_params: params} = conn, _params) do
-    params =
-      params
-      |> Map.take([
-        :email,
-        :bio,
-        :captcha_solution,
-        :captcha_token,
-        :captcha_answer_data,
-        :token,
-        :password,
-        :fullname
-      ])
-      |> Map.put(:nickname, params.username)
-      |> Map.put(:fullname, params.fullname || params.username)
-      |> Map.put(:bio, params.bio || "")
-      |> Map.put(:confirm, params.password)
-      |> Map.put(:trusted_app, app.trusted)
-
     with :ok <- validate_email_param(params),
+         :ok <- TwitterAPI.validate_captcha(app, params),
          {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true),
          {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do
       json(conn, %{
@@ -119,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
         created_at: Token.Utils.format_created_at(token)
       })
     else
-      {:error, errors} -> json_response(conn, :bad_request, errors)
+      {:error, error} -> json_response(conn, :bad_request, %{error: error})
     end
   end
 
@@ -131,11 +117,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
     render_error(conn, :forbidden, "Invalid credentials")
   end
 
-  defp validate_email_param(%{:email => email}) when not is_nil(email), do: :ok
+  defp validate_email_param(%{email: email}) when not is_nil(email), do: :ok
 
   defp validate_email_param(_) do
     case Pleroma.Config.get([:instance, :account_activation_required]) do
-      true -> {:error, %{"error" => "Missing parameters"}}
+      true -> {:error, dgettext("errors", "Missing parameter: %{name}", name: "email")}
       _ -> :ok
     end
   end
@@ -158,7 +144,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
     params =
       params
-      |> Map.from_struct()
       |> Enum.filter(fn {_, value} -> not is_nil(value) end)
       |> Enum.into(%{})
 
@@ -217,11 +202,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       Enum.map(fields, fn {_, v} -> v end)
     else
       Enum.map(fields, fn
-        %Pleroma.Web.ApiSpec.Schemas.AccountAttributeField{} = field ->
-          %{"name" => field.name, "value" => field.value}
-
-        field ->
-          field
+        %{} = field -> %{"name" => field.name, "value" => field.value}
+        field -> field
       end)
     end
   end
@@ -374,8 +356,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
   @doc "POST /api/v1/accounts/:id/unblock"
   def unblock(%{assigns: %{user: blocker, account: blocked}} = conn, _params) do
-    with {:ok, _user_block} <- User.unblock(blocker, blocked),
-         {:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do
+    with {:ok, _activity} <- CommonAPI.unblock(blocker, blocked) do
       render(conn, "relationship.json", user: blocker, target: blocked)
     else
       {:error, message} -> json_response(conn, :forbidden, %{error: message})
@@ -383,7 +364,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   end
 
   @doc "POST /api/v1/follows"
-  def follows(%{body_params: %{uri: uri}} = conn, _) do
+  def follow_by_uri(%{body_params: %{uri: uri}} = conn, _) do
     case User.get_cached_by_nickname(uri) do
       %User{} = user ->
         conn