Switch to native Elixir dependency for OAuth (#14)

* Switch to OAuther from erlang-oauth

* Clean up warnings

* Cleanup per PR review.
This commit is contained in:
Gordon Brown 2017-03-15 13:15:49 -06:00 committed by Sean Callan
parent 2d2d94803d
commit b4b7096e60
5 changed files with 78 additions and 44 deletions

View File

@ -99,25 +99,28 @@ defmodule Ueberauth.Strategy.Twitter do
end
defp fetch_user(conn, token) do
params = [include_entities: false, skip_status: true, include_email: true]
params = [{"include_entities", false}, {"skip_status", true}, {"include_email", true}]
case Twitter.OAuth.get("/1.1/account/verify_credentials.json", params, token) do
{:ok, {{_, 401, _}, _, _}} ->
{:ok, %{status_code: 401, body: _, headers: _}} ->
set_errors!(conn, [error("token", "unauthorized")])
{:ok, {{_, status_code, _}, _, body}} when status_code in 200..399 ->
body = body |> List.to_string |> Poison.decode!
{:ok, %{status_code: status_code, body: body, headers: _}} when status_code in 200..399 ->
body = Poison.decode!(body)
conn
|> put_private(:twitter_token, token)
|> put_private(:twitter_user, body)
{:ok, {_, _, body}} ->
body = body |> List.to_string |> Poison.decode!
{:ok, %{status_code: _, body: body, headers: _}} ->
body = Poison.decode!(body)
error = List.first(body["errors"])
set_errors!(conn, [error("token", error["message"])])
end
end
defp option(conn, key) do
Dict.get(options(conn), key, Dict.get(default_options, key))
default = Keyword.get(default_options(), key)
conn
|> options
|> Keyword.get(key, default)
end
end

View File

@ -0,0 +1,37 @@
defmodule Ueberauth.Strategy.Twitter.OAuth.Internal do
@moduledoc """
A layer to handle OAuth signing, etc.
"""
def get(url, extraparams, {consumer_key, consumer_secret, _}, token \\ "", token_secret \\ "") do
creds = OAuther.credentials(
consumer_key: consumer_key,
consumer_secret: consumer_secret,
token: token,
token_secret: token_secret
)
{header, params} =
"get"
|> OAuther.sign(url, extraparams, creds)
|> OAuther.header
HTTPoison.get(url, [header], params: params)
end
def params_decode(resp) do
resp
|> String.split("&", trim: true)
|> Enum.map(&String.split(&1, "="))
|> Enum.map(&List.to_tuple/1)
|> Enum.into(%{})
# |> Enum.reduce(%{}, fn({name, val}, acc) -> Map.put_new(acc, name, val) end)
end
def token(params) do
params["oauth_token"]
end
def token_secret(params) do
params["oauth_token_secret"]
end
end

View File

@ -10,6 +10,8 @@ defmodule Ueberauth.Strategy.Twitter.OAuth do
redirect_uri: System.get_env("TWITTER_REDIRECT_URI")
"""
alias Ueberauth.Strategy.Twitter.OAuth.Internal
@defaults [access_token: "/oauth/access_token",
authorize_url: "/oauth/authorize",
request_token: "/oauth/request_token",
@ -19,9 +21,8 @@ defmodule Ueberauth.Strategy.Twitter.OAuth do
opts
|> client
|> to_url(:access_token)
|> String.to_char_list
|> :oauth.get([oauth_verifier: verifier], consumer(client), token, token_secret)
|> decode_access_response
|> Internal.get([{"oauth_verifier", verifier}], consumer(client()), token, token_secret)
|> decode_response
end
def access_token!(access_token, verifier, opts \\ []) do
@ -34,7 +35,7 @@ defmodule Ueberauth.Strategy.Twitter.OAuth do
def authorize_url!({token, _token_secret}, opts \\ []) do
opts
|> client
|> to_url(:authorize_url, %{"oauth_token" => List.to_string(token)})
|> to_url(:authorize_url, %{"oauth_token" => token})
end
def client(opts \\ []) do
@ -48,21 +49,19 @@ defmodule Ueberauth.Strategy.Twitter.OAuth do
def get(url, access_token), do: get(url, [], access_token)
def get(url, params, {token, token_secret}) do
client
client()
|> to_url(url)
|> String.to_char_list
|> :oauth.get(params, consumer(client), token, token_secret)
|> Internal.get(params, consumer(client()), token, token_secret)
end
def request_token(params \\ [], opts \\ []) do
client = client(opts)
params = Keyword.put_new(params, :oauth_callback, client.redirect_uri)
params = [{"oauth_callback", client.redirect_uri} | params]
client
|> to_url(:request_token)
|> String.to_char_list
|> :oauth.get(params, consumer(client))
|> decode_request_response
|> Internal.get(params, consumer(client))
|> decode_response
end
def request_token!(params \\ [], opts \\ []) do
@ -74,27 +73,22 @@ defmodule Ueberauth.Strategy.Twitter.OAuth do
defp consumer(client), do: {client.consumer_key, client.consumer_secret, :hmac_sha1}
defp decode_access_response({:ok, {{_, 200, _}, _, _} = resp}) do
params = :oauth.params_decode(resp)
token = :oauth.token(params)
token_secret = :oauth.token_secret(params)
defp decode_response({:ok, %{status_code: 200, body: body, headers: _}}) do
params = Internal.params_decode(body)
token = Internal.token(params)
token_secret = Internal.token_secret(params)
{:ok, {token, token_secret}}
end
defp decode_access_response({:ok, {{_, status_code, status_description}, _, _}}), do: {:error, "#{status_code} - #{status_description}"}
defp decode_access_response({:error, {error, [_, {:inet, [:inet], error_reason}]}}), do: {:error, "#{error}: #{error_reason}"}
defp decode_access_response(error), do: {:error, error}
defp decode_request_response({:ok, {{_, 200, _}, _, _} = resp}) do
params = :oauth.params_decode(resp)
token = :oauth.token(params)
token_secret = :oauth.token_secret(params)
{:ok, {token, token_secret}}
defp decode_response({:ok, %{status_code: status_code, body: _, headers: _}}) do
{:error, "#{status_code}"}
end
defp decode_response({:error, %{reason: reason}}) do
{:error, "#{reason}"}
end
defp decode_response(error) do
{:error, error}
end
defp decode_request_response({:ok, {{_, status_code, status_description}, _, _}}), do: {:error, "#{status_code} - #{status_description}"}
defp decode_request_response({:error, {error, [_, {:inet, [:inet], error_reason}]}}), do: {:error, "#{error}: #{error_reason}"}
defp decode_request_response(error), do: {:error, error}
defp endpoint("/" <> _path = endpoint, client), do: client.site <> endpoint
defp endpoint(endpoint, _client), do: endpoint

14
mix.exs
View File

@ -8,25 +8,25 @@ defmodule UeberauthTwitter.Mixfile do
[app: :ueberauth_twitter,
version: @version,
name: "Ueberauth Twitter Strategy",
package: package,
package: package(),
elixir: "~> 1.1",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
source_url: @url,
homepage_url: @url,
description: description,
deps: deps,
docs: docs]
description: description(),
deps: deps(),
docs: docs()]
end
def application do
[applications: [:logger, :httpoison, :oauth, :ueberauth]]
[applications: [:logger, :httpoison, :oauther, :ueberauth]]
end
defp deps do
[
{:httpoison, "~> 0.7"},
{:oauth, github: "tim/erlang-oauth"},
{:oauther, "~> 1.1"},
{:poison, "~> 1.3 or ~> 2.0"},
{:ueberauth, "~> 0.2"},
@ -38,7 +38,7 @@ defmodule UeberauthTwitter.Mixfile do
end
defp docs do
[extras: docs_extras, main: "extra-readme"]
[extras: docs_extras(), main: "extra-readme"]
end
defp docs_extras do

View File

@ -10,7 +10,7 @@
"mimetype_parser": {:hex, :mimetype_parser, "0.1.0"},
"oauth": {:git, "https://github.com/tim/erlang-oauth.git", "cd31addc828179983564fd57738f1680a4a4d1ff", []},
"oauth2": {:hex, :oauth2, "0.5.0"},
"oauther": {:hex, :oauther, "1.0.2"},
"oauther": {:hex, :oauther, "1.1.0", "c9a56e200507ce64e069f5273143db0cddd7904cd5d1fe46920388a48f22441b", [:mix], []},
"plug": {:hex, :plug, "1.0.3", "8bbcbdaa4cb15170b9a15cb12153e8a6d9e176ce78e4c1990ea0b505b0ca24a0", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}]},
"poison": {:hex, :poison, "1.5.0", "f2f4f460623a6f154683abae34352525e1d918380267cdbd949a07ba57503248", [:mix], []},
"ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5", "2e73e068cd6393526f9fa6d399353d7c9477d6886ba005f323b592d389fb47be", [:make], []},