Skip to content

Commit

Permalink
Merge pull request manastech#5 from veelenga/feature/twitter_provider
Browse files Browse the repository at this point in the history
Twitter provider
  • Loading branch information
msa7 authored Sep 25, 2017
2 parents 2fc4db9 + 7f87775 commit 0d5620c
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 22 deletions.
59 changes: 59 additions & 0 deletions spec/providers/twitter_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require "../spec_helper"

describe MultiAuth::Provider::Twitter do
request_token_params = {
oauth_token: "NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0",
oauth_token_secret: "veNRnAWe6inFuo8o2u8SLLZLjolYDmDP7SzL0YfYI",
oauth_callback_confirmed: "true",
}

access_token_params = {
oauth_token: "7588892-kagSNqWge8gB1WwE3plnFsJHAZVfxWD7Vb57p0b4",
oauth_token_secret: "PbKfYqSryyeKDWz4ebtY3o5ogNLG11WJuZBc9fQrQo",
}

verify_credentials_params = {
id: 38895958,
name: "Sean Cook",
screen_name: "theSeanCook",
location: "San Francisco",
url: "http://twitter.com",
description: "I taught your phone that thing you like. The Mobile Partner Engineer @Twitter.",
profile_image_url: "http://a0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG",
email: "[email protected]",
}

describe "#authorize_uri" do
it "generates authorize uri" do
WebMock.stub(:post, "https://api.twitter.com/oauth/request_token")
.to_return(body: HTTP::Params.encode request_token_params)
uri = MultiAuth.make("twitter", "/callback").authorize_uri
uri.should eq "https://api.twitter.com/oauth/authorize?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&oauth_callback=%2Fcallback"
end
end

describe "#fetch_tw_user" do
it "successfully fetches user params" do
WebMock.stub(:post, "https://api.twitter.com/oauth/access_token")
.to_return(body: HTTP::Params.encode request_token_params)

WebMock.stub(:get, "https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true")
.to_return(body: verify_credentials_params.to_json)

user = MultiAuth.make("twitter", "/callback").user({"oauth_token" => "token", "oauth_verifier" => "verifier"})

user.uid.should eq verify_credentials_params[:id].to_s
user.email.should eq verify_credentials_params[:email]
user.name.should eq verify_credentials_params[:name]
user.nickname.should eq verify_credentials_params[:screen_name]
user.location.should eq verify_credentials_params[:location]
user.description.should eq verify_credentials_params[:description]
user.image.should eq verify_credentials_params[:profile_image_url]
user.urls.should eq({"twitter" => verify_credentials_params[:url]})

user.provider.should eq "twitter"
user.raw_json.should_not be_nil
user.access_token.should_not be_nil
end
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ MultiAuth.config("google", "google_id", "google_secret")
MultiAuth.config("github", "github_id", "github_secret")
MultiAuth.config("facebook", "facebook_id", "facebook_secret")
MultiAuth.config("vk", "vk_id", "vk_secret")
MultiAuth.config("twitter", "twitter_consumer_key", "twitter_consumer_secret")
5 changes: 3 additions & 2 deletions src/multi_auth.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require "oauth"
require "oauth2"
require "./multi_auth/**"

Expand All @@ -12,7 +13,7 @@ module MultiAuth
@@configuration
end

def self.config(provider, client_id, client_secret)
@@configuration[provider] = [client_id, client_secret]
def self.config(provider, key, secret)
@@configuration[provider] = [key, secret]
end
end
5 changes: 3 additions & 2 deletions src/multi_auth/engine.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ class MultiAuth::Engine
when "github" then Provider::Github
when "facebook" then Provider::Facebook
when "vk" then Provider::Vk
when "twitter" then Provider::Twitter
else
raise "Provider #{provider} not implemented"
end

client_id, client_secret = MultiAuth.configuration[provider]
@provider = provider_class.new(redirect_uri, client_id, client_secret)
key, secret = MultiAuth.configuration[provider]
@provider = provider_class.new(redirect_uri, key, secret)
end

getter provider : Provider
Expand Down
10 changes: 5 additions & 5 deletions src/multi_auth/provider.cr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
abstract class MultiAuth::Provider
getter redirect_uri : String
getter client_id : String
getter client_secret : String

def initialize(@redirect_uri : String, @client_id : String, @client_secret : String)
end
getter key : String
getter secret : String

abstract def authorize_uri(scope = nil)
abstract def user(params : Hash(String, String))

def initialize(@redirect_uri : String, @key : String, @secret : String)
end
end
8 changes: 4 additions & 4 deletions src/multi_auth/providers/facebook.cr
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class MultiAuth::Provider::Facebook < MultiAuth::Provider
private def client
OAuth2::Client.new(
"www.facebook.com",
client_id,
client_secret,
key,
secret,
redirect_uri: redirect_uri,
authorize_uri: "/v2.9/dialog/oauth",
)
Expand All @@ -72,8 +72,8 @@ class MultiAuth::Provider::Facebook < MultiAuth::Provider
private def token_client
OAuth2::Client.new(
"graph.facebook.com",
client_id,
client_secret,
key,
secret,
redirect_uri: redirect_uri,
token_uri: "/v2.9/oauth/access_token"
)
Expand Down
4 changes: 2 additions & 2 deletions src/multi_auth/providers/github.cr
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class MultiAuth::Provider::Github < MultiAuth::Provider
private def client
OAuth2::Client.new(
"github.com",
client_id,
client_secret,
key,
secret,
authorize_uri: "/login/oauth/authorize",
token_uri: "/login/oauth/access_token"
)
Expand Down
8 changes: 4 additions & 4 deletions src/multi_auth/providers/google.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class MultiAuth::Provider::Google < MultiAuth::Provider

client = OAuth2::Client.new(
"accounts.google.com",
client_id,
client_secret,
key,
secret,
authorize_uri: "/o/oauth2/v2/auth",
redirect_uri: redirect_uri
)
Expand All @@ -24,8 +24,8 @@ class MultiAuth::Provider::Google < MultiAuth::Provider
def user(params : Hash(String, String))
client = OAuth2::Client.new(
"www.googleapis.com",
client_id,
client_secret,
key,
secret,
token_uri: "/oauth2/v4/token",
redirect_uri: redirect_uri
)
Expand Down
62 changes: 62 additions & 0 deletions src/multi_auth/providers/twitter.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
class MultiAuth::Provider::Twitter < MultiAuth::Provider
def authorize_uri(scope = nil)
request_token = consumer.get_request_token(redirect_uri)
consumer.get_authorize_uri(request_token, redirect_uri)
end

def user(params : Hash(String, String))
tw_user = fetch_tw_user(params["oauth_token"], params["oauth_verifier"])

User.new(
"twitter",
tw_user.id,
tw_user.name,
tw_user.raw_json.to_s,
tw_user.access_token.not_nil!
).tap do |user|
user.email = tw_user.email
user.nickname = tw_user.screen_name
user.location = tw_user.location
user.description = tw_user.description
user.image = tw_user.profile_image_url
if url = tw_user.url
user.urls = {"twitter" => url}
end
end
end

private class TwUser
property raw_json : String?
property access_token : OAuth::AccessToken?

JSON.mapping(
id: {type: String, converter: String::RawConverter},
name: String,
screen_name: String,
location: String?,
description: String?,
url: String?,
profile_image_url: String?,
email: String?
)
end

private def fetch_tw_user(oauth_token, oauth_verifier)
request_token = OAuth::RequestToken.new oauth_token, ""
access_token = consumer.get_access_token(request_token, oauth_verifier)

client = HTTP::Client.new("api.twitter.com", tls: true)
access_token.authenticate(client, key, secret)

raw_json = client.get("/1.1/account/verify_credentials.json?include_email=true").body

TwUser.from_json(raw_json).tap do |user|
user.access_token = access_token
user.raw_json = raw_json
end
end

private def consumer
@consumer ||= OAuth::Consumer.new("api.twitter.com", key, secret)
end
end
4 changes: 2 additions & 2 deletions src/multi_auth/providers/vk.cr
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class MultiAuth::Provider::Vk < MultiAuth::Provider
private def client
OAuth2::Client.new(
"oauth.vk.com",
client_id,
client_secret,
key,
secret,
redirect_uri: redirect_uri,
authorize_uri: "/authorize",
token_uri: "/access_token"
Expand Down
2 changes: 1 addition & 1 deletion src/multi_auth/user.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class MultiAuth::User
getter uid : String
getter name : String
getter raw_json : String
getter access_token : OAuth2::AccessToken
getter access_token : OAuth::AccessToken | OAuth2::AccessToken

property email : String?
property nickname : String?
Expand Down

0 comments on commit 0d5620c

Please sign in to comment.