Hello,
I am currently implementing a system, which needs blocking some locales on certain environments. I don’t know what might be wrong in my solution. They way I implemented it:
- Set environmental variable, which defines allowed locales.
- In the plug read the current locale. If the locale is not in allowed locales - put default locale and redirect to the last correct (without forbidden variable) page. If there is no correct page, redirect to the main page.
Redirects are working fine. It redirects me to the correct page (last page without forbidden locale). The problem is that after redirect the app still has forbidden locale, though I’m setting it up before redirect to correct one. Then the plug launches again and redirects me again… and again… and again…
defmodule MyAppWeb.CheckLocalePlug do
import MyApp.Gettext, only: [default_locale: 0]
def init(opts), do: opts
def call(conn, _) do
if Gettext.get_locale() in MyApp.Gettext.get_allowed_locales() do
conn
else
#inspecting Gettext.get_locale() here gives forbidden locale
Gettext.put_locale(default_locale())
#inspecting Gettext.get_locale() here gives corrected locale
conn
|> Plug.Conn.halt()
|> Plug.Conn.assign(:locale, default_locale())
|> Phoenix.Controller.redirect(to: last_allowed_path(conn))
# after redirect there is still forbidden locale :(
end
end
defp last_allowed_path(conn) do
conn
|> NavigationHistory.last_paths()
|> find_first_allowed_path()
end
defp find_first_allowed_path([]), do: "/"
defp find_first_allowed_path([head | tail]) do
maybe_locale = head |> String.split("/") |> Enum.reject(&(&1 == "")) |> List.first()
case {is_locale?(maybe_locale), is_allowed_locale?(maybe_locale)} do
{true, true} -> head
{true, false} -> find_first_allowed_path(tail)
{false, _} -> head
end)
end
defp is_locale?(maybe_locale) do
(maybe_locale in MyApp.Gettext.get_locales())
end
defp is_allowed_locale?(maybe_locale) do
(maybe_locale in MyApp.Gettext.get_allowed_locales())
end
end