Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

o_status_controller.ex 4.7KB

4 yıl önce
5 yıl önce
4 yıl önce
6 yıl önce
6 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 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(Pleroma.Web.Plugs.EnsureAuthenticatedPlug,
  17. unless_func: &Pleroma.Web.Plugs.FederatingPlug.federating?/1
  18. )
  19. plug(
  20. RateLimiter,
  21. [name: :ap_routes, params: ["uuid"]] when action in [:object, :activity]
  22. )
  23. plug(
  24. Pleroma.Web.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