Skip to content

Commit

Permalink
Update OAuth2.Client.get_token! errors (#98)
Browse files Browse the repository at this point in the history
* Update OAuth2.Client.get_token! errors

Updates the `OAuth2.Client.get_token!` function to handle error OAuth2.Response structs. I sent some incomplete data to Facebook Graph and saw this error bubble up:

```
[error] %ArgumentError{message: "raise/1 expects a module name, string or exception as the first argument, got: %OAuth2.Response{body: %{\"error\" => %{\"code\" => 101, \"fbtrace_id\" => \"Eelth+pfiU9\", \"message\" => \"Missing client_id parameter.\", \"type\" => \"OAuthException\"}}, headers: [{\"www-authenticate\", \"OAuth \\\"Facebook Platform\\\" \\\"invalid_client\\\" \\\"Missing client_id parameter.\\\"\"}, {\"access-control-allow-origin\", \"*\"}, {\"pragma\", \"no-cache\"}, {\"cache-control\", \"no-store\"}, {\"x-fb-rev\", \"3349395\"}, {\"content-type\", \"application/json\"}, {\"x-fb-trace-id\", \"Eelth+pfiU9\"}, {\"facebook-api-version\", \"v2.8\"}, {\"expires\", \"Sat, 01 Jan 2000 00:00:00 GMT\"}, {\"x-fb-debug\", \"9GWPCrYAIzlrSnt0iLqP/3E4hdmOJpP7QXxBOXTG2Ew7CloqVwka+HXAjyCTewfTaH0F/sUVkDLMcm7+6jOEEQ==\"}, {\"date\", \"Thu, 05 Oct 2017 15:36:54 GMT\"}, {\"connection\", \"keep-alive\"}, {\"content-length\", \"114\"}], status_code: 400}"}
```

Using `OAuth2.Request.request!` as a model, I added a similar error handling case to `OAuth2.Client.get_token!`. Now the error raised looks like:

```
[error] #PID<0.1063.0> running ExampleOAuth2Web.Endpoint terminated
Server: oauth2.example.dev:80 (http)
Request: POST /
** (exit) an exception was raised:
    ** (OAuth2.Error) Server responded with status: 400

Headers:

www-authenticate: OAuth "Facebook Platform" "invalid_client" "Missing client_id parameter."
access-control-allow-origin: *
pragma: no-cache
cache-control: no-store
x-fb-rev: 3349509
content-type: application/json
x-fb-trace-id: CIc8eDTN/BC
facebook-api-version: v2.8
expires: Sat, 01 Jan 2000 00:00:00 GMT
x-fb-debug: wJzExwqDXtAkHKtBNo4xKE21zBO730qctNXaP9A7bqenLRuTkGq109qvx8iOy063OiE3uVunf/Mt1trqvhuwVg==
date: Thu, 05 Oct 2017 15:40:21 GMT
connection: keep-alive
content-length: 115

Body:

%{"error" => %{"code" => 101, "fbtrace_id" => "CIc8eDTN/BC", "message" => "Missing client_id parameter.", "type" => "OAuthException"}}

        (oauth2) lib/oauth2/client.ex:249: OAuth2.Client.get_token!/4
```

* Add test

* Additional test coverage
  • Loading branch information
chrislaskey authored and scrogson committed Oct 6, 2017
1 parent 246897a commit 6d1808c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
17 changes: 15 additions & 2 deletions lib/oauth2/client.ex
Expand Up @@ -244,8 +244,21 @@ defmodule OAuth2.Client do
@spec get_token!(t, params, headers, Keyword.t) :: Client.t | Error.t
def get_token!(client, params \\ [], headers \\ [], opts \\ []) do
case get_token(client, params, headers, opts) do
{:ok, client} -> client
{:error, error} -> raise error
{:ok, client} ->
client
{:error, %Response{status_code: code, headers: headers, body: body}} ->
raise %Error{reason: """
Server responded with status: #{code}
Headers:
#{Enum.reduce(headers, "", fn {k, v}, acc -> acc <> "#{k}: #{v}\n" end)}
Body:
#{inspect body}
"""}
{:error, error} ->
raise error
end
end

Expand Down
27 changes: 27 additions & 0 deletions test/oauth2/client_test.exs
Expand Up @@ -7,6 +7,7 @@ defmodule OAuth2.ClientTest do
import OAuth2.TestHelpers

alias OAuth2.Client
alias OAuth2.Response

setup do
server = Bypass.open
Expand Down Expand Up @@ -59,6 +60,24 @@ defmodule OAuth2.ClientTest do
assert token.access_token == "test1234"
end

test "get_token, get_token! when response error", %{client: client, server: server} do
code = [code: "code1234"]
headers = [{"accept", "application/json"}]

bypass server, "POST", "/oauth/token", fn conn ->
assert conn.query_string == ""
send_resp(conn, 500, ~s({"error":"missing_client_id"}))
end

assert {:error, error} = Client.get_token(client, code, headers)
assert %Response{body: body, status_code: 500} = error
assert body == %{"error" => "missing_client_id"}

assert_raise OAuth2.Error, ~r/Body/, fn ->
Client.get_token!(client, code, headers)
end
end

test "refresh_token and refresh_token! with a POST", %{server: server, client_with_token: client} do
bypass server, "POST", "/oauth/token", fn conn ->
assert get_req_header(conn, "authorization") == []
Expand Down Expand Up @@ -124,6 +143,14 @@ defmodule OAuth2.ClientTest do
assert {"content-type", "application/xml"} = List.keyfind(client.headers, "content-type", 0)
end

test "basic_auth", %{client: client} do
%OAuth2.Client{client_id: id, client_secret: secret} = client
client = basic_auth(client)

assert {"authorization", value} = List.keyfind(client.headers, "authorization", 0)
assert value == "Basic " <> Base.encode64(id <> ":" <> secret)
end

## GET

test "GET", %{server: server, client_with_token: client} do
Expand Down

0 comments on commit 6d1808c

Please sign in to comment.