twitter-login 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,17 +28,17 @@ frameworks.
28
28
 
29
29
  ## Sinatra
30
30
  enable :sessions
31
- use Twitter::Login, :key => 'CONSUMER KEY', :secret => 'SECRET'
31
+ use Twitter::Login, :consumer_key => 'KEY', :secret => 'SECRET'
32
32
  helpers Twitter::Login::Helpers
33
33
 
34
34
  ## Rails
35
35
  # environment.rb:
36
- config.middleware.use Twitter::Login, :key => 'CONSUMER KEY', :secret => 'SECRET'
36
+ config.middleware.use Twitter::Login, :consumer_key => 'KEY', :secret => 'SECRET'
37
37
 
38
38
  # application_controller.rb
39
39
  include Twitter::Login::Helpers
40
40
 
41
- Fill in the `:key`, `:secret` placeholders with real values. You're done.
41
+ Fill in the `:consumer_key`, `:secret` placeholders with real values. You're done.
42
42
 
43
43
 
44
44
  What it does
@@ -58,7 +58,7 @@ Configuration
58
58
 
59
59
  Available options for `Twitter::Login` middleware are:
60
60
 
61
- * `:key` -- OAuth consumer key *(required)*
61
+ * `:consumer_key` -- OAuth consumer key *(required)*
62
62
  * `:secret` -- OAuth secret *(required)*
63
63
  * `:login_path` -- where user goes to login (default: "/login")
64
64
  * `:return_to` -- where user goes after login (default: "/")
@@ -72,8 +72,8 @@ The `Twitter::Login::Helpers` module (for Sinatra, Rails) adds these methods to
72
72
  * `twitter_user` (Hashie::Mash) -- Info about authenticated user. Check this object to
73
73
  know whether there is a currently logged-in user. Access user data like `twitter_user.screen_name`
74
74
  * `twitter_logout` -- Erases info about Twitter login from session, effectively logging-out the Twitter user
75
- * `twitter_consumer` (Twitter::Base) -- An OAuth consumer client from ["twitter" gem][gem].
76
- With it you can query anything on behalf of authenticated user, e.g. `twitter_consumer.friends_timeline`
75
+ * `twitter_client` (Twitter::Base) -- An OAuth consumer client from ["twitter" gem][gem].
76
+ With it you can query anything on behalf of authenticated user, e.g. `twitter_client.friends_timeline`
77
77
 
78
78
  [register]: http://twitter.com/apps/new
79
79
  [gem]: http://rdoc.info/projects/jnunemaker/twitter
@@ -5,20 +5,23 @@ require 'hashie/mash'
5
5
  class Twitter::Login
6
6
  attr_reader :options
7
7
 
8
- DEFAULTS = {
9
- :login_path => '/login', :return_to => '/',
10
- :site => 'http://twitter.com', :authorize_path => '/oauth/authenticate'
11
- }
8
+ class << self
9
+ attr_accessor :consumer_key, :secret
10
+ end
11
+
12
+ DEFAULTS = { :login_path => '/login', :return_to => '/' }
12
13
 
13
14
  def initialize(app, options)
14
15
  @app = app
15
16
  @options = DEFAULTS.merge options
17
+ self.class.consumer_key, self.class.secret = @options[:consumer_key], @options[:secret]
16
18
  end
17
19
 
18
20
  def call(env)
19
21
  request = Request.new(env)
20
22
 
21
23
  if request.get? and request.path == options[:login_path]
24
+ @oauth = nil
22
25
  # detect if Twitter redirected back here
23
26
  if request[:oauth_verifier]
24
27
  handle_twitter_authorization(request) do
@@ -26,7 +29,7 @@ class Twitter::Login
26
29
  end
27
30
  elsif request[:denied]
28
31
  # user refused to log in with Twitter, so give up
29
- redirect_to_return_path(request)
32
+ handle_denied_access(request)
30
33
  else
31
34
  # user clicked to login; send them to Twitter
32
35
  redirect_to_twitter(request)
@@ -37,13 +40,14 @@ class Twitter::Login
37
40
  end
38
41
 
39
42
  module Helpers
40
- def twitter_consumer
41
- token = OAuth::AccessToken.new(oauth_consumer, *session[:access_token])
42
- Twitter::Base.new token
43
+ def twitter_client
44
+ oauth = twitter_oauth
45
+ oauth.authorize_from_access(*session[:access_token])
46
+ Twitter::Base.new oauth
43
47
  end
44
48
 
45
- def oauth_consumer
46
- OAuth::Consumer.new(*session[:oauth_consumer])
49
+ def twitter_oauth
50
+ Twitter::OAuth.new Twitter::Login.consumer_key, Twitter::Login.secret
47
51
  end
