logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

ostatus_controller.ex (4791B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.OStatus.OStatusController do
  5. use Pleroma.Web, :controller
  6. alias Fallback.RedirectController
  7. alias Pleroma.Activity
  8. alias Pleroma.Object
  9. alias Pleroma.Plugs.RateLimiter
  10. alias Pleroma.User
  11. alias Pleroma.Web.ActivityPub.ActivityPubController
  12. alias Pleroma.Web.ActivityPub.Visibility
  13. alias Pleroma.Web.Endpoint
  14. alias Pleroma.Web.Metadata.PlayerView
  15. alias Pleroma.Web.Router
  16. plug(Pleroma.Plugs.EnsureAuthenticatedPlug,
  17. unless_func: &Pleroma.Web.FederatingPlug.federating?/1
  18. )
  19. plug(
  20. RateLimiter,
  21. [name: :ap_routes, params: ["uuid"]] when action in [:object, :activity]
  22. )
  23. plug(
  24. Pleroma.Plugs.SetFormatPlug
  25. when action in [:object, :activity, :notice]
  26. )
  27. action_fallback(:errors)
  28. def object(%{assigns: %{format: format}} = conn, _params)
  29. when format in ["json", "activity+json"] do
  30. ActivityPubController.call(conn, :object)
  31. end
  32. def object(%{assigns: %{format: format}} = conn, _params) do
  33. with id <- Endpoint.url() <> conn.request_path,
  34. {_, %Activity{} = activity} <-
  35. {:activity, Activity.get_create_by_object_ap_id_with_object(id)},
  36. {_, true} <- {:public?, Visibility.is_public?(activity)} do
  37. case format do
  38. _ -> redirect(conn, to: "/notice/#{activity.id}")
  39. end
  40. else
  41. reason when reason in [{:public?, false}, {:activity, nil}] ->
  42. {:error, :not_found}
  43. e ->
  44. e
  45. end
  46. end
  47. def activity(%{assigns: %{format: format}} = conn, _params)
  48. when format in ["json", "activity+json"] do
  49. ActivityPubController.call(conn, :activity)
  50. end
  51. def activity(%{assigns: %{format: format}} = conn, _params) do
  52. with id <- Endpoint.url() <> conn.request_path,
  53. {_, %Activity{} = activity} <- {:activity, Activity.normalize(id)},
  54. {_, true} <- {:public?, Visibility.is_public?(activity)} do
  55. case format do
  56. _ -> redirect(conn, to: "/notice/#{activity.id}")
  57. end
  58. else
  59. reason when reason in [{:public?, false}, {:activity, nil}] ->
  60. {:error, :not_found}
  61. e ->
  62. e
  63. end
  64. end
  65. def notice(%{assigns: %{format: format}} = conn, %{"id" => id}) do
  66. with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id_with_object(id)},
  67. {_, true} <- {:public?, Visibility.is_public?(activity)},
  68. %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
  69. cond do
  70. format in ["json", "activity+json"] ->
  71. if activity.local do
  72. %{data: %{"id" => redirect_url}} = Object.normalize(activity)
  73. redirect(conn, external: redirect_url)
  74. else
  75. {:error, :not_found}
  76. end
  77. activity.data["type"] == "Create" ->
  78. %Object{} = object = Object.normalize(activity)
  79. RedirectController.redirector_with_meta(
  80. conn,
  81. %{
  82. activity_id: activity.id,
  83. object: object,
  84. url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
  85. user: user
  86. }
  87. )
  88. true ->
  89. RedirectController.redirector(conn, nil)
  90. end
  91. else
  92. reason when reason in [{:public?, false}, {:activity, nil}] ->
  93. conn
  94. |> put_status(404)
  95. |> RedirectController.redirector(nil, 404)
  96. e ->
  97. e
  98. end
  99. end
  100. # Returns an HTML embedded <audio> or <video> player suitable for embed iframes.
  101. def notice_player(conn, %{"id" => id}) do
  102. with %Activity{data: %{"type" => "Create"}} = activity <- Activity.get_by_id_with_object(id),
  103. true <- Visibility.is_public?(activity),
  104. %Object{} = object <- Object.normalize(activity),
  105. %{data: %{"attachment" => [%{"url" => [url | _]} | _]}} <- object,
  106. true <- String.starts_with?(url["mediaType"], ["audio", "video"]) do
  107. conn
  108. |> put_layout(:metadata_player)
  109. |> put_resp_header("x-frame-options", "ALLOW")
  110. |> put_resp_header(
  111. "content-security-policy",
  112. "default-src 'none';style-src 'self' 'unsafe-inline';img-src 'self' data: https:; media-src 'self' https:;"
  113. )
  114. |> put_view(PlayerView)
  115. |> render("player.html", url)
  116. else
  117. _error ->
  118. conn
  119. |> put_status(404)
  120. |> RedirectController.redirector(nil, 404)
  121. end
  122. end
  123. defp errors(conn, {:error, :not_found}) do
  124. render_error(conn, :not_found, "Not found")
  125. end
  126. defp errors(conn, {:fetch_user, nil}), do: errors(conn, {:error, :not_found})
  127. defp errors(conn, _) do
  128. render_error(conn, :internal_server_error, "Something went wrong")
  129. end
  130. end