twitter-login 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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