48
52
 
49
53
  def twitter_user
@@ -53,7 +57,7 @@ class Twitter::Login
53
57
  end
54
58
 
55
59
  def twitter_logout
56
- [:oauth_consumer, :access_token, :twitter_user].each do |key|
60
+ [:access_token, :twitter_user].each do |key|
57
61
  session[key] = nil # work around a Rails 2.3.5 bug
58
62
  session.delete key
59
63
  end
@@ -83,17 +87,16 @@ class Twitter::Login
83
87
 
84
88
  def redirect_to_twitter(request)
85
89
  # create a request token and store its parameter in session
86
- token = oauth_consumer.get_request_token(:oauth_callback => request.url)
87
- request.session[:request_token] = [token.token, token.secret]
90
+ oauth.set_callback_url(request.url)
91
+ request.session[:request_token] = [oauth.request_token.token, oauth.request_token.secret]
88
92
  # redirect to Twitter authorization page
89
- redirect token.authorize_url
93
+ redirect oauth.request_token.authorize_url
90
94
  end
91
95
 
92
96
  def handle_twitter_authorization(request)
93
- access_token = get_access_token(request)
97
+ authorize_from_request(request)
94
98
 
95
99
  # get and store authenticated user's info from Twitter
96
- twitter = Twitter::Base.new access_token
97
100
  request.session[:twitter_user] = twitter.verify_credentials.to_hash
98
101
 
99
102
  # pass the request down to the main app
@@ -109,20 +112,21 @@ class Twitter::Login
109
112
  end
110
113
  end
111
114
 
115
+ def handle_denied_access(request)
116
+ request.session[:request_token] = nil # work around a Rails 2.3.5 bug
117
+ request.session.delete(:request_token)
118
+ redirect_to_return_path(request)
119
+ end
120
+
112
121
  private
113
122
 
114
- def get_access_token(request)
115
- # replace the request token in session with access token
116
- request_token = ::OAuth::RequestToken.new(oauth_consumer, *request.session[:request_token])
117
- access_token = request_token.get_access_token(:oauth_verifier => request[:oauth_verifier])
123
+ # replace the request token in session with access token
124
+ def authorize_from_request(request)
125
+ rtoken, rsecret = request.session[:request_token]
126
+ oauth.authorize_from_request(rtoken, rsecret, request[:oauth_verifier])
118
127
 
119
- # store access token and OAuth consumer parameters in session
120
128
  request.session.delete(:request_token)
121
- request.session[:access_token] = [access_token.token, access_token.secret]
122
- consumer = access_token.consumer
123
- request.session[:oauth_consumer] = [consumer.key, consumer.secret, consumer.options]
124
-
125
- return access_token
129
+ request.session[:access_token] = [oauth.access_token.token, oauth.access_token.secret]
126
130
  end
127
131
 
128
132
  def redirect_to_return_path(request)
@@ -133,8 +137,11 @@ class Twitter::Login
133
137
  ["302", {'Location' => url, 'Content-type' => 'text/plain'}, []]
134
138
  end
135
139
 
136
- def oauth_consumer
137
- ::OAuth::Consumer.new options[:key], options[:secret],
138
- :site => options[:site], :authorize_path => options[:authorize_path]
140
+ def oauth
141
+ @oauth ||= Twitter::OAuth.new options[:consumer_key], options[:secret], :sign_in => true
142
+ end
143
+
144
+ def twitter
145
+ Twitter::Base.new oauth
139
146
  end
140
147
  end
@@ -21,7 +21,7 @@ describe Twitter::Login do
21
21
 
22
22
  builder = Rack::Builder.new
23
23
  builder.use Rack::Session::Cookie
24
- builder.use described_class, :key => 'abc', :secret => '123'
24
+ builder.use described_class, :consumer_key => 'abc', :secret => '123'
25
25
  builder.run main_app
26
26
  builder.to_app
27
27
  end
@@ -31,12 +31,21 @@ describe Twitter::Login do
31
31
  @request = Rack::MockRequest.new(@app)
32
32
  end
33
33
 
34
+ it "should expose consumer key/secret globally" do
35
+ Twitter::Login.consumer_key.should == 'abc'
36
+ Twitter::Login.secret.should == '123'
37
+ end
38
+
39
+ it "should ignore normal requests" do
40
+ get('/', :lint => true)
41
+ response.status.should == 200
42
+ response.body.should == 'Hello world'
43
+ end
44
+
34
45
  it "should login with Twitter" do
