X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fplugs%2Ffrontend_static.ex;h=41b8ba46b90d659a5ba17069f9a8da6eae87076b;hb=f12d3cce39e6bdfbe4aa8364ba1051a6b72155fc;hp=1b0b368138dbb6d14ba1fec9f403bddaabb915c6;hpb=24ce3249736c96686c00a10abe47659579535259;p=akkoma diff --git a/lib/pleroma/web/plugs/frontend_static.ex b/lib/pleroma/web/plugs/frontend_static.ex index 1b0b36813..41b8ba46b 100644 --- a/lib/pleroma/web/plugs/frontend_static.ex +++ b/lib/pleroma/web/plugs/frontend_static.ex @@ -1,21 +1,27 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors +# Copyright © 2017-2021 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.Plugs.FrontendStatic do require Pleroma.Constants + @frontend_cookie_name "preferred_frontend" + @moduledoc """ This is a shim to call `Plug.Static` but with runtime `from` configuration`. It dispatches to the different frontends. """ @behaviour Plug - def file_path(path, frontend_type \\ :primary) do - if configuration = Pleroma.Config.get([:frontends, frontend_type]) do - instance_static_path = Pleroma.Config.get([:instance, :static_dir], "instance/static") + defp instance_static_path do + Pleroma.Config.get([:instance, :static_dir], "instance/static") + end + def file_path(path, frontend_type \\ :primary) + + def file_path(path, frontend_type) when is_atom(frontend_type) do + if configuration = Pleroma.Config.get([:frontends, frontend_type]) do Path.join([ - instance_static_path, + instance_static_path(), "frontends", configuration["name"], configuration["ref"], @@ -26,16 +32,29 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do end end + def file_path(path, frontend_type) when is_binary(frontend_type) do + Path.join([ + instance_static_path(), + "frontends", + frontend_type, + path + ]) + end + def init(opts) do opts |> Keyword.put(:from, "__unconfigured_frontend_static_plug") |> Plug.Static.init() |> Map.put(:frontend_type, opts[:frontend_type]) + |> Map.put(:if, Keyword.get(opts, :if, true)) end def call(conn, opts) do - with false <- invalid_path?(conn.path_info), - frontend_type <- Map.get(opts, :frontend_type, :primary), + with false <- api_route?(conn.path_info), + false <- invalid_path?(conn.path_info), + true <- enabled?(opts[:if]), + fallback_frontend_type <- Map.get(opts, :frontend_type, :primary), + frontend_type <- preferred_or_fallback(conn, fallback_frontend_type), path when not is_nil(path) <- file_path("", frontend_type) do call_static(conn, opts, path) else @@ -44,6 +63,35 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do end end + def preferred_frontend(conn) do + %{req_cookies: cookies} = + conn + |> Plug.Conn.fetch_cookies() + + Map.get(cookies, @frontend_cookie_name) + end + + # Only override primary frontend + def preferred_or_fallback(conn, :primary) do + case preferred_frontend(conn) do + nil -> + :primary + + frontend -> + if Enum.member?(Pleroma.Config.get([:frontends, :pickable], []), frontend) do + frontend + else + :primary + end + end + end + + def preferred_or_fallback(_conn, fallback), do: fallback + + defp enabled?(if_opt) when is_function(if_opt), do: if_opt.() + defp enabled?(true), do: true + defp enabled?(_), do: false + defp invalid_path?(list) do invalid_path?(list, :binary.compile_pattern(["/", "\\", ":", "\0"])) end @@ -52,6 +100,13 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t) defp invalid_path?([], _match), do: false + defp api_route?([]), do: false + + defp api_route?([h | t]) do + api_routes = Pleroma.Web.Router.get_api_routes() + if h in api_routes, do: true, else: api_route?(t) + end + defp call_static(conn, opts, from) do opts = Map.put(opts, :from, from) Plug.Static.call(conn, opts)