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.
- 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
|