logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

o_status_controller.ex (4552B)


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