pelle-oauth-plugin 0.3.5
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/.gitignore +5 -0
- data/CHANGELOG +76 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +375 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/generators/oauth_consumer/USAGE +10 -0
- data/generators/oauth_consumer/oauth_consumer_generator.rb +49 -0
- data/generators/oauth_consumer/templates/consumer_token.rb +5 -0
- data/generators/oauth_consumer/templates/controller.rb +14 -0
- data/generators/oauth_consumer/templates/migration.rb +20 -0
- data/generators/oauth_consumer/templates/oauth_config.rb +37 -0
- data/generators/oauth_consumer/templates/show.html.erb +7 -0
- data/generators/oauth_consumer/templates/show.html.haml +8 -0
- data/generators/oauth_provider/USAGE +20 -0
- data/generators/oauth_provider/lib/insert_routes.rb +67 -0
- data/generators/oauth_provider/oauth_provider_generator.rb +124 -0
- data/generators/oauth_provider/templates/_form.html.erb +17 -0
- data/generators/oauth_provider/templates/_form.html.haml +21 -0
- data/generators/oauth_provider/templates/access_token.rb +10 -0
- data/generators/oauth_provider/templates/authorize.html.erb +14 -0
- data/generators/oauth_provider/templates/authorize.html.haml +16 -0
- data/generators/oauth_provider/templates/authorize_failure.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_failure.html.haml +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.haml +1 -0
- data/generators/oauth_provider/templates/client_application.rb +55 -0
- data/generators/oauth_provider/templates/client_application_spec.rb +29 -0
- data/generators/oauth_provider/templates/client_application_test.rb +42 -0
- data/generators/oauth_provider/templates/client_applications.yml +23 -0
- data/generators/oauth_provider/templates/clients_controller.rb +52 -0
- data/generators/oauth_provider/templates/clients_controller_spec.rb +239 -0
- data/generators/oauth_provider/templates/clients_controller_test.rb +280 -0
- data/generators/oauth_provider/templates/controller.rb +5 -0
- data/generators/oauth_provider/templates/controller_spec.rb +367 -0
- data/generators/oauth_provider/templates/controller_spec_helper.rb +80 -0
- data/generators/oauth_provider/templates/controller_test.rb +310 -0
- data/generators/oauth_provider/templates/controller_test_helper.rb +115 -0
- data/generators/oauth_provider/templates/edit.html.erb +7 -0
- data/generators/oauth_provider/templates/edit.html.haml +4 -0
- data/generators/oauth_provider/templates/index.html.erb +43 -0
- data/generators/oauth_provider/templates/index.html.haml +39 -0
- data/generators/oauth_provider/templates/migration.rb +46 -0
- data/generators/oauth_provider/templates/new.html.erb +5 -0
- data/generators/oauth_provider/templates/new.html.haml +5 -0
- data/generators/oauth_provider/templates/oauth_nonce.rb +13 -0
- data/generators/oauth_provider/templates/oauth_nonce_spec.rb +24 -0
- data/generators/oauth_provider/templates/oauth_nonce_test.rb +26 -0
- data/generators/oauth_provider/templates/oauth_nonces.yml +13 -0
- data/generators/oauth_provider/templates/oauth_token.rb +31 -0
- data/generators/oauth_provider/templates/oauth_token_spec.rb +309 -0
- data/generators/oauth_provider/templates/oauth_token_test.rb +57 -0
- data/generators/oauth_provider/templates/oauth_tokens.yml +17 -0
- data/generators/oauth_provider/templates/request_token.rb +40 -0
- data/generators/oauth_provider/templates/show.html.erb +27 -0
- data/generators/oauth_provider/templates/show.html.haml +30 -0
- data/init.rb +7 -0
- data/install.rb +2 -0
- data/lib/oauth/controllers/application_controller_methods.rb +110 -0
- data/lib/oauth/controllers/consumer_controller.rb +69 -0
- data/lib/oauth/controllers/provider_controller.rb +78 -0
- data/lib/oauth/models/consumers/service_loader.rb +18 -0
- data/lib/oauth/models/consumers/services/agree2_token.rb +14 -0
- data/lib/oauth/models/consumers/services/twitter_token.rb +19 -0
- data/lib/oauth/models/consumers/token.rb +60 -0
- data/oauth-plugin.gemspec +104 -0
- data/tasks/oauth_tasks.rake +4 -0
- data/uninstall.rb +1 -0
- metadata +129 -0
@@ -0,0 +1,310 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../oauth_controller_test_helper'
|
3
|
+
require 'oauth/client/action_controller_request'
|
4
|
+
|
5
|
+
class OauthController; def rescue_action(e) raise e end; end
|
6
|
+
|
7
|
+
class OauthControllerRequestTokenTest < ActionController::TestCase
|
8
|
+
include OAuthControllerTestHelper
|
9
|
+
tests OauthController
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@controller = OauthController.new
|
13
|
+
setup_oauth
|
14
|
+
sign_request_with_oauth
|
15
|
+
@client_application.stubs(:create_request_token).returns(@request_token)
|
16
|
+
end
|
17
|
+
|
18
|
+
def do_get
|
19
|
+
get :request_token
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_be_successful
|
23
|
+
do_get
|
24
|
+
assert @response.success?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_query_for_client_application
|
28
|
+
ClientApplication.expects(:find_by_key).with('key').returns(@client_application)
|
29
|
+
do_get
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_request_token_from_client_application
|
33
|
+
@client_application.expects(:create_request_token).returns(@request_token)
|
34
|
+
do_get
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_should_return_token_string
|
38
|
+
do_get
|
39
|
+
assert_equal @request_token_string, @response.body
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class OauthControllerTokenAuthorizationTest < ActionController::TestCase
|
44
|
+
include OAuthControllerTestHelper
|
45
|
+
tests OauthController
|
46
|
+
|
47
|
+
def setup
|
48
|
+
@controller = OauthController.new
|
49
|
+
login
|
50
|
+
setup_oauth
|
51
|
+
RequestToken.stubs(:find_by_token).returns(@request_token)
|
52
|
+
end
|
53
|
+
|
54
|
+
def do_get
|
55
|
+
get :authorize, :oauth_token => @request_token.token
|
56
|
+
end
|
57
|
+
|
58
|
+
def do_post
|
59
|
+
@request_token.expects(:authorize!).with(@user)
|
60
|
+
post :authorize,:oauth_token=>@request_token.token,:authorize=>"1"
|
61
|
+
end
|
62
|
+
|
63
|
+
def do_post_without_user_authorization
|
64
|
+
@request_token.expects(:invalidate!)
|
65
|
+
post :authorize,:oauth_token=>@request_token.token,:authorize=>"0"
|
66
|
+
end
|
67
|
+
|
68
|
+
def do_post_with_callback
|
69
|
+
@request_token.expects(:authorize!).with(@user)
|
70
|
+
post :authorize,:oauth_token=>@request_token.token,:oauth_callback=>"http://application/alternative",:authorize=>"1"
|
71
|
+
end
|
72
|
+
|
73
|
+
def do_post_with_no_application_callback
|
74
|
+
@request_token.expects(:authorize!).with(@user)
|
75
|
+
@client_application.stubs(:callback_url).returns(nil)
|
76
|
+
post :authorize, :oauth_token => @request_token.token, :authorize=>"1"
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_be_successful
|
80
|
+
do_get
|
81
|
+
assert @response.success?
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_should_query_for_client_application
|
85
|
+
RequestToken.expects(:find_by_token).returns(@request_token)
|
86
|
+
do_get
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_assign_token
|
90
|
+
do_get
|
91
|
+
assert_equal @request_token, assigns(:token)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_render_authorize_template
|
95
|
+
do_get
|
96
|
+
assert_template('authorize')
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_should_redirect_to_default_callback
|
100
|
+
do_post
|
101
|
+
assert_response :redirect
|
102
|
+
assert_redirected_to("http://application/callback?oauth_token=#{@request_token.token}")
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_should_redirect_to_callback_in_query
|
106
|
+
do_post_with_callback
|
107
|
+
assert_response :redirect
|
108
|
+
assert_redirected_to("http://application/alternative?oauth_token=#{@request_token.token}")
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_should_be_successful_on_authorize_without_any_application_callback
|
112
|
+
do_post_with_no_application_callback
|
113
|
+
assert @response.success?
|
114
|
+
assert_template('authorize_success')
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_should_render_failure_screen_on_user_invalidation
|
118
|
+
do_post_without_user_authorization
|
119
|
+
assert_template('authorize_failure')
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_should_render_failure_screen_if_token_is_invalidated
|
123
|
+
@request_token.expects(:invalidated?).returns(true)
|
124
|
+
do_get
|
125
|
+
assert_template('authorize_failure')
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
class OauthControllerGetAccessTokenTest < ActionController::TestCase
|
132
|
+
include OAuthControllerTestHelper
|
133
|
+
tests OauthController
|
134
|
+
|
135
|
+
def setup
|
136
|
+
@controller = OauthController.new
|
137
|
+
setup_oauth
|
138
|
+
sign_request_with_oauth @request_token
|
139
|
+
@request_token.stubs(:exchange!).returns(@access_token)
|
140
|
+
end
|
141
|
+
|
142
|
+
def do_get
|
143
|
+
get :access_token
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_should_be_successful
|
147
|
+
do_get
|
148
|
+
assert @response.success?
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_should_query_for_client_application
|
152
|
+
ClientApplication.expects(:find_token).with(@request_token.token).returns(@request_token)
|
153
|
+
do_get
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_should_request_token_from_client_application
|
157
|
+
@request_token.expects(:exchange!).returns(@access_token)
|
158
|
+
do_get
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_should__return_token_string
|
162
|
+
do_get
|
163
|
+
assert_equal @access_token_string, @response.body
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class OauthorizedController < ApplicationController
|
168
|
+
before_filter :login_or_oauth_required,:only=>:both
|
169
|
+
before_filter :login_required,:only=>:interactive
|
170
|
+
before_filter :oauth_required,:only=>:token_only
|
171
|
+
|
172
|
+
def interactive
|
173
|
+
render :text => "interactive"
|
174
|
+
end
|
175
|
+
|
176
|
+
def token_only
|
177
|
+
render :text => "token"
|
178
|
+
end
|
179
|
+
|
180
|
+
def both
|
181
|
+
render :text => "both"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
class OauthControllerAccessControlTest < ActionController::TestCase
|
187
|
+
include OAuthControllerTestHelper
|
188
|
+
tests OauthorizedController
|
189
|
+
|
190
|
+
def setup
|
191
|
+
@controller = OauthorizedController.new
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_should__have_access_token_set_up_correctly
|
195
|
+
setup_to_authorize_request
|
196
|
+
assert @access_token.is_a?(AccessToken)
|
197
|
+
assert @access_token.authorized?
|
198
|
+
assert !@access_token.invalidated?
|
199
|
+
assert_equal @user, @access_token.user
|
200
|
+
assert_equal @client_application, @access_token.client_application
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_should_return_false_for_oauth_by_default
|
204
|
+
assert_equal false, @controller.send(:oauth?)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_should_return_nil_for_current_token_by_default
|
208
|
+
assert_nil @controller.send(:current_token)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_should_allow_oauth_when_using_login_or_oauth_required
|
212
|
+
setup_to_authorize_request
|
213
|
+
sign_request_with_oauth(@access_token)
|
214
|
+
ClientApplication.expects(:find_token).with(@access_token.token).returns(@access_token)
|
215
|
+
get :both
|
216
|
+
assert_equal @access_token, @controller.send(:current_token)
|
217
|
+
assert @controller.send(:current_token).is_a?(AccessToken)
|
218
|
+
assert_equal @user, @controller.send(:current_user)
|
219
|
+
assert_equal @client_application, @controller.send(:current_client_application)
|
220
|
+
assert_equal '200', @response.code
|
221
|
+
assert @response.success?
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_should_allow_interactive_when_using_login_or_oauth_required
|
225
|
+
login
|
226
|
+
get :both
|
227
|
+
assert @response.success?
|
228
|
+
assert_equal @user, @controller.send(:current_user)
|
229
|
+
assert_nil @controller.send(:current_token)
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_should_allow_oauth_when_using_oauth_required
|
233
|
+
setup_to_authorize_request
|
234
|
+
sign_request_with_oauth(@access_token)
|
235
|
+
ClientApplication.expects(:find_token).with(@access_token.token).returns(@access_token)
|
236
|
+
get :token_only
|
237
|
+
assert_equal @access_token, @controller.send(:current_token)
|
238
|
+
assert_equal @client_application, @controller.send(:current_client_application)
|
239
|
+
assert_equal @user, @controller.send(:current_user)
|
240
|
+
assert_equal '200', @response.code
|
241
|
+
assert @response.success?
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_should_disallow_oauth_using_request_token_when_using_oauth_required
|
245
|
+
setup_to_authorize_request
|
246
|
+
ClientApplication.expects(:find_token).with(@request_token.token).returns(@request_token)
|
247
|
+
sign_request_with_oauth(@request_token)
|
248
|
+
get :token_only
|
249
|
+
assert_equal '401', @response.code
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_should_disallow_interactive_when_using_oauth_required
|
253
|
+
login
|
254
|
+
get :token_only
|
255
|
+
assert_equal '401', @response.code
|
256
|
+
|
257
|
+
assert_equal @user, @controller.send(:current_user)
|
258
|
+
assert_nil @controller.send(:current_token)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_should_disallow_oauth_when_using_login_required
|
262
|
+
setup_to_authorize_request
|
263
|
+
sign_request_with_oauth(@access_token)
|
264
|
+
get :interactive
|
265
|
+
assert_equal "302",@response.code
|
266
|
+
assert_nil @controller.send(:current_user)
|
267
|
+
assert_nil @controller.send(:current_token)
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_should_allow_interactive_when_using_login_required
|
271
|
+
login
|
272
|
+
get :interactive
|
273
|
+
assert @response.success?
|
274
|
+
assert_equal @user, @controller.send(:current_user)
|
275
|
+
assert_nil @controller.send(:current_token)
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
class OauthControllerRevokeTest < ActionController::TestCase
|
281
|
+
include OAuthControllerTestHelper
|
282
|
+
tests OauthController
|
283
|
+
|
284
|
+
def setup
|
285
|
+
@controller = OauthController.new
|
286
|
+
setup_oauth_for_user
|
287
|
+
@request_token.stubs(:invalidate!)
|
288
|
+
end
|
289
|
+
|
290
|
+
def do_post
|
291
|
+
post :revoke, :token => "TOKEN STRING"
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_should_redirect_to_index
|
295
|
+
do_post
|
296
|
+
assert_response :redirect
|
297
|
+
assert_redirected_to('http://test.host/oauth_clients')
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_should_query_current_users_tokens
|
301
|
+
@tokens.expects(:find_by_token).returns(@request_token)
|
302
|
+
do_post
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_should_call_invalidate_on_token
|
306
|
+
@request_token.expects(:invalidate!)
|
307
|
+
do_post
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require "mocha"
|
2
|
+
module OAuthControllerTestHelper
|
3
|
+
|
4
|
+
# Some custom stuff since we're using Mocha
|
5
|
+
def mock_model(model_class, options_and_stubs = {})
|
6
|
+
id = rand(10000)
|
7
|
+
options_and_stubs.reverse_merge! :id => id,
|
8
|
+
:to_param => id.to_s,
|
9
|
+
:new_record? => false,
|
10
|
+
:errors => stub("errors", :count => 0)
|
11
|
+
|
12
|
+
m = stub("#{model_class.name}_#{options_and_stubs[:id]}", options_and_stubs)
|
13
|
+
m.instance_eval <<-CODE
|
14
|
+
def is_a?(other)
|
15
|
+
#{model_class}.ancestors.include?(other)
|
16
|
+
end
|
17
|
+
def kind_of?(other)
|
18
|
+
#{model_class}.ancestors.include?(other)
|
19
|
+
end
|
20
|
+
def instance_of?(other)
|
21
|
+
other == #{model_class}
|
22
|
+
end
|
23
|
+
def class
|
24
|
+
#{model_class}
|
25
|
+
end
|
26
|
+
CODE
|
27
|
+
yield m if block_given?
|
28
|
+
m
|
29
|
+
end
|
30
|
+
|
31
|
+
def mock_full_client_application
|
32
|
+
mock_model(ClientApplication,
|
33
|
+
:name => "App1",
|
34
|
+
:url => "http://app.com",
|
35
|
+
:callback_url => "http://app.com/callback",
|
36
|
+
:support_url => "http://app.com/support",
|
37
|
+
:key => "asd23423yy",
|
38
|
+
:secret => "secret",
|
39
|
+
:oauth_server => OAuth::Server.new("http://kowabunga.com")
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def login
|
44
|
+
@controller.stubs(:local_request?).returns(true)
|
45
|
+
@user = mock_model(User, :login => "ron")
|
46
|
+
@controller.stubs(:current_user).returns(@user)
|
47
|
+
@tokens=[]
|
48
|
+
@tokens.stubs(:find).returns(@tokens)
|
49
|
+
@user.stubs(:tokens).returns(@tokens)
|
50
|
+
User.stubs(:find_by_id).returns(@user)
|
51
|
+
end
|
52
|
+
|
53
|
+
def login_as_application_owner
|
54
|
+
login
|
55
|
+
@client_application = mock_full_client_application
|
56
|
+
@client_applications = [@client_application]
|
57
|
+
|
58
|
+
@user.stubs(:client_applications).returns(@client_applications)
|
59
|
+
@client_applications.stubs(:find).returns(@client_application)
|
60
|
+
end
|
61
|
+
|
62
|
+
def setup_oauth
|
63
|
+
@controller.stubs(:local_request?).returns(true)
|
64
|
+
@user||=mock_model(User)
|
65
|
+
|
66
|
+
User.stubs(:find_by_id).returns(@user)
|
67
|
+
|
68
|
+
@server=OAuth::Server.new "http://test.host"
|
69
|
+
@consumer=OAuth::Consumer.new('key','secret',{:site=>"http://test.host"})
|
70
|
+
|
71
|
+
@client_application = mock_full_client_application
|
72
|
+
@controller.stubs(:current_client_application).returns(@client_application)
|
73
|
+
ClientApplication.stubs(:find_by_key).returns(@client_application)
|
74
|
+
@client_application.stubs(:key).returns(@consumer.key)
|
75
|
+
@client_application.stubs(:secret).returns(@consumer.secret)
|
76
|
+
@client_application.stubs(:name).returns("Client Application name")
|
77
|
+
@client_application.stubs(:callback_url).returns("http://application/callback")
|
78
|
+
@request_token=mock_model(RequestToken,:token=>'request_token',:client_application=>@client_application,:secret=>"request_secret",:user=>@user)
|
79
|
+
@request_token.stubs(:invalidated?).returns(false)
|
80
|
+
ClientApplication.stubs(:find_token).returns(@request_token)
|
81
|
+
|
82
|
+
@request_token_string="oauth_token=request_token&oauth_token_secret=request_secret"
|
83
|
+
@request_token.stubs(:to_query).returns(@request_token_string)
|
84
|
+
|
85
|
+
@access_token=mock_model(AccessToken,:token=>'access_token',:client_application=>@client_application,:secret=>"access_secret",:user=>@user)
|
86
|
+
@access_token.stubs(:invalidated?).returns(false)
|
87
|
+
@access_token.stubs(:authorized?).returns(true)
|
88
|
+
@access_token_string="oauth_token=access_token&oauth_token_secret=access_secret"
|
89
|
+
@access_token.stubs(:to_query).returns(@access_token_string)
|
90
|
+
|
91
|
+
@client_application.stubs(:authorize_request?).returns(true)
|
92
|
+
# @client_application.stubs(:sign_request_with_oauth_token).returns(@request_token)
|
93
|
+
@client_application.stubs(:exchange_for_access_token).returns(@access_token)
|
94
|
+
end
|
95
|
+
|
96
|
+
def setup_oauth_for_user
|
97
|
+
login
|
98
|
+
setup_oauth
|
99
|
+
@tokens=[@request_token]
|
100
|
+
@tokens.stubs(:find).returns(@tokens)
|
101
|
+
@tokens.stubs(:find_by_token).returns(@request_token)
|
102
|
+
@user.stubs(:tokens).returns(@tokens)
|
103
|
+
end
|
104
|
+
|
105
|
+
def sign_request_with_oauth(token=nil)
|
106
|
+
ActionController::TestRequest.use_oauth=true
|
107
|
+
@request.configure_oauth(@consumer, token)
|
108
|
+
end
|
109
|
+
|
110
|
+
def setup_to_authorize_request
|
111
|
+
setup_oauth
|
112
|
+
OauthToken.stubs(:find_by_token).with( @access_token.token).returns(@access_token)
|
113
|
+
@access_token.stubs(:is_a?).returns(true)
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<h1>Edit your application</h1>
|
2
|
+
<%% form_for :client_application, @client_application, :url => oauth_client_path(@client_application), :html => {:method => :put} do |f| %>
|
3
|
+
<%%= render :partial => "form", :locals => { :f => f } %>
|
4
|
+
<%%= submit_tag "Edit" %>
|
5
|
+
<%% end %>
|
6
|
+
<%%= link_to 'Show', oauth_client_path(@client_application) %> |
|
7
|
+
<%%= link_to 'Back', oauth_clients_path %>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<div class="flash"><%%= flash[:notice] %></div>
|
2
|
+
<h1>OAuth Client Applications</h1>
|
3
|
+
<%% unless @tokens.empty? %>
|
4
|
+
<p>The following tokens have been issued to applications in your name</p>
|
5
|
+
<table>
|
6
|
+
<tr><th>Application</th><th>Issued</th><th> </th></tr>
|
7
|
+
<%% @tokens.each do |token|%>
|
8
|
+
<%% content_tag_for :tr, token do %>
|
9
|
+
<td><%%= link_to token.client_application.name, token.client_application.url %></td>
|
10
|
+
<td><%%= token.authorized_at %></td>
|
11
|
+
<td>
|
12
|
+
<%% form_tag :controller => 'oauth', :action => 'revoke' do %>
|
13
|
+
<%%= hidden_field_tag 'token', token.token %>
|
14
|
+
<%%= submit_tag "Revoke!" %>
|
15
|
+
<%% end %>
|
16
|
+
</td>
|
17
|
+
<%% end %>
|
18
|
+
<%% end %>
|
19
|
+
|
20
|
+
</table>
|
21
|
+
<%% end %>
|
22
|
+
<h3>Application Developers</h3>
|
23
|
+
<%% if @client_applications.empty? %>
|
24
|
+
<p>
|
25
|
+
Do you have an application you would like to register for use with us using the <a href="http://oauth.net">OAuth</a> standard?
|
26
|
+
</p>
|
27
|
+
<p>
|
28
|
+
You must register your web application before it can make OAuth requests to this service
|
29
|
+
</p>
|
30
|
+
<%% else %>
|
31
|
+
<p>
|
32
|
+
You have the following client applications registered:
|
33
|
+
</p>
|
34
|
+
<%% @client_applications.each do |client|%>
|
35
|
+
<%% div_for client do %>
|
36
|
+
<%%= link_to client.name, oauth_client_path(client) %>-
|
37
|
+
<%%= link_to 'Edit', edit_oauth_client_path(client) %>
|
38
|
+
<%%= link_to 'Delete', oauth_client_path(client), :confirm => "Are you sure?", :method => :delete %>
|
39
|
+
<%% end %>
|
40
|
+
<%% end %>
|
41
|
+
<%% end %>
|
42
|
+
<br />
|
43
|
+
<h3><%%= link_to "Register your application", :action => :new %></h3>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.flash= flash[:notice]
|
2
|
+
%h1 OAuth Client Applications
|
3
|
+
- unless @tokens.empty?
|
4
|
+
|
5
|
+
%p
|
6
|
+
The following tokens have been issued to applications in your name
|
7
|
+
|
8
|
+
%table
|
9
|
+
%tr
|
10
|
+
%th Application
|
11
|
+
%th Issued
|
12
|
+
%th
|
13
|
+
- @tokens.each do |token|
|
14
|
+
- content_tag_for :tr, token do
|
15
|
+
%td= link_to token.client_application.name, token.client_application.url
|
16
|
+
%td= token.authorized_at
|
17
|
+
%td
|
18
|
+
- form_tag :controller => 'oauth', :action => 'revoke' do
|
19
|
+
= hidden_field_tag 'token', token.token
|
20
|
+
= submit_tag "Revoke!"
|
21
|
+
|
22
|
+
%h3 Application Developers
|
23
|
+
|
24
|
+
- if @client_applications.empty?
|
25
|
+
%p
|
26
|
+
Do you have an application you would like to register for use with us using the <a href="http://oauth.net">OAuth</a> standard?
|
27
|
+
You must register your web application before it can make OAuth requests to this service
|
28
|
+
- else
|
29
|
+
%p
|
30
|
+
You have the following client applications registered:
|
31
|
+
|
32
|
+
- @client_applications.each do |client|
|
33
|
+
- div_for client do
|
34
|
+
= link_to client.name, :action => :show, :id => client.id
|
35
|
+
= link_to 'Edit', edit_oauth_client_path(client)
|
36
|
+
= link_to 'Delete', oauth_client_path(client), :confirm => "Are you sure?", :method => :delete
|
37
|
+
%br
|
38
|
+
%h3
|
39
|
+
= link_to "Register your application", :action => :new
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class CreateOauthTables < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :client_applications do |t|
|
4
|
+
t.string :name
|
5
|
+
t.string :url
|
6
|
+
t.string :support_url
|
7
|
+
t.string :callback_url
|
8
|
+
t.string :key, :limit => 20
|
9
|
+
t.string :secret, :limit => 40
|
10
|
+
t.integer :user_id
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
add_index :client_applications, :key, :unique
|
15
|
+
|
16
|
+
create_table :oauth_tokens do |t|
|
17
|
+
t.integer :user_id
|
18
|
+
t.string :type, :limit => 20
|
19
|
+
t.integer :client_application_id
|
20
|
+
t.string :token, :limit => 20
|
21
|
+
t.string :secret, :limit => 40
|
22
|
+
t.string :callback_url
|
23
|
+
t.string :verifier, :limit => 20
|
24
|
+
t.timestamp :authorized_at, :invalidated_at
|
25
|
+
t.timestamps
|
26
|
+
end
|
27
|
+
|
28
|
+
add_index :oauth_tokens, :token, :unique
|
29
|
+
|
30
|
+
create_table :oauth_nonces do |t|
|
31
|
+
t.string :nonce
|
32
|
+
t.integer :timestamp
|
33
|
+
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
add_index :oauth_nonces,[:nonce, :timestamp], :unique
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.down
|
41
|
+
drop_table :client_applications
|
42
|
+
drop_table :oauth_tokens
|
43
|
+
drop_table :oauth_nonces
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
|
2
|
+
# Thus you can use the same nonce with a different timestamp and viceversa.
|
3
|
+
class OauthNonce < ActiveRecord::Base
|
4
|
+
validates_presence_of :nonce, :timestamp
|
5
|
+
validates_uniqueness_of :nonce, :scope => :timestamp
|
6
|
+
|
7
|
+
# Remembers a nonce and it's associated timestamp. It returns false if it has already been used
|
8
|
+
def self.remember(nonce, timestamp)
|
9
|
+
oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp)
|
10
|
+
return false if oauth_nonce.new_record?
|
11
|
+
oauth_nonce
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'oauth/helper'
|
3
|
+
describe OauthNonce do
|
4
|
+
include OAuth::Helper
|
5
|
+
before(:each) do
|
6
|
+
@oauth_nonce = OauthNonce.remember(generate_key, Time.now.to_i)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be valid" do
|
10
|
+
@oauth_nonce.should be_valid
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not have errors" do
|
14
|
+
@oauth_nonce.errors.full_messages.should == []
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not be a new record" do
|
18
|
+
@oauth_nonce.should_not be_new_record
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not allow a second one with the same values" do
|
22
|
+
OauthNonce.remember(@oauth_nonce.nonce,@oauth_nonce.timestamp).should == false
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'oauth/helper'
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
|
4
|
+
class ClientNoneTest < ActiveSupport::TestCase
|
5
|
+
include OAuth::Helper
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@oauth_nonce = OauthNonce.remember(generate_key,Time.now.to_i)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_should_be_valid
|
12
|
+
assert @oauth_nonce.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_not_have_errors
|
16
|
+
assert_equal [], @oauth_nonce.errors.full_messages
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_not_be_a_new_record
|
20
|
+
assert !@oauth_nonce.new_record?
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_shuold_not_allow_a_second_one_with_the_same_values
|
24
|
+
assert_equal false, OauthNonce.remember(@oauth_nonce.nonce, @oauth_nonce.timestamp)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
2
|
+
one:
|
3
|
+
id: 1
|
4
|
+
nonce: a_nonce
|
5
|
+
timestamp: 1
|
6
|
+
created_at: 2007-11-25 17:27:04
|
7
|
+
updated_at: 2007-11-25 17:27:04
|
8
|
+
two:
|
9
|
+
id: 2
|
10
|
+
nonce: b_nonce
|
11
|
+
timestamp: 2
|
12
|
+
created_at: 2007-11-25 17:27:04
|
13
|
+
updated_at: 2007-11-25 17:27:04
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class OauthToken < ActiveRecord::Base
|
2
|
+
belongs_to :client_application
|
3
|
+
belongs_to :user
|
4
|
+
validates_uniqueness_of :token
|
5
|
+
validates_presence_of :client_application, :token, :secret
|
6
|
+
before_validation_on_create :generate_keys
|
7
|
+
|
8
|
+
def invalidated?
|
9
|
+
invalidated_at != nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def invalidate!
|
13
|
+
update_attribute(:invalidated_at, Time.now)
|
14
|
+
end
|
15
|
+
|
16
|
+
def authorized?
|
17
|
+
authorized_at != nil && !invalidated?
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_query
|
21
|
+
"oauth_token=#{token}&oauth_token_secret=#{secret}"
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def generate_keys
|
27
|
+
oauth_token = client_application.oauth_server.generate_credentials
|
28
|
+
self.token = oauth_token[0][0,20]
|
29
|
+
self.secret = oauth_token[1][0,40]
|
30
|
+
end
|
31
|
+
end
|