From 6099878ac56f2c75ced80bccde2868b5ce9226b8 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 15 Nov 2020 19:49:38 +0100 Subject: [PATCH] Allow Ueberauth providers to be used at runtime Close #504 Signed-off-by: Thomas Citharel --- lib/web/controllers/auth_controller.ex | 53 +++++++++++++++++-- test/web/controllers/auth_controller_test.exs | 6 +++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/lib/web/controllers/auth_controller.ex b/lib/web/controllers/auth_controller.ex index 9e6c9d62c..57bf358b5 100644 --- a/lib/web/controllers/auth_controller.ex +++ b/lib/web/controllers/auth_controller.ex @@ -9,8 +9,15 @@ defmodule Mobilizon.Web.AuthController do plug(Ueberauth) - def request(conn, %{"provider" => provider} = _params) do - redirect(conn, to: "/login?code=Login Provider not found&provider=#{provider}") + def request(conn, %{"provider" => provider_name} = _params) do + case provider_config(provider_name) do + {:ok, provider_config} -> + conn + |> Ueberauth.run_request(provider_name, provider_config) + + {:error, error} -> + redirect_to_error(conn, error, provider_name) + end end def callback( @@ -19,7 +26,7 @@ defmodule Mobilizon.Web.AuthController do ) do Logger.warn("Unable to login user with #{provider} #{inspect(fails)}") - redirect(conn, to: "/login?code=Error with Login Provider&provider=#{provider}") + redirect_to_error(conn, :unknown_error, provider) end def callback( @@ -59,7 +66,19 @@ defmodule Mobilizon.Web.AuthController do else err -> Logger.warn("Unable to login user \"#{email}\" #{inspect(err)}") - redirect(conn, to: "/login?code=Error with Login Provider&provider=#{strategy}") + redirect_to_error(conn, :unknown_error, strategy) + end + end + + def callback(conn, %{"provider" => provider_name} = params) do + case provider_config(provider_name) do + {:ok, provider_config} -> + conn + |> Ueberauth.run_callback(provider_name, provider_config) + |> callback(params) + + {:error, error} -> + redirect_to_error(conn, error, provider_name) end end @@ -79,4 +98,30 @@ defmodule Mobilizon.Web.AuthController do do: email defp email_from_ueberauth(_), do: nil + + defp provider_config(provider_name) do + with ueberauth when is_list(ueberauth) <- Application.get_env(:ueberauth, Ueberauth), + providers when is_list(providers) <- Keyword.get(ueberauth, :providers), + providers_keys <- providers |> Keyword.keys() |> Enum.map(&Atom.to_string/1), + {:supported, true} <- {:supported, provider_name in providers_keys}, + provider_name <- String.to_existing_atom(provider_name), + provider_config <- Keyword.get(providers, provider_name) do + {:ok, provider_config} + else + {:supported, false} -> + {:error, :not_supported} + + _ -> + {:error, :unknown_error} + end + end + + @spec redirect_to_error(Plug.Conn.t(), atom(), String.t()) :: Plug.Conn.t() + defp redirect_to_error(conn, :not_supported, provider_name) do + redirect(conn, to: "/login?code=Login Provider not found&provider=#{provider_name}") + end + + defp redirect_to_error(conn, :unknown_error, provider_name) do + redirect(conn, to: "/login?code=Error with Login Provider&provider=#{provider_name}") + end end diff --git a/test/web/controllers/auth_controller_test.exs b/test/web/controllers/auth_controller_test.exs index ca2bad443..f002bcf92 100644 --- a/test/web/controllers/auth_controller_test.exs +++ b/test/web/controllers/auth_controller_test.exs @@ -5,6 +5,12 @@ defmodule Mobilizon.Web.AuthControllerTest do @email "someone@somewhere.tld" + setup do + Application.put_env(:ueberauth, Ueberauth, + providers: [twitter: {Ueberauth.Strategy.Twitter, []}] + ) + end + test "login and registration", %{conn: conn} do conn =