defmodule Ueberauth.Strategy.Hubspot do
use Ueberauth.Strategy,
oauth2_module: Ueberauth.Strategy.Hubspot.OAuth
def handle_request!(conn) do
scope = conn.params["scope"] || "oauth"
opts = [scopes: scope, redirect_uri: callback_url(conn)] |> with_state_param(conn)
redirect!(conn, Ueberauth.Strategy.Hubspot.OAuth.authorize_url!(opts))
end
def handle_callback!(%Plug.Conn{params: %{"code" => code}} = conn) do
redirect_uri = callback_url(conn)
module = option(conn, :oauth2_module)
result =
module.get_token!([code: code, redirect_uri: redirect_uri], redirect_uri: redirect_uri)
case result do
%OAuth2.AccessToken{} = access_token ->
if access_token.access_token == nil do
err = access_token.other_params["error"]
desc = access_token.other_params["error_description"]
set_errors!(conn, [error(err, desc)])
else
conn
|> put_private(:hubspot_token, access_token)
|> fetch_access_token_info(access_token)
end
{:error, client} ->
set_errors!(conn, [error(client.body["error"], client.body["error_description"])])
end
end
def handle_callback!(conn) do
set_errors!(conn, [error("missing_code", "No code received")])
end
def handle_cleanup!(conn) do
put_private(conn, :hubspot_token, nil)
end
def credentials(conn) do
token = conn.private.hubspot_token
%Ueberauth.Auth.Credentials{
expires: !!token.expires_at,
expires_at: token.expires_at,
scopes: conn.private.access_token_info["scopes"],
refresh_token: token.refresh_token,
token: token.access_token,
token_type: token.token_type
}
end
def extra(conn) do
access_token_info = conn.private.access_token_info
%Ueberauth.Auth.Extra{
raw_info: %{
hub_id: access_token_info["hub_id"],
app_id: access_token_info["app_id"]
}
}
end
def info(conn) do
%Ueberauth.Auth.Info{
email: conn.private.access_token_info["user"]
}
end
# Private
defp fetch_access_token_info(conn, %OAuth2.AccessToken{} = access_token) do
# We need to hit another endpoint to get the user's email address.
# We just stick this response in the conn and fetch it out in the strategy callbacks
base_api_url = Ueberauth.Strategy.Hubspot.OAuth.base_api_url()
url = "#{base_api_url}/oauth/v1/access-tokens/#{access_token.access_token}"
resp = Ueberauth.Strategy.Hubspot.OAuth.get(url)
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: body}}
when status_code in 200..399 ->
put_private(conn, :access_token_info, body)
{:error, %OAuth2.Error{reason: reason}} ->
set_errors!(conn, [error("OAuth2", reason)])
end
end
defp option(conn, key) do
default = Keyword.get(default_options(), key)
conn
|> options
|> Keyword.get(key, default)
end
defp option(nil, conn, key), do: option(conn, key)
defp option(value, _conn, _key), do: value
end