FrontendStatic: Add plug to serve frontends based on configuration.
This commit is contained in:
		
							parent
							
								
									14c28dcbd1
								
							
						
					
					
						commit
						ad5c42628a
					
				
					 5 changed files with 122 additions and 5 deletions
				
			
		
							
								
								
									
										54
									
								
								lib/pleroma/plugs/frontend_static.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								lib/pleroma/plugs/frontend_static.ex
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Plugs.FrontendStatic do
 | 
			
		||||
  require Pleroma.Constants
 | 
			
		||||
 | 
			
		||||
  @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")
 | 
			
		||||
 | 
			
		||||
      Path.join([
 | 
			
		||||
        instance_static_path,
 | 
			
		||||
        "frontends",
 | 
			
		||||
        configuration["name"],
 | 
			
		||||
        configuration["ref"],
 | 
			
		||||
        path
 | 
			
		||||
      ])
 | 
			
		||||
    else
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def init(opts) do
 | 
			
		||||
    opts
 | 
			
		||||
    |> Keyword.put(:from, "__unconfigured_frontend_static_plug")
 | 
			
		||||
    |> Plug.Static.init()
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def call(conn, opts) do
 | 
			
		||||
    frontend_type = Map.get(opts, :frontend_type, :primary)
 | 
			
		||||
    path = file_path("", frontend_type)
 | 
			
		||||
 | 
			
		||||
    if path do
 | 
			
		||||
      conn
 | 
			
		||||
      |> call_static(opts, path)
 | 
			
		||||
    else
 | 
			
		||||
      conn
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp call_static(conn, opts, from) do
 | 
			
		||||
    opts =
 | 
			
		||||
      opts
 | 
			
		||||
      |> Map.put(:from, from)
 | 
			
		||||
 | 
			
		||||
    Plug.Static.call(conn, opts)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -16,11 +16,11 @@ def file_path(path) do
 | 
			
		|||
    instance_path =
 | 
			
		||||
      Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
 | 
			
		||||
 | 
			
		||||
    if File.exists?(instance_path) do
 | 
			
		||||
      instance_path
 | 
			
		||||
    else
 | 
			
		||||
    frontend_path = Pleroma.Plugs.FrontendStatic.file_path(path, :primary)
 | 
			
		||||
 | 
			
		||||
    (File.exists?(instance_path) && instance_path) ||
 | 
			
		||||
      (frontend_path && File.exists?(frontend_path) && frontend_path) ||
 | 
			
		||||
      Path.join(Application.app_dir(:pleroma, "priv/static/"), path)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def init(opts) do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,17 @@ defmodule Pleroma.Web.Endpoint do
 | 
			
		|||
    }
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # Careful! No `only` restriction here, as we don't know what frontends contain.
 | 
			
		||||
  plug(Pleroma.Plugs.FrontendStatic,
 | 
			
		||||
    at: "/",
 | 
			
		||||
    frontend_type: :primary,
 | 
			
		||||
    gzip: true,
 | 
			
		||||
    cache_control_for_etags: @static_cache_control,
 | 
			
		||||
    headers: %{
 | 
			
		||||
      "cache-control" => @static_cache_control
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # Serve at "/" the static files from "priv/static" directory.
 | 
			
		||||
  #
 | 
			
		||||
  # You should set gzip to true if you are running phoenix.digest
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								test/plugs/frontend_static_test.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								test/plugs/frontend_static_test.exs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.FrontendStaticPlugTest do
 | 
			
		||||
  use Pleroma.Web.ConnCase
 | 
			
		||||
 | 
			
		||||
  @dir "test/tmp/instance_static"
 | 
			
		||||
 | 
			
		||||
  setup do
 | 
			
		||||
    File.mkdir_p!(@dir)
 | 
			
		||||
    on_exit(fn -> File.rm_rf(@dir) end)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  setup do: clear_config([:instance, :static_dir], @dir)
 | 
			
		||||
 | 
			
		||||
  test "overrides existing static files", %{conn: conn} do
 | 
			
		||||
    name = "pelmora"
 | 
			
		||||
    ref = "uguu"
 | 
			
		||||
 | 
			
		||||
    clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
 | 
			
		||||
    path = "#{@dir}/frontends/#{name}/#{ref}"
 | 
			
		||||
 | 
			
		||||
    File.mkdir_p!(path)
 | 
			
		||||
    File.write!("#{path}/index.html", "from frontend plug")
 | 
			
		||||
 | 
			
		||||
    index = get(conn, "/")
 | 
			
		||||
    assert html_response(index, 200) == "from frontend plug"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.RuntimeStaticPlugTest do
 | 
			
		||||
defmodule Pleroma.Web.InstanceStaticPlugTest do
 | 
			
		||||
  use Pleroma.Web.ConnCase
 | 
			
		||||
 | 
			
		||||
  @dir "test/tmp/instance_static"
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +24,28 @@ test "overrides index" do
 | 
			
		|||
    assert html_response(index, 200) == "hello world"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "also overrides frontend files", %{conn: conn} do
 | 
			
		||||
    name = "pelmora"
 | 
			
		||||
    ref = "uguu"
 | 
			
		||||
 | 
			
		||||
    clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
 | 
			
		||||
 | 
			
		||||
    bundled_index = get(conn, "/")
 | 
			
		||||
    refute html_response(bundled_index, 200) == "from frontend plug"
 | 
			
		||||
 | 
			
		||||
    path = "#{@dir}/frontends/#{name}/#{ref}"
 | 
			
		||||
    File.mkdir_p!(path)
 | 
			
		||||
    File.write!("#{path}/index.html", "from frontend plug")
 | 
			
		||||
 | 
			
		||||
    index = get(conn, "/")
 | 
			
		||||
    assert html_response(index, 200) == "from frontend plug"
 | 
			
		||||
 | 
			
		||||
    File.write!(@dir <> "/index.html", "from instance static")
 | 
			
		||||
 | 
			
		||||
    index = get(conn, "/")
 | 
			
		||||
    assert html_response(index, 200) == "from instance static"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "overrides any file in static/static" do
 | 
			
		||||
    bundled_index = get(build_conn(), "/static/terms-of-service.html")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue