-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
407 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
/deps | ||
erl_crash.dump | ||
*.ez | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Contributing to Ueberauth Twitter | ||
|
||
## Pull Requests Welcome | ||
1. Fork ueberauth_twitter | ||
2. Create a topic branch | ||
3. Make logically-grouped commits with clear commit messages | ||
4. Push commits to your fork | ||
5. Open a pull request against ueberauth_twitter/master | ||
|
||
## Issues | ||
|
||
If you believe there to be a bug, please provide the maintainers with enough | ||
detail to reproduce or a link to an app exhibiting unexpected behavior. For | ||
help, please start with Stack Overflow. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
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 | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use Mix.Config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
defmodule Ueberauth.Strategy.Twitter do | ||
@moduledoc """ | ||
Twitter Strategy for Überauth. | ||
""" | ||
|
||
use Ueberauth.Strategy, uid_field: :id_str | ||
|
||
alias Ueberauth.Auth.Info | ||
alias Ueberauth.Auth.Credentials | ||
alias Ueberauth.Auth.Extra | ||
alias Ueberauth.Strategy.Twitter | ||
|
||
@doc """ | ||
Handles initial request for Twitter authentication. | ||
""" | ||
def handle_request!(conn) do | ||
token = Twitter.OAuth.request_token!([], [redirect_uri: callback_url(conn)]) | ||
|
||
conn | ||
|> put_session(:twitter_token, token) | ||
|> redirect!(Twitter.OAuth.authorize_url!(token)) | ||
end | ||
|
||
@doc """ | ||
Handles the callback from Twitter. | ||
""" | ||
def handle_callback!(%Plug.Conn{params: %{"oauth_verifier" => oauth_verifier}} = conn) do | ||
token = get_session(conn, :twitter_token) | ||
case Twitter.OAuth.access_token(token, oauth_verifier) do | ||
{:ok, access_token} -> fetch_user(conn, access_token) | ||
{:error, error} -> set_errors!(conn, [error(error.code, error.reason)]) | ||
end | ||
end | ||
|
||
@doc false | ||
def handle_callback!(conn) do | ||
set_errors!(conn, [error("missing_code", "No code received")]) | ||
end | ||
|
||
@doc false | ||
def handle_cleanup!(conn) do | ||
conn | ||
|> put_private(:twitter_user, nil) | ||
|> put_session(:twitter_token, nil) | ||
end | ||
|
||
@doc """ | ||
Fetches the uid field from the response. | ||
""" | ||
def uid(conn) do | ||
uid_field = | ||
conn | ||
|> option(:uid_field) | ||
|> to_string | ||
|
||
conn.private.twitter_user[uid_field] | ||
end | ||
|
||
@doc """ | ||
Includes the credentials from the twitter response. | ||
""" | ||
def credentials(conn) do | ||
{token, _secret} = get_session(conn, :twitter_token | ||
|
||
%Credentials{token: token} | ||
end | ||
|
||
@doc """ | ||
Fetches the fields to populate the info section of the `Ueberauth.Auth` struct. | ||
""" | ||
def info(conn) do | ||
user = conn.private.twitter_user | ||
|
||
%Info{ | ||
email: user["email"], | ||
image: user["profile_image_url"], | ||
name: user["name"], | ||
nickname: user["screen_name"], | ||
description: user["description"], | ||
urls: %{ | ||
Twitter: "https://twitter.com/#{user["screen_name"]}", | ||
Website: user["url"] | ||
} | ||
} | ||
end | ||
|
||
@doc """ | ||
Stores the raw information (including the token) obtained from the twitter callback. | ||
""" | ||
def extra(conn) do | ||
{token, _secret} = get_session(conn, :twitter_token) | ||
|
||
%Extra{ | ||
raw_info: %{ | ||
token: token, | ||
user: conn.private.twitter_user | ||
} | ||
} | ||
end | ||
|
||
defp fetch_user(conn, token) do | ||
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, _}, _, _}} -> | ||
set_errors!(conn, [error("token", "unauthorized")]) | ||
{:ok, {{_, status_code, _}, _, body}} when status_code in 200..399 -> | ||
body = body |> List.to_string |> Poison.decode! | ||
|
||
conn | ||
|> put_private(:twitter_token, token) | ||
|> put_private(:twitter_user, body) | ||
{:ok, {_, _, body}} -> | ||
body = body |> List.to_string |> Poison.decode! | ||
|
||
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)) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
defmodule Ueberauth.Strategy.Twitter.OAuth do | ||
@moduledoc """ | ||
OAuth1 for Twitter. | ||
Add `consumer_key` and `consumer_secret` to your configuration: | ||
config :ueberauth, Ueberauth.Strategy.Twitter.OAuth, | ||
consumer_key: System.get_env("TWITTER_CONSUMER_KEY"), | ||
consumer_secret: System.get_env("TWITTER_CONSUMER_SECRET"), | ||
redirect_uri: System.get_env("TWITTER_REDIRECT_URI") | ||
""" | ||
|
||
@defaults [access_token: "/oauth/access_token", | ||
authorize_url: "/oauth/authorize", | ||
request_token: "/oauth/request_token", | ||
site: "https://api.twitter.com"] | ||
|
||
def access_token({token, token_secret}, verifier, opts \\ []) do | ||
opts | ||
|> client | ||
|> to_url(:access_token) | ||
|> String.to_char_list | ||
|> :oauth.get([oauth_verifier: verifier], consumer(client), token, token_secret) | ||
|> decode_access_response | ||
end | ||
|
||
def access_token!(access_token, verifier, opts \\ []) do | ||
case access_token(access_token, verifier, opts) do | ||
{:ok, token} -> token | ||
{:error, error} -> raise error | ||
end | ||
end | ||
|
||
def authorize_url!({token, _token_secret}, opts \\ []) do | ||
opts | ||
|> client | ||
|> to_url(:authorize_url, %{"oauth_token" => List.to_string(token)}) | ||
end | ||
|
||
def client(opts \\ []) do | ||
config = Application.get_env(:ueberauth, __MODULE__) | ||
|
||
@defaults | ||
|> Keyword.merge(config) | ||
|> Keyword.merge(opts) | ||
|> Enum.into(%{}) | ||
end | ||
|
||
def get(url, access_token), do: get(url, [], access_token) | ||
def get(url, params \\ [], {token, token_secret}) do | ||
client | ||
|> to_url(url) | ||
|> String.to_char_list | ||
|> :oauth.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) | ||
|
||
client | ||
|> to_url(:request_token) | ||
|> String.to_char_list | ||
|> :oauth.get(params, consumer(client)) | ||
|> decode_request_response | ||
end | ||
|
||
def request_token!(params \\ [], opts \\ []) do | ||
case request_token(params, opts) do | ||
{:ok, token} -> token | ||
{:error, error} -> raise error | ||
end | ||
end | ||
|
||
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) | ||
|
||
{:ok, {token, token_secret}} | ||
end | ||
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}} | ||
end | ||
defp decode_request_response(error), do: {:error, error} | ||
|
||
defp endpoint("/" <> _path = endpoint, client), do: client.site <> endpoint | ||
defp endpoint(endpoint, _client), do: endpoint | ||
|
||
defp to_url(client, endpoint, params \\ nil) do | ||
endpoint = | ||
client | ||
|> Map.get(endpoint, endpoint) | ||
|> endpoint(client) | ||
|
||
unless params == nil do | ||
endpoint = endpoint <> "?" <> URI.encode_query(params) | ||
end | ||
|
||
endpoint | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
defmodule UeberauthTwitter do | ||
end |
Oops, something went wrong.