Merge branch 'develop' into 'develop'
[akkoma] / lib / pleroma / web / mastodon_api / mastodon_api_controller.ex
index e89186ae360101ee84224ab8221927de052be525..922b83ed0814791a0f1e9a5fa4e93485826d028c 100644 (file)
@@ -4,12 +4,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   alias Pleroma.Web
   alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView}
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.Utils
   alias Pleroma.Web.{CommonAPI, OStatus}
   alias Pleroma.Web.OAuth.{Authorization, Token, App}
   alias Comeonin.Pbkdf2
   import Ecto.Query
   require Logger
 
+  action_fallback(:errors)
+
   def create_app(conn, params) do
     with cs <- App.register_changeset(%App{}, params) |> IO.inspect(),
          {:ok, app} <- Repo.insert(cs) |> IO.inspect() do
@@ -69,6 +72,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         user
       end
 
+    user =
+      if locked = params["locked"] do
+        with locked <- locked == "true",
+             new_info <- Map.put(user.info, "locked", locked),
+             change <- User.info_changeset(user, %{info: new_info}),
+             {:ok, user} <- User.update_and_set_cache(change) do
+          user
+        else
+          _e -> user
+        end
+      else
+        user
+      end
+
     with changeset <- User.update_changeset(user, params),
          {:ok, user} <- User.update_and_set_cache(changeset) do
       if original_user != user do
@@ -134,6 +151,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
       %{
         "shortcode" => shortcode,
         "static_url" => url,
+        "visible_in_picker" => true,
         "url" => url
       }
     end)
@@ -236,12 +254,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
       conn
       |> add_link_headers(:user_statuses, activities, params["id"])
-      |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity})
+      |> render(StatusView, "index.json", %{
+        activities: activities,
+        for: reading_user,
+        as: :activity
+      })
     end
   end
 
-  def dm_timeline(%{assigns: %{user: user}} = conn, params) do
-    query = ActivityPub.fetch_activities_query([user.ap_id], %{visibility: "direct"})
+  def dm_timeline(%{assigns: %{user: user}} = conn, _params) do
+    query =
+      ActivityPub.fetch_activities_query([user.ap_id], %{"type" => "Create", visibility: "direct"})
+
     activities = Repo.all(query)
 
     conn
@@ -291,6 +315,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  def post_status(conn, %{"status" => "", "media_ids" => media_ids} = params)
+      when length(media_ids) > 0 do
+    params =
+      params
+      |> Map.put("status", ".")
+
+    post_status(conn, params)
+  end
+
   def post_status(%{assigns: %{user: user}} = conn, %{"status" => _} = params) do
     params =
       params
@@ -321,27 +354,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   end
 
   def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
-    with {:ok, announce, _activity} = CommonAPI.repeat(ap_id_or_id, user) do
+    with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user) do
       render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity})
     end
   end
 
   def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
-    with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unrepeat(ap_id_or_id, user),
+    with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user),
          %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
       render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
     end
   end
 
   def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
-    with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user),
+    with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user),
          %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
       render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
     end
   end
 
   def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
-    with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user),
+    with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user),
          %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
       render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
     end
@@ -458,6 +491,53 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  def follow_requests(%{assigns: %{user: followed}} = conn, _params) do
+    with {:ok, follow_requests} <- User.get_follow_requests(followed) do
+      render(conn, AccountView, "accounts.json", %{users: follow_requests, as: :user})
+    end
+  end
+
+  def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
+    with %User{} = follower <- Repo.get(User, id),
+         {:ok, follower} <- User.maybe_follow(follower, followed),
+         %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
+         {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"),
+         {:ok, _activity} <-
+           ActivityPub.accept(%{
+             to: [follower.ap_id],
+             actor: followed.ap_id,
+             object: follow_activity.data["id"],
+             type: "Accept"
+           }) do
+      render(conn, AccountView, "relationship.json", %{user: followed, target: follower})
+    else
+      {:error, message} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Jason.encode!(%{"error" => message}))
+    end
+  end
+
+  def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
+    with %User{} = follower <- Repo.get(User, id),
+         %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
+         {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"),
+         {:ok, _activity} <-
+           ActivityPub.reject(%{
+             to: [follower.ap_id],
+             actor: followed.ap_id,
+             object: follow_activity.data["id"],
+             type: "Reject"
+           }) do
+      render(conn, AccountView, "relationship.json", %{user: followed, target: follower})
+    else
+      {:error, message} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Jason.encode!(%{"error" => message}))
+    end
+  end
+
   def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
     with %User{} = followed <- Repo.get(User, id),
          {:ok, follower} <- User.maybe_direct_follow(follower, followed),
@@ -527,6 +607,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do
+    json(conn, info["domain_blocks"] || [])
+  end
+
+  def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do
+    User.block_domain(blocker, domain)
+    json(conn, %{})
+  end
+
+  def unblock_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do
+    User.unblock_domain(blocker, domain)
+    json(conn, %{})
+  end
+
   def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
     accounts = User.search(query, params["resolve"] == "true")
 
@@ -913,4 +1007,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         nil
     end
   end
+
+  def errors(conn, _) do
+    conn
+    |> put_status(500)
+    |> json("Something went wrong")
+  end
 end