2020-09-12 19:43:16 +02:00
|
|
|
defmodule PhilomenaWeb.CheckCaptchaPlug do
|
|
|
|
import Plug.Conn
|
|
|
|
import Phoenix.Controller
|
|
|
|
|
|
|
|
def init([]), do: false
|
|
|
|
|
|
|
|
def call(conn, _opts) do
|
|
|
|
case captcha_enabled?() do
|
|
|
|
true -> maybe_check_captcha(conn, conn.assigns.current_user)
|
|
|
|
false -> conn
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defp maybe_check_captcha(conn, nil) do
|
|
|
|
case valid_solution?(conn.params) do
|
|
|
|
true ->
|
|
|
|
conn
|
|
|
|
|
|
|
|
false ->
|
|
|
|
conn
|
|
|
|
|> put_flash(
|
2023-11-23 17:07:49 +01:00
|
|
|
:warning,
|
2020-09-12 19:43:16 +02:00
|
|
|
"There was an error verifying you're not a robot. Please try again."
|
|
|
|
)
|
2020-09-28 05:47:32 +02:00
|
|
|
|> do_failure_response(conn.assigns.ajax?)
|
2020-09-12 19:43:16 +02:00
|
|
|
|> halt()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defp maybe_check_captcha(conn, _user), do: conn
|
|
|
|
|
|
|
|
defp valid_solution?(%{"h-captcha-response" => captcha_token}) do
|
|
|
|
{:ok, %{body: body, status: 200}} =
|
|
|
|
Philomena.Http.post(
|
|
|
|
"https://hcaptcha.com/siteverify",
|
|
|
|
URI.encode_query(%{"response" => captcha_token, "secret" => hcaptcha_secret_key()}),
|
|
|
|
[{"Content-Type", "application/x-www-form-urlencoded"}]
|
|
|
|
)
|
|
|
|
|
|
|
|
body
|
|
|
|
|> Jason.decode!()
|
|
|
|
|> Map.get("success", false)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp valid_solution?(_params), do: false
|
|
|
|
|
|
|
|
defp do_failure_response(conn, true) do
|
|
|
|
conn
|
|
|
|
|> put_status(:multiple_choices)
|
|
|
|
|> text("")
|
|
|
|
end
|
|
|
|
|
|
|
|
defp do_failure_response(conn, _false) do
|
|
|
|
redirect(conn, external: conn.assigns.referrer)
|
|
|
|
end
|
|
|
|
|
|
|
|
def captcha_enabled? do
|
|
|
|
Application.get_env(:philomena, :captcha) != false
|
|
|
|
end
|
|
|
|
|
|
|
|
def hcaptcha_secret_key do
|
|
|
|
Application.get_env(:philomena, :hcaptcha_secret_key)
|
|
|
|
end
|
|
|
|
end
|