Skip to content

Commit

Permalink
break out the oauth2 stuff into a class so i can use it in the sinatr…
Browse files Browse the repository at this point in the history
…a gem too
  • Loading branch information
atmos committed Jun 3, 2010
1 parent 6666390 commit b3846b1
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -14,7 +14,7 @@ group :test do
gem 'webrat', '~>0.7.0'
gem 'bundler', '~>0.9.25'
gem 'randexp', '>=0.1.4'
gem 'addressable', '~>2.1.2'
gem 'addressable', '~>2.1.2', :require => 'addressable/uri'
gem 'rack-test', '~>0.5.3', :require => 'rack/test'
end

Expand Down
1 change: 1 addition & 0 deletions lib/warden-github.rb
Expand Up @@ -9,5 +9,6 @@ class GithubMisconfiguredError < StandardError; end
end

require 'warden-github/user'
require 'warden-github/proxy'
require 'warden-github/version'
require 'warden-github/strategy'
33 changes: 33 additions & 0 deletions lib/warden-github/proxy.rb
@@ -0,0 +1,33 @@
module Warden
module Github
module Oauth
class Proxy
def initialize(client_id, secret, callback_url)
@client_id, @secret, @callback_url = client_id, secret, callback_url
end

def client
@client ||= OAuth2::Client.new(@client_id, @secret,
:site => 'https://github.com',
:authorize_path => '/login/oauth/authorize',
:access_token_path => '/login/oauth/access_token')
end

def access_token_for(code)
web_server.get_access_token(code, :redirect_uri => @callback_url)
end

def authorize_url
web_server.authorize_url(
:scope => 'email,offline_access',
:redirect_uri => @callback_url
)
end

def web_server
client.web_server
end
end
end
end
end
31 changes: 19 additions & 12 deletions lib/warden-github/strategy.rb
Expand Up @@ -8,28 +8,35 @@ def params
def authenticate!
if params['code']
begin
access_token = oauth_client.web_server.get_access_token(params['code'], :redirect_uri => callback_url)
access_token = access_token_for(params['code'])
user = JSON.parse(access_token.get('/api/v2/json/user/show'))
success!(Warden::Github::Oauth::User.new(user['user'], access_token.token))
rescue OAuth2::HTTPError
%(<p>Outdated ?code=#{params[:code]}:</p><p>#{$!}</p><p><a href="/auth/github">Retry</a></p>)
%(<p>Outdated ?code=#{params['code']}:</p><p>#{$!}</p><p><a href="/auth/github">Retry</a></p>)
end
else
url = oauth_client.web_server.authorize_url(
:scope => 'email,offline_access',
:redirect_uri => callback_url
)
throw(:halt, [ 302, {'Location' => url}, [ ]])
throw(:halt, [ 302, {'Location' => authorize_url}, [ ]])
end
end

private

def oauth_client
OAuth2::Client.new(env['warden'].config[:github_client_id],
env['warden'].config[:github_secret],
:site => 'https://github.com',
:authorize_path => '/login/oauth/authorize',
:access_token_path => '/login/oauth/access_token')
oauth_proxy.client
end

def authorize_url
oauth_proxy.authorize_url
end

def access_token_for(code)
oauth_proxy.access_token_for(code)
end

def oauth_proxy
@oauth_proxy ||= Warden::Github::Oauth::Proxy.new(env['warden'].config[:github_client_id],
env['warden'].config[:github_secret],
callback_url)
end

def callback_url
Expand Down
6 changes: 4 additions & 2 deletions lib/warden-github/user.rb
Expand Up @@ -2,15 +2,17 @@ module Warden
module Github
module Oauth
class User < Struct.new(:attribs, :token)
extend Forwardable

def name
attribs['name']
end

def email
attribs['email']
end

def company
attribs['company']
end
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion spec/oauth_spec.rb
Expand Up @@ -5,8 +5,9 @@
response = get "/"

uri = Addressable::URI.parse(response.headers["Location"])
uri.should_not be_nil

uri.scheme.should eql('https')
uri.host.should eql('github.com')

params = uri.query_values
params['type'].should eql('web_server')
Expand Down
32 changes: 32 additions & 0 deletions spec/proxy_spec.rb
@@ -0,0 +1,32 @@
require File.dirname(__FILE__) + '/spec_helper'

describe "Warden::Github::Oauth::Proxy" do
before(:all) do
sha = Digest::SHA1.hexdigest(Time.now.to_s)
@proxy = Warden::Github::Oauth::Proxy.new(sha[0..19], sha[0..39],
'http://example.org/auth/github/callback')
end

it "returns an authorize url" do
uri = Addressable::URI.parse(@proxy.authorize_url)

uri.scheme.should eql('https')
uri.host.should eql('github.com')

params = uri.query_values
params['type'].should eql('web_server')
params['scope'].should eql('email,offline_access')
params['client_id'].should match(/\w{20}/)
params['redirect_uri'].should eql('http://example.org/auth/github/callback')
end

it "has a client object" do
@proxy.client.should_not be_nil
end

it "returns access tokens" do
pending "this hits the network" do
lambda { @proxy.access_token_for(/\w{20}/.gen) }.should_not raise_error
end
end
end

0 comments on commit b3846b1

Please sign in to comment.