aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma')
-rw-r--r--lib/pleroma/emails/user_email.ex2
-rw-r--r--lib/pleroma/frontend.ex56
-rw-r--r--lib/pleroma/plugs/frontend_plug.ex11
-rw-r--r--lib/pleroma/plugs/frontend_static.ex2
-rw-r--r--lib/pleroma/plugs/instance_static.ex11
-rw-r--r--lib/pleroma/web/controller/frontend/headless_controller.ex9
-rw-r--r--lib/pleroma/web/controller/frontend/kenoma_controller.ex4
-rw-r--r--lib/pleroma/web/controller/frontend/pleroma_controller.ex4
-rw-r--r--lib/pleroma/web/controller/frontend_controller.ex131
-rw-r--r--lib/pleroma/web/endpoint.ex1
-rw-r--r--lib/pleroma/web/fallback_redirect_controller.ex108
-rw-r--r--lib/pleroma/web/feed/user_controller.ex5
-rw-r--r--lib/pleroma/web/ostatus/ostatus_controller.ex26
-rw-r--r--lib/pleroma/web/preload/instance.ex13
-rw-r--r--lib/pleroma/web/router.ex12
-rw-r--r--lib/pleroma/web/web.ex2
16 files changed, 247 insertions, 150 deletions
diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex
index 313533859..1a1f6fb4b 100644
--- a/lib/pleroma/emails/user_email.ex
+++ b/lib/pleroma/emails/user_email.ex
@@ -52,7 +52,7 @@ defmodule Pleroma.Emails.UserEmail do
to_name \\ nil
) do
registration_url =
- Router.Helpers.redirect_url(
+ Router.Helpers.frontend_url(
Endpoint,
:registration_page,
user_invite_token.token
diff --git a/lib/pleroma/frontend.ex b/lib/pleroma/frontend.ex
new file mode 100644
index 000000000..646a0c806
--- /dev/null
+++ b/lib/pleroma/frontend.ex
@@ -0,0 +1,56 @@
+defmodule Pleroma.Frontend do
+ @type frontend_kind :: :primary
+
+ def get_config(frontend \\ :primary)
+
+ def get_config(:primary) do
+ primary_fe_config = Pleroma.Config.get([:frontends, :primary], %{"name" => "pleroma"})
+
+ {config, controller} =
+ if primary_fe_config["name"] == "none" do
+ {%{}, Pleroma.Web.Frontend.HeadlessController}
+ else
+ {primary_fe_config,
+ Module.concat([
+ Pleroma.Web.Frontend,
+ String.capitalize(primary_fe_config["name"]) <> "Controller"
+ ])}
+ end
+
+ %{"config" => config, "controller" => controller}
+ end
+
+ @spec file_path(String.t(), frontend_kind()) :: {:ok, String.t()} | {:error, String.t()}
+ def file_path(file, kind \\ :primary) do
+ config = get_config(kind)
+
+ instance_static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static")
+
+ frontend_path =
+ case config["config"] do
+ %{"name" => name, "ref" => ref} ->
+ Path.join([instance_static_dir, "frontends", name, ref, file])
+
+ _ ->
+ false
+ end
+
+ instance_path = Path.join([instance_static_dir, file])
+ priv_path = Application.app_dir(:pleroma, ["priv", "static", file])
+
+ cond do
+ File.exists?(instance_path) ->
+ {:ok, instance_path}
+
+ frontend_path && File.exists?(frontend_path) ->
+ {:ok, frontend_path}
+
+ File.exists?(priv_path) ->
+ {:ok, priv_path}
+
+ true ->
+ {:error,
+ "File #{file} not found in #{inspect([instance_path, frontend_path, priv_path])}"}
+ end
+ end
+end
diff --git a/lib/pleroma/plugs/frontend_plug.ex b/lib/pleroma/plugs/frontend_plug.ex
new file mode 100644
index 000000000..b6bc23ae7
--- /dev/null
+++ b/lib/pleroma/plugs/frontend_plug.ex
@@ -0,0 +1,11 @@
+defmodule Pleroma.Plugs.FrontendPlug do
+ import Plug.Conn
+
+ @behaviour Plug
+
+ def init(opts), do: opts
+
+ def call(conn, _opts) do
+ put_private(conn, :frontend, Pleroma.Frontend.get_config())
+ end
+end
diff --git a/lib/pleroma/plugs/frontend_static.ex b/lib/pleroma/plugs/frontend_static.ex
index f549ca75f..815f3bb20 100644
--- a/lib/pleroma/plugs/frontend_static.ex
+++ b/lib/pleroma/plugs/frontend_static.ex
@@ -21,8 +21,6 @@ defmodule Pleroma.Plugs.FrontendStatic do
configuration["ref"],
path
])
- else
- nil
end
end
diff --git a/lib/pleroma/plugs/instance_static.ex b/lib/pleroma/plugs/instance_static.ex
index 0fb57e422..bb813a41a 100644
--- a/lib/pleroma/plugs/instance_static.ex
+++ b/lib/pleroma/plugs/instance_static.ex
@@ -12,17 +12,6 @@ defmodule Pleroma.Plugs.InstanceStatic do
"""
@behaviour Plug
- def file_path(path) do
- instance_path =
- Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
-
- 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
-
def init(opts) do
opts
|> Keyword.put(:from, "__unconfigured_instance_static_plug")
diff --git a/lib/pleroma/web/controller/frontend/headless_controller.ex b/lib/pleroma/web/controller/frontend/headless_controller.ex
new file mode 100644
index 000000000..fe60c05dc
--- /dev/null
+++ b/lib/pleroma/web/controller/frontend/headless_controller.ex
@@ -0,0 +1,9 @@
+defmodule Pleroma.Web.Frontend.HeadlessController do
+ use Pleroma.Web, :controller
+
+ def fallback(conn, _params) do
+ conn
+ |> put_status(404)
+ |> text("")
+ end
+end
diff --git a/lib/pleroma/web/controller/frontend/kenoma_controller.ex b/lib/pleroma/web/controller/frontend/kenoma_controller.ex
new file mode 100644
index 000000000..dbd487e7e
--- /dev/null
+++ b/lib/pleroma/web/controller/frontend/kenoma_controller.ex
@@ -0,0 +1,4 @@
+defmodule Pleroma.Web.Frontend.KenomaController do
+ use Pleroma.Web, :controller
+ use Pleroma.Web.FrontendController
+end
diff --git a/lib/pleroma/web/controller/frontend/pleroma_controller.ex b/lib/pleroma/web/controller/frontend/pleroma_controller.ex
new file mode 100644
index 000000000..18a376e6b
--- /dev/null
+++ b/lib/pleroma/web/controller/frontend/pleroma_controller.ex
@@ -0,0 +1,4 @@
+defmodule Pleroma.Web.Frontend.PleromaController do
+ use Pleroma.Web, :controller
+ use Pleroma.Web.FrontendController
+end
diff --git a/lib/pleroma/web/controller/frontend_controller.ex b/lib/pleroma/web/controller/frontend_controller.ex
new file mode 100644
index 000000000..2e9082db1
--- /dev/null
+++ b/lib/pleroma/web/controller/frontend_controller.ex
@@ -0,0 +1,131 @@
+defmodule Pleroma.Web.FrontendController do
+ use Pleroma.Web, :controller
+
+ defmacro __using__(_opts) do
+ quote do
+ require Logger
+ alias Pleroma.User
+
+ def fallback(conn, _params) do
+ conn
+ |> put_status(404)
+ |> text("Not found")
+ end
+
+ def registration_page(conn, params) do
+ index(conn, params)
+ end
+
+ def api_not_implemented(conn, _params) do
+ conn
+ |> put_status(404)
+ |> json(%{error: "Not implemented"})
+ end
+
+ def empty(conn, _params) do
+ conn
+ |> put_status(204)
+ |> text("")
+ end
+
+ def index(conn, _params) do
+ {:ok, path} = Pleroma.Frontend.file_path("index.html")
+
+ conn
+ |> put_resp_content_type("text/html")
+ |> send_file(conn.status || 200, path)
+ end
+
+ def index_with_preload(conn, %{"path" => ["pleroma", "admin"]}) do
+ redirect(conn, to: "/pleroma/admin/")
+ end
+
+ def index_with_preload(conn, params) do
+ index_with_generated_data(conn, params, [:preload])
+ end
+
+ def index_with_meta(conn, %{"maybe_nickname_or_id" => maybe_nickname_or_id} = params) do
+ with %User{} = user <- User.get_cached_by_nickname_or_id(maybe_nickname_or_id) do
+ index_with_meta(conn, %{user: user})
+ else
+ nil ->
+ index(conn, params)
+ end
+ end
+
+ def index_with_meta(conn, params) do
+ index_with_generated_data(conn, params, [:metadata, :preload])
+ end
+
+ defp index_with_generated_data(conn, params, generators) do
+ {:ok, path} = Pleroma.Frontend.file_path("index.html")
+ {:ok, index_content} = File.read(path)
+
+ generated =
+ Enum.reduce(generators, "", fn generator, acc ->
+ acc <> generate_data(conn, params, generator)
+ end)
+
+ response = String.replace(index_content, "<!--server-generated-meta-->", generated)
+
+ html(conn, response)
+ end
+
+ defp generate_data(conn, params, :preload) do
+ try do
+ Pleroma.Web.Preload.build_tags(conn, params)
+ rescue
+ e ->
+ Logger.error(
+ "Preloading for #{conn.request_path} failed.\n" <>
+ Exception.format(:error, e, __STACKTRACE__)
+ )
+
+ ""
+ end
+ end
+
+ defp generate_data(conn, params, :metadata) do
+ try do
+ Pleroma.Web.Metadata.build_tags(params)
+ rescue
+ e ->
+ Logger.error(
+ "Metadata rendering for #{conn.request_path} failed.\n" <>
+ Exception.format(:error, e, __STACKTRACE__)
+ )
+
+ ""
+ end
+ end
+
+ defoverridable api_not_implemented: 2,
+ empty: 2,
+ fallback: 2,
+ index: 2,
+ index_with_preload: 2,
+ index_with_meta: 2,
+ registration_page: 2
+ end
+ end
+
+ defp action(conn, _opts) do
+ fe_config = conn.private[:frontend] || Pleroma.Frontend.get_config(:primary)
+
+ action_name = action_name(conn)
+
+ {controller, action} =
+ cond do
+ function_exported?(fe_config["controller"], action_name, 2) ->
+ {fe_config["controller"], action_name}
+
+ true ->
+ {fe_config["controller"], :fallback}
+ end
+
+ conn
+ |> put_private(:frontend, fe_config)
+ |> put_view(Phoenix.Controller.__view__(controller))
+ |> controller.call(controller.init(action))
+ end
+end
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index 527fb288d..22dfe8298 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -13,6 +13,7 @@ defmodule Pleroma.Web.Endpoint do
plug(CORSPlug)
plug(Pleroma.Plugs.HTTPSecurityPlug)
plug(Pleroma.Plugs.UploadedMedia)
+ plug(Pleroma.Plugs.FrontendPlug)
@static_cache_control "public, no-cache"
diff --git a/lib/pleroma/web/fallback_redirect_controller.ex b/lib/pleroma/web/fallback_redirect_controller.ex
deleted file mode 100644
index 431ad5485..000000000
--- a/lib/pleroma/web/fallback_redirect_controller.ex
+++ /dev/null
@@ -1,108 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Fallback.RedirectController do
- use Pleroma.Web, :controller
-
- require Logger
-
- alias Pleroma.User
- alias Pleroma.Web.Metadata
- alias Pleroma.Web.Preload
-
- def api_not_implemented(conn, _params) do
- conn
- |> put_status(404)
- |> json(%{error: "Not implemented"})
- end
-
- def redirector(conn, _params, code \\ 200) do
- conn
- |> put_resp_content_type("text/html")
- |> send_file(code, index_file_path())
- end
-
- def redirector_with_meta(conn, %{"maybe_nickname_or_id" => maybe_nickname_or_id} = params) do
- with %User{} = user <- User.get_cached_by_nickname_or_id(maybe_nickname_or_id) do
- redirector_with_meta(conn, %{user: user})
- else
- nil ->
- redirector(conn, params)
- end
- end
-
- def redirector_with_meta(conn, params) do
- {:ok, index_content} = File.read(index_file_path())
-
- tags = build_tags(conn, params)
- preloads = preload_data(conn, params)
-
- response =
- index_content
- |> String.replace("<!--server-generated-meta-->", tags <> preloads)
-
- conn
- |> put_resp_content_type("text/html")
- |> send_resp(200, response)
- end
-
- def redirector_with_preload(conn, %{"path" => ["pleroma", "admin"]}) do
- redirect(conn, to: "/pleroma/admin/")
- end
-
- def redirector_with_preload(conn, params) do
- {:ok, index_content} = File.read(index_file_path())
- preloads = preload_data(conn, params)
-
- response =
- index_content
- |> String.replace("<!--server-generated-meta-->", preloads)
-
- conn
- |> put_resp_content_type("text/html")
- |> send_resp(200, response)
- end
-
- def registration_page(conn, params) do
- redirector(conn, params)
- end
-
- def empty(conn, _params) do
- conn
- |> put_status(204)
- |> text("")
- end
-
- defp index_file_path do
- Pleroma.Plugs.InstanceStatic.file_path("index.html")
- end
-
- defp build_tags(conn, params) do
- try do
- Metadata.build_tags(params)
- rescue
- e ->
- Logger.error(
- "Metadata rendering for #{conn.request_path} failed.\n" <>
- Exception.format(:error, e, __STACKTRACE__)
- )
-
- ""
- end
- end
-
- defp preload_data(conn, params) do
- try do
- Preload.build_tags(conn, params)
- rescue
- e ->
- Logger.error(
- "Preloading for #{conn.request_path} failed.\n" <>
- Exception.format(:error, e, __STACKTRACE__)
- )
-
- ""
- end
- end
-end
diff --git a/lib/pleroma/web/feed/user_controller.ex b/lib/pleroma/web/feed/user_controller.ex
index 9cd334a33..7118c087c 100644
--- a/lib/pleroma/web/feed/user_controller.ex
+++ b/lib/pleroma/web/feed/user_controller.ex
@@ -5,7 +5,6 @@
defmodule Pleroma.Web.Feed.UserController do
use Pleroma.Web, :controller
- alias Fallback.RedirectController
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.ActivityPubController
@@ -17,7 +16,9 @@ defmodule Pleroma.Web.Feed.UserController do
def feed_redirect(%{assigns: %{format: "html"}} = conn, %{"nickname" => nickname}) do
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname_or_id(nickname)} do
- RedirectController.redirector_with_meta(conn, %{user: user})
+ conn
+ |> Map.put(:params, %{user: user})
+ |> Pleroma.Web.FrontendController.call(:index_with_meta)
end
end
diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex
index de1b0b3f0..a1b8a3adc 100644
--- a/lib/pleroma/web/ostatus/ostatus_controller.ex
+++ b/lib/pleroma/web/ostatus/ostatus_controller.ex
@@ -5,7 +5,6 @@
defmodule Pleroma.Web.OStatus.OStatusController do
use Pleroma.Web, :controller
- alias Fallback.RedirectController
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Plugs.RateLimiter
@@ -91,24 +90,25 @@ defmodule Pleroma.Web.OStatus.OStatusController do
activity.data["type"] == "Create" ->
%Object{} = object = Object.normalize(activity)
- RedirectController.redirector_with_meta(
- conn,
- %{
- activity_id: activity.id,
- object: object,
- url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
- user: user
- }
- )
+ params = %{
+ activity_id: activity.id,
+ object: object,
+ url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
+ user: user
+ }
+
+ conn
+ |> Map.put(:params, params)
+ |> Pleroma.Web.FrontendController.call(:index_with_meta)
true ->
- RedirectController.redirector(conn, nil)
+ Pleroma.Web.FrontendController.call(conn, :index)
end
else
reason when reason in [{:public?, false}, {:activity, nil}] ->
conn
|> put_status(404)
- |> RedirectController.redirector(nil, 404)
+ |> Pleroma.Web.FrontendController.call(:index)
e ->
e
@@ -135,7 +135,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
_error ->
conn
|> put_status(404)
- |> RedirectController.redirector(nil, 404)
+ |> Pleroma.Web.FrontendController.call(:index)
end
end
diff --git a/lib/pleroma/web/preload/instance.ex b/lib/pleroma/web/preload/instance.ex
index 50d1f3382..ad8f33f6f 100644
--- a/lib/pleroma/web/preload/instance.ex
+++ b/lib/pleroma/web/preload/instance.ex
@@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.Instance do
- alias Pleroma.Plugs.InstanceStatic
alias Pleroma.Web.MastodonAPI.InstanceView
alias Pleroma.Web.Nodeinfo.Nodeinfo
alias Pleroma.Web.Preload.Providers.Provider
@@ -28,13 +27,13 @@ defmodule Pleroma.Web.Preload.Providers.Instance do
end
defp build_panel_tag(acc) do
- instance_path = InstanceStatic.file_path(@panel_url |> to_string())
+ case Pleroma.Frontend.file_path(@panel_url |> to_string()) do
+ {:ok, file} ->
+ panel_data = File.read!(file)
+ Map.put(acc, @panel_url, panel_data)
- if File.exists?(instance_path) do
- panel_data = File.read!(instance_path)
- Map.put(acc, @panel_url, panel_data)
- else
- acc
+ _ ->
+ acc
end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index c6433cc53..1e3ecf298 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -715,12 +715,12 @@ defmodule Pleroma.Web.Router do
get("/check_password", MongooseIMController, :check_password)
end
- scope "/", Fallback do
- get("/registration/:token", RedirectController, :registration_page)
- get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
- get("/api*path", RedirectController, :api_not_implemented)
- get("/*path", RedirectController, :redirector_with_preload)
+ scope "/", Pleroma.Web do
+ get("/registration/:token", FrontendController, :registration_page)
+ get("/:maybe_nickname_or_id", FrontendController, :index_with_meta)
+ get("/api*path", FrontendController, :api_not_implemented)
+ get("/*path", FrontendController, :index_with_preload)
- options("/*path", RedirectController, :empty)
+ options("/*path", FrontendController, :empty)
end
end
diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex
index 4f9281851..920d68461 100644
--- a/lib/pleroma/web/web.ex
+++ b/lib/pleroma/web/web.ex
@@ -120,6 +120,8 @@ defmodule Pleroma.Web do
conn
end
end
+
+ defoverridable(action: 2)
end
end