From e4a5a2ddf1ebe95066e5525fd05e718ac8867744 Mon Sep 17 00:00:00 2001 From: Sean Callan Date: Tue, 18 Jul 2017 00:13:15 -0600 Subject: [PATCH 01/62] Update dependencies and version --- mix.exs | 6 +++--- mix.lock | 29 +++++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/mix.exs b/mix.exs index 2f67625..e545a51 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project - @version "0.5.0" + @version "0.6.0" @url "https://github.com/ueberauth/ueberauth_google" def project do @@ -25,10 +25,10 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, "~> 0.8"}, + {:oauth2, "~> 0.9"}, {:ueberauth, "~> 0.4"}, - {:credo, "~> 0.5", only: [:dev, :test]}, + {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, {:ex_doc, "~> 0.3", only: :dev}, ] diff --git a/mix.lock b/mix.lock index 7b2d242..d95b51e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,17 +1,18 @@ -%{"bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []}, - "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, - "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, optional: false]}]}, - "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, - "hackney": {:hex, :hackney, "1.6.3", "d489d7ca2d4323e307bedc4bfe684323a7bf773ecfd77938f3ee8074e488e140", [:mix, :rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, +%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, + "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, + "credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, + "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, - "oauth2": {:hex, :oauth2, "0.8.0", "9650476a695a22c75fa9a0a8fed8094a135ba1972a7f421450e9b10cba3547dd", [:mix], [{:hackney, "~> 1.6", [hex: :hackney, optional: false]}]}, - "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, + "oauth2": {:hex, :oauth2, "0.9.1", "cac86d87f35ec835bfe4c791263bdb88c0d8bf1617d64f555ede4e9d913e35ef", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, optional: false]}]}} + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}} From 67ef990e0f6d55275fed5b7db1a7cb1cee540be9 Mon Sep 17 00:00:00 2001 From: Sean Callan Date: Tue, 18 Jul 2017 00:13:36 -0600 Subject: [PATCH 02/62] Add OSX and vim files to ignore --- .gitignore | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/.gitignore b/.gitignore index 9607671..ec63485 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,55 @@ + +# Created by https://www.gitignore.io/api/elixir,osx,vim + +### Elixir ### /_build +/cover /deps erl_crash.dump *.ez +*.beam + +### Elixir Patch ### +/doc +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + +# End of https://www.gitignore.io/api/elixir,osx,vim From c215a149873cb0db996d39890560a2b37c011486 Mon Sep 17 00:00:00 2001 From: Evadne Wu Date: Fri, 1 Sep 2017 16:45:50 +0100 Subject: [PATCH 03/62] fixes crash on regular OAuth callback errors (#41) - for example, redeeming the code again would crash because the strategy was using OAuth2.Client.get_token!, which will attempt to illegially raise an exception using a OAuth response struct --- lib/ueberauth/strategy/google.ex | 12 ++++++------ lib/ueberauth/strategy/google/oauth.ex | 16 ++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index c0dc3c7..ad6126b 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -32,13 +32,13 @@ defmodule Ueberauth.Strategy.Google do Handles the callback from Google. """ def handle_callback!(%Plug.Conn{params: %{"code" => code}} = conn) do + params = [code: code] opts = [redirect_uri: callback_url(conn)] - token = Ueberauth.Strategy.Google.OAuth.get_token!([code: code], opts) - - if token.access_token == nil do - set_errors!(conn, [error(token.other_params["error"], token.other_params["error_description"])]) - else - fetch_user(conn, token) + case Ueberauth.Strategy.Google.OAuth.get_access_token(params, opts) do + {:ok, token} -> + fetch_user(conn, token) + {:error, {error_code, error_description}} -> + set_errors!(conn, [error(error_code, error_description)]) end end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 160f584..9f4b654 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -51,12 +51,16 @@ defmodule Ueberauth.Strategy.Google.OAuth do |> OAuth2.Client.get(url, headers, opts) end - def get_token!(params \\ [], opts \\ []) do - client = - opts - |> client - |> OAuth2.Client.get_token!(params) - client.token + def get_access_token(params \\ [], opts \\ []) do + case opts |> client |> OAuth2.Client.get_token(params) do + {:error, %{body: %{"error" => error, "error_description" => description}}} -> + {:error, {error, description}} + {:ok, %{token: %{access_token: nil} = token}} -> + %{"error" => error, "error_description" => description} = token.other_params + {:error, {error, description}} + {:ok, %{token: token}} -> + {:ok, token} + end end # Strategy Callbacks From 3a7949fdc5a007c2a124aa0b6a5bd808688d9a68 Mon Sep 17 00:00:00 2001 From: Dave Lucia Date: Fri, 17 Nov 2017 14:07:01 -0500 Subject: [PATCH 04/62] Fix CaseClauseError in fetch_user for {:error, Response} tuple (#43) --- lib/ueberauth/strategy/google.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index ad6126b..389225c 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -128,6 +128,8 @@ defmodule Ueberauth.Strategy.Google do set_errors!(conn, [error("token", "unauthorized")]) {:ok, %OAuth2.Response{status_code: status_code, body: user}} when status_code in 200..399 -> put_private(conn, :google_user, user) + {:error, %OAuth2.Response{status_code: status_code}} -> + set_errors!(conn, [error("OAuth2", status_code)]) {:error, %OAuth2.Error{reason: reason}} -> set_errors!(conn, [error("OAuth2", reason)]) end From c751fb0b968a36c3b8bc6f49c91da7c32750158a Mon Sep 17 00:00:00 2001 From: Sean Callan Date: Fri, 17 Nov 2017 12:07:53 -0700 Subject: [PATCH 05/62] Release 0.7 --- README.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1f0aece..57a8522 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ```elixir def deps do - [{:ueberauth_google, "~> 0.5"}] + [{:ueberauth_google, "~> 0.7"}] end ``` diff --git a/mix.exs b/mix.exs index e545a51..a466037 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project - @version "0.6.0" + @version "0.7.0" @url "https://github.com/ueberauth/ueberauth_google" def project do From 3f5c12609a8a0af050441cbd14648284e55fecc0 Mon Sep 17 00:00:00 2001 From: Chad Gorshing Date: Mon, 8 Jan 2018 09:50:06 -0600 Subject: [PATCH 06/62] Corrected "email" scope. (#46) See https://developers.google.com/identity/protocols/googlescopes for more information in the "Google Sign-In" section. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57a8522..8740396 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ By default the requested scope is "email". Scope can be configured either explic ```elixir config :ueberauth, Ueberauth, providers: [ - google: {Ueberauth.Strategy.Google, [default_scope: "emails profile plus.me"]} + google: {Ueberauth.Strategy.Google, [default_scope: "email profile plus.me"]} ] ``` From 453e52a37ad90a7335e9f2c3f81d4a7543650d2f Mon Sep 17 00:00:00 2001 From: Chad Gorshing Date: Mon, 26 Feb 2018 08:57:24 -0600 Subject: [PATCH 07/62] Update README.md (#47) Corrected a minor typo in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8740396..c8eddea 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ For an example implementation see the [Überauth Example](https://github.com/ueb ## Calling -Depending on the configured url you can initial the request through: +Depending on the configured url you can initiate the request through: /auth/google From 5a79321eabbd70326f8e22bf4c5541d591179333 Mon Sep 17 00:00:00 2001 From: Venkat Dinavahi Date: Wed, 25 Apr 2018 00:04:59 -0400 Subject: [PATCH 08/62] replaced deprecated approval_prompt with prompt (#51) --- README.md | 4 ++-- lib/ueberauth/strategy/google.ex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c8eddea..35217f9 100644 --- a/README.md +++ b/README.md @@ -83,12 +83,12 @@ config :ueberauth, Ueberauth, ] ``` -You can also pass options such as the `hd` parameter to limit sign-in to a particular Google Apps hosted domain, or `approval_prompt` and `access_type` options to request refresh_tokens and offline access. +You can also pass options such as the `hd` parameter to limit sign-in to a particular Google Apps hosted domain, or `prompt` and `access_type` options to request refresh_tokens and offline access. ```elixir config :ueberauth, Ueberauth, providers: [ - google: {Ueberauth.Strategy.Google, [hd: "example.com", approval_prompt: "force", access_type: "offline"]} + google: {Ueberauth.Strategy.Google, [hd: "example.com", prompt: "select_account", access_type: "offline"]} ] ``` diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 389225c..408d281 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -18,7 +18,7 @@ defmodule Ueberauth.Strategy.Google do opts = [scope: scopes] |> with_optional(:hd, conn) - |> with_optional(:approval_prompt, conn) + |> with_optional(:prompt, conn) |> with_optional(:access_type, conn) |> with_param(:access_type, conn) |> with_param(:prompt, conn) From 6b88c9f66cdb73b86360744daef7fc5ac390395a Mon Sep 17 00:00:00 2001 From: henb Date: Thu, 21 Jun 2018 04:34:02 +0300 Subject: [PATCH 09/62] Fixed redirect_uri from config (#55) --- lib/ueberauth/strategy/google.ex | 7 ++++--- lib/ueberauth/strategy/google/oauth.ex | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 408d281..9efa3b4 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -15,7 +15,7 @@ defmodule Ueberauth.Strategy.Google do def handle_request!(conn) do scopes = conn.params["scope"] || option(conn, :default_scope) - opts = + params = [scope: scopes] |> with_optional(:hd, conn) |> with_optional(:prompt, conn) @@ -23,9 +23,10 @@ defmodule Ueberauth.Strategy.Google do |> with_param(:access_type, conn) |> with_param(:prompt, conn) |> with_param(:state, conn) - |> Keyword.put(:redirect_uri, callback_url(conn)) - redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(opts)) + opts = [redirect_uri: callback_url(conn)] + + redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) end @doc """ diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 9f4b654..02102d5 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -29,8 +29,8 @@ defmodule Ueberauth.Strategy.Google.OAuth do opts = @defaults - |> Keyword.merge(config) |> Keyword.merge(opts) + |> Keyword.merge(config) OAuth2.Client.new(opts) end From c1916865fafec10ecf2da5f305af0703de862023 Mon Sep 17 00:00:00 2001 From: Sean Callan Date: Wed, 19 Dec 2018 09:23:30 -0700 Subject: [PATCH 10/62] Release 0.8 --- mix.exs | 2 +- mix.lock | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/mix.exs b/mix.exs index a466037..6f9d8fe 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project - @version "0.7.0" + @version "0.8.0" @url "https://github.com/ueberauth/ueberauth_google" def project do diff --git a/mix.lock b/mix.lock index d95b51e..de80c01 100644 --- a/mix.lock +++ b/mix.lock @@ -1,18 +1,20 @@ -%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, +%{ + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, "credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, - "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, + "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, "oauth2": {:hex, :oauth2, "0.9.1", "cac86d87f35ec835bfe4c791263bdb88c0d8bf1617d64f555ede4e9d913e35ef", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, - "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}} + "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}, +} From 26e2a44882593f47898cc17ecfa16d9a6765c471 Mon Sep 17 00:00:00 2001 From: Grant Nelson Date: Wed, 19 Dec 2018 11:25:19 -0500 Subject: [PATCH 11/62] TravisCI minimal config for Elixir projects using Elixir ~>1.3 (#54) * Create travis.yml with language: elixir * Updated .travis.yml Trying again, based on other elixir .travis.yml files and reading the TravisCI docs. * Converted elixir versions to strings in travis.yml --- .travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2ae7c1c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: elixir + +cache: + directories: + - ~/.hex + - ~/.mix + - deps + +elixir: + - '1.3' + - '1.4' + - '1.5' + - '1.6' + +script: + - mix test From b696c6d188790c5f6a848de828963bd3ff57d508 Mon Sep 17 00:00:00 2001 From: Carsten Zimmermann Date: Thu, 3 Jan 2019 17:07:16 +0100 Subject: [PATCH 12/62] Update release version in README (#57) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35217f9..e664160 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ```elixir def deps do - [{:ueberauth_google, "~> 0.7"}] + [{:ueberauth_google, "~> 0.8"}] end ``` From 88b9ae851ffda0d34e991ee85e84a0803f7448d0 Mon Sep 17 00:00:00 2001 From: Evadne Wu Date: Sat, 9 Mar 2019 17:21:43 +0000 Subject: [PATCH 13/62] Amended oAuth strategy to resolve m/f/a tuples (#60) * Amended oAuth strategy to resolve m/f/a tuples - this allows specifying {m, f, a} tuples for things such as Client ID / Client Secret * Moved config resolution to after all values have been merged * Amended Strategy to also derive crednetials from options - This is in addition to deriving from the Environment --- lib/ueberauth/strategy/google.ex | 20 +++++++++++++++----- lib/ueberauth/strategy/google/oauth.ex | 18 +++++++++++------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 9efa3b4..c41ebe8 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -24,17 +24,17 @@ defmodule Ueberauth.Strategy.Google do |> with_param(:prompt, conn) |> with_param(:state, conn) - opts = [redirect_uri: callback_url(conn)] - + opts = oauth_client_options_from_conn(conn) redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) end - + @doc """ Handles the callback from Google. """ def handle_callback!(%Plug.Conn{params: %{"code" => code}} = conn) do params = [code: code] - opts = [redirect_uri: callback_url(conn)] + opts = oauth_client_options_from_conn(conn) + case Ueberauth.Strategy.Google.OAuth.get_access_token(params, opts) do {:ok, token} -> fetch_user(conn, token) @@ -116,7 +116,6 @@ defmodule Ueberauth.Strategy.Google do } end - defp fetch_user(conn, token) do conn = put_private(conn, :google_token, token) @@ -144,6 +143,17 @@ defmodule Ueberauth.Strategy.Google do if option(conn, key), do: Keyword.put(opts, key, option(conn, key)), else: opts end + defp oauth_client_options_from_conn(conn) do + base_options = [redirect_uri: callback_url(conn)] + request_options = conn.private[:ueberauth_request_options].options + + case {request_options[:client_id], request_options[:client_secret]} do + {nil, _} -> base_options + {_, nil} -> base_options + {id, secret} -> [client_id: id, client_secret: secret] ++ base_options + end + end + defp option(conn, key) do Keyword.get(options(conn), key, Keyword.get(default_options(), key)) end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 02102d5..0cec195 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -25,13 +25,8 @@ defmodule Ueberauth.Strategy.Google.OAuth do These options are only useful for usage outside the normal callback phase of Ueberauth. """ def client(opts \\ []) do - config = Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth) - - opts = - @defaults - |> Keyword.merge(opts) - |> Keyword.merge(config) - + config = Application.get_env(:ueberauth, __MODULE__, []) + opts = @defaults |> Keyword.merge(opts) |> Keyword.merge(config) |> resolve_values() OAuth2.Client.new(opts) end @@ -75,4 +70,13 @@ defmodule Ueberauth.Strategy.Google.OAuth do |> put_header("Accept", "application/json") |> OAuth2.Strategy.AuthCode.get_token(params, headers) end + + defp resolve_values(list) do + for {key, value} <- list do + {key, resolve_value(value)} + end + end + + defp resolve_value({m, f, a}) when is_atom(m) and is_atom(f), do: apply(m, f, a) + defp resolve_value(v), do: v end From ad0a11016d8ce02726008c9eb58130a1004e50d7 Mon Sep 17 00:00:00 2001 From: Marcin Lewandowski Date: Thu, 14 Mar 2019 20:50:06 +0100 Subject: [PATCH 14/62] Added information about reading client_id/client_secret from MFA to the README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index e664160..28e6a6a 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,24 @@ 1. Update your provider configuration: + Use that if you want to read client ID/secret from the environment + variables in the compile time: + ```elixir config :ueberauth, Ueberauth.Strategy.Google.OAuth, client_id: System.get_env("GOOGLE_CLIENT_ID"), client_secret: System.get_env("GOOGLE_CLIENT_SECRET") ``` + Use that if you want to read client ID/secret from the environment + variables in the run time: + + ```elixir + config :ueberauth, Ueberauth.Strategy.Google.OAuth, + client_id: {System, :get_env, ["GOOGLE_CLIENT_ID"]}, + client_secret: {System, :get_env, ["GOOGLE_CLIENT_SECRET"]} + ``` + 1. Include the Überauth plug in your controller: ```elixir From c0ff1cb5e89bb0ec8a2964b97f3dadbf8d83034e Mon Sep 17 00:00:00 2001 From: snewcomer Date: Sat, 5 Jan 2019 13:37:18 -0800 Subject: [PATCH 15/62] Set json library on OAuth2 --- lib/ueberauth/strategy/google/oauth.ex | 5 ++++- mix.exs | 2 +- mix.lock | 11 ++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 0cec195..d4424cc 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -27,7 +27,10 @@ defmodule Ueberauth.Strategy.Google.OAuth do def client(opts \\ []) do config = Application.get_env(:ueberauth, __MODULE__, []) opts = @defaults |> Keyword.merge(opts) |> Keyword.merge(config) |> resolve_values() + json_library = Application.get_env(:ueberauth, :json_library) + OAuth2.Client.new(opts) + |> OAuth2.Client.put_serializer("application/json", json_library) end @doc """ @@ -76,7 +79,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do {key, resolve_value(value)} end end - + defp resolve_value({m, f, a}) when is_atom(m) and is_atom(f), do: apply(m, f, a) defp resolve_value(v), do: v end diff --git a/mix.exs b/mix.exs index 6f9d8fe..a7108d1 100644 --- a/mix.exs +++ b/mix.exs @@ -25,7 +25,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, "~> 0.9"}, + {:oauth2, github: "scrogson/oauth2", branch: "register_serializers"}, {:ueberauth, "~> 0.4"}, {:credo, "~> 0.8", only: [:dev, :test]}, diff --git a/mix.lock b/mix.lock index de80c01..3bd8e19 100644 --- a/mix.lock +++ b/mix.lock @@ -1,20 +1,21 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, - "oauth2": {:hex, :oauth2, "0.9.1", "cac86d87f35ec835bfe4c791263bdb88c0d8bf1617d64f555ede4e9d913e35ef", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "oauth2": {:git, "https://github.com/scrogson/oauth2.git", "92aa2ea25e5df0e6c0fc89f7d918704f72b71988", [branch: "register_serializers"]}, + "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, } From 43514034a35b0de07893a7f783a7a17c67a6dc2b Mon Sep 17 00:00:00 2001 From: snewcomer Date: Sat, 5 Jan 2019 22:46:04 -0800 Subject: [PATCH 16/62] use json_library hook. Need new release of ueberauth with new hooks --- mix.exs | 2 +- mix.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.exs b/mix.exs index a7108d1..d2a6b0c 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ {:oauth2, github: "scrogson/oauth2", branch: "register_serializers"}, - {:ueberauth, "~> 0.4"}, + {:ueberauth, github: "ueberauth/ueberauth"}, {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, diff --git a/mix.lock b/mix.lock index 3bd8e19..c4539c0 100644 --- a/mix.lock +++ b/mix.lock @@ -8,14 +8,14 @@ "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], [], "hexpm"}, + "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, "oauth2": {:git, "https://github.com/scrogson/oauth2.git", "92aa2ea25e5df0e6c0fc89f7d918704f72b71988", [branch: "register_serializers"]}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, - "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, - "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "ueberauth": {:git, "https://github.com/ueberauth/ueberauth.git", "2087e031c3ff486e0aafb4684659a3e224d2aa29", []}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, } From a728ae445b02c472dabf3995f5f660c28a514430 Mon Sep 17 00:00:00 2001 From: snewcomer Date: Fri, 15 Mar 2019 07:30:35 -0700 Subject: [PATCH 17/62] Update to latest ueberauth and oauth2 --- mix.exs | 4 ++-- mix.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.exs b/mix.exs index d2a6b0c..3e19702 100644 --- a/mix.exs +++ b/mix.exs @@ -25,8 +25,8 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, github: "scrogson/oauth2", branch: "register_serializers"}, - {:ueberauth, github: "ueberauth/ueberauth"}, + {:oauth2, "~> 1.0.0"}, + {:ueberauth, "~> 0.6.0"}, {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, diff --git a/mix.lock b/mix.lock index c4539c0..5ff23bf 100644 --- a/mix.lock +++ b/mix.lock @@ -11,11 +11,11 @@ "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, - "oauth2": {:git, "https://github.com/scrogson/oauth2.git", "92aa2ea25e5df0e6c0fc89f7d918704f72b71988", [branch: "register_serializers"]}, + "oauth2": {:hex, :oauth2, "1.0.0", "7ae134c369bb9f7e96ed9404d12f34e938daa14745f1601876526599be4c80f2", [:mix], [{:hackney, "~> 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, - "ueberauth": {:git, "https://github.com/ueberauth/ueberauth.git", "2087e031c3ff486e0aafb4684659a3e224d2aa29", []}, + "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, } From 6c1b38332954153ba8620612a5e8dc17b308ac58 Mon Sep 17 00:00:00 2001 From: snewcomer Date: Fri, 15 Mar 2019 07:32:17 -0700 Subject: [PATCH 18/62] removed unused deps from lockfile --- mix.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/mix.lock b/mix.lock index 5ff23bf..23f98f6 100644 --- a/mix.lock +++ b/mix.lock @@ -5,16 +5,13 @@ "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, "oauth2": {:hex, :oauth2, "1.0.0", "7ae134c369bb9f7e96ed9404d12f34e938daa14745f1601876526599be4c80f2", [:mix], [{:hackney, "~> 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, - "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, From 381bc298dd769a4f85e6d4863a325688ce440c91 Mon Sep 17 00:00:00 2001 From: snewcomer Date: Fri, 15 Mar 2019 07:35:48 -0700 Subject: [PATCH 19/62] remove space --- lib/ueberauth/strategy/google/oauth.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index d4424cc..64bec93 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -79,7 +79,6 @@ defmodule Ueberauth.Strategy.Google.OAuth do {key, resolve_value(value)} end end - defp resolve_value({m, f, a}) when is_atom(m) and is_atom(f), do: apply(m, f, a) defp resolve_value(v), do: v end From 34fe5dc36edc0ad175aefe45185fc4ad4b56ffe2 Mon Sep 17 00:00:00 2001 From: snewcomer Date: Fri, 15 Mar 2019 07:37:18 -0700 Subject: [PATCH 20/62] Revert "remove space" This reverts commit 381bc298dd769a4f85e6d4863a325688ce440c91. --- lib/ueberauth/strategy/google/oauth.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 64bec93..d4424cc 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -79,6 +79,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do {key, resolve_value(value)} end end + defp resolve_value({m, f, a}) when is_atom(m) and is_atom(f), do: apply(m, f, a) defp resolve_value(v), do: v end From 6525cb8f99adaccce264486923382f59be1ec14b Mon Sep 17 00:00:00 2001 From: snewcomer Date: Fri, 15 Mar 2019 10:36:00 -0700 Subject: [PATCH 21/62] actually use json_library method --- lib/ueberauth/strategy/google/oauth.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index d4424cc..986ad9d 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -27,7 +27,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do def client(opts \\ []) do config = Application.get_env(:ueberauth, __MODULE__, []) opts = @defaults |> Keyword.merge(opts) |> Keyword.merge(config) |> resolve_values() - json_library = Application.get_env(:ueberauth, :json_library) + json_library = Ueberauth.json_library() OAuth2.Client.new(opts) |> OAuth2.Client.put_serializer("application/json", json_library) From c2cc7036ce74cf28fab77d5f8982f66c5505b3d0 Mon Sep 17 00:00:00 2001 From: Andy Kent Date: Sun, 7 Jul 2019 22:23:15 +0100 Subject: [PATCH 22/62] Add support for optional login_hint param --- lib/ueberauth/strategy/google.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index c41ebe8..83c4ed8 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -20,14 +20,16 @@ defmodule Ueberauth.Strategy.Google do |> with_optional(:hd, conn) |> with_optional(:prompt, conn) |> with_optional(:access_type, conn) + |> with_optional(:login_hint, conn) |> with_param(:access_type, conn) |> with_param(:prompt, conn) + |> with_param(:login_hint, conn) |> with_param(:state, conn) opts = oauth_client_options_from_conn(conn) redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) end - + @doc """ Handles the callback from Google. """ @@ -146,7 +148,7 @@ defmodule Ueberauth.Strategy.Google do defp oauth_client_options_from_conn(conn) do base_options = [redirect_uri: callback_url(conn)] request_options = conn.private[:ueberauth_request_options].options - + case {request_options[:client_id], request_options[:client_secret]} do {nil, _} -> base_options {_, nil} -> base_options From ecc0cf380d16455c9cc34b8eeefff82936b34aa3 Mon Sep 17 00:00:00 2001 From: foxtrod Date: Thu, 1 Aug 2019 11:48:25 +0300 Subject: [PATCH 23/62] add birthday --- lib/ueberauth/strategy/google.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index c41ebe8..a4caa42 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -97,6 +97,7 @@ defmodule Ueberauth.Strategy.Google do image: user["picture"], last_name: user["family_name"], name: user["name"], + birthday: user["birthday"], urls: %{ profile: user["profile"], website: user["hd"] From 41ba33f53e2acea390c1bb00de5ce1c1fd71d538 Mon Sep 17 00:00:00 2001 From: foxtrod Date: Fri, 2 Aug 2019 13:38:16 +0300 Subject: [PATCH 24/62] change mix --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 3e19702..a0fce25 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ {:oauth2, "~> 1.0.0"}, - {:ueberauth, "~> 0.6.0"}, + {:ueberauth, "~> 0.6.0", git: "https://github.com/foxtrod/ueberauth.git"}, {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, From dee3f5beab310eb5eed1dd2e17bc7ef054311ab5 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sat, 3 Aug 2019 16:24:09 -0700 Subject: [PATCH 25/62] Fix markdown --- CHANGELOG.md | 26 ++++++++++++++------------ CONTRIBUTING.md | 1 + 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 290cbb1..b206c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,24 @@ -# v 0.6.0 +# Changelog -* Add support for access_type per request using url parameter +## v0.6.0 -# v 0.5.0 +* Add support for access_type per request using url parameter. + +## v0.5.0 * Add support for new params: access_type, approval_prompt, state. -* Fix Elixir warnings +* Fix Elixir warnings. -# v 0.4.0 +## v0.4.0 -* Target Elixir 1.3 and greater -* Fix OAuth bug with 0.6.0 pin +* Target Elixir 1.3 and greater. +* Fix OAuth bug with 0.6.0 pin. -# v 0.3.0 +## v0.3.0 -* Use OpenID endpoint for profile information -* Update authorize and token URLs +* Use OpenID endpoint for profile information. +* Update authorize and token URLs. -# v 0.2.0 +## v0.2.0 -* Release 0.2.0 to follow Ueberauth +* Release 0.2.0 to follow Ueberauth. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 98fada1..b4e2d6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,7 @@ # Contributing to Ueberauth Google ## Pull Requests Welcome + 1. Fork ueberauth_google 2. Create a topic branch 3. Make logically-grouped commits with clear commit messages From 3feed4b1fbac37945ffe4894ed0532d6c4f5d0f0 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sat, 3 Aug 2019 16:28:57 -0700 Subject: [PATCH 26/62] Bump version and add changelog --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b206c0d..8eb972a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## v0.9.0 + +### Enhancement + +* Add support for optional login_hint param [#61](https://github.com/ueberauth/ueberauth_google/pull/61) +* Use json_library method from Ueberauth config [#58](https://github.com/ueberauth/ueberauth_google/pull/58) +* Allows specifying `{m, f, a}` tuples for things such as Client ID + and Client Secret [#60](https://github.com/ueberauth/ueberauth_google/pull/60) + ## v0.6.0 * Add support for access_type per request using url parameter. diff --git a/mix.exs b/mix.exs index 3e19702..c14299f 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project - @version "0.8.0" + @version "0.9.0" @url "https://github.com/ueberauth/ueberauth_google" def project do From 98d3e735ca745d507d312179cd53d71245a90cd3 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sun, 4 Aug 2019 21:02:02 -0700 Subject: [PATCH 27/62] Fix elixir versions --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ae7c1c..523cdf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,8 @@ cache: - deps elixir: - - '1.3' - - '1.4' - - '1.5' - - '1.6' + - '1.8' + - '1.9' script: - mix test From 1456715985289468d2b40cc18d7e8b4edc82e741 Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Wed, 21 Aug 2019 09:10:11 +0200 Subject: [PATCH 28/62] Allow newest oauth2 client with security fixes oauth2 has a recent possibly backwards incompatible release that makes sure the spec is followed and authorization headers are respected (https://github.com/scrogson/oauth2/blob/master/CHANGELOG.md#v200-2019-07-15) This fixed scrogson/oauth2#128 hence I think it's important to include. Decided to not require 2.x as that might conflict too hard with other libraries. Also decided to allow minor version bumps as @scrogson seems to be good about semver <3 As #66 isn't merged yet I'd like it if this could get in with the release. fixes #67 --- mix.exs | 2 +- mix.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mix.exs b/mix.exs index 3e19702..4418f97 100644 --- a/mix.exs +++ b/mix.exs @@ -25,7 +25,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, "~> 1.0.0"}, + {:oauth2, "~> 1.0 or ~> 2.0"}, {:ueberauth, "~> 0.6.0"}, {:credo, "~> 0.8", only: [:dev, :test]}, diff --git a/mix.lock b/mix.lock index 23f98f6..757dfcf 100644 --- a/mix.lock +++ b/mix.lock @@ -1,18 +1,18 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, + "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "oauth2": {:hex, :oauth2, "1.0.0", "7ae134c369bb9f7e96ed9404d12f34e938daa14745f1601876526599be4c80f2", [:mix], [{:hackney, "~> 1.13.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, + "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, } From 92007249ce0bac7b26dcf94b708435356f147afd Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Wed, 21 Aug 2019 09:32:57 +0200 Subject: [PATCH 29/62] travis please? From dcf016e4078c020a854e4d578345e5d1e5615af7 Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Wed, 21 Aug 2019 09:37:14 +0200 Subject: [PATCH 30/62] newer elixir versions so travis doesnt fail --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ae7c1c..378fd5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ cache: - deps elixir: - - '1.3' - - '1.4' - - '1.5' - - '1.6' + - 1.6 + - 1.7 + - 1.8 + - 1.9 script: - mix test From e7d8e2c9a1f40895a81e76764c4ab3cb6aae252d Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Wed, 21 Aug 2019 06:48:18 -0700 Subject: [PATCH 31/62] Fix deps --- mix.exs | 5 ++--- mix.lock | 10 +++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/mix.exs b/mix.exs index 783a436..c2b648f 100644 --- a/mix.exs +++ b/mix.exs @@ -28,9 +28,8 @@ defmodule UeberauthGoogle.Mixfile do {:oauth2, "~> 1.0 or ~> 2.0"}, {:ueberauth, "~> 0.6.0"}, - {:credo, "~> 0.8", only: [:dev, :test]}, - {:earmark, ">= 0.0.0", only: :dev}, - {:ex_doc, "~> 0.3", only: :dev}, + {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, + {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, ] end diff --git a/mix.lock b/mix.lock index 757dfcf..2f540f8 100644 --- a/mix.lock +++ b/mix.lock @@ -1,14 +1,18 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, + "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, From 997375a58844878a0127a3b0ca6ec248ba57910a Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Wed, 21 Aug 2019 21:20:15 +0200 Subject: [PATCH 32/62] Include version badge in README I find it to be extremely useful if I quickly want to check what the latest version to install is. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28e6a6a..d336970 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Überauth Google +# Überauth Google [![Hex Version](https://img.shields.io/hexpm/v/ueberauth_google.svg)](https://hex.pm/packages/ueberauth_google) > Google OAuth2 strategy for Überauth. From bec7fa7e137a6ae34a1a0aa424a9c10907c7fb64 Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Fri, 23 Aug 2019 10:23:58 +0200 Subject: [PATCH 33/62] `hd:` doesn't limit login to a domain but only suggests it The previous wording was misleading as it could be interpreted as a security mechanism which it definitely isn't. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d336970..e7c6b63 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ 1. Update your provider configuration: - Use that if you want to read client ID/secret from the environment + Use that if you want to read client ID/secret from the environment variables in the compile time: ```elixir @@ -42,7 +42,7 @@ client_secret: System.get_env("GOOGLE_CLIENT_SECRET") ``` - Use that if you want to read client ID/secret from the environment + Use that if you want to read client ID/secret from the environment variables in the run time: ```elixir @@ -95,7 +95,7 @@ config :ueberauth, Ueberauth, ] ``` -You can also pass options such as the `hd` parameter to limit sign-in to a particular Google Apps hosted domain, or `prompt` and `access_type` options to request refresh_tokens and offline access. +You can also pass options such as the `hd` parameter to suggest a particular Google Apps hosted domain (caution, can still be overridden by the user), or `prompt` and `access_type` options to request refresh_tokens and offline access. ```elixir config :ueberauth, Ueberauth, From fd69ba66324908b48c9dc920121b72aeecc3153b Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Sat, 24 Aug 2019 14:04:35 +0200 Subject: [PATCH 34/62] Added OAuth version relaxation to Changelog It was important for me and I think it might be important for others :tada: --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eb972a..0703f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Use json_library method from Ueberauth config [#58](https://github.com/ueberauth/ueberauth_google/pull/58) * Allows specifying `{m, f, a}` tuples for things such as Client ID and Client Secret [#60](https://github.com/ueberauth/ueberauth_google/pull/60) +* Allows the newest oauth2 package versions with potential security fixes [#68](https://github.com/ueberauth/ueberauth_google/pull/68) ## v0.6.0 From 73fb36325ce0910306341d2e7b81118a8d762424 Mon Sep 17 00:00:00 2001 From: GK Date: Wed, 11 Sep 2019 23:47:47 +0200 Subject: [PATCH 35/62] use id token as token for token flow --- lib/ueberauth/strategy/google.ex | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 9b4a1bb..2033f71 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -51,7 +51,9 @@ defmodule Ueberauth.Strategy.Google do client = Ueberauth.Strategy.Google.OAuth.client case verify_token(conn, client, id_token) do {:ok, user} -> - put_user(conn, user) + conn + |> put_private(:google_token, OAuth2.AccessToken.new(id_token)) + |> put_private(:google_user, user) {:error, reason} -> set_errors!(conn, [error("token", reason)]) end @@ -148,12 +150,6 @@ defmodule Ueberauth.Strategy.Google do end end - defp put_user(conn, user) do - token = %OAuth2.AccessToken{} - conn = put_private(conn, :google_token, token) - put_private(conn, :google_user, user) - end - defp with_param(opts, key, conn) do if value = conn.params[to_string(key)], do: Keyword.put(opts, key, value), else: opts end From f16861770878c94320259a245b1a9c277d9b8a92 Mon Sep 17 00:00:00 2001 From: GK Date: Sun, 22 Sep 2019 23:03:38 +0200 Subject: [PATCH 36/62] fix oauth issue --- .gitignore | 2 ++ lib/ueberauth/strategy/google.ex | 13 +++++++++---- lib/ueberauth/strategy/google/oauth.ex | 2 +- mix.exs | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 9607671..fa07668 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ /deps erl_crash.dump *.ez + +.elixir_ls/ \ No newline at end of file diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 2033f71..24e9afc 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -167,17 +167,22 @@ defmodule Ueberauth.Strategy.Google do params = %{"id_token" => id_token} resp = OAuth2.Client.get(client, url, [], params: params) + allowed_client_ids = + if is_binary(@allowed_client_ids), + do: String.split(@allowed_client_ids, ","), + else: @allowed_client_ids || [] + case resp do {:ok, %OAuth2.Response{status_code: 200, body: %{"aud" => aud} = body }} -> - if Enum.member?(@allowed_client_ids, aud) do + if Enum.member?(allowed_client_ids, aud) do {:ok, body} else - {:error, "Unknown client id #{aud}"} + {:error, "Unknown client id #{aud}, allowed client ids are #{inspect @allowed_client_ids}"} end - _ -> - {:error, "Token verification failed"} + resp -> + {:error, "Token verification failed"} end end end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 160f584..4edd670 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -32,7 +32,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do |> Keyword.merge(config) |> Keyword.merge(opts) - OAuth2.Client.new(opts) + OAuth2.Client.new(opts) |> put_serializer("application/json", Jason) end @doc """ diff --git a/mix.exs b/mix.exs index 2f67625..85934a8 100644 --- a/mix.exs +++ b/mix.exs @@ -31,6 +31,7 @@ defmodule UeberauthGoogle.Mixfile do {:credo, "~> 0.5", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, {:ex_doc, "~> 0.3", only: :dev}, + {:jason, "~> 1.0"} ] end From 17d5ef7793eac2b3a2cce046bee37c625d462802 Mon Sep 17 00:00:00 2001 From: GK Date: Sun, 29 Sep 2019 14:28:33 +0200 Subject: [PATCH 37/62] support custom oauth endpoints --- lib/ueberauth/strategy/google.ex | 4 ++-- lib/ueberauth/strategy/google/oauth.ex | 18 +++++++++++------- mix.lock | 7 +++++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 24e9afc..f21cb9f 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -137,7 +137,7 @@ defmodule Ueberauth.Strategy.Google do conn = put_private(conn, :google_token, token) # userinfo_endpoint from https://accounts.google.com/.well-known/openid-configuration - path = "https://www.googleapis.com/oauth2/v3/userinfo" + path = Ueberauth.Strategy.Google.OAuth.config()[:fetch_user_url] resp = Ueberauth.Strategy.Google.OAuth.get(token, path) case resp do @@ -163,7 +163,7 @@ defmodule Ueberauth.Strategy.Google do end def verify_token(conn, client, id_token) do - url = "https://www.googleapis.com/oauth2/v3/tokeninfo" + url = Ueberauth.Strategy.Google.OAuth.config()[:token_info_url] params = %{"id_token" => id_token} resp = OAuth2.Client.get(client, url, [], params: params) diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 4edd670..0a37940 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -14,7 +14,9 @@ defmodule Ueberauth.Strategy.Google.OAuth do strategy: __MODULE__, site: "https://accounts.google.com", authorize_url: "/o/oauth2/v2/auth", - token_url: "https://www.googleapis.com/oauth2/v4/token" + token_url: "https://www.googleapis.com/oauth2/v4/token", + token_info_url: "https://www.googleapis.com/oauth2/v3/tokeninfo", + fetch_user_url: "https://www.googleapis.com/oauth2/v3/userinfo" ] @doc """ @@ -25,14 +27,16 @@ defmodule Ueberauth.Strategy.Google.OAuth do These options are only useful for usage outside the normal callback phase of Ueberauth. """ def client(opts \\ []) do - config = Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth) + OAuth2.Client.new(config(opts)) + |> put_serializer("application/json", Jason) + end - opts = - @defaults - |> Keyword.merge(config) - |> Keyword.merge(opts) + def config(opts \\ []) do + config = Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth) - OAuth2.Client.new(opts) |> put_serializer("application/json", Jason) + @defaults + |> Keyword.merge(config) + |> Keyword.merge(opts) end @doc """ diff --git a/mix.lock b/mix.lock index 7b2d242..bb2f625 100644 --- a/mix.lock +++ b/mix.lock @@ -1,4 +1,5 @@ -%{"bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []}, +%{ + "bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []}, "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, optional: false]}]}, "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []}, @@ -6,6 +7,7 @@ "hackney": {:hex, :hackney, "1.6.3", "d489d7ca2d4323e307bedc4bfe684323a7bf773ecfd77938f3ee8074e488e140", [:mix, :rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, @@ -14,4 +16,5 @@ "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, optional: false]}]}} + "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, optional: false]}]}, +} From ee3cbc3f8b2942de87ee33f489f50cef4136df52 Mon Sep 17 00:00:00 2001 From: GK Date: Sun, 29 Sep 2019 19:25:54 +0200 Subject: [PATCH 38/62] fix an issue where allow client_id might not be retrieved --- lib/ueberauth/strategy/google.ex | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index f21cb9f..065fba1 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -162,26 +162,29 @@ defmodule Ueberauth.Strategy.Google do Keyword.get(options(conn), key, Keyword.get(default_options(), key)) end - def verify_token(conn, client, id_token) do - url = Ueberauth.Strategy.Google.OAuth.config()[:token_info_url] + defp verify_token(conn, client, id_token) do + config = Ueberauth.Strategy.Google.OAuth.config() + allowed_client_ids = config[:allowed_client_ids] + url = config[:token_info_url] params = %{"id_token" => id_token} resp = OAuth2.Client.get(client, url, [], params: params) - allowed_client_ids = - if is_binary(@allowed_client_ids), - do: String.split(@allowed_client_ids, ","), - else: @allowed_client_ids || [] + normalized_allowed_client_ids = + if is_binary(allowed_client_ids), + do: String.split(allowed_client_ids, ","), + else: allowed_client_ids || [] case resp do {:ok, %OAuth2.Response{status_code: 200, body: %{"aud" => aud} = body }} -> - if Enum.member?(allowed_client_ids, aud) do + if Enum.member?(normalized_allowed_client_ids, aud) do {:ok, body} else - {:error, "Unknown client id #{aud}, allowed client ids are #{inspect @allowed_client_ids}"} + {:error, "Unknown client id #{aud}, allowed client ids are #{inspect allowed_client_ids}"} end resp -> + IO.inspect resp {:error, "Token verification failed"} end end From be8de6f69dbab9e786ab3806c367a97c0060c983 Mon Sep 17 00:00:00 2001 From: foxtrod Date: Wed, 23 Oct 2019 22:10:47 +0300 Subject: [PATCH 39/62] change mix --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index a0fce25..3e19702 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ {:oauth2, "~> 1.0.0"}, - {:ueberauth, "~> 0.6.0", git: "https://github.com/foxtrod/ueberauth.git"}, + {:ueberauth, "~> 0.6.0"}, {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, From 0e8da6e868c61f6905b224a908c6d20374926f32 Mon Sep 17 00:00:00 2001 From: Matt Pinkston Date: Fri, 28 Feb 2020 19:02:09 +0900 Subject: [PATCH 40/62] Allow the userinfo endpoint to be configured via options. This is useful for environments where the url is different such as China --- README.md | 21 +++++++++++++++++++++ lib/ueberauth/strategy/google.ex | 18 ++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e7c6b63..312da0a 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,27 @@ config :ueberauth, Ueberauth, ] ``` +In some cases, it may be necessary to update the user info endpoint, such as when deploying to countries that block access to the default endpoint. + +```elixir +config :ueberauth, Ueberauth, + providers: [ + google: {Ueberauth.Strategy.Google, [userinfo_endpoint: "https://www.googleapis.cn/oauth2/v3/userinfo"]} + ] +``` + +This may also be set via runtime configuration by passing a 2 or 3 argument tuple. To use this feature, the first argument must be the atom `:system`, and the second argument must represent the environment variable containing the endpoint url. +A third argument may be passed representing a default value if the environment variable is not found, otherwise the library default will be used. + +```elixir +config :ueberauth, Ueberauth, + providers: [ + google: {Ueberauth.Strategy.Google, [ + userinfo_endpoint: {:system, "GOOGLE_USERINFO_ENDPOINT", "https://www.googleapis.cn/oauth2/v3/userinfo"} + ]} + ] +``` + To guard against client-side request modification, it's important to still check the domain in `info.urls[:website]` within the `Ueberauth.Auth` struct if you want to limit sign-in to a specific domain. ## License diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 83c4ed8..fd75ccf 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -3,7 +3,11 @@ defmodule Ueberauth.Strategy.Google do Google Strategy for Überauth. """ - use Ueberauth.Strategy, uid_field: :sub, default_scope: "email", hd: nil + use Ueberauth.Strategy, + uid_field: :sub, + default_scope: "email", + hd: nil, + userinfo_endpoint: "https://www.googleapis.com/oauth2/v3/userinfo" alias Ueberauth.Auth.Info alias Ueberauth.Auth.Credentials @@ -122,7 +126,17 @@ defmodule Ueberauth.Strategy.Google do conn = put_private(conn, :google_token, token) # userinfo_endpoint from https://accounts.google.com/.well-known/openid-configuration - path = "https://www.googleapis.com/oauth2/v3/userinfo" + # the userinfo_endpoint may be overridden in options when necessary. + path = + case option(conn, :userinfo_endpoint) do + {:system, varname, default} -> + System.get_env(varname, default) + {:system, varname} -> + System.get_env(varname, Keyword.get(default_options(), :userinfo_endpoint)) + other -> + other + end + resp = Ueberauth.Strategy.Google.OAuth.get(token, path) case resp do From 174cba04ca61bb257fddd0ac5a3255ef73150504 Mon Sep 17 00:00:00 2001 From: Matt Pinkston Date: Thu, 5 Mar 2020 18:44:14 +0900 Subject: [PATCH 41/62] added tests --- .formatter.exs | 4 ++ config/config.exs | 10 +++ mix.exs | 1 + mix.lock | 47 +++++++------ test/strategy/google_test.exs | 121 +++++++++++++++++++++++++++++++++ test/ueber_google_test.exs | 8 --- test/ueberauth_google_test.exs | 4 ++ 7 files changed, 167 insertions(+), 28 deletions(-) create mode 100644 .formatter.exs create mode 100644 test/strategy/google_test.exs delete mode 100644 test/ueber_google_test.exs create mode 100644 test/ueberauth_google_test.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..bb09258 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], + line_length: 120 +] diff --git a/config/config.exs b/config/config.exs index d2d855e..795f918 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1 +1,11 @@ use Mix.Config + +config :ueberauth, Ueberauth, + providers: [ + google: {Ueberauth.Strategy.Google, []} + ] + +config :ueberauth, Ueberauth.Strategy.Google.OAuth, + client_id: "client_id", + client_secret: "client_secret", + token_url: "token_url" diff --git a/mix.exs b/mix.exs index c2b648f..e19c74a 100644 --- a/mix.exs +++ b/mix.exs @@ -30,6 +30,7 @@ defmodule UeberauthGoogle.Mixfile do {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, + {:mock, "~> 0.3", only: :test} ] end diff --git a/mix.lock b/mix.lock index 2f540f8..2004852 100644 --- a/mix.lock +++ b/mix.lock @@ -1,22 +1,29 @@ %{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, - "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, - "plug": {:hex, :plug, "1.5.1", "1ff35bdecfb616f1a2b1c935ab5e4c47303f866cb929d2a76f0541e553a58165", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.3", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, - "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"}, + "credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95ef6f8105e9b9d61c567204d8df9c382bb9ae5dff7c11c25b69d7c022e1183e"}, + "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm", "762b999fd414fb41e297944228aa1de2cd4a3876a07f968c8b11d1e9a2190d07"}, + "ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "93d2fee94d2f88abf507628378371ea5fab08ed03fa59a6daa3d4469d9159ddd"}, + "exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, + "exvcr": {:hex, :exvcr, "0.11.1", "a5e5f57a67538e032e16cfea6cfb1232314fb146e3ceedf1cde4a11f12fb7a58", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "984a4d52d9e01d5f0e28d45718565a41dffab3ac18e029ae45d42f16a2a58a1d"}, + "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "c2790c9f0f7205f4a362512192dee8179097394400e745e4d20bab7226a8eaad"}, + "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"}, + "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, + "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"}, + "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "e6d886252f1a41f4ba06ecf2b4c8d38760b34b1c08a11c28f7397b2e03995964"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm", "00e3ebdc821fb3a36957320d49e8f4bfa310d73ea31c90e5f925dc75e030da8f"}, + "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "881b8364ac7385f9fddc7949379cbe3f7081da37233a1aa7aab844670a91e7e7"}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, + "plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "9902eda2c52ada2a096434682e99a2493f5d06a94d6ac6bcfff9805f952350f1"}, + "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm", "603561dc0fd62f4f2ea9b890f4e20e1a0d388746d6e20557cafb1b16950de88c"}, + "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "81ea8303ef676a7b8e6e308584e9b9232d2b6fb02110d00dba351edd823a7d96"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, } diff --git a/test/strategy/google_test.exs b/test/strategy/google_test.exs new file mode 100644 index 0000000..d5f0b93 --- /dev/null +++ b/test/strategy/google_test.exs @@ -0,0 +1,121 @@ +defmodule Ueberauth.Strategy.GoogleTest do + use ExUnit.Case, async: true + use Plug.Test + + import Mock + import Plug.Conn + + setup_with_mocks([ + {OAuth2.Client, [:passthrough], + [ + get_token: &oauth2_get_token/2, + get: &oauth2_get/4 + ]} + ]) do + :ok + end + + def set_options(routes, conn, opt) do + case Enum.find_index(routes, &(elem(&1, 0) == {conn.request_path, conn.method})) do + nil -> + routes + + idx -> + update_in(routes, [Access.at(idx), Access.elem(1), Access.elem(2)], &%{&1 | options: opt}) + end + end + + defp token(client, opts), do: {:ok, %{client | token: OAuth2.AccessToken.new(opts)}} + defp response(body, code \\ 200), do: {:ok, %OAuth2.Response{status_code: code, body: body}} + + def oauth2_get_token(client, code: "success_code"), do: token(client, "success_token") + def oauth2_get_token(client, code: "uid_code"), do: token(client, "uid_token") + def oauth2_get_token(client, code: "userinfo_code"), do: token(client, "userinfo_token") + + def oauth2_get(%{token: %{access_token: "success_token"}}, _url, _, _), + do: response(%{"sub" => "1234_fred", "name" => "Fred Jones", "email" => "fred_jones@example.com"}) + + def oauth2_get(%{token: %{access_token: "uid_token"}}, _url, _, _), + do: response(%{"uid_field" => "1234_daphne", "name" => "Daphne Blake"}) + + def oauth2_get(%{token: %{access_token: "userinfo_token"}}, "https://www.googleapis.com/oauth2/v3/userinfo", _, _), + do: response(%{"sub" => "1234_velma", "name" => "Velma Dinkley"}) + + def oauth2_get(%{token: %{access_token: "userinfo_token"}}, "example.com/shaggy", _, _), + do: response(%{"sub" => "1234_shaggy", "name" => "Norville Rogers"}) + + def oauth2_get(%{token: %{access_token: "userinfo_token"}}, "example.com/scooby", _, _), + do: response(%{"sub" => "1234_scooby", "name" => "Scooby Doo"}) + + test "handle_request! redirects to appropriate auth uri" do + conn = conn(:get, "/auth/google", %{}) + # Make sure the hd and scope params are included for good measure + routes = Ueberauth.init() |> set_options(conn, hd: "example.com", default_scope: "email openid") + + resp = Ueberauth.call(conn, routes) + + assert resp.status == 302 + assert [location] = get_resp_header(resp, "location") + + redirect_uri = URI.parse(location) + assert redirect_uri.host == "accounts.google.com" + assert redirect_uri.path == "/o/oauth2/v2/auth" + + assert %{ + "client_id" => "client_id", + "redirect_uri" => "http://www.example.com/auth/google/callback", + "response_type" => "code", + "scope" => "email openid", + "hd" => "example.com" + } = Plug.Conn.Query.decode(redirect_uri.query) + end + + test "handle_callback! assigns required fields on successful auth" do + conn = conn(:get, "/auth/google/callback", %{code: "success_code"}) + routes = Ueberauth.init([]) + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.credentials.token == "success_token" + assert auth.info.name == "Fred Jones" + assert auth.info.email == "fred_jones@example.com" + assert auth.uid == "1234_fred" + end + + test "uid_field is picked according to the specified option" do + conn = conn(:get, "/auth/google/callback", %{code: "uid_code"}) + routes = Ueberauth.init() |> set_options(conn, uid_field: "uid_field") + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.info.name == "Daphne Blake" + assert auth.uid == "1234_daphne" + end + + test "userinfo is fetched according to userinfo_endpoint" do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: "example.com/shaggy") + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.info.name == "Norville Rogers" + end + + test "userinfo can be set via runtime config with default" do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET", "example.com/shaggy"}) + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.info.name == "Norville Rogers" + end + + test "userinfo uses default library value if runtime env not found" do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET"}) + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.info.name == "Velma Dinkley" + end + + test "userinfo can be set via runtime config" do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "UEBERAUTH_SCOOBY_DOO"}) + + System.put_env("UEBERAUTH_SCOOBY_DOO", "example.com/scooby") + assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) + assert auth.info.name == "Scooby Doo" + System.delete_env("UEBERAUTH_SCOOBY_DOO") + end +end diff --git a/test/ueber_google_test.exs b/test/ueber_google_test.exs deleted file mode 100644 index 377d513..0000000 --- a/test/ueber_google_test.exs +++ /dev/null @@ -1,8 +0,0 @@ -defmodule UeberauthGoogleTest do - use ExUnit.Case - doctest UeberauthGoogle - - test "the truth" do - assert 1 + 1 == 2 - end -end diff --git a/test/ueberauth_google_test.exs b/test/ueberauth_google_test.exs new file mode 100644 index 0000000..d43bb38 --- /dev/null +++ b/test/ueberauth_google_test.exs @@ -0,0 +1,4 @@ +defmodule UeberauthGoogleTest do + use ExUnit.Case, async: true + doctest UeberauthGoogle +end From 50956cc50d20526795af0b3238194907f7506108 Mon Sep 17 00:00:00 2001 From: Matt Pinkston Date: Thu, 5 Mar 2020 18:50:07 +0900 Subject: [PATCH 42/62] tweak for elixir < 1.9 compatibility --- lib/ueberauth/strategy/google.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index fd75ccf..820102f 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -130,9 +130,9 @@ defmodule Ueberauth.Strategy.Google do path = case option(conn, :userinfo_endpoint) do {:system, varname, default} -> - System.get_env(varname, default) + System.get_env(varname) || default {:system, varname} -> - System.get_env(varname, Keyword.get(default_options(), :userinfo_endpoint)) + System.get_env(varname) || Keyword.get(default_options(), :userinfo_endpoint) other -> other end From b3c95fa85d661f2dc7d9cdd7aa93dc11f446883f Mon Sep 17 00:00:00 2001 From: Hans Pagh Date: Thu, 5 Mar 2020 13:15:45 +0100 Subject: [PATCH 43/62] update ueberauth dep --- mix.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 3e19702..5c98f7c 100644 --- a/mix.exs +++ b/mix.exs @@ -25,8 +25,8 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, "~> 1.0.0"}, - {:ueberauth, "~> 0.6.0"}, + {:oauth2, "~> 1.0 or ~> 2.0"}, + {:ueberauth, "~> 0.6.1"}, {:credo, "~> 0.8", only: [:dev, :test]}, {:earmark, ">= 0.0.0", only: :dev}, From c9ef7910d4decdab66023cbdc9d90ad714a2f4ce Mon Sep 17 00:00:00 2001 From: Hans Pagh Date: Thu, 5 Mar 2020 13:40:51 +0100 Subject: [PATCH 44/62] use version 0.6.3 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index a56172b..cddbcb3 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ {:oauth2, "~> 1.0 or ~> 2.0"}, - {:ueberauth, "~> 0.6.1"}, + {:ueberauth, "~> 0.6.3"}, {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, From b6686fb0c54df1c898cd5be7c75e87613d9d01bf Mon Sep 17 00:00:00 2001 From: Ruben Amortegui Date: Wed, 15 Apr 2020 18:02:32 -0600 Subject: [PATCH 45/62] Update lock version of plug and ueberauth --- mix.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 2004852..11b60d1 100644 --- a/mix.lock +++ b/mix.lock @@ -21,9 +21,9 @@ "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm", "00e3ebdc821fb3a36957320d49e8f4bfa310d73ea31c90e5f925dc75e030da8f"}, "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "881b8364ac7385f9fddc7949379cbe3f7081da37233a1aa7aab844670a91e7e7"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, - "plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "9902eda2c52ada2a096434682e99a2493f5d06a94d6ac6bcfff9805f952350f1"}, + "plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"}, "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm", "603561dc0fd62f4f2ea9b890f4e20e1a0d388746d6e20557cafb1b16950de88c"}, - "ueberauth": {:hex, :ueberauth, "0.6.1", "9e90d3337dddf38b1ca2753aca9b1e53d8a52b890191cdc55240247c89230412", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "81ea8303ef676a7b8e6e308584e9b9232d2b6fb02110d00dba351edd823a7d96"}, + "ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, } From 194a34bfab03c96058715cc44f967a05d3df569e Mon Sep 17 00:00:00 2001 From: Ruben Amortegui Date: Wed, 15 Apr 2020 18:02:48 -0600 Subject: [PATCH 46/62] Update docs to match current version of the app --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 312da0a..65b2def 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ```elixir def deps do - [{:ueberauth_google, "~> 0.8"}] + [{:ueberauth_google, "~> 0.9"}] end ``` From 967bf94b38c5677088c1afbed3a12fbdac27230e Mon Sep 17 00:00:00 2001 From: GK Date: Sun, 31 May 2020 20:27:04 +0200 Subject: [PATCH 47/62] skip ssl peer verification --- lib/ueberauth/strategy/google.ex | 45 +++++++++++++++++--------- lib/ueberauth/strategy/google/oauth.ex | 25 ++++++++------ mix.exs | 2 +- mix.lock | 32 +++++++++--------- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 065fba1..5bcdf0b 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -9,7 +9,9 @@ defmodule Ueberauth.Strategy.Google do alias Ueberauth.Auth.Credentials alias Ueberauth.Auth.Extra - @allowed_client_ids Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth)[:allowed_client_ids] + @allowed_client_ids Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth)[ + :allowed_client_ids + ] @doc """ Handles initial request for Google authentication. @@ -38,7 +40,9 @@ defmodule Ueberauth.Strategy.Google do token = Ueberauth.Strategy.Google.OAuth.get_token!([code: code], opts) if token.access_token == nil do - set_errors!(conn, [error(token.other_params["error"], token.other_params["error_description"])]) + set_errors!(conn, [ + error(token.other_params["error"], token.other_params["error_description"]) + ]) else fetch_user(conn, token) end @@ -48,12 +52,14 @@ defmodule Ueberauth.Strategy.Google do Handles the callback from app. """ def handle_callback!(%Plug.Conn{params: %{"id_token" => id_token}} = conn) do - client = Ueberauth.Strategy.Google.OAuth.client + client = Ueberauth.Strategy.Google.OAuth.client() + case verify_token(conn, client, id_token) do {:ok, user} -> conn |> put_private(:google_token, OAuth2.AccessToken.new(id_token)) |> put_private(:google_user, user) + {:error, reason} -> set_errors!(conn, [error("token", reason)]) end @@ -87,9 +93,9 @@ defmodule Ueberauth.Strategy.Google do Includes the credentials from the google response. """ def credentials(conn) do - token = conn.private.google_token - scope_string = (token.other_params["scope"] || "") - scopes = String.split(scope_string, ",") + token = conn.private.google_token + scope_string = token.other_params["scope"] || "" + scopes = String.split(scope_string, ",") %Credentials{ expires: !!token.expires_at, @@ -132,7 +138,6 @@ defmodule Ueberauth.Strategy.Google do } end - defp fetch_user(conn, token) do conn = put_private(conn, :google_token, token) @@ -143,8 +148,11 @@ defmodule Ueberauth.Strategy.Google do case resp do {:ok, %OAuth2.Response{status_code: 401, body: _body}} -> set_errors!(conn, [error("token", "unauthorized")]) - {:ok, %OAuth2.Response{status_code: status_code, body: user}} when status_code in 200..399 -> + + {:ok, %OAuth2.Response{status_code: status_code, body: user}} + when status_code in 200..399 -> put_private(conn, :google_user, user) + {:error, %OAuth2.Error{reason: reason}} -> set_errors!(conn, [error("OAuth2", reason)]) end @@ -167,7 +175,12 @@ defmodule Ueberauth.Strategy.Google do allowed_client_ids = config[:allowed_client_ids] url = config[:token_info_url] params = %{"id_token" => id_token} - resp = OAuth2.Client.get(client, url, [], params: params) + + resp = + OAuth2.Client.get(client, url, [], + params: params, + ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()] + ) normalized_allowed_client_ids = if is_binary(allowed_client_ids), @@ -175,17 +188,17 @@ defmodule Ueberauth.Strategy.Google do else: allowed_client_ids || [] case resp do - {:ok, %OAuth2.Response{status_code: 200, - body: %{"aud" => aud} = body - }} -> + {:ok, %OAuth2.Response{status_code: 200, body: %{"aud" => aud} = body}} -> if Enum.member?(normalized_allowed_client_ids, aud) do {:ok, body} else - {:error, "Unknown client id #{aud}, allowed client ids are #{inspect allowed_client_ids}"} + {:error, + "Unknown client id #{aud}, allowed client ids are #{inspect(allowed_client_ids)}"} end - resp -> - IO.inspect resp - {:error, "Token verification failed"} + + resp -> + IO.inspect(resp) + {:error, "Token verification failed"} end end end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 0a37940..b860f0b 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -11,13 +11,13 @@ defmodule Ueberauth.Strategy.Google.OAuth do use OAuth2.Strategy @defaults [ - strategy: __MODULE__, - site: "https://accounts.google.com", - authorize_url: "/o/oauth2/v2/auth", - token_url: "https://www.googleapis.com/oauth2/v4/token", - token_info_url: "https://www.googleapis.com/oauth2/v3/tokeninfo", - fetch_user_url: "https://www.googleapis.com/oauth2/v3/userinfo" - ] + strategy: __MODULE__, + site: "https://accounts.google.com", + authorize_url: "/o/oauth2/v2/auth", + token_url: "https://www.googleapis.com/oauth2/v4/token", + token_info_url: "https://www.googleapis.com/oauth2/v3/tokeninfo", + fetch_user_url: "https://www.googleapis.com/oauth2/v3/userinfo" + ] @doc """ Construct a client for requests to Google. @@ -52,14 +52,21 @@ defmodule Ueberauth.Strategy.Google.OAuth do [token: token] |> client |> put_param("client_secret", client().client_secret) - |> OAuth2.Client.get(url, headers, opts) + |> OAuth2.Client.get( + url, + headers, + opts ++ [ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()]] + ) end def get_token!(params \\ [], opts \\ []) do client = opts |> client - |> OAuth2.Client.get_token!(params) + |> OAuth2.Client.get_token!(params, [], + ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()] + ) + client.token end diff --git a/mix.exs b/mix.exs index 85934a8..3e3e5e9 100644 --- a/mix.exs +++ b/mix.exs @@ -25,7 +25,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ - {:oauth2, "~> 0.8"}, + {:oauth2, "~> 0.9.4"}, {:ueberauth, "~> 0.4"}, {:credo, "~> 0.5", only: [:dev, :test]}, diff --git a/mix.lock b/mix.lock index bb2f625..4e944f2 100644 --- a/mix.lock +++ b/mix.lock @@ -1,20 +1,22 @@ %{ - "bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []}, - "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, - "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, optional: false]}]}, - "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, - "hackney": {:hex, :hackney, "1.6.3", "d489d7ca2d4323e307bedc4bfe684323a7bf773ecfd77938f3ee8074e488e140", [:mix, :rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, + "bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], [], "hexpm", "4fb7b2f7b04af13cf210b132f8d10db52d4a57d36cb974e8025d7fdb12ca97fc"}, + "certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"}, + "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm", "90bca5180fe64c47343969ad3e32bf1edc18d929689e8c00c810655a7a391427"}, + "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm", "db7b13d74a9edc54d3681762154d164d4a661cd27673cca80760344449877664"}, + "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm", "b2c71148cb42a23e3610b7810b1600d61b10e1a9eb4e8a5db35d398057469528"}, + "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"}, "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, - "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, + "idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], [], "hexpm", "8aad5eef6d9d20899918868b10e79fc2dafe72a79102882c2947999c10b30cd9"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, - "oauth2": {:hex, :oauth2, "0.8.0", "9650476a695a22c75fa9a0a8fed8094a135ba1972a7f421450e9b10cba3547dd", [:mix], [{:hackney, "~> 1.6", [hex: :hackney, optional: false]}]}, - "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, + "oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, + "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "2788381ac3aa424a6dbf308aad08a1ebdefdcaad4fc8d21be56817d23a923ace"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, optional: false]}]}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d3bcb678a8fdcd0add619eacb3e45e51003f50aa434ea732746ea25c37f6c92b"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"}, } From 9abed05302d7dfaa2998a5fd0c9b83d04679fde2 Mon Sep 17 00:00:00 2001 From: Max Strother Date: Fri, 21 Aug 2020 14:08:16 +0200 Subject: [PATCH 48/62] Add support for optional include_granted_scopes param --- README.md | 4 ++-- lib/ueberauth/strategy/google.ex | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 65b2def..1dca876 100644 --- a/README.md +++ b/README.md @@ -95,12 +95,12 @@ config :ueberauth, Ueberauth, ] ``` -You can also pass options such as the `hd` parameter to suggest a particular Google Apps hosted domain (caution, can still be overridden by the user), or `prompt` and `access_type` options to request refresh_tokens and offline access. +You can also pass options such as the `hd` parameter to suggest a particular Google Apps hosted domain (caution, can still be overridden by the user), `prompt` and `access_type` options to request refresh_tokens and offline access (both have to be present), or `include_granted_scopes` parameter to allow [incremental authorization](https://developers.google.com/identity/protocols/oauth2/web-server#incrementalAuth). ```elixir config :ueberauth, Ueberauth, providers: [ - google: {Ueberauth.Strategy.Google, [hd: "example.com", prompt: "select_account", access_type: "offline"]} + google: {Ueberauth.Strategy.Google, [hd: "example.com", prompt: "select_account", access_type: "offline", include_granted_scopes: true]} ] ``` diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 5cb249c..bda2847 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -25,6 +25,7 @@ defmodule Ueberauth.Strategy.Google do |> with_optional(:prompt, conn) |> with_optional(:access_type, conn) |> with_optional(:login_hint, conn) + |> with_optional(:include_granted_scopes, conn) |> with_param(:access_type, conn) |> with_param(:prompt, conn) |> with_param(:login_hint, conn) From 2e5df9d83a3cf86a56d2a3fa8e8b93823a8ace19 Mon Sep 17 00:00:00 2001 From: Hans Pagh Date: Tue, 20 Oct 2020 10:42:26 +0200 Subject: [PATCH 49/62] release 0.10.0 --- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- mix.exs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0703f4d..64eddfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## v0.11.0 (Unreleased) + + +## v0.10.0 + +### Enhancement + +* Updated docs [#69](https://github.com/ueberauth/ueberauth_google/pull/69) [#70](https://github.com/ueberauth/ueberauth_google/pull/70) +* Support for birthday [#73](https://github.com/ueberauth/ueberauth_google/pull/73) +* Allow for userinfo endpoint to be configured [#75](https://github.com/ueberauth/ueberauth_google/pull/75) +* Updated plug and ueberauth packages [#76](https://github.com/ueberauth/ueberauth_google/pull/76) + +Thanks goes to all the contributes + ## v0.9.0 ### Enhancement diff --git a/README.md b/README.md index 1dca876..dcf1b2a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ```elixir def deps do - [{:ueberauth_google, "~> 0.9"}] + [{:ueberauth_google, "~> 0.10"}] end ``` diff --git a/mix.exs b/mix.exs index cddbcb3..a05fa8d 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project - @version "0.9.0" + @version "0.10.0" @url "https://github.com/ueberauth/ueberauth_google" def project do From b2088d1ac657136d848d2f51bd99625fa5415cc9 Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Thu, 1 Apr 2021 20:25:20 +0800 Subject: [PATCH 50/62] Misc doc changes Besides other documentation changes, this commit ensures the generated HTML doc for HexDocs.pm will become the main source doc for this Elixir library which leverage on latest ExDoc features. --- .formatter.exs | 1 + .gitignore | 3 ++ CHANGELOG.md | 20 ++++---- CONTRIBUTING.md | 2 +- LICENSE | 3 +- README.md | 44 +++++++++++------ lib/ueberauth/strategy/google/oauth.ex | 7 +-- mix.exs | 65 ++++++++++++++------------ mix.lock | 10 ++-- 9 files changed, 91 insertions(+), 64 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index bb09258..0a70dc0 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,3 +1,4 @@ +# Used by "mix format" [ inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], line_length: 120 diff --git a/.gitignore b/.gitignore index ec63485..e746ad7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,10 @@ /_build /cover /deps +/tmp +/.fetch erl_crash.dump +ueberauth_google-*.tar *.ez *.beam diff --git a/CHANGELOG.md b/CHANGELOG.md index 64eddfa..b877ce4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## v0.11.0 (Unreleased) -## v0.10.0 +## v0.10.0 - 2020-10-20 ### Enhancement @@ -14,35 +14,35 @@ Thanks goes to all the contributes -## v0.9.0 +## v0.9.0 - 2019-08-21 ### Enhancement * Add support for optional login_hint param [#61](https://github.com/ueberauth/ueberauth_google/pull/61) -* Use json_library method from Ueberauth config [#58](https://github.com/ueberauth/ueberauth_google/pull/58) +* Use `json_library` method from Ueberauth config [#58](https://github.com/ueberauth/ueberauth_google/pull/58) * Allows specifying `{m, f, a}` tuples for things such as Client ID and Client Secret [#60](https://github.com/ueberauth/ueberauth_google/pull/60) * Allows the newest oauth2 package versions with potential security fixes [#68](https://github.com/ueberauth/ueberauth_google/pull/68) -## v0.6.0 +## v0.6.0 - 2017-07-18 -* Add support for access_type per request using url parameter. +* Add support for `access_type` per request using `url` parameter. -## v0.5.0 +## v0.5.0 - 2016-12-27 -* Add support for new params: access_type, approval_prompt, state. +* Add support for new params: `access_type`, `approval_prompt`, `state`. * Fix Elixir warnings. -## v0.4.0 +## v0.4.0 - 2016-09-21 * Target Elixir 1.3 and greater. * Fix OAuth bug with 0.6.0 pin. -## v0.3.0 +## v0.3.0 - 2016-08-15 * Use OpenID endpoint for profile information. * Update authorize and token URLs. -## v0.2.0 +## v0.2.0 - 2016-12-10 * Release 0.2.0 to follow Ueberauth. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b4e2d6b..c748f44 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Ueberauth Google +# Contributing ## Pull Requests Welcome diff --git a/LICENSE b/LICENSE index 473a36e..4f1532b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Sean +Copyright (c) 2015 Sean Callan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index dcf1b2a..9885737 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,40 @@ -# Überauth Google [![Hex Version](https://img.shields.io/hexpm/v/ueberauth_google.svg)](https://hex.pm/packages/ueberauth_google) +# Überauth Google + +[![Build Status](https://travis-ci.org/ueberauth/ueberauth_google.svg?branch=master)](https://travis-ci.org/ueberauth/ueberauth_google) +[![Module Version](https://img.shields.io/hexpm/v/ueberauth_google.svg)](https://hex.pm/packages/ueberauth_google) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/ueberauth_google/) +[![Total Download](https://img.shields.io/hexpm/dt/ueberauth_google.svg)](https://hex.pm/packages/ueberauth_google) +[![License](https://img.shields.io/hexpm/l/ueberauth_google.svg)](https://github.com/ueberauth/ueberauth_google/blob/master/LICENSE) +[![Last Updated](https://img.shields.io/github/last-commit/ueberauth/ueberauth_google.svg)](https://github.com/ueberauth/ueberauth_google/commits/master) + > Google OAuth2 strategy for Überauth. ## Installation -1. Setup your application at [Google Developer Console](https://console.developers.google.com/home). +1. Setup your application at [Google Developer Console](https://console.developers.google.com/home). -1. Add `:ueberauth_google` to your list of dependencies in `mix.exs`: +2. Add `:ueberauth_google` to your list of dependencies in `mix.exs`: ```elixir def deps do - [{:ueberauth_google, "~> 0.10"}] + [ + {:ueberauth_google, "~> 0.10"} + ] end ``` -1. Add the strategy to your applications: +3. Add the strategy to your applications: ```elixir def application do - [applications: [:ueberauth_google]] + [ + applications: [:ueberauth_google] + ] end ``` -1. Add Google to your Überauth configuration: +4. Add Google to your Überauth configuration: ```elixir config :ueberauth, Ueberauth, @@ -31,7 +43,7 @@ ] ``` -1. Update your provider configuration: +5. Update your provider configuration: Use that if you want to read client ID/secret from the environment variables in the compile time: @@ -51,7 +63,7 @@ client_secret: {System, :get_env, ["GOOGLE_CLIENT_SECRET"]} ``` -1. Include the Überauth plug in your controller: +6. Include the Überauth plug in your controller: ```elixir defmodule MyApp.AuthController do @@ -61,7 +73,7 @@ end ``` -1. Create the request and callback routes if you haven't already: +7. Create the request and callback routes if you haven't already: ```elixir scope "/auth", MyApp do @@ -72,7 +84,7 @@ end ``` -1. Your controller needs to implement callbacks to deal with `Ueberauth.Auth` and `Ueberauth.Failure` responses. +8. Your controller needs to implement callbacks to deal with `Ueberauth.Auth` and `Ueberauth.Failure` responses. For an example implementation see the [Überauth Example](https://github.com/ueberauth/ueberauth_example) application. @@ -113,8 +125,8 @@ config :ueberauth, Ueberauth, ] ``` -This may also be set via runtime configuration by passing a 2 or 3 argument tuple. To use this feature, the first argument must be the atom `:system`, and the second argument must represent the environment variable containing the endpoint url. -A third argument may be passed representing a default value if the environment variable is not found, otherwise the library default will be used. +This may also be set via runtime configuration by passing a 2 or 3 argument tuple. To use this feature, the first argument must be the atom `:system`, and the second argument must represent the environment variable containing the endpoint url. +A third argument may be passed representing a default value if the environment variable is not found, otherwise the library default will be used. ```elixir config :ueberauth, Ueberauth, @@ -127,6 +139,8 @@ config :ueberauth, Ueberauth, To guard against client-side request modification, it's important to still check the domain in `info.urls[:website]` within the `Ueberauth.Auth` struct if you want to limit sign-in to a specific domain. -## License +## Copyright and License + +Copyright (c) 2015 Sean Callan -Please see [LICENSE](https://github.com/ueberauth/ueberauth_google/blob/master/LICENSE) for licensing details. +Released under the MIT License, which can be found in the repository in [LICENSE](https://github.com/ueberauth/ueberauth_google/blob/master/LICENSE). diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 986ad9d..930769c 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -4,9 +4,10 @@ defmodule Ueberauth.Strategy.Google.OAuth do Add `client_id` and `client_secret` to your configuration: - config :ueberauth, Ueberauth.Strategy.Google.OAuth, - client_id: System.get_env("GOOGLE_APP_ID"), - client_secret: System.get_env("GOOGLE_APP_SECRET") + config :ueberauth, Ueberauth.Strategy.Google.OAuth, + client_id: System.get_env("GOOGLE_APP_ID"), + client_secret: System.get_env("GOOGLE_APP_SECRET") + """ use OAuth2.Strategy diff --git a/mix.exs b/mix.exs index a05fa8d..6449335 100644 --- a/mix.exs +++ b/mix.exs @@ -1,51 +1,58 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project + @source_url "https://github.com/ueberauth/ueberauth_google" @version "0.10.0" - @url "https://github.com/ueberauth/ueberauth_google" def project do - [app: :ueberauth_google, - version: @version, - name: "Ueberauth Google Strategy", - package: package(), - elixir: "~> 1.3", - build_embedded: Mix.env == :prod, - start_permanent: Mix.env == :prod, - source_url: @url, - homepage_url: @url, - description: description(), - deps: deps(), - docs: docs()] + [ + app: :ueberauth_google, + version: @version, + name: "Üeberauth Google", + elixir: "~> 1.8", + start_permanent: Mix.env() == :prod, + package: package(), + deps: deps(), + docs: docs() + ] end def application do - [applications: [:logger, :oauth2, :ueberauth]] + [ + extra_applications: [:logger, :oauth2, :ueberauth] + ] end defp deps do [ - {:oauth2, "~> 1.0 or ~> 2.0"}, - {:ueberauth, "~> 0.6.3"}, - - {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, - {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, - {:mock, "~> 0.3", only: :test} + {:oauth2, "~> 1.0 or ~> 2.0"}, + {:ueberauth, "~> 0.6.3"}, + {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, + {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, + {:mock, "~> 0.3", only: :test} ] end defp docs do - [extras: ["README.md", "CONTRIBUTING.md"]] - end - - defp description do - "An Uberauth strategy for Google authentication." + [ + extras: ["CHANGELOG.md", "CONTRIBUTING.md", "README.md"], + main: "readme", + source_url: @source_url, + homepage_url: @source_url, + formatters: ["html"] + ] end defp package do - [files: ["lib", "mix.exs", "README.md", "LICENSE"], - maintainers: ["Sean Callan"], - licenses: ["MIT"], - links: %{"GitHub": @url}] + [ + description: "An Uberauth strategy for Google authentication.", + files: ["lib", "mix.exs", "README.md", "CHANGELOG.md", "CONTRIBUTING.md", "LICENSE"], + maintainers: ["Sean Callan"], + licenses: ["MIT"], + links: %{ + Changelog: "https://hexdocs.pm/ueberauth_google/changelog.html", + GitHub: @source_url + } + ] end end diff --git a/mix.lock b/mix.lock index 11b60d1..e97382e 100644 --- a/mix.lock +++ b/mix.lock @@ -3,7 +3,8 @@ "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"}, "credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95ef6f8105e9b9d61c567204d8df9c382bb9ae5dff7c11c25b69d7c022e1183e"}, "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm", "762b999fd414fb41e297944228aa1de2cd4a3876a07f968c8b11d1e9a2190d07"}, - "ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "93d2fee94d2f88abf507628378371ea5fab08ed03fa59a6daa3d4469d9159ddd"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"}, + "ex_doc": {:hex, :ex_doc, "0.24.1", "15673de99154f93ca7f05900e4e4155ced1ee0cd34e0caeee567900a616871a4", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "07972f17bdf7dc7b5bd76ec97b556b26178ed3f056e7ec9288eb7cea7f91cce2"}, "exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "exvcr": {:hex, :exvcr, "0.11.1", "a5e5f57a67538e032e16cfea6cfb1232314fb146e3ceedf1cde4a11f12fb7a58", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "984a4d52d9e01d5f0e28d45718565a41dffab3ac18e029ae45d42f16a2a58a1d"}, @@ -11,14 +12,15 @@ "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, - "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"}, + "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "e6d886252f1a41f4ba06ecf2b4c8d38760b34b1c08a11c28f7397b2e03995964"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm", "00e3ebdc821fb3a36957320d49e8f4bfa310d73ea31c90e5f925dc75e030da8f"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "881b8364ac7385f9fddc7949379cbe3f7081da37233a1aa7aab844670a91e7e7"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, "plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"}, From abeb9075891c4b24da95752415a3924f6ac5d191 Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Thu, 15 Jul 2021 19:17:56 -0400 Subject: [PATCH 51/62] upgrade ueberauth to 0.7.0 + refactor state param logic so it's compatible --- lib/ueberauth/strategy/google.ex | 2 +- mix.exs | 2 +- mix.lock | 9 +++--- test/strategy/google_test.exs | 53 +++++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index bda2847..1acbbd4 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -29,7 +29,7 @@ defmodule Ueberauth.Strategy.Google do |> with_param(:access_type, conn) |> with_param(:prompt, conn) |> with_param(:login_hint, conn) - |> with_param(:state, conn) + |> with_state_param(conn) opts = oauth_client_options_from_conn(conn) redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) diff --git a/mix.exs b/mix.exs index 6449335..c999730 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule UeberauthGoogle.Mixfile do defp deps do [ {:oauth2, "~> 1.0 or ~> 2.0"}, - {:ueberauth, "~> 0.6.3"}, + {:ueberauth, "~> 0.7.0"}, {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false}, {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false}, {:mock, "~> 0.3", only: :test} diff --git a/mix.lock b/mix.lock index e97382e..1c43d1f 100644 --- a/mix.lock +++ b/mix.lock @@ -17,15 +17,16 @@ "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, + "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "e6d886252f1a41f4ba06ecf2b4c8d38760b34b1c08a11c28f7397b2e03995964"}, "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, "oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "881b8364ac7385f9fddc7949379cbe3f7081da37233a1aa7aab844670a91e7e7"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, - "plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"}, - "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, + "plug": {:hex, :plug, "1.11.1", "f2992bac66fdae679453c9e86134a4201f6f43a687d8ff1cd1b2862d53c80259", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "23524e4fefbb587c11f0833b3910bfb414bf2e2534d61928e920f54e3a1b881f"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm", "603561dc0fd62f4f2ea9b890f4e20e1a0d388746d6e20557cafb1b16950de88c"}, - "ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"}, + "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, + "ueberauth": {:hex, :ueberauth, "0.7.0", "9c44f41798b5fa27f872561b6f7d2bb0f10f03fdd22b90f454232d7b087f4b75", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2efad9022e949834f16cc52cd935165049d81fa9e925690f91035c2e4b58d905"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, } diff --git a/test/strategy/google_test.exs b/test/strategy/google_test.exs index d5f0b93..bb4d642 100644 --- a/test/strategy/google_test.exs +++ b/test/strategy/google_test.exs @@ -4,6 +4,7 @@ defmodule Ueberauth.Strategy.GoogleTest do import Mock import Plug.Conn + import Ueberauth.Strategy.Helpers setup_with_mocks([ {OAuth2.Client, [:passthrough], @@ -12,7 +13,12 @@ defmodule Ueberauth.Strategy.GoogleTest do get: &oauth2_get/4 ]} ]) do - :ok + # Create a connection with Ueberauth's CSRF cookies so they can be recycled during tests + routes = Ueberauth.init([]) + csrf_conn = conn(:get, "/auth/google", %{}) |> Ueberauth.call(routes) + csrf_state = with_state_param([], csrf_conn) |> Keyword.get(:state) + + {:ok, csrf_conn: csrf_conn, csrf_state: csrf_state} end def set_options(routes, conn, opt) do @@ -47,6 +53,13 @@ defmodule Ueberauth.Strategy.GoogleTest do def oauth2_get(%{token: %{access_token: "userinfo_token"}}, "example.com/scooby", _, _), do: response(%{"sub" => "1234_scooby", "name" => "Scooby Doo"}) + defp set_csrf_cookies(conn, csrf_conn) do + conn + |> init_test_session(%{}) + |> recycle_cookies(csrf_conn) + |> fetch_cookies() + end + test "handle_request! redirects to appropriate auth uri" do conn = conn(:get, "/auth/google", %{}) # Make sure the hd and scope params are included for good measure @@ -70,8 +83,8 @@ defmodule Ueberauth.Strategy.GoogleTest do } = Plug.Conn.Query.decode(redirect_uri.query) end - test "handle_callback! assigns required fields on successful auth" do - conn = conn(:get, "/auth/google/callback", %{code: "success_code"}) + test "handle_callback! assigns required fields on successful auth", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "success_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init([]) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.credentials.token == "success_token" @@ -80,42 +93,54 @@ defmodule Ueberauth.Strategy.GoogleTest do assert auth.uid == "1234_fred" end - test "uid_field is picked according to the specified option" do - conn = conn(:get, "/auth/google/callback", %{code: "uid_code"}) + test "uid_field is picked according to the specified option", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "uid_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init() |> set_options(conn, uid_field: "uid_field") assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Daphne Blake" assert auth.uid == "1234_daphne" end - test "userinfo is fetched according to userinfo_endpoint" do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + test "userinfo is fetched according to userinfo_endpoint", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: "example.com/shaggy") assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Norville Rogers" end - test "userinfo can be set via runtime config with default" do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + test "userinfo can be set via runtime config with default", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET", "example.com/shaggy"}) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Norville Rogers" end - test "userinfo uses default library value if runtime env not found" do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + test "userinfo uses default library value if runtime env not found", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET"}) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Velma Dinkley" end - test "userinfo can be set via runtime config" do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code"}) + test "userinfo can be set via runtime config", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do + conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "UEBERAUTH_SCOOBY_DOO"}) - System.put_env("UEBERAUTH_SCOOBY_DOO", "example.com/scooby") assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Scooby Doo" System.delete_env("UEBERAUTH_SCOOBY_DOO") end + + test "state param is present in the redirect uri" do + conn = conn(:get, "/auth/google", %{}) + + routes = Ueberauth.init() + resp = Ueberauth.call(conn, routes) + + assert [location] = get_resp_header(resp, "location") + + redirect_uri = URI.parse(location) + + assert redirect_uri.query =~ "state=" + end end From 79090d2d98db10409e2d679c70249db7569cf50e Mon Sep 17 00:00:00 2001 From: Greg Rychlewski Date: Thu, 15 Jul 2021 19:18:29 -0400 Subject: [PATCH 52/62] mix format --- test/strategy/google_test.exs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/test/strategy/google_test.exs b/test/strategy/google_test.exs index bb4d642..48743ab 100644 --- a/test/strategy/google_test.exs +++ b/test/strategy/google_test.exs @@ -84,7 +84,9 @@ defmodule Ueberauth.Strategy.GoogleTest do end test "handle_callback! assigns required fields on successful auth", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do - conn = conn(:get, "/auth/google/callback", %{code: "success_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + conn = + conn(:get, "/auth/google/callback", %{code: "success_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + routes = Ueberauth.init([]) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.credentials.token == "success_token" @@ -102,28 +104,36 @@ defmodule Ueberauth.Strategy.GoogleTest do end test "userinfo is fetched according to userinfo_endpoint", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + conn = + conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: "example.com/shaggy") assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Norville Rogers" end test "userinfo can be set via runtime config with default", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + conn = + conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET", "example.com/shaggy"}) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Norville Rogers" end test "userinfo uses default library value if runtime env not found", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + conn = + conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "NOT_SET"}) assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) assert auth.info.name == "Velma Dinkley" end test "userinfo can be set via runtime config", %{csrf_state: csrf_state, csrf_conn: csrf_conn} do - conn = conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + conn = + conn(:get, "/auth/google/callback", %{code: "userinfo_code", state: csrf_state}) |> set_csrf_cookies(csrf_conn) + routes = Ueberauth.init() |> set_options(conn, userinfo_endpoint: {:system, "UEBERAUTH_SCOOBY_DOO"}) System.put_env("UEBERAUTH_SCOOBY_DOO", "example.com/scooby") assert %Plug.Conn{assigns: %{ueberauth_auth: auth}} = Ueberauth.call(conn, routes) From 1b830f6116e9b5f48bf004172d07634b5030cc33 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Thu, 15 Jul 2021 19:52:17 -0400 Subject: [PATCH 53/62] Versioning --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b877ce4..b6db4bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ # Changelog -## v0.11.0 (Unreleased) +## (Unreleased) +## v0.10.1 + +* Misc doc changes [81](https://github.com/ueberauth/ueberauth_google/pull/81) +* Upgrade Ueberauth and Refactor CSRF State Logic [82](https://github.com/ueberauth/ueberauth_google/pull/82) ## v0.10.0 - 2020-10-20 From ee6f9ddff059a0b8eb2cddaf64d3eefcc2202450 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Thu, 15 Jul 2021 20:07:17 -0400 Subject: [PATCH 54/62] Update version --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index c999730..6d3d0be 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule UeberauthGoogle.Mixfile do use Mix.Project @source_url "https://github.com/ueberauth/ueberauth_google" - @version "0.10.0" + @version "0.10.1" def project do [ From e38f39b8e0d6ecc0fdf5ba0d6e1cd2546ac41397 Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Wed, 8 Sep 2021 14:00:35 -0700 Subject: [PATCH 55/62] Remove :applications instructions from readme Elixir 1.4 (released in 2016) add application inference, so now in almost all situations it is not necessary to add a dependency to `:applications`. And if you set just a single application in `:applications` then you will break your release. Since ueberauth_google only support Elixir 1.8 and up, we don't need to mention :applications anymore --- README.md | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9885737..6ed15b0 100644 --- a/README.md +++ b/README.md @@ -24,17 +24,7 @@ end ``` -3. Add the strategy to your applications: - - ```elixir - def application do - [ - applications: [:ueberauth_google] - ] - end - ``` - -4. Add Google to your Überauth configuration: +3. Add Google to your Überauth configuration: ```elixir config :ueberauth, Ueberauth, @@ -43,7 +33,7 @@ ] ``` -5. Update your provider configuration: +4. Update your provider configuration: Use that if you want to read client ID/secret from the environment variables in the compile time: @@ -63,7 +53,7 @@ client_secret: {System, :get_env, ["GOOGLE_CLIENT_SECRET"]} ``` -6. Include the Überauth plug in your controller: +5. Include the Überauth plug in your controller: ```elixir defmodule MyApp.AuthController do @@ -73,7 +63,7 @@ end ``` -7. Create the request and callback routes if you haven't already: +6. Create the request and callback routes if you haven't already: ```elixir scope "/auth", MyApp do @@ -84,7 +74,7 @@ end ``` -8. Your controller needs to implement callbacks to deal with `Ueberauth.Auth` and `Ueberauth.Failure` responses. +7. Your controller needs to implement callbacks to deal with `Ueberauth.Auth` and `Ueberauth.Failure` responses. For an example implementation see the [Überauth Example](https://github.com/ueberauth/ueberauth_example) application. From facf8b7bb95b52ae3ae0c1479109525b065bab32 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sun, 17 Oct 2021 14:14:51 -0400 Subject: [PATCH 56/62] chore: add workflows --- .github/CODEOWNERS | 3 +++ .github/workflows/ci.yml | 51 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 32 ++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..09f3be6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Order is important. The last matching pattern takes the most precedence. +# Default owners for everything in the repo. +* @ueberauth/developers diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d57516b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: Continuous Integration + +on: + pull_request: + types: [opened, reopened, synchronize] + push: + branches: + - 'master' +jobs: + Test: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v1 + + - name: Set up Elixir + uses: erlef/setup-elixir@v1 + with: + elixir-version: '1.11' + otp-version: '22.3' + + - name: Install Dependencies + run: | + mix local.rebar --force + mix local.hex --force + mix deps.get + - name: Run Tests + run: mix test + + Linting: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v1 + + - name: Set up Elixir + uses: erlef/setup-elixir@v1 + with: + elixir-version: '1.11' + otp-version: '22.3' + + - name: Install Dependencies + run: | + mix local.rebar --force + mix local.hex --force + mix deps.get + - name: Run Formatter + run: mix format --check-formatted + + - name: Run Credo + run: mix credo diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..61d5739 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: Hexpm Release + +on: + release: + types: [published] + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Elixir + uses: erlef/setup-elixir@v1 + with: + elixir-version: '1.11' + otp-version: '22.3' + - name: Restore dependencies cache + uses: actions/cache@v2 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} + restore-keys: ${{ runner.os }}-mix- + - name: Install dependencies + run: | + mix local.rebar --force + mix local.hex --force + mix deps.get + - name: Run Hex Publish + run: mix hex.publish --yes + env: + HEX_API_KEY: ${{ secrets.HEX_API_KEY }} From 65e506b2f6765181a55efc7050d7ceb315cd5c56 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sun, 17 Oct 2021 14:39:54 -0400 Subject: [PATCH 57/62] chore: fix ci --- lib/ueberauth/strategy/google.ex | 12 +++++++++--- lib/ueberauth/strategy/google/oauth.ex | 12 +++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 1acbbd4..e209777 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -45,6 +45,7 @@ defmodule Ueberauth.Strategy.Google do case Ueberauth.Strategy.Google.OAuth.get_access_token(params, opts) do {:ok, token} -> fetch_user(conn, token) + {:error, {error_code, error_description}} -> set_errors!(conn, [error(error_code, error_description)]) end @@ -78,9 +79,9 @@ defmodule Ueberauth.Strategy.Google do Includes the credentials from the google response. """ def credentials(conn) do - token = conn.private.google_token - scope_string = (token.other_params["scope"] || "") - scopes = String.split(scope_string, ",") + token = conn.private.google_token + scope_string = token.other_params["scope"] || "" + scopes = String.split(scope_string, ",") %Credentials{ expires: !!token.expires_at, @@ -133,8 +134,10 @@ defmodule Ueberauth.Strategy.Google do case option(conn, :userinfo_endpoint) do {:system, varname, default} -> System.get_env(varname) || default + {:system, varname} -> System.get_env(varname) || Keyword.get(default_options(), :userinfo_endpoint) + other -> other end @@ -144,10 +147,13 @@ defmodule Ueberauth.Strategy.Google do case resp do {:ok, %OAuth2.Response{status_code: 401, body: _body}} -> set_errors!(conn, [error("token", "unauthorized")]) + {:ok, %OAuth2.Response{status_code: status_code, body: user}} when status_code in 200..399 -> put_private(conn, :google_user, user) + {:error, %OAuth2.Response{status_code: status_code}} -> set_errors!(conn, [error("OAuth2", status_code)]) + {:error, %OAuth2.Error{reason: reason}} -> set_errors!(conn, [error("OAuth2", reason)]) end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 930769c..a8b1d19 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -12,11 +12,11 @@ defmodule Ueberauth.Strategy.Google.OAuth do use OAuth2.Strategy @defaults [ - strategy: __MODULE__, - site: "https://accounts.google.com", - authorize_url: "/o/oauth2/v2/auth", - token_url: "https://www.googleapis.com/oauth2/v4/token" - ] + strategy: __MODULE__, + site: "https://accounts.google.com", + authorize_url: "/o/oauth2/v2/auth", + token_url: "https://www.googleapis.com/oauth2/v4/token" + ] @doc """ Construct a client for requests to Google. @@ -54,9 +54,11 @@ defmodule Ueberauth.Strategy.Google.OAuth do case opts |> client |> OAuth2.Client.get_token(params) do {:error, %{body: %{"error" => error, "error_description" => description}}} -> {:error, {error, description}} + {:ok, %{token: %{access_token: nil} = token}} -> %{"error" => error, "error_description" => description} = token.other_params {:error, {error, description}} + {:ok, %{token: token}} -> {:ok, token} end From becc95360ea5e2a9ffc6bc1481d2514440b5194b Mon Sep 17 00:00:00 2001 From: Yordis Prieto Lazo Date: Sun, 17 Oct 2021 14:50:39 -0400 Subject: [PATCH 58/62] chore: fix credo --- lib/ueberauth/strategy/google.ex | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index e209777..765fdbf 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -130,25 +130,14 @@ defmodule Ueberauth.Strategy.Google do # userinfo_endpoint from https://accounts.google.com/.well-known/openid-configuration # the userinfo_endpoint may be overridden in options when necessary. - path = - case option(conn, :userinfo_endpoint) do - {:system, varname, default} -> - System.get_env(varname) || default - - {:system, varname} -> - System.get_env(varname) || Keyword.get(default_options(), :userinfo_endpoint) - - other -> - other - end - - resp = Ueberauth.Strategy.Google.OAuth.get(token, path) + resp = Ueberauth.Strategy.Google.OAuth.get(token, get_userinfo_endpoint(conn)) case resp do {:ok, %OAuth2.Response{status_code: 401, body: _body}} -> set_errors!(conn, [error("token", "unauthorized")]) - {:ok, %OAuth2.Response{status_code: status_code, body: user}} when status_code in 200..399 -> + {:ok, %OAuth2.Response{status_code: status_code, body: user}} + when status_code in 200..399 -> put_private(conn, :google_user, user) {:error, %OAuth2.Response{status_code: status_code}} -> @@ -159,6 +148,19 @@ defmodule Ueberauth.Strategy.Google do end end + defp get_userinfo_endpoint(conn) do + case option(conn, :userinfo_endpoint) do + {:system, varname, default} -> + System.get_env(varname) || default + + {:system, varname} -> + System.get_env(varname) || Keyword.get(default_options(), :userinfo_endpoint) + + other -> + other + end + end + defp with_param(opts, key, conn) do if value = conn.params[to_string(key)], do: Keyword.put(opts, key, value), else: opts end From c8871937af9a34dca4bd496c051362585093a4eb Mon Sep 17 00:00:00 2001 From: GK Date: Sat, 9 Dec 2023 10:28:05 +0100 Subject: [PATCH 59/62] feat: Do not throw when token is invalid --- lib/ueberauth/strategy/google.ex | 13 ++----------- lib/ueberauth/strategy/google/oauth.ex | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index e3f1f6f..2f74f52 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -169,17 +169,8 @@ defmodule Ueberauth.Strategy.Google do end end - defp get_userinfo_endpoint(conn) do - case option(conn, :userinfo_endpoint) do - {:system, varname, default} -> - System.get_env(varname) || default - - {:system, varname} -> - System.get_env(varname) || Keyword.get(default_options(), :userinfo_endpoint) - - other -> - other - end + defp get_userinfo_endpoint(_conn) do + Ueberauth.Strategy.Google.OAuth.config()[:fetch_user_url] end defp with_param(opts, key, conn) do diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 7f426eb..8e7c616 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -61,7 +61,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do end def get_access_token(params \\ [], opts \\ []) do - case opts |> client |> OAuth2.Client.get_token!(params) do + case opts |> client |> OAuth2.Client.get_token(params) do {:error, %{body: %{"error" => error, "error_description" => description}}} -> {:error, {error, description}} From eeec9ce10b75d7e58d144454853e5610cd470c4a Mon Sep 17 00:00:00 2001 From: GK Date: Sat, 9 Dec 2023 10:41:20 +0100 Subject: [PATCH 60/62] fix: Fix build --- lib/ueberauth/strategy/google.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 2f74f52..1f85e0b 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -33,7 +33,7 @@ defmodule Ueberauth.Strategy.Google do |> with_param(:access_type, conn) |> with_param(:prompt, conn) |> with_param(:login_hint, conn) - |> with_state_param(conn) + # |> with_state_param(conn) opts = oauth_client_options_from_conn(conn) redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) From 8ea58c6b160aeb96f3f425698bbd377fd5fea732 Mon Sep 17 00:00:00 2001 From: GK Date: Sat, 9 Dec 2023 20:49:54 +0100 Subject: [PATCH 61/62] feat: Ignore csrf --- lib/ueberauth/strategy/google.ex | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 1f85e0b..946b467 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -5,6 +5,7 @@ defmodule Ueberauth.Strategy.Google do use Ueberauth.Strategy, uid_field: :sub, + ignores_csrf_attack: true, default_scope: "email", hd: nil, userinfo_endpoint: "https://www.googleapis.com/oauth2/v3/userinfo" @@ -186,9 +187,14 @@ defmodule Ueberauth.Strategy.Google do request_options = conn.private[:ueberauth_request_options].options case {request_options[:client_id], request_options[:client_secret]} do - {nil, _} -> base_options - {_, nil} -> base_options - {id, secret} -> [client_id: id, client_secret: secret] ++ base_options + {nil, _} -> + IO.puts "[google strategy] no client_id" + base_options + {_, nil} -> + IO.puts "[google strategy] no client_client" + base_options + {id, secret} -> + [client_id: id, client_secret: secret] ++ base_options end end From 581848daa17ec0f6c5a92eafcffc5b03d5d03833 Mon Sep 17 00:00:00 2001 From: GK Date: Sat, 28 Dec 2024 12:17:05 +0100 Subject: [PATCH 62/62] feat: Support local google token verification --- config/config.exs | 7 +- lib/ueberauth/strategy/google.ex | 35 ++++------ lib/ueberauth/strategy/google/jwks.ex | 94 ++++++++++++++++++++++++++ lib/ueberauth/strategy/google/oauth.ex | 59 +++++++++++++++- lib/ueberauth_google.ex | 11 ++- lib/your_app/application.ex | 13 ++++ mix.exs | 16 +++-- mix.lock | 17 ++--- 8 files changed, 210 insertions(+), 42 deletions(-) create mode 100644 lib/ueberauth/strategy/google/jwks.ex create mode 100644 lib/your_app/application.ex diff --git a/config/config.exs b/config/config.exs index 795f918..e1b540a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -6,6 +6,7 @@ config :ueberauth, Ueberauth, ] config :ueberauth, Ueberauth.Strategy.Google.OAuth, - client_id: "client_id", - client_secret: "client_secret", - token_url: "token_url" + client_id: "your_client_id", + client_secret: "your_client_secret", + token_url: "token_url", + jwks_url: "https://www.googleapis.com/oauth2/v3/certs" diff --git a/lib/ueberauth/strategy/google.ex b/lib/ueberauth/strategy/google.ex index 946b467..11994c6 100644 --- a/lib/ueberauth/strategy/google.ex +++ b/lib/ueberauth/strategy/google.ex @@ -34,7 +34,8 @@ defmodule Ueberauth.Strategy.Google do |> with_param(:access_type, conn) |> with_param(:prompt, conn) |> with_param(:login_hint, conn) - # |> with_state_param(conn) + + # |> with_state_param(conn) opts = oauth_client_options_from_conn(conn) redirect!(conn, Ueberauth.Strategy.Google.OAuth.authorize_url!(params, opts)) @@ -64,6 +65,8 @@ defmodule Ueberauth.Strategy.Google do case verify_token(conn, client, id_token) do {:ok, user} -> + IO.inspect(user) + conn |> put_private(:google_token, OAuth2.AccessToken.new(id_token)) |> put_private(:google_user, user) @@ -188,11 +191,13 @@ defmodule Ueberauth.Strategy.Google do case {request_options[:client_id], request_options[:client_secret]} do {nil, _} -> - IO.puts "[google strategy] no client_id" + IO.puts("[google strategy] no client_id") base_options + {_, nil} -> - IO.puts "[google strategy] no client_client" + IO.puts("[google strategy] no client_client") base_options + {id, secret} -> [client_id: id, client_secret: secret] ++ base_options end @@ -205,32 +210,22 @@ defmodule Ueberauth.Strategy.Google do defp verify_token(conn, client, id_token) do config = Ueberauth.Strategy.Google.OAuth.config() allowed_client_ids = config[:allowed_client_ids] - url = config[:token_info_url] - params = %{"id_token" => id_token} - - resp = - OAuth2.Client.get(client, url, [], - params: params, - ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()] - ) normalized_allowed_client_ids = if is_binary(allowed_client_ids), do: String.split(allowed_client_ids, ","), else: allowed_client_ids || [] - case resp do - {:ok, %OAuth2.Response{status_code: 200, body: %{"aud" => aud} = body}} -> - if Enum.member?(normalized_allowed_client_ids, aud) do - {:ok, body} + case Ueberauth.Strategy.Google.OAuth.verify_id_token(id_token) do + {:ok, claims} -> + if Enum.member?(normalized_allowed_client_ids, claims["aud"]) do + {:ok, claims} else - {:error, - "Unknown client id #{aud}, allowed client ids are #{inspect(allowed_client_ids)}"} + {:error, "Unknown client id #{claims["aud"]}, allowed client ids are #{inspect(allowed_client_ids)}"} end - resp -> - IO.inspect(resp) - {:error, "Token verification failed"} + {:error, reason} -> + {:error, "Token verification failed: #{reason}"} end end end diff --git a/lib/ueberauth/strategy/google/jwks.ex b/lib/ueberauth/strategy/google/jwks.ex new file mode 100644 index 0000000..2544334 --- /dev/null +++ b/lib/ueberauth/strategy/google/jwks.ex @@ -0,0 +1,94 @@ +defmodule Ueberauth.Strategy.Google.JWKS do + @moduledoc """ + Handles Google's JWKS (JSON Web Key Set) caching and verification. + """ + + use GenServer + require Logger + + @default_jwks_url "https://www.googleapis.com/oauth2/v3/certs" + # Refresh 5 minutes before expiry + @cache_early_refresh_seconds 300 + + def start_link(opts \\ []) do + GenServer.start_link(__MODULE__, opts, name: __MODULE__) + end + + def init(_opts) do + {:ok, %{jwks: nil, last_refresh: nil, expires_at: nil}} + end + + def get_key(kid) do + GenServer.call(__MODULE__, {:get_key, kid}) + end + + def handle_call({:get_key, kid}, _from, state) do + with {:ok, state} <- ensure_fresh_keys(state), + {:ok, key} <- find_key(kid, state.jwks) do + {:reply, {:ok, key}, state} + else + error -> {:reply, error, state} + end + end + + defp ensure_fresh_keys(%{jwks: nil} = state) do + fetch_keys(state) + end + + defp ensure_fresh_keys(%{expires_at: expires_at} = state) do + now = System.system_time(:second) + + if now + @cache_early_refresh_seconds >= expires_at do + fetch_keys(state) + else + {:ok, state} + end + end + + defp fetch_keys(state) do + jwks_url = Application.get_env(:ueberauth, Ueberauth.Strategy.Google.OAuth)[:jwks_url] || @default_jwks_url + + case HTTPoison.get(jwks_url) do + {:ok, %{status_code: 200, body: body, headers: headers}} -> + expires_at = extract_max_age_from_headers(headers) + jwks = body |> Jason.decode!() + + {:ok, %{state | jwks: jwks, last_refresh: System.system_time(:second), expires_at: expires_at}} + + error -> + Logger.error("Failed to fetch JWKS: #{inspect(error)}") + {:error, :jwks_fetch_failed} + end + end + + defp extract_max_age_from_headers(headers) do + headers + |> Enum.find(fn {key, _} -> String.downcase(key) == "cache-control" end) + |> case do + {_, value} -> + value + |> String.split(",") + |> Enum.find(&String.contains?(&1, "max-age=")) + |> case do + # Default 1 hour + nil -> + System.system_time(:second) + 3600 + + max_age -> + [_, seconds] = Regex.run(~r/max-age=(\d+)/, max_age) + System.system_time(:second) + String.to_integer(seconds) + end + + # Default 1 hour + nil -> + System.system_time(:second) + 3600 + end + end + + defp find_key(kid, %{"keys" => keys}) do + case Enum.find(keys, &(&1["kid"] == kid)) do + nil -> {:error, :key_not_found} + key -> {:ok, key} + end + end +end diff --git a/lib/ueberauth/strategy/google/oauth.ex b/lib/ueberauth/strategy/google/oauth.ex index 8e7c616..a2c4ff1 100644 --- a/lib/ueberauth/strategy/google/oauth.ex +++ b/lib/ueberauth/strategy/google/oauth.ex @@ -78,9 +78,7 @@ defmodule Ueberauth.Strategy.Google.OAuth do client = opts |> client - |> OAuth2.Client.get_token!(params, [], - ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()] - ) + |> OAuth2.Client.get_token!(params, [], ssl_options: [verify: :verify_none, cacertfile: :certifi.cacertfile()]) client.token end @@ -106,4 +104,59 @@ defmodule Ueberauth.Strategy.Google.OAuth do defp resolve_value({m, f, a}) when is_atom(m) and is_atom(f), do: apply(m, f, a) defp resolve_value(v), do: v + + @doc """ + Verifies the ID token from Google OAuth2 response. + Returns {:ok, claims} if the token is valid, {:error, reason} otherwise. + """ + def verify_id_token(id_token) do + with {:ok, %{"kid" => kid}} <- peek_protected(id_token), + {:ok, key} <- Ueberauth.Strategy.Google.JWKS.get_key(kid), + jwk <- JOSE.JWK.from_map(key), + {:ok, claims} <- verify_token_signature(id_token, jwk) do + verify_claims(claims) + end + end + + defp peek_protected(token) do + case JOSE.JWS.peek_protected(token) do + protected when is_binary(protected) -> + case Jason.decode(protected) do + {:ok, %{"kid" => _kid} = claims} -> {:ok, claims} + _ -> {:error, :invalid_token_format} + end + + other -> + IO.inspect(other) + {:error, :invalid_token_format} + end + end + + defp verify_token_signature(token, jwk) do + case JOSE.JWT.verify(jwk, token) do + {true, %JOSE.JWT{fields: claims}, _} -> {:ok, claims} + {false, _, _} -> {:error, :invalid_signature} + _ -> {:error, :verification_failed} + end + end + + defp verify_claims(claims) do + now = System.system_time(:second) + iss = "https://accounts.google.com" + + cond do + claims["iss"] != iss -> + {:error, :invalid_issuer} + + claims["exp"] < now -> + {:error, :token_expired} + + # Allow 5 minutes clock skew + claims["iat"] > now + 300 -> + {:error, :invalid_issued_at} + + true -> + {:ok, claims} + end + end end diff --git a/lib/ueberauth_google.ex b/lib/ueberauth_google.ex index 8fc6df1..b7eec63 100644 --- a/lib/ueberauth_google.ex +++ b/lib/ueberauth_google.ex @@ -1,3 +1,12 @@ defmodule UeberauthGoogle do - @moduledoc false + use Application + + def start(_type, _args) do + children = [ + Ueberauth.Strategy.Google.JWKS + ] + + opts = [strategy: :one_for_one, name: UeberauthGoogle.Supervisor] + Supervisor.start_link(children, opts) + end end diff --git a/lib/your_app/application.ex b/lib/your_app/application.ex new file mode 100644 index 0000000..38ff8f9 --- /dev/null +++ b/lib/your_app/application.ex @@ -0,0 +1,13 @@ +defmodule YourApp.Application do + use Application + + def start(_type, _args) do + children = [ + # ... your other children ... + Ueberauth.Strategy.Google.JWKS + ] + + opts = [strategy: :one_for_one, name: YourApp.Supervisor] + Supervisor.start_link(children, opts) + end +end diff --git a/mix.exs b/mix.exs index e665486..c7d257a 100644 --- a/mix.exs +++ b/mix.exs @@ -19,19 +19,21 @@ defmodule UeberauthGoogle.Mixfile do def application do [ + mod: {UeberauthGoogle, []}, extra_applications: [:logger, :oauth2, :ueberauth] ] end defp deps do [ - {:oauth2, "~> 0.9.4"}, - {:ueberauth, "~> 0.4"}, - - {:credo, "~> 0.5", only: [:dev, :test]}, - {:earmark, ">= 0.0.0", only: :dev}, - {:ex_doc, "~> 0.3", only: :dev}, - {:jason, "~> 1.0"} + {:oauth2, "~> 0.9.4"}, + {:ueberauth, "~> 0.4"}, + {:credo, "~> 0.5", only: [:dev, :test]}, + {:earmark, ">= 0.0.0", only: :dev}, + {:ex_doc, "~> 0.3", only: :dev}, + {:jason, "~> 1.0"}, + {:jose, "~> 1.11"}, + {:httpoison, "~> 2.0"} ] end diff --git a/mix.lock b/mix.lock index 4e944f2..c130b8e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,22 +1,23 @@ %{ "bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], [], "hexpm", "4fb7b2f7b04af13cf210b132f8d10db52d4a57d36cb974e8025d7fdb12ca97fc"}, - "certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"}, + "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm", "90bca5180fe64c47343969ad3e32bf1edc18d929689e8c00c810655a7a391427"}, "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm", "db7b13d74a9edc54d3681762154d164d4a661cd27673cca80760344449877664"}, "ex_doc": {:hex, :ex_doc, "0.13.2", "1059a588d2ad3ffab25a0b85c58abf08e437d3e7a9124ac255e1d15cec68ab79", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm", "b2c71148cb42a23e3610b7810b1600d61b10e1a9eb4e8a5db35d398057469528"}, - "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"}, - "httpoison": {:hex, :httpoison, "0.9.1", "6c2b4eaf2588a6f3ef29663d28c992531ca3f0bc832a97e0359bc822978e1c5d", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"}, + "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, + "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"}, + "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], [], "hexpm", "8aad5eef6d9d20899918868b10e79fc2dafe72a79102882c2947999c10b30cd9"}, - "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.2", "221d2d3f727e89d80de5e1610fc2ce444514aa56f873da1b8fc9c033143e5d6a", [:mix], []}, "oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"}, - "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, + "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "plug": {:hex, :plug, "1.2.0", "496bef96634a49d7803ab2671482f0c5ce9ce0b7b9bc25bc0ae8e09859dd2004", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "2788381ac3aa424a6dbf308aad08a1ebdefdcaad4fc8d21be56817d23a923ace"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "ueberauth": {:hex, :ueberauth, "0.4.0", "bc72d5e5a7bdcbfcf28a756e34630816edabc926303bdce7e171f7ac7ffa4f91", [:mix], [{:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d3bcb678a8fdcd0add619eacb3e45e51003f50aa434ea732746ea25c37f6c92b"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, }