From 20c521e67b79e7bdf77c5359abc31d4c87ef92c5 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Mon, 23 Dec 2019 13:57:14 -0500 Subject: [PATCH] tor plug --- lib/philomena_web/plugs/tor_plug.ex | 38 +++++++++++++++++++++++++++++ lib/philomena_web/router.ex | 17 ++++++++++--- 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 lib/philomena_web/plugs/tor_plug.ex diff --git a/lib/philomena_web/plugs/tor_plug.ex b/lib/philomena_web/plugs/tor_plug.ex new file mode 100644 index 00000000..11541e02 --- /dev/null +++ b/lib/philomena_web/plugs/tor_plug.ex @@ -0,0 +1,38 @@ +defmodule PhilomenaWeb.TorPlug do + @moduledoc """ + This plug ensures that a Tor user is authenticated. + + ## Example + + plug PhilomenaWeb.TorPlug + """ + alias PhilomenaWeb.Router.Helpers, as: Routes + alias Phoenix.Controller + alias Plug.Conn + + @doc false + @spec init(any()) :: any() + def init(opts), do: opts + + @doc false + @spec call(Conn.t(), any()) :: Conn.t() + def call(conn, _opts) do + onion? = onion?(conn.host) + user = conn.assigns.current_user + ip = conn.remote_ip + + maybe_redirect(conn, user, ip, onion?) + end + + def maybe_redirect(conn, nil, {127, 0, 0, 1}, true) do + conn + |> Controller.redirect(to: Routes.pow_session_path(conn, :new)) + |> Conn.halt() + end + def maybe_redirect(conn, _user, _ip, _onion?), do: conn + + # This is allowed, because nginx won't forward the request + # to the appserver if the hostname isn't in a specific list + # of allowed hostnames. + def onion?(host), do: String.ends_with?(host, ".onion") +end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 1240c22d..00d80330 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -44,6 +44,10 @@ defmodule PhilomenaWeb.Router do plug PhilomenaWeb.TotpPlug end + pipeline :ensure_tor_authorized do + plug PhilomenaWeb.TorPlug + end + pipeline :ensure_not_banned do plug PhilomenaWeb.FilterBannedUsersPlug end @@ -54,15 +58,20 @@ defmodule PhilomenaWeb.Router do end scope "/" do - pipe_through [:browser, :ensure_totp, :ensure_not_banned] + pipe_through [:browser, :ensure_totp, :ensure_not_banned, :ensure_tor_authorized] pow_registration_routes() end scope "/" do pipe_through [:browser, :ensure_totp] - + pow_session_routes() + end + + scope "/" do + pipe_through [:browser, :ensure_totp, :ensure_tor_authorized] + pow_extension_routes() end @@ -85,7 +94,7 @@ defmodule PhilomenaWeb.Router do end scope "/api/v1/json", PhilomenaWeb.Api.Json, as: :api_json do - pipe_through [:accepts_json, :api] + pipe_through [:accepts_json, :api, :ensure_tor_authorized] resources "/images", ImageController, only: [:show] scope "/search", Search, as: :search do @@ -270,7 +279,7 @@ defmodule PhilomenaWeb.Router do end scope "/", PhilomenaWeb do - pipe_through [:browser, :ensure_totp] + pipe_through [:browser, :ensure_totp, :ensure_tor_authorized] get "/", ActivityController, :index