From af68a42ef7841013476831e92d3841088fa875df Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Wed, 20 Mar 2019 20:25:48 +0300 Subject: [PATCH] [#923] Support for multiple OAuth consumer strategies. --- config/config.exs | 24 +++++++++------ lib/pleroma/web/oauth/oauth_controller.ex | 29 +++++++++++++------ .../templates/o_auth/o_auth/consumer.html.eex | 20 +++++-------- .../web/templates/o_auth/o_auth/show.html.eex | 1 - mix.exs | 13 +++++---- mix.lock | 1 + 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/config/config.exs b/config/config.exs index 03baf894d..7d8de5af6 100644 --- a/config/config.exs +++ b/config/config.exs @@ -381,20 +381,26 @@ base: System.get_env("LDAP_BASE") || "dc=example,dc=com", uid: System.get_env("LDAP_UID") || "cn" -config :pleroma, :auth, oauth_consumer_enabled: System.get_env("OAUTH_CONSUMER_ENABLED") == "true" +oauth_consumer_strategies = String.split(System.get_env("OAUTH_CONSUMER_STRATEGIES" || "")) + +ueberauth_providers = + for strategy <- oauth_consumer_strategies do + strategy_module_name = + System.get_env("UEBERAUTH_#{String.upcase(strategy)}_STRATEGY_MODULE") || + "Elixir.Ueberauth.Strategy.#{String.capitalize(strategy)}" + + strategy_module = String.to_atom(strategy_module_name) + {String.to_atom(strategy), {strategy_module, [callback_params: ["state"]]}} + end config :ueberauth, Ueberauth, base_path: "/oauth", - providers: [ - twitter: - {Ueberauth.Strategy.Twitter, - [callback_params: ~w[client_id redirect_uri scope scopes]]} - ] + providers: ueberauth_providers -config :ueberauth, Ueberauth.Strategy.Twitter.OAuth, - consumer_key: System.get_env("TWITTER_CONSUMER_KEY"), - consumer_secret: System.get_env("TWITTER_CONSUMER_SECRET") +config :pleroma, :auth, + oauth_consumer_strategies: oauth_consumer_strategies, + oauth_consumer_enabled: oauth_consumer_strategies != [] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index a2c62ae68..b300c96df 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -187,25 +187,25 @@ def request(conn, params) do |> redirect(to: "/") end - def callback(%{assigns: %{ueberauth_failure: failure}} = conn, %{"redirect_uri" => redirect_uri}) do + def callback(%{assigns: %{ueberauth_failure: failure}} = conn, params) do + params = callback_params(params) messages = for e <- Map.get(failure, :errors, []), do: e.message message = Enum.join(messages, "; ") conn |> put_flash(:error, "Failed to authenticate: #{message}.") - |> redirect(external: redirect_uri(conn, redirect_uri)) + |> redirect(external: redirect_uri(conn, params["redirect_uri"])) end - def callback( - conn, - %{"client_id" => client_id, "redirect_uri" => redirect_uri} = params - ) do + def callback(conn, params) do + params = callback_params(params) + with {:ok, registration} <- Authenticator.get_registration(conn, params) do user = Repo.preload(registration, :user).user auth_params = %{ - "client_id" => client_id, - "redirect_uri" => redirect_uri, + "client_id" => params["client_id"], + "redirect_uri" => params["redirect_uri"], "scopes" => oauth_scopes(params, nil) } @@ -230,10 +230,21 @@ def callback( _ -> conn |> put_flash(:error, "Failed to set up user account.") - |> redirect(external: redirect_uri(conn, redirect_uri)) + |> redirect(external: redirect_uri(conn, params["redirect_uri"])) end end + defp callback_params(%{"state" => state} = params) do + [client_id, redirect_uri, scope, state] = String.split(state, "|") + + Map.merge(params, %{ + "client_id" => client_id, + "redirect_uri" => redirect_uri, + "scope" => scope, + "state" => state + }) + end + def registration_details(conn, params) do render(conn, "register.html", %{ client_id: params["client_id"], diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex index e7251bce8..a64859a49 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -1,14 +1,10 @@ -

External OAuth Authorization

-<%= form_for @conn, o_auth_path(@conn, :request, :twitter), [method: "get"], fn f -> %> -
- <%= label f, :scope, "Permissions" %> -
- <%= text_input f, :scope, value: Enum.join(@available_scopes, " ") %> -
-
+
+
+

Sign in with external provider

- <%= hidden_input f, :client_id, value: @client_id %> - <%= hidden_input f, :redirect_uri, value: @redirect_uri %> - <%= hidden_input f, :state, value: @state%> - <%= submit "Sign in with Twitter" %> +<%= for strategy <- Pleroma.Config.get([:auth, :oauth_consumer_strategies], []) do %> + <%= form_for @conn, o_auth_path(@conn, :request, strategy), [method: "get"], fn f -> %> + <%= hidden_input f, :state, value: Enum.join([@client_id, @redirect_uri, Enum.join(@available_scopes, " "), @state], "|") %> + <%= submit "Sign in with #{String.capitalize(strategy)}" %> + <% end %> <% end %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index 2fa7837fc..b2381869a 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -37,6 +37,5 @@ <% end %> <%= if Pleroma.Config.get([:auth, :oauth_consumer_enabled]) do %> -
<%= render @view_module, "consumer.html", assigns %> <% end %> diff --git a/mix.exs b/mix.exs index 25711bc26..f7ab008ac 100644 --- a/mix.exs +++ b/mix.exs @@ -44,7 +44,7 @@ def project do def application do [ mod: {Pleroma.Application, []}, - extra_applications: [:logger, :runtime_tools, :comeonin, :ueberauth_twitter], + extra_applications: [:logger, :runtime_tools, :comeonin], included_applications: [:ex_syslogger] ] end @@ -57,6 +57,12 @@ defp elixirc_paths(_), do: ["lib"] # # Type `mix help deps` for examples and options. defp deps do + oauth_strategies = String.split(System.get_env("OAUTH_CONSUMER_STRATEGIES") || "") + + oauth_deps = + for s <- oauth_strategies, + do: {String.to_atom("ueberauth_#{s}"), ">= 0.0.0"} + [ {:phoenix, "~> 1.4.1"}, {:plug_cowboy, "~> 2.0"}, @@ -94,14 +100,11 @@ defp deps do {:floki, "~> 0.20.0"}, {:ex_syslogger, github: "slashmili/ex_syslogger", tag: "1.4.0"}, {:timex, "~> 3.5"}, - {:oauth, github: "tim/erlang-oauth"}, - # {:oauth2, "~> 0.8", override: true}, {:ueberauth, "~> 0.4"}, - {:ueberauth_twitter, "~> 0.2"}, {:auto_linker, git: "https://git.pleroma.social/pleroma/auto_linker.git", ref: "94193ca5f97c1f9fdf3d1469653e2d46fac34bcd"} - ] + ] ++ oauth_deps end # Aliases are shortcuts or tasks specific to the current project. diff --git a/mix.lock b/mix.lock index 92660b70a..6a6cee1a9 100644 --- a/mix.lock +++ b/mix.lock @@ -67,6 +67,7 @@ "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.5.17", "50793e3d85af49736701da1a040c415c97dc1caf6464112fd9bd18f425d3053b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "ueberauth": {:hex, :ueberauth, "0.5.0", "4570ec94d7f784dc4c4aa94c83391dbd9b9bd7b66baa30e95a666c5ec1b168b1", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "ueberauth_facebook": {:hex, :ueberauth_facebook, "0.8.0", "9ec8571f804dd5c06f4e305d70606b39fc0ac8a8f43ed56ebb76012a97d14729", [:mix], [{:oauth2, "~> 0.9", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm"}, "ueberauth_twitter": {:hex, :ueberauth_twitter, "0.2.4", "770ac273cc696cde986582e7a36df0923deb39fa3deff0152fbf150343809f81", [:mix], [{:httpoison, "~> 0.7", [hex: :httpoison, repo: "hexpm", optional: false]}, {:oauther, "~> 1.1", [hex: :oauther, repo: "hexpm", optional: false]}, {:poison, "~> 1.3 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.2", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, "unsafe": {:hex, :unsafe, "1.0.0", "7c21742cd05380c7875546b023481d3a26f52df8e5dfedcb9f958f322baae305", [:mix], [], "hexpm"},