81 lines
2.2 KiB
Elixir
81 lines
2.2 KiB
Elixir
defmodule WhoNeedHelp.GoogleAuthFake do
|
|
@behaviour WhoNeedHelp.GoogleAuth
|
|
|
|
@impl true
|
|
def enabled?, do: true
|
|
|
|
@impl true
|
|
def authorize_url(redirect_uri) do
|
|
{:ok,
|
|
%{
|
|
url:
|
|
"https://accounts.google.example/authorize?" <>
|
|
URI.encode_query(%{"redirect_uri" => redirect_uri, "state" => "google-test-state"}),
|
|
session_params: %{
|
|
state: "google-test-state",
|
|
nonce: "google-test-nonce",
|
|
code_verifier: "google-test-verifier"
|
|
}
|
|
}}
|
|
end
|
|
|
|
@impl true
|
|
def callback(_redirect_uri, params, %{state: state}) do
|
|
cond do
|
|
params["state"] != state ->
|
|
{:error, :invalid_state}
|
|
|
|
params["code"] in [nil, ""] ->
|
|
{:error, :missing_code}
|
|
|
|
params["email_verified"] == "false" ->
|
|
{:error, :email_not_verified}
|
|
|
|
true ->
|
|
email = params["email"] || "google-user@example.com"
|
|
|
|
{:ok,
|
|
%{
|
|
provider_uid: params["uid"] || "google-user-42",
|
|
email: email,
|
|
email_verified: true,
|
|
display_name: params["name"] || "Google Neighbor",
|
|
hosted_domain: normalize_hosted_domain(params["hd"])
|
|
}}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def client_id, do: {:ok, "google-native-test-client.apps.googleusercontent.com"}
|
|
|
|
@impl true
|
|
def verify_id_token(id_token, nonce) do
|
|
with ["native-test", encoded_nonce, provider_uid, encoded_email, encoded_name] <-
|
|
String.split(id_token, ":", parts: 5),
|
|
{:ok, token_nonce} <- Base.url_decode64(encoded_nonce, padding: false),
|
|
true <- token_nonce == nonce,
|
|
{:ok, email} <- Base.url_decode64(encoded_email, padding: false),
|
|
{:ok, name} <- Base.url_decode64(encoded_name, padding: false) do
|
|
{:ok,
|
|
%{
|
|
provider_uid: provider_uid,
|
|
email: String.downcase(email),
|
|
email_verified: true,
|
|
display_name: name,
|
|
hosted_domain: nil
|
|
}}
|
|
else
|
|
_invalid_or_replayed -> {:error, :invalid_id_token}
|
|
end
|
|
end
|
|
|
|
defp normalize_hosted_domain(domain) when is_binary(domain) do
|
|
case domain |> String.trim() |> String.downcase() do
|
|
"" -> nil
|
|
normalized -> normalized
|
|
end
|
|
end
|
|
|
|
defp normalize_hosted_domain(_domain), do: nil
|
|
end
|