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.
- data/lib/twitter/login.rb +34 -57
- data/spec/login_spec.rb +19 -16
- metadata +7 -7
data/lib/twitter/login.rb
CHANGED
@@ -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 = {
|
16
|
+
DEFAULTS = {
|
17
|
+
:return_to => '/',
|
18
|
+
:site => 'http://api.twitter.com',
|
19
|
+
:authorize_path => '/oauth/authenticate'
|
20
|
+
}
|
17
21
|
|
18
|
-
def initialize(
|
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
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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 =>
|
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
|
-
|
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
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
154
|
-
:site =>
|
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
|
data/spec/login_spec.rb
CHANGED
@@ -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(:
|
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[:
|
54
|
+
session[:request_token].should == ['abc', '123']
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should authorize with Twitter" do
|
58
|
-
|
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
|
-
|
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
|
-
|
65
|
-
|
63
|
+
twitter = mock('Twitter Base')
|
64
|
+
Twitter::Base.should_receive(:new).with(oauth).and_return(twitter)
|
66
65
|
|
67
|
-
|
68
|
-
|
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 = {:
|
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[:
|
75
|
-
session[:
|
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[:
|
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
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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:
|
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.
|
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
|