35
- consumer = mock_oauth_consumer('OAuth Consumer')
36
- token = mock('Request Token', :authorize_url => 'http://disney.com/oauth', :token => 'abc', :secret => '123')
37
- consumer.should_receive(:get_request_token).with(:oauth_callback => 'http://example.org/login').and_return(token)
38
- # request.session[:request_token] = token
39
- # redirect token.authorize_url
46
+ request_token = mock('Request Token', :authorize_url => 'http://disney.com/oauth', :token => 'abc', :secret => '123')
47
+ oauth = mock_oauth('Twitter OAuth', :request_token => request_token)
48
+ oauth.should_receive(:set_callback_url).with('http://example.org/login')
40
49
 
41
50
  get('/login', :lint => true)
42
51
  response.status.should == 302
@@ -46,31 +55,40 @@ describe Twitter::Login do
46
55
  end
47
56
 
48
57
  it "should authorize with Twitter" do
49
- consumer = mock_oauth_consumer('OAuth Consumer', :key => 'con', :secret => 'sumer', :options => {:one=>'two'})
50
- request_token = mock('Request Token')
51
- OAuth::RequestToken.should_receive(:new).with(consumer, 'abc', '123').and_return(request_token)
52
- access_token = mock('Access Token', :token => 'access1', :secret => '42', :consumer => consumer)
53
- request_token.should_receive(:get_access_token).with(:oauth_verifier => 'abc').and_return(access_token)
58
+ consumer = mock('OAuth consumer')
59
+ access_token = mock('Access Token', :token => 'access1', :secret => '42')
60
+ oauth = mock_oauth('Twitter OAuth', :access_token => access_token, :consumer => consumer)
61
+ oauth.should_receive(:authorize_from_request).with('abc', '123', 'allrighty')
54
62
 
55
63
  twitter = mock('Twitter Base')
56
- Twitter::Base.should_receive(:new).with(access_token).and_return(twitter)
57
- user_credentials = Hashie::Mash.new :screen_name => 'faker',
58
- :name => 'Fake Jr.', :profile_image_url => 'http://disney.com/mickey.png',
59
- :followers_count => '13', :friends_count => '6', :statuses_count => '52'
60
- twitter.should_receive(:verify_credentials).and_return(user_credentials)
64
+ Twitter::Base.should_receive(:new).with(oauth).and_return(twitter)
65
+
66
+ twitter.should_receive(:verify_credentials).and_return {
67
+ Hashie::Mash.new :screen_name => 'faker',
68
+ :name => 'Fake Jr.', :profile_image_url => 'http://disney.com/mickey.png',
69
+ :followers_count => '13', :friends_count => '6', :statuses_count => '52'
70
+ }
61
71
 
62
72
  session_data = {:request_token => ['abc', '123']}
63
- get('/login?oauth_verifier=abc', build_session(session_data).update(:lint => true))
73
+ get('/login?oauth_verifier=allrighty', build_session(session_data).update(:lint => true))
64
74
  response.status.should == 302
65
75
  response['Location'].should == 'http://example.org/'
66
76
  session[:request_token].should be_nil
67
77
  session[:access_token].should == ['access1', '42']
68
- session[:oauth_consumer].should == ['con', 'sumer', {:one => 'two'}]
78
+ session[:oauth_consumer].should be_nil
69
79
 
70
80
  current_user = session[:twitter_user]
71
81
  current_user['screen_name'].should == 'faker'
72
82
  end
73
83
 
84
+ it "should handle denied access" do
85
+ session_data = {:request_token => ['abc', '123']}
86
+ get('/login?denied=OMG', build_session(session_data).update(:lint => true))
87
+ response.status.should == 302
88
+ response['Location'].should == 'http://example.org/'
89
+ session[:request_token].should be_nil
90
+ end
91
+
74
92
  protected
75
93
 
76
94
  [:get, :post, :put, :delete, :head].each do |method|
@@ -104,11 +122,9 @@ describe Twitter::Login do
104
122
  [Marshal.dump(obj)].pack('m*')
105
123
  end
106
124
 
107
- def mock_oauth_consumer(*args)
125
+ def mock_oauth(*args)
108
126
  consumer = mock(*args)
109
- OAuth::Consumer.should_receive(:new).and_return(consumer)
110
- # .with(instance_of(String), instance_of(String),
111
- # :site => 'http://twitter.com', :authorize_path => '/oauth/authenticate')
127
+ Twitter::OAuth.should_receive(:new).and_return(consumer)
112
128
  consumer
113
129
  end
114
130
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter-login
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Mislav Marohni\xC4\x87"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-03 00:00:00 +01:00
12
+ date: 2010-01-04 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency