twitter-login 0.3.1 → 0.4.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.
Files changed (3) hide show
  1. data/lib/twitter/login.rb +34 -57
  2. data/spec/login_spec.rb +19 -16
  3. metadata +7 -7
@@ -10,36 +10,38 @@ class Twitter::Login
10
10
  attr_reader :options
11
11
 
12
12
  class << self
13
- attr_accessor :consumer_key, :secret
13
+ attr_accessor :consumer_key, :secret, :site
14
14
  end
15
15
 
16
- DEFAULTS = { :login_path => '/login', :return_to => '/' }
16
+ DEFAULTS = {
17
+ :return_to => '/',
18
+ :site => 'http://api.twitter.com',
19
+ :authorize_path => '/oauth/authenticate'
20
+ }
17
21
 
18
- def initialize(app, options)
19
- @app = app
22
+ def initialize(options)
20
23
  @options = DEFAULTS.merge options
21
24
  self.class.consumer_key, self.class.secret = @options[:consumer_key], @options[:secret]
25
+ self.class.site = @options[:site]
26
+ end
27
+
28
+ def login_handler(options = {})
29
+ @options.update options
30
+ return self
22
31
  end
23
32
 
24
33
  def call(env)
25
34
  request = Request.new(env)
26
-
27
- if request.get? and request.path == options[:login_path]
28
- @oauth = nil
29
- # detect if Twitter redirected back here
30
- if request[:oauth_verifier]
31
- handle_twitter_authorization(request) do
32
- @app.call(env)
33
- end
34
- elsif request[:denied]
35
- # user refused to log in with Twitter, so give up
36
- handle_denied_access(request)
37
- else
38
- # user clicked to login; send them to Twitter
39
- redirect_to_twitter(request)
40
- end
35
+
36
+ if request[:oauth_verifier]
37
+ # user authorized the app
38
+ handle_twitter_authorization(request)
39
+ elsif request[:denied]
40
+ # user refused to log in with Twitter
41
+ handle_denied_access(request)
41
42
  else
42
- @app.call(env)
43
+ # starting the login process; send user to Twitter
44
+ redirect_to_twitter(request)
43
45
  end
44
46
  end
45
47
 
@@ -50,7 +52,7 @@ class Twitter::Login
50
52
 
51
53
  def twitter_oauth
52
54
  OAuth::Consumer.new Twitter::Login.consumer_key, Twitter::Login.secret,
53
- :site => 'http://api.twitter.com'
55
+ :site => Twitter::Login.site
54
56
  end
55
57
 
56
58
  def twitter_user
@@ -92,36 +94,23 @@ class Twitter::Login
92
94
  # create a request token and store its parameter in session
93
95
  request_token = oauth.get_request_token(:oauth_callback => request.url)
94
96
  request.session[:twitter_request_token] = [request_token.token, request_token.secret]
97
+
95
98
  # redirect to Twitter authorization page
96
99
  redirect request_token.authorize_url
97
100
  end
98
101
 
99
102
  def handle_twitter_authorization(request)
100
103
  access_token = authorize_from_request(request)
101
- response = access_token.get('/1/account/verify_credentials.json')
102
104
 
103
105
  # get and store authenticated user's info from Twitter
104
- request.session[:twitter_user] = user_hash_from_response(response)
105
-
106
- # pass the request down to the main app
107
- response = begin
108
- yield
109
- rescue
110
- raise unless $!.class.name == 'ActionController::RoutingError'
111
- [404]
112
- end
106
+ response = access_token.get('/1/account/verify_credentials.json')
107
+ request.session[:twitter_user] = Yajl::Parser.parse response.body
113
108
 
114
- # check if the app implemented anything at :login_path
115
- if response[0].to_i == 404
116
- # if not, redirect to :return_to path
117
- redirect_to_return_path(request)
118
- else
119
- # use the response from the app without modification
120
- response
121
- end
109
+ redirect_to_return_path(request)
122
110
  end
123
111
 
124
112
  def handle_denied_access(request)
113
+ # cleanup session and set an error identifier
125
114
  request.session[:twitter_request_token] = nil # work around a Rails 2.3.5 bug
126
115
  request.session.delete(:twitter_request_token)
127
116
  request.session[:twitter_error] = 'user_denied'
@@ -134,11 +123,11 @@ class Twitter::Login
134
123
  def authorize_from_request(request)
135
124
  rtoken, rsecret = request.session[:twitter_request_token]
136
125
  request_token = OAuth::RequestToken.new(oauth, rtoken, rsecret)
137
- access_token = request_token.get_access_token(:oauth_verifier => request[:oauth_verifier])
138
126
 
139
- request.session.delete(:twitter_request_token)
140
- request.session[:twitter_access_token] = [access_token.token, access_token.secret]
141
- return access_token
127
+ request_token.get_access_token(:oauth_verifier => request[:oauth_verifier]).tap do |access_token|
128
+ request.session.delete(:twitter_request_token)
129
+ request.session[:twitter_access_token] = [access_token.token, access_token.secret]
130
+ end
142
131
  end
143
132
 
144
133
  def redirect_to_return_path(request)
@@ -150,19 +139,7 @@ class Twitter::Login
150
139
  end
151
140
 
152
141
  def oauth
153
- @oauth ||= OAuth::Consumer.new(options[:consumer_key], options[:secret],
154
- :site => 'http://api.twitter.com',
155
- :authorize_path => '/oauth/authenticate'
156
- )
157
- end
158
-
159
- def user_hash_from_response(api_response)
160
- parse_response(api_response).reject { |key, _|
161
- key == 'status' or key =~ /^profile_|_color$/
162
- }
163
- end
164
-
165
- def parse_response(api_response)
166
- Yajl::Parser.parse api_response.body
142
+ OAuth::Consumer.new options[:consumer_key], options[:secret],
143
+ :site => options[:site], :authorize_path => options[:authorize_path]
167
144
  end
168
145
  end
@@ -44,35 +44,38 @@ describe Twitter::Login do
44
44
 
45
45
  it "should login with Twitter" do
46
46
  request_token = mock('Request Token', :authorize_url => 'http://disney.com/oauth', :token => 'abc', :secret => '123')
47
- oauth = mock_oauth('Twitter OAuth')
48
- oauth.should_receive(:get_request_token).with(:oauth_callback => 'http://example.org/login').and_return(request_token)
47
+ oauth = mock_oauth('Twitter OAuth', :request_token => request_token)
48
+ oauth.should_receive(:set_callback_url).with('http://example.org/login')
49
49
 
50
50
  get('/login', :lint => true)
51
51
  response.status.should == 302
52
52
  response['Location'].should == 'http://disney.com/oauth'
53
53
  response.body.should be_empty
54
- session[:twitter_request_token].should == ['abc', '123']
54
+ session[:request_token].should == ['abc', '123']
55
55
  end
56
56
 
57
57
  it "should authorize with Twitter" do
58
- oauth = mock_oauth('Twitter OAuth')
59
- request_token = mock('Request Token')
60
- OAuth::RequestToken.should_receive(:new).with(oauth, 'abc', '123').and_return(request_token)
58
+ consumer = mock('OAuth consumer')
61
59
  access_token = mock('Access Token', :token => 'access1', :secret => '42')
62
- request_token.should_receive(:get_access_token).with(:oauth_verifier => 'allrighty').and_return(access_token)
60
+ oauth = mock_oauth('Twitter OAuth', :access_token => access_token, :consumer => consumer)
61
+ oauth.should_receive(:authorize_from_request).with('abc', '123', 'allrighty')
63
62
 
64
- payload = { :screen_name => 'faker', :name => 'Fake Jr.', :followers_count => '13',
65
- :profile_image_url => 'http://disney.com/mickey.png', :friends_count => '6', :statuses_count => '52' }
63
+ twitter = mock('Twitter Base')
64
+ Twitter::Base.should_receive(:new).with(oauth).and_return(twitter)
66
65
 
67
- http_response = mock('HTTP response', :body => Yajl::Encoder.encode(payload))
68
- access_token.should_receive(:get).with('/1/account/verify_credentials.json').and_return(http_response)
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
+ }
69
71
 
70
- session_data = {:twitter_request_token => ['abc', '123']}
72
+ session_data = {:request_token => ['abc', '123']}
71
73
  get('/login?oauth_verifier=allrighty', build_session(session_data).update(:lint => true))
72
74
  response.status.should == 302
73
75
  response['Location'].should == 'http://example.org/'
74
- session[:twitter_request_token].should be_nil
75
- session[:twitter_access_token].should == ['access1', '42']
76
+ session[:request_token].should be_nil
77
+ session[:access_token].should == ['access1', '42']
78
+ session[:oauth_consumer].should be_nil
76
79
 
77
80
  current_user = session[:twitter_user]
78
81
  current_user['screen_name'].should == 'faker'
@@ -83,7 +86,7 @@ describe Twitter::Login do
83
86
  get('/login?denied=OMG', build_session(session_data).update(:lint => true))
84
87
  response.status.should == 302
85
88
  response['Location'].should == 'http://example.org/'
86
- session[:twitter_request_token].should be_nil
89
+ session[:request_token].should be_nil
87
90
  end
88
91
 
89
92
  protected
@@ -121,7 +124,7 @@ describe Twitter::Login do
121
124
 
122
125
  def mock_oauth(*args)
123
126
  consumer = mock(*args)
124
- OAuth::Consumer.should_receive(:new).and_return(consumer)
127
+ Twitter::OAuth.should_receive(:new).and_return(consumer)
125
128
  consumer
126
129
  end
127
130
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter-login
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease:
4
+ hash: 15
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 1
10
- version: 0.3.1
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Mislav Marohni\xC4\x87"
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-17 00:00:00 +01:00
18
+ date: 2010-09-17 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  requirements: []
141
141
 
142
142
  rubyforge_project:
143
- rubygems_version: 1.5.0
143
+ rubygems_version: 1.3.7
144
144
  signing_key:
145
145
  specification_version: 3
146
146
  summary: Rack middleware to provide login functionality through Twitter