logo

pleroma

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

frontend_static.ex (2892B)


  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.Plugs.FrontendStatic do
  5. require Pleroma.Constants
  6. @frontend_cookie_name "preferred_frontend"
  7. @moduledoc """
  8. This is a shim to call `Plug.Static` but with runtime `from` configuration`. It dispatches to the different frontends.
  9. """
  10. @behaviour Plug
  11. defp instance_static_path do
  12. Pleroma.Config.get([:instance, :static_dir], "instance/static")
  13. end
  14. def file_path(path, frontend_type \\ :primary)
  15. def file_path(path, frontend_type) when is_atom(frontend_type) do
  16. if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
  17. Path.join([
  18. instance_static_path(),
  19. "frontends",
  20. configuration["name"],
  21. configuration["ref"],
  22. path
  23. ])
  24. else
  25. nil
  26. end
  27. end
  28. def file_path(path, frontend_type) when is_binary(frontend_type) do
  29. Path.join([
  30. instance_static_path(),
  31. "frontends",
  32. frontend_type,
  33. path
  34. ])
  35. end
  36. def init(opts) do
  37. opts
  38. |> Keyword.put(:from, "__unconfigured_frontend_static_plug")
  39. |> Plug.Static.init()
  40. |> Map.put(:frontend_type, opts[:frontend_type])
  41. end
  42. def call(conn, opts) do
  43. with false <- api_route?(conn.path_info),
  44. false <- invalid_path?(conn.path_info),
  45. fallback_frontend_type <- Map.get(opts, :frontend_type, :primary),
  46. frontend_type <- preferred_or_fallback(conn, fallback_frontend_type),
  47. path when not is_nil(path) <- file_path("", frontend_type) do
  48. call_static(conn, opts, path)
  49. else
  50. _ ->
  51. conn
  52. end
  53. end
  54. def preferred_frontend(conn) do
  55. %{req_cookies: cookies} =
  56. conn
  57. |> Plug.Conn.fetch_cookies()
  58. Map.get(cookies, @frontend_cookie_name)
  59. end
  60. # Only override primary frontend
  61. def preferred_or_fallback(conn, :primary) do
  62. case preferred_frontend(conn) do
  63. nil ->
  64. :primary
  65. frontend ->
  66. if Enum.member?(Pleroma.Config.get([:frontends, :pickable], []), frontend) do
  67. frontend
  68. else
  69. :primary
  70. end
  71. end
  72. end
  73. def preferred_or_fallback(_conn, fallback), do: fallback
  74. defp invalid_path?(list) do
  75. invalid_path?(list, :binary.compile_pattern(["/", "\\", ":", "\0"]))
  76. end
  77. defp invalid_path?([h | _], _match) when h in [".", "..", ""], do: true
  78. defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t)
  79. defp invalid_path?([], _match), do: false
  80. defp api_route?([]), do: false
  81. defp api_route?([h | t]) do
  82. api_routes = Pleroma.Web.Router.get_api_routes()
  83. if h in api_routes, do: true, else: api_route?(t)
  84. end
  85. defp call_static(conn, opts, from) do
  86. opts = Map.put(opts, :from, from)
  87. Plug.Static.call(conn, opts)
  88. end
  89. end