Merge branch 'features/users-raw_bio' into 'develop'
[akkoma] / lib / pleroma / web / mastodon_api / controllers / account_controller.ex
index 61b0e2f633c939599ca1d0ee56cb49e7eb523114..c38c2b895b09a8631886273141757521af4710df 100644 (file)
@@ -10,10 +10,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       add_link_headers: 2,
       truthy_param?: 1,
       assign_account_by_id: 2,
-      json_response: 3,
-      skip_relationships?: 1
+      embed_relationships?: 1,
+      json_response: 3
     ]
 
+  alias Pleroma.Maps
   alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
   alias Pleroma.Plugs.OAuthScopesPlug
   alias Pleroma.Plugs.RateLimiter
@@ -27,7 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   alias Pleroma.Web.OAuth.Token
   alias Pleroma.Web.TwitterAPI.TwitterAPI
 
-  plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
+  plug(Pleroma.Web.ApiSpec.CastAndValidate)
 
   plug(:skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :create)
 
@@ -81,7 +82,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
   plug(
     RateLimiter,
-    [name: :relation_id_action, params: ["id", "uri"]] when action in @relationship_actions
+    [name: :relation_id_action, params: [:id, :uri]] when action in @relationship_actions
   )
 
   plug(RateLimiter, [name: :relations_actions] when action in @relationship_actions)
@@ -139,9 +140,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   end
 
   @doc "PATCH /api/v1/accounts/update_credentials"
-  def update_credentials(%{assigns: %{user: original_user}, body_params: params} = conn, _params) do
-    user = original_user
-
+  def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _params) do
     params =
       params
       |> Enum.filter(fn {_, value} -> not is_nil(value) end)
@@ -162,39 +161,50 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
         :discoverable
       ]
       |> Enum.reduce(%{}, fn key, acc ->
-        add_if_present(acc, params, key, key, &{:ok, truthy_param?(&1)})
+        Maps.put_if_present(acc, key, params[key], &{:ok, truthy_param?(&1)})
       end)
-      |> add_if_present(params, :display_name, :name)
-      |> add_if_present(params, :note, :bio)
-      |> add_if_present(params, :avatar, :avatar)
-      |> add_if_present(params, :header, :banner)
-      |> add_if_present(params, :pleroma_background_image, :background)
-      |> add_if_present(
-        params,
-        :fields_attributes,
+      |> Maps.put_if_present(:name, params[:display_name])
+      |> Maps.put_if_present(:bio, params[:note])
+      |> Maps.put_if_present(:raw_bio, params[:note])
+      |> Maps.put_if_present(:avatar, params[:avatar])
+      |> Maps.put_if_present(:banner, params[:header])
+      |> Maps.put_if_present(:background, params[:pleroma_background_image])
+      |> Maps.put_if_present(
         :raw_fields,
+        params[:fields_attributes],
         &{:ok, normalize_fields_attributes(&1)}
       )
-      |> add_if_present(params, :pleroma_settings_store, :pleroma_settings_store)
-      |> add_if_present(params, :default_scope, :default_scope)
-      |> add_if_present(params, :actor_type, :actor_type)
+      |> Maps.put_if_present(:pleroma_settings_store, params[:pleroma_settings_store])
+      |> Maps.put_if_present(:default_scope, params[:default_scope])
+      |> Maps.put_if_present(:default_scope, params["source"]["privacy"])
+      |> Maps.put_if_present(:actor_type, params[:actor_type])
 
     changeset = User.update_changeset(user, user_params)
 
     with {:ok, user} <- User.update_and_set_cache(changeset) do
+      user
+      |> build_update_activity_params()
+      |> ActivityPub.update()
+
       render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
     else
       _e -> render_error(conn, :forbidden, "Invalid request")
     end
   end
 
-  defp add_if_present(map, params, params_field, map_field, value_function \\ &{:ok, &1}) do
-    with true <- Map.has_key?(params, params_field),
-         {:ok, new_value} <- value_function.(Map.get(params, params_field)) do
-      Map.put(map, map_field, new_value)
-    else
-      _ -> map
-    end
+  # Hotfix, handling will be redone with the pipeline
+  defp build_update_activity_params(user) do
+    object =
+      Pleroma.Web.ActivityPub.UserView.render("user.json", user: user)
+      |> Map.delete("@context")
+
+    %{
+      local: true,
+      to: [user.follower_address],
+      cc: [],
+      object: object,
+      actor: user.ap_id
+    }
   end
 
   defp normalize_fields_attributes(fields) do
@@ -235,9 +245,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       params =
         params
         |> Map.delete(:tagged)
-        |> Enum.filter(&(not is_nil(&1)))
-        |> Map.new(fn {key, value} -> {to_string(key), value} end)
-        |> Map.put("tag", params[:tagged])
+        |> Map.put(:tag, params[:tagged])
 
       activities = ActivityPub.fetch_user_activities(user, reading_user, params)
 
@@ -247,8 +255,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
       |> render("index.json",
         activities: activities,
         for: reading_user,
-        as: :activity,
-        skip_relationships: skip_relationships?(params)
+        as: :activity
       )
     else
       _e -> render_error(conn, :not_found, "Can't find user")
@@ -271,7 +278,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
     conn
     |> add_link_headers(followers)
-    |> render("index.json", for: for_user, users: followers, as: :user)
+    # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
+    |> render("index.json",
+      for: for_user,
+      users: followers,
+      as: :user,
+      embed_relationships: embed_relationships?(params)
+    )
   end
 
   @doc "GET /api/v1/accounts/:id/following"
@@ -290,7 +303,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
     conn
     |> add_link_headers(followers)
-    |> render("index.json", for: for_user, users: followers, as: :user)
+    # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
+    |> render("index.json",
+      for: for_user,
+      users: followers,
+      as: :user,
+      embed_relationships: embed_relationships?(params)
+    )
   end
 
   @doc "GET /api/v1/accounts/:id/lists"
@@ -356,8 +375,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})