Remote Timeline: add Streaming support
[akkoma] / lib / pleroma / web / ostatus / ostatus_controller.ex
index 76a244d0ffc304be6682e8ef2835480fe0cb8680..de1b0b3f003fea6150dfedddf7a1a69bba9e2993 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OStatus.OStatusController do
@@ -8,17 +8,21 @@ defmodule Pleroma.Web.OStatus.OStatusController do
   alias Fallback.RedirectController
   alias Pleroma.Activity
   alias Pleroma.Object
+  alias Pleroma.Plugs.RateLimiter
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPubController
-  alias Pleroma.Web.ActivityPub.ObjectView
   alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.Web.Endpoint
   alias Pleroma.Web.Metadata.PlayerView
   alias Pleroma.Web.Router
 
+  plug(Pleroma.Plugs.EnsureAuthenticatedPlug,
+    unless_func: &Pleroma.Web.FederatingPlug.federating?/1
+  )
+
   plug(
-    Pleroma.Plugs.RateLimiter,
-    {:ap_routes, params: ["uuid"]} when action in [:object, :activity]
+    RateLimiter,
+    [name: :ap_routes, params: ["uuid"]] when action in [:object, :activity]
   )
 
   plug(
@@ -28,20 +32,18 @@ defmodule Pleroma.Web.OStatus.OStatusController do
 
   action_fallback(:errors)
 
-  def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid})
+  def object(%{assigns: %{format: format}} = conn, _params)
       when format in ["json", "activity+json"] do
     ActivityPubController.call(conn, :object)
   end
 
-  def object(%{assigns: %{format: format}} = conn, %{"uuid" => uuid}) do
-    with id <- o_status_url(conn, :object, uuid),
+  def object(%{assigns: %{format: format}} = conn, _params) do
+    with id <- Endpoint.url() <> conn.request_path,
          {_, %Activity{} = activity} <-
            {:activity, Activity.get_create_by_object_ap_id_with_object(id)},
-         {_, true} <- {:public?, Visibility.is_public?(activity)},
-         %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
+         {_, true} <- {:public?, Visibility.is_public?(activity)} do
       case format do
-        "html" -> redirect(conn, to: "/notice/#{activity.id}")
-        _ -> represent_activity(conn, nil, activity, user)
+        _ -> redirect(conn, to: "/notice/#{activity.id}")
       end
     else
       reason when reason in [{:public?, false}, {:activity, nil}] ->
@@ -52,19 +54,17 @@ defmodule Pleroma.Web.OStatus.OStatusController do
     end
   end
 
-  def activity(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid})
+  def activity(%{assigns: %{format: format}} = conn, _params)
       when format in ["json", "activity+json"] do
     ActivityPubController.call(conn, :activity)
   end
 
-  def activity(%{assigns: %{format: format}} = conn, %{"uuid" => uuid}) do
-    with id <- o_status_url(conn, :activity, uuid),
+  def activity(%{assigns: %{format: format}} = conn, _params) do
+    with id <- Endpoint.url() <> conn.request_path,
          {_, %Activity{} = activity} <- {:activity, Activity.normalize(id)},
-         {_, true} <- {:public?, Visibility.is_public?(activity)},
-         %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
+         {_, true} <- {:public?, Visibility.is_public?(activity)} do
       case format do
-        "html" -> redirect(conn, to: "/notice/#{activity.id}")
-        _ -> represent_activity(conn, format, activity, user)
+        _ -> redirect(conn, to: "/notice/#{activity.id}")
       end
     else
       reason when reason in [{:public?, false}, {:activity, nil}] ->
@@ -76,41 +76,42 @@ defmodule Pleroma.Web.OStatus.OStatusController do
   end
 
   def notice(%{assigns: %{format: format}} = conn, %{"id" => id}) do
-    if Pleroma.Config.get([:instance, :static_fe], false) do
-      Pleroma.Web.StaticFE.StaticFEController.show(conn, %{"notice_id" => id})
-    else
-      with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id_with_object(id)},
-           {_, true} <- {:public?, Visibility.is_public?(activity)},
-             %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
-        cond do
-          format == "html" && activity.data["type"] == "Create" ->
-            %Object{} = object = Object.normalize(activity)
-
-            RedirectController.redirector_with_meta(
-              conn,
-              %{
-                activity_id: activity.id,
-                object: object,
-                url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
-                user: user
-              }
-            )
-
-          format == "html" ->
-            RedirectController.redirector(conn, nil)
-
-          true ->
-            represent_activity(conn, format, activity, user)
-        end
-      else
-        reason when reason in [{:public?, false}, {:activity, nil}] ->
-          conn
-          |> put_status(404)
-          |> RedirectController.redirector(nil, 404)
-
-        e ->
-          e
+    with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id_with_object(id)},
+         {_, true} <- {:public?, Visibility.is_public?(activity)},
+         %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
+      cond do
+        format in ["json", "activity+json"] ->
+          if activity.local do
+            %{data: %{"id" => redirect_url}} = Object.normalize(activity)
+            redirect(conn, external: redirect_url)
+          else
+            {:error, :not_found}
+          end
+
+        activity.data["type"] == "Create" ->
+          %Object{} = object = Object.normalize(activity)
+
+          RedirectController.redirector_with_meta(
+            conn,
+            %{
+              activity_id: activity.id,
+              object: object,
+              url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
+              user: user
+            }
+          )
+
+        true ->
+          RedirectController.redirector(conn, nil)
       end
+    else
+      reason when reason in [{:public?, false}, {:activity, nil}] ->
+        conn
+        |> put_status(404)
+        |> RedirectController.redirector(nil, 404)
+
+      e ->
+        e
     end
   end
 
@@ -138,31 +139,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do
     end
   end
 
-  defp represent_activity(
-         conn,
-         "activity+json",
-         %Activity{data: %{"type" => "Create"}} = activity,
-         _user
-       ) do
-    object = Object.normalize(activity)
-
-    conn
-    |> put_resp_header("content-type", "application/activity+json")
-    |> put_view(ObjectView)
-    |> render("object.json", %{object: object})
-  end
-
-  defp represent_activity(_conn, _, _, _) do
-    {:error, :not_found}
-  end
-
-  def errors(conn, {:error, :not_found}) do
+  defp errors(conn, {:error, :not_found}) do
     render_error(conn, :not_found, "Not found")
   end
 
-  def errors(conn, {:fetch_user, nil}), do: errors(conn, {:error, :not_found})
+  defp errors(conn, {:fetch_user, nil}), do: errors(conn, {:error, :not_found})
 
-  def errors(conn, _) do
+  defp errors(conn, _) do
     render_error(conn, :internal_server_error, "Something went wrong")
   end
 end