oauth 0.2.4 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oauth might be problematic. Click here for more details.

data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.2.6 2008-9-9 The lets RSA release
2
+
3
+ - Bill Kocik's fix for Ruby 1.8.7
4
+ - Fixed rsa verification, so you can actually create an OAuth server yourself now using Ruby and RSA
5
+ - Added better testing for RSA
6
+ - Fixed issue where token was being included for rsa signatures
7
+ - Chris Mear added support for a private_key_file option for rsa signatures
8
+ - Scott Hill fixed several edge cases where parameters were incorrectly being signed
9
+ - Patch from choonkeat fixing a problem with rsa signing.
10
+
1
11
  == 0.2.2 2008-2-22 Lets actually support SSL release
2
12
 
3
13
  It didn't actually use https when required.
data/README.txt CHANGED
@@ -1 +1,73 @@
1
- README
1
+ = Ruby OAuth GEM
2
+
3
+ == What
4
+
5
+ This is a RubyGem for implementing both OAuth clients and servers in Ruby applications.
6
+
7
+ See the OAuth specs http://oauth.net/core/1.0/
8
+
9
+ == Installing
10
+
11
+ sudo gem install oauth
12
+
13
+ You can also install it from the oauth rubyforge project http://rubyforge.org/projects/oauth/.
14
+
15
+ The source code is now hosted on the OAuth GitHub Project http://github.com/pelle/oauth/tree/master
16
+
17
+ == The basics
18
+
19
+ This is a ruby library which is intended to be used in creating Ruby Consumer and Service Provider applications. It is NOT a Rails plugin, but could easily be used for the foundation for such a Rails plugin.
20
+
21
+ As a matter of fact it has been pulled out from an OAuth Rails Plugin http://code.google.com/p/oauth-plugin/ which now requires this GEM.
22
+
23
+ == Demonstration of usage
24
+
25
+ Create a new consumer instance by passing it a configuration hash:
26
+
27
+ @consumer=OAuth::Consumer.new( "key","secret", {
28
+ :site=>"https://agree2"
29
+ })
30
+
31
+ Start the process by requesting a token
32
+
33
+ @request_token=@consumer.get_request_token
34
+ session[:request_token]=@request_token
35
+ redirect_to @request_token.authorize_url
36
+
37
+ When user returns create an access_token
38
+
39
+ @access_token=@request_token.get_access_token
40
+ @photos=@access_token.get('/photos.xml')
41
+
42
+ For more detailed instructions I have written this OAuth Client Tutorial http://stakeventures.com/articles/2008/02/23/developing-oauth-clients-in-ruby and "How to turn your rails site into an OAuth Provider ":http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider .
43
+
44
+ Finally be sure to check out the OAuth RDoc Manual http://oauth.rubyforge.org/rdoc/ .
45
+
46
+ == Documentation Wiki
47
+
48
+ There is some documentation on the Google Code project for the "OAuth Rails Plugin":http://code.google.com/p/oauth-plugin/ :
49
+
50
+ * RequestToken http://code.google.com/p/oauth-plugin/wiki/RequestToken
51
+ * AccessToken http://code.google.com/p/oauth-plugin/wiki/AccessToken
52
+
53
+ == Forum
54
+
55
+ http://groups.google.com/group/oauth-ruby
56
+
57
+
58
+ == How to submit patches
59
+
60
+ Read the "8 steps for fixing other people's code" http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/.
61
+
62
+ The source code is now hosted on the OAuth GitHub Project http://github.com/pelle/oauth/tree/master
63
+
64
+ To submit a patch, please fork the oauth project and create a patch with tests. Once you're happy with it send a pull request and post a message to the google group.
65
+
66
+ == License
67
+
68
+ This code is free to use under the terms of the MIT license.
69
+
70
+ == Contact
71
+
72
+ Comments are welcome. Send an email to "Pelle Braendgaard" pelleb@gmail.com email via the OAuth Ruby mailing list http://groups.google.com/group/oauth-ruby
73
+
@@ -56,7 +56,7 @@ module OAuth::Client
56
56
 
57
57
  def header
58
58
  parameters = oauth_parameters
59
- parameters.merge!( { 'oauth_signature' => signature( { :parameters => parameters } ) } )
59
+ parameters.merge!( { 'oauth_signature' => signature( options.merge({ :parameters => parameters }) ) } )
60
60
 
61
61
  header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
62
62
 
@@ -1,3 +1,4 @@
1
+ require 'oauth/helper'
1
2
  require 'oauth/client/helper'
2
3
  require 'oauth/request_proxy/net_http'
3
4
 
@@ -6,7 +6,7 @@ module OAuth
6
6
 
7
7
  @@default_options={
8
8
  # Signature method used by server. Defaults to HMAC-SHA1
9
- :oauth_signature_method=>'HMAC-SHA1',
9
+ :signature_method => 'HMAC-SHA1',
10
10
 
11
11
  # default paths on site. These are the same as the defaults set up by the generators
12
12
  :request_token_path=>'/oauth/request_token',
@@ -77,16 +77,21 @@ module OAuth
77
77
  end
78
78
 
79
79
  # Contains the root URI for this site
80
- def uri(url=nil)
81
- @uri||=URI.parse(url||site)
80
+ def uri(custom_uri=nil)
81
+ if custom_uri
82
+ @uri = custom_uri
83
+ @http = create_http # yike, oh well. less intrusive this way
84
+ else # if no custom passed, we use existing, which, if unset, is set to site uri
85
+ @uri ||= URI.parse(site)
86
+ end
82
87
  end
83
88
 
84
89
  # Makes a request to the service for a new OAuth::RequestToken
85
90
  #
86
91
  # @request_token=@consumer.get_request_token
87
92
  #
88
- def get_request_token
89
- response=token_request(http_method,request_token_path)
93
+ def get_request_token(request_options={}, *arguments)
94
+ response=token_request(http_method,request_token_path, nil, request_options, *arguments)
90
95
  OAuth::RequestToken.new(self,response[:oauth_token],response[:oauth_token_secret])
91
96
  end
92
97
 
@@ -121,16 +126,16 @@ module OAuth
121
126
 
122
127
  # Sign the Request object. Use this if you have an externally generated http request object you want to sign.
123
128
  def sign!(request,token=nil, request_options = {})
124
- request.oauth!(http,self,token,{:scheme=>scheme}.merge(request_options))
129
+ request.oauth!(http, self, token, options.merge(request_options))
125
130
  end
126
131
 
127
132
  # Return the signature_base_string
128
133
  def signature_base_string(request,token=nil, request_options = {})
129
- request.signature_base_string(http,self,token,{:scheme=>scheme}.merge(request_options))
134
+ request.signature_base_string(http, self, token, options.merge(request_options))
130
135
  end
131
136
 
132
137
  def site
133
- @options[:site]
138
+ @options[:site].to_s
134
139
  end
135
140
 
136
141
  def scheme
@@ -203,6 +208,11 @@ module OAuth
203
208
  request
204
209
  end
205
210
 
206
-
211
+ # Unset cached http instance because it cannot be marshalled when
212
+ # it has already been used and use_ssl is set to true
213
+ def marshal_dump(*args)
214
+ @http = nil
215
+ self
216
+ end
207
217
  end
208
218
  end
@@ -27,6 +27,28 @@ module OAuth::RequestProxy
27
27
  params.merge(options[:parameters] || {})
28
28
  end
29
29
  end
30
+
31
+ # Override from OAuth::RequestProxy::Base to avoid roundtrip
32
+ # conversion to Hash or Array and thus preserve the original
33
+ # parameter names
34
+ def parameters_for_signature
35
+ params = []
36
+ params << options[:parameters].to_query if options[:parameters]
37
+
38
+ unless options[:clobber_request]
39
+ params << header_params.to_query
40
+ params << request.query_string unless request.query_string.blank?
41
+ if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
42
+ params << CGI.unescape(request.raw_post)
43
+ end
44
+ end
45
+
46
+ params.
47
+ join('&').split('&').
48
+ reject { |kv| kv =~ /^oauth_signature=.*/}.
49
+ reject(&:blank?).
50
+ map { |p| p.split('=') }
51
+ end
30
52
 
31
53
  protected
32
54
 
@@ -24,6 +24,7 @@ module OAuth::RequestProxy
24
24
  def parameters_for_signature
25
25
  p = parameters.dup
26
26
  p.delete("oauth_signature")
27
+ p.delete("oauth_token") if signature_method=='RSA-SHA1'
27
28
  p
28
29
  end
29
30
 
@@ -44,7 +44,10 @@ module OAuth::RequestProxy::Net
44
44
  end
45
45
 
46
46
  def query_string
47
- [ query_params, post_params, auth_header_params ].compact.join('&')
47
+ params = [ query_params, auth_header_params ]
48
+ is_form_urlencoded = request['Content-Type'] != nil && request['Content-Type'].downcase == 'application/x-www-form-urlencoded'
49
+ params << post_params if method.to_s.upcase == 'POST' && is_form_urlencoded
50
+ params.compact.join('&')
48
51
  end
49
52
 
50
53
  def query_params
@@ -7,6 +7,8 @@ module OAuth::Signature
7
7
  class Base
8
8
  include OAuth::Helper
9
9
 
10
+ attr_accessor :options
11
+
10
12
  def self.implements(signature_method)
11
13
  OAuth::Signature.available_methods[signature_method] = self
12
14
  end
@@ -21,16 +23,17 @@ module OAuth::Signature
21
23
  def initialize(request, options = {}, &block)
22
24
  raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
23
25
  @request = request
26
+ @options = options
24
27
  if block_given?
25
28
  @token_secret, @consumer_secret = yield block.arity == 1 ? token : [token, consumer_key,nonce,request.timestamp]
26
29
  else
27
- @consumer_secret = options[:consumer].secret
28
- @token_secret = options[:token] ? options[:token].secret : ''
30
+ @consumer_secret = @options[:consumer].secret
31
+ @token_secret = @options[:token] ? @options[:token].secret : ''
29
32
  end
30
33
  end
31
34
 
32
35
  def signature
33
- Base64.encode64(digest).chomp
36
+ Base64.encode64(digest).chomp.gsub(/\n/,'')
34
37
  end
35
38
 
36
39
  def ==(cmp_signature)
@@ -15,5 +15,9 @@ module OAuth::Signature
15
15
  def signature_base_string
16
16
  secret
17
17
  end
18
+
19
+ def secret
20
+ escape super
21
+ end
18
22
  end
19
23
  end
@@ -6,14 +6,38 @@ module OAuth::Signature::RSA
6
6
  implements 'rsa-sha1'
7
7
 
8
8
  def ==(cmp_signature)
9
- public_key = OpenSSL::PKey::RSA.new(request.consumer.secret)
10
- public_key.verify(OpenSSL::Digest::SHA1.new, cmp_signature, signature_base_string)
9
+ public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(cmp_signature.is_a?(Array) ? cmp_signature.first : cmp_signature), signature_base_string)
11
10
  end
12
11
 
12
+ def public_key
13
+ if consumer_secret.is_a?(String)
14
+ decode_public_key
15
+ elsif consumer_secret.is_a?(OpenSSL::X509::Certificate)
16
+ consumer_secret.public_key
17
+ else
18
+ consumer_secret
19
+ end
20
+ end
21
+
13
22
  private
14
-
23
+
24
+ def decode_public_key
25
+ case consumer_secret
26
+ when /-----BEGIN CERTIFICATE-----/
27
+ OpenSSL::X509::Certificate.new( consumer_secret).public_key
28
+ else
29
+ OpenSSL::PKey::RSA.new( consumer_secret)
30
+ end
31
+ end
32
+
15
33
  def digest
16
- private_key = OpenSSL::PKey::RSA.new(request.consumer.secret)
34
+ private_key = OpenSSL::PKey::RSA.new(
35
+ if options[:private_key_file]
36
+ IO.read(options[:private_key_file])
37
+ else
38
+ consumer_secret
39
+ end
40
+ )
17
41
  private_key.sign(OpenSSL::Digest::SHA1.new, signature_base_string)
18
42
  end
19
43
  end
data/lib/oauth/token.rb CHANGED
@@ -69,6 +69,20 @@ module OAuth
69
69
 
70
70
  # The Access Token is used for the actual "real" web service calls thatyou perform against the server
71
71
  class AccessToken<ConsumerToken
72
+
73
+ # The less intrusive way. Otherwise, if we are to do it correctly inside consumer,
74
+ # we need to restructure and touch more methods: requst(), sign!(), etc.
75
+ def request(http_method, path, *arguments)
76
+ request_uri = URI.parse(path)
77
+ site_uri = consumer.uri
78
+ is_service_uri_different = (request_uri.absolute? && request_uri != site_uri)
79
+ consumer.uri(request_uri) if is_service_uri_different
80
+ resp = super(http_method, path, *arguments)
81
+ # NOTE: reset for wholesomeness? meaning that we admit only AccessToken service calls may use different URIs?
82
+ # so reset in case consumer is still used for other token-management tasks subsequently?
83
+ consumer.uri(site_uri) if is_service_uri_different
84
+ resp
85
+ end
72
86
 
73
87
  # Make a regular get request using AccessToken
74
88
  #
data/lib/oauth/version.rb CHANGED
@@ -2,7 +2,7 @@ module Oauth #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 4
5
+ TINY = 6
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -31,4 +31,4 @@ namespace :manifest do
31
31
  task :refresh do
32
32
  `rake check_manifest | patch -p0 > Manifest.txt`
33
33
  end
34
- end
34
+ end
@@ -1,10 +1,27 @@
1
1
  require File.dirname(__FILE__) + '/test_helper.rb'
2
2
  require 'oauth/request_proxy/action_controller_request.rb'
3
+ require 'action_controller'
4
+ require 'action_controller/test_process'
3
5
 
4
6
  class ActionControllerRequestProxyTest < Test::Unit::TestCase
5
7
 
6
- def test_truth
7
- assert true
8
+ def request_proxy(parameters)
9
+ request = ActionController::TestRequest.new({}, parameters)
10
+ request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
11
+ OAuth::RequestProxy.proxy(request)
12
+ end
13
+
14
+ def test_parameter_keys_should_preserve_brackets_from_hash
15
+ assert_equal(
16
+ [["message[body]", "This is a test"]],
17
+ request_proxy({ :message => { :body => 'This is a test' }}).parameters_for_signature
18
+ )
8
19
  end
9
20
 
21
+ def test_parameter_keys_should_preserve_brackets_from_array
22
+ assert_equal(
23
+ [["foo[]", "123"], ["foo[]", "456"]],
24
+ request_proxy({ :foo => [123, 456] }).parameters_for_signature.sort
25
+ )
26
+ end
10
27
  end
@@ -1,5 +1,9 @@
1
+ require 'rubygems'
2
+ gem 'oauth'
1
3
  require 'test/unit'
2
4
  require 'oauth/consumer'
5
+ require 'oauth/signature/rsa/sha1'
6
+
3
7
 
4
8
  # This performs testing against Andy Smith's test server http://term.ie/oauth/example/
5
9
  # Thanks Andy.
@@ -84,7 +88,42 @@ class ConsumerTest < Test::Unit::TestCase
84
88
 
85
89
  assert_equal 'GET', request.method
86
90
  assert_equal '/test?key=value', request.path
87
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"", request['authorization']
91
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
92
+ end
93
+
94
+ def test_that_setting_signature_method_on_consumer_effects_signing
95
+ require 'oauth/signature/plaintext'
96
+ request = Net::HTTP::Get.new(@request_uri.path)
97
+ consumer = @consumer.dup
98
+ consumer.options[:signature_method] = 'PLAINTEXT'
99
+ token = OAuth::ConsumerToken.new(consumer, 'token_411a7f', '3196ffd991c8ebdb')
100
+ token.sign!(request, {:nonce => @nonce, :timestamp => @timestamp})
101
+
102
+ assert_no_match /oauth_signature_method="HMAC-SHA1"/, request['authorization']
103
+ assert_match /oauth_signature_method="PLAINTEXT"/, request['authorization']
104
+ end
105
+
106
+ def test_that_setting_signature_method_on_consumer_effects_signature_base_string
107
+ require 'oauth/signature/plaintext'
108
+ request = Net::HTTP::Get.new(@request_uri.path)
109
+ consumer = @consumer.dup
110
+ consumer.options[:signature_method] = 'PLAINTEXT'
111
+
112
+ request = Net::HTTP::Get.new('/')
113
+ signature_base_string = consumer.signature_base_string(request)
114
+
115
+ assert_no_match /HMAC-SHA1/, signature_base_string
116
+ assert_equal "#{consumer.secret}%26", signature_base_string
117
+ end
118
+
119
+ def test_that_plaintext_signature_works
120
+ require 'oauth/signature/plaintext'
121
+ consumer = OAuth::Consumer.new("key", "secret",
122
+ :site => "http://term.ie", :signature_method => 'PLAINTEXT')
123
+ access_token = OAuth::AccessToken.new(consumer, 'accesskey', 'accesssecret')
124
+ response = access_token.get("/oauth/example/echo_api.php?echo=hello")
125
+
126
+ assert_equal 'echo=hello', response.body
88
127
  end
89
128
 
90
129
  def test_that_signing_auth_headers_on_post_requests_works
@@ -96,7 +135,7 @@ class ConsumerTest < Test::Unit::TestCase
96
135
  assert_equal 'POST', request.method
97
136
  assert_equal '/test', request.path
98
137
  assert_equal 'key=value', request.body
99
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"", request['authorization']
138
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
100
139
  end
101
140
 
102
141
  def test_that_signing_post_params_works
@@ -115,7 +154,7 @@ class ConsumerTest < Test::Unit::TestCase
115
154
 
116
155
  assert_equal 'GET', request.method
117
156
  assert_equal '/test?key=value', request.path
118
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"", request['authorization']
157
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
119
158
  end
120
159
 
121
160
  def test_that_using_auth_headers_on_post_on_create_signed_requests_works
@@ -123,7 +162,7 @@ class ConsumerTest < Test::Unit::TestCase
123
162
  assert_equal 'POST', request.method
124
163
  assert_equal '/test', request.path
125
164
  assert_equal 'key=value', request.body
126
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"", request['authorization']
165
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
127
166
  end
128
167
 
129
168
  def test_that_signing_post_params_works
@@ -192,12 +231,54 @@ class ConsumerTest < Test::Unit::TestCase
192
231
  assert_equal "200",@response.code
193
232
  assert_equal( "ok=hello&test=this",@response.body)
194
233
  end
234
+
235
+
236
+ # This test does an actual https request (the result doesn't matter)
237
+ # to initialize the same way as get_request_token does. Can be any
238
+ # site that supports https.
239
+ #
240
+ # It also generates "warning: using default DH parameters." which I
241
+ # don't know how to get rid of
242
+ def test_serialization_with_https
243
+ consumer = OAuth::Consumer.new('token', 'secret', :site => 'https://plazes.net')
244
+ consumer.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
245
+ consumer.http.get('/')
246
+
247
+ assert_nothing_raised do
248
+ # Specifically this should not raise TypeError: no marshal_dump
249
+ # is defined for class OpenSSL::SSL::SSLContext
250
+ Marshal.dump(consumer)
251
+ end
252
+ end
253
+
254
+ def test_get_request_token_with_custom_arguments
255
+ @consumer=OAuth::Consumer.new(
256
+ "key",
257
+ "secret",
258
+ {
259
+ :site=>"http://term.ie",
260
+ :request_token_path=>"/oauth/example/request_token.php",
261
+ :access_token_path=>"/oauth/example/access_token.php",
262
+ :authorize_path=>"/oauth/example/authorize.php"
263
+ })
264
+
265
+
266
+ debug = ""
267
+ @consumer.http.set_debug_output(debug)
268
+
269
+ # get_request_token should receive our custom request_options and *arguments parameters from get_request_token.
270
+ @consumer.get_request_token({}, {:scope => "http://www.google.com/calendar/feeds http://picasaweb.google.com/data"})
271
+
272
+ # Because this is a POST request, create_http_request should take the first element of *arguments
273
+ # and turn it into URL-encoded data in the body of the POST.
274
+ assert_match /^<- "scope=http%3a%2f%2fwww.google.com%2fcalendar%2ffeeds%20http%3a%2f%2fpicasaweb.google.com%2fdata"/,
275
+ debug
276
+ end
277
+
195
278
  protected
196
279
 
197
280
  def request_parameters_to_s
198
281
  @request_parameters.map { |k,v| "#{k}=#{v}" }.join("&")
199
282
  end
200
-
201
283
 
202
284
  end
203
-
@@ -19,7 +19,7 @@ class NetHTTPClientTest < Test::Unit::TestCase
19
19
 
20
20
  assert_equal 'GET', request.method
21
21
  assert_equal '/test?key=value', request.path
22
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"", request['authorization']
22
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"1oO2izFav1GP4kEH2EskwXkCRFg%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
23
23
  end
24
24
 
25
25
  def test_that_using_auth_headers_on_post_requests_works
@@ -30,7 +30,7 @@ class NetHTTPClientTest < Test::Unit::TestCase
30
30
  assert_equal 'POST', request.method
31
31
  assert_equal '/test', request.path
32
32
  assert_equal 'key=value', request.body
33
- assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"", request['authorization']
33
+ assert_equal "OAuth realm=\"\", oauth_nonce=\"225579211881198842005988698334675835446\", oauth_signature_method=\"HMAC-SHA1\", oauth_token=\"token_411a7f\", oauth_timestamp=\"1199645624\", oauth_consumer_key=\"consumer_key_86cad9\", oauth_signature=\"26g7wHTtNO6ZWJaLltcueppHYiI%3D\", oauth_version=\"1.0\"".split(', ').sort, request['authorization'].split(', ').sort
34
34
  end
35
35
 
36
36
  def test_that_using_post_params_works
@@ -100,7 +100,7 @@ class NetHTTPClientTest < Test::Unit::TestCase
100
100
  request.oauth!(http, consumer, token, {:nonce => nonce, :timestamp => timestamp,:realm=>"http://photos.example.net/"})
101
101
 
102
102
  assert_equal 'GET', request.method
103
- assert_equal 'OAuth realm="http://photos.example.net/", oauth_nonce="kllo9940pd9333jh", oauth_signature_method="HMAC-SHA1", oauth_token="nnch734d00sl2jdk", oauth_timestamp="1191242096", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", oauth_version="1.0"', request['authorization']
103
+ assert_equal 'OAuth realm="http://photos.example.net/", oauth_nonce="kllo9940pd9333jh", oauth_signature_method="HMAC-SHA1", oauth_token="nnch734d00sl2jdk", oauth_timestamp="1191242096", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", oauth_version="1.0"'.split(', ').sort, request['authorization'].split(', ').sort
104
104
 
105
105
  end
106
106
 
@@ -129,6 +129,36 @@ class NetHTTPClientTest < Test::Unit::TestCase
129
129
  # assert_equal request['authorization'],response.body
130
130
  assert_equal "oauth_token=requestkey&oauth_token_secret=requestsecret",response.body
131
131
  end
132
+
133
+ def test_that_put_bodies_not_signed
134
+ request = Net::HTTP::Put.new(@request_uri.path)
135
+ request.body = "<?xml version=\"1.0\"?><foo><bar>baz</bar></foo>"
136
+ request["Content-Type"] = "application/xml"
137
+ signature_base_string=request.signature_base_string(@http, @consumer, nil, { :nonce => @nonce, :timestamp => @timestamp })
138
+ assert_equal "PUT&http%3A%2F%2Fexample.com%2Ftest&oauth_consumer_key%3Dconsumer_key_86cad9%26oauth_nonce%3D225579211881198842005988698334675835446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1199645624%26oauth_token%3D%26oauth_version%3D1.0", signature_base_string
139
+ end
140
+
141
+ def test_that_put_bodies_not_signed_even_if_form_urlencoded
142
+ request = Net::HTTP::Put.new(@request_uri.path)
143
+ request.set_form_data( { 'key2' => 'value2' } )
144
+ signature_base_string=request.signature_base_string(@http, @consumer, nil, { :nonce => @nonce, :timestamp => @timestamp })
145
+ assert_equal "PUT&http%3A%2F%2Fexample.com%2Ftest&oauth_consumer_key%3Dconsumer_key_86cad9%26oauth_nonce%3D225579211881198842005988698334675835446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1199645624%26oauth_token%3D%26oauth_version%3D1.0", signature_base_string
146
+ end
147
+
148
+ def test_that_post_bodies_signed_if_form_urlencoded
149
+ request = Net::HTTP::Post.new(@request_uri.path)
150
+ request.set_form_data( { 'key2' => 'value2' } )
151
+ signature_base_string=request.signature_base_string(@http, @consumer, nil, { :nonce => @nonce, :timestamp => @timestamp })
152
+ assert_equal "POST&http%3A%2F%2Fexample.com%2Ftest&key2%3Dvalue2%26oauth_consumer_key%3Dconsumer_key_86cad9%26oauth_nonce%3D225579211881198842005988698334675835446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1199645624%26oauth_token%3D%26oauth_version%3D1.0", signature_base_string
153
+ end
154
+
155
+ def test_that_post_bodies_not_signed_if_other_content_type
156
+ request = Net::HTTP::Post.new(@request_uri.path)
157
+ request.body = "<?xml version=\"1.0\"?><foo><bar>baz</bar></foo>"
158
+ request["Content-Type"] = "application/xml"
159
+ signature_base_string=request.signature_base_string(@http, @consumer, nil, { :nonce => @nonce, :timestamp => @timestamp })
160
+ assert_equal "POST&http%3A%2F%2Fexample.com%2Ftest&oauth_consumer_key%3Dconsumer_key_86cad9%26oauth_nonce%3D225579211881198842005988698334675835446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1199645624%26oauth_token%3D%26oauth_version%3D1.0", signature_base_string
161
+ end
132
162
 
133
163
  protected
134
164
 
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require 'oauth/consumer'
3
+ require 'oauth/signature/rsa/sha1'
4
+
5
+ class TestSignatureRsaSha1 < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @request = Net::HTTP::Get.new('/photos?file=vacaction.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1196666512&oauth_nonce=13917289812797014437&oauth_signature_method=RSA-SHA1')
9
+
10
+ @consumer = OAuth::Consumer.new('dpf43f3p2l4k3l03', OpenSSL::PKey::RSA.new(IO.read(File.dirname(__FILE__) + "/keys/rsa.pem")))
11
+
12
+ end
13
+
14
+ def test_that_rsa_sha1_implements_rsa_sha1
15
+ assert OAuth::Signature.available_methods.include?('rsa-sha1')
16
+ end
17
+
18
+ def test_that_get_request_from_oauth_test_cases_produces_matching_signature_base_string
19
+ sbs = OAuth::Signature.signature_base_string(@request, { :consumer => @consumer,
20
+ :uri => 'http://photos.example.net/photos' } )
21
+
22
+ assert_equal 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacaction.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3D13917289812797014437%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1196666512%26oauth_version%3D1.0%26size%3Doriginal', sbs
23
+ end
24
+
25
+ def test_that_get_request_from_oauth_test_cases_produces_matching_signature
26
+ signature = OAuth::Signature.sign(@request, { :consumer => @consumer,
27
+ :uri => 'http://photos.example.net/photos' } )
28
+
29
+ assert_equal 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=', signature
30
+
31
+ end
32
+
33
+ def test_that_get_request_from_oauth_test_cases_produces_matching_signature_using_private_key_file
34
+ @consumer = OAuth::Consumer.new('dpf43f3p2l4k3l03',nil)
35
+
36
+ signature = OAuth::Signature.sign(@request, { :consumer => @consumer,
37
+ :private_key_file=>File.dirname(__FILE__) + "/keys/rsa.pem",
38
+ :uri => 'http://photos.example.net/photos' } )
39
+
40
+ assert_equal 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=', signature
41
+ end
42
+
43
+ def test_that_get_request_from_oauth_test_cases_verifies_signature
44
+ @request = Net::HTTP::Get.new('/photos?oauth_signature_method=RSA-SHA1&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1196666512&oauth_nonce=13917289812797014437&file=vacaction.jpg&size=original&oauth_signature=jvTp%2FwX1TYtByB1m%2BPbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2%2F9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW%2F%2Fe%2BRinhejgCuzoH26dyF8iY2ZZ%2F5D1ilgeijhV%2FvBka5twt399mXwaYdCwFYE%3D')
45
+ @consumer = OAuth::Consumer.new('dpf43f3p2l4k3l03',OpenSSL::X509::Certificate.new(IO.read(File.dirname(__FILE__) + "/keys/rsa.cert")))
46
+
47
+ assert OAuth::Signature.verify(@request, { :consumer => @consumer,
48
+ :uri => 'http://photos.example.net/photos' } )
49
+
50
+ end
51
+
52
+ def test_that_get_request_from_oauth_test_cases_verifies_signature_with_pem
53
+ @request = Net::HTTP::Get.new('/photos?oauth_signature_method=RSA-SHA1&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1196666512&oauth_nonce=13917289812797014437&file=vacaction.jpg&size=original&oauth_signature=jvTp%2FwX1TYtByB1m%2BPbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2%2F9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW%2F%2Fe%2BRinhejgCuzoH26dyF8iY2ZZ%2F5D1ilgeijhV%2FvBka5twt399mXwaYdCwFYE%3D')
54
+ assert OAuth::Signature.verify(@request, { :consumer => @consumer,
55
+ :uri => 'http://photos.example.net/photos' } )
56
+
57
+ end
58
+
59
+ end
data/website/index.html CHANGED
@@ -33,103 +33,50 @@
33
33
  <h1>Ruby OAuth GEM</h1>
34
34
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/oauth"; return false'>
35
35
  <p>Get Version</p>
36
- <a href="http://rubyforge.org/projects/oauth" class="numbers">0.2.3</a>
36
+ <a href="http://rubyforge.org/projects/oauth" class="numbers">0.2.5</a>
37
37
  </div>
38
38
  <h2>What</h2>
39
-
40
-
41
- <p>This is a RubyGem for implementing both OAuth clients and servers in Ruby applications.</p>
42
-
43
-
44
- <p>See the <a href="http://oauth.net/core/1.0/">OAuth specs</a></p>
45
-
46
-
47
- <h2>Installing</h2>
48
-
49
-
50
- <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">oauth</span></pre></p>
51
-
52
-
53
- <p>You can also install it from the <a href="http://rubyforge.org/projects/oauth/">oauth rubyforge project</a>.</p>
54
-
55
-
56
- <h2>The basics</h2>
57
-
58
-
59
- <p>This is a ruby library which is intended to be used in creating Ruby Consumer and Service Provider applications. It is <span class="caps">NOT</span> a Rails plugin, but could easily be used for the foundation for such a Rails plugin.</p>
60
-
61
-
62
- <p>As a matter of fact it has been pulled out from an <a href="http://code.google.com/p/oauth-plugin/">OAuth Rails Plugin</a> which now requires this <span class="caps">GEM</span>.</p>
63
-
64
-
65
- <h2>Demonstration of usage</h2>
66
-
67
-
68
- <p>Create a new consumer instance by passing it a configuration hash:</p>
69
-
70
-
39
+ <p>This is a RubyGem for implementing both OAuth clients and servers in Ruby applications.</p>
40
+ <p>See the <a href="http://oauth.net/core/1.0/">OAuth specs</a></p>
41
+ <h2>Installing</h2>
42
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">oauth</span></pre></p>
43
+ <p>You can also install it from the <a href="http://rubyforge.org/projects/oauth/">oauth rubyforge project</a>.</p>
44
+ <p>The source code is now hosted on the <a href="http://github.com/pelle/oauth/tree/master">OAuth GitHub Project</a></p>
45
+ <h2>The basics</h2>
46
+ <p>This is a ruby library which is intended to be used in creating Ruby Consumer and Service Provider applications. It is <span class="caps">NOT</span> a Rails plugin, but could easily be used for the foundation for such a Rails plugin.</p>
47
+ <p>As a matter of fact it has been pulled out from an <a href="http://code.google.com/p/oauth-plugin/">OAuth Rails Plugin</a> which now requires this <span class="caps">GEM</span>.</p>
48
+ <h2>Demonstration of usage</h2>
49
+ <p>Create a new consumer instance by passing it a configuration hash:</p>
71
50
  <pre><code>@consumer=OAuth::Consumer.new( "key","secret", {
72
- :site=&gt;"https://agree2"
51
+ :site=&gt;"https://agree2"
73
52
  })</code></pre>
74
-
75
- <p>Start the process by requesting a token</p>
76
-
77
-
53
+ <p>Start the process by requesting a token</p>
78
54
  <pre><code>@request_token=@consumer.get_request_token
79
55
  session[:request_token]=@request_token
80
56
  redirect_to @request_token.authorize_url</code></pre>
81
-
82
- <p>When user returns create an access_token</p>
83
-
84
-
57
+ <p>When user returns create an access_token</p>
85
58
  <pre><code>@access_token=@request_token.get_access_token
86
59
  @photos=@access_token.get('/photos.xml')</code></pre>
87
-
88
- <p>For more detailed instructions I have written this <a href="http://stakeventures.com/articles/2008/02/23/developing-oauth-clients-in-ruby">OAuth Client Tutorial</a> and <a href="http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider">How to turn your rails site into an OAuth Provider</a>.</p>
89
-
90
-
91
- <p>Finally be sure to check out the <a href="http://oauth.rubyforge.org/rdoc/">OAuth RDoc Manual</a>.</p>
92
-
93
-
94
- <h2>Documentation Wiki</h2>
95
-
96
-
97
- <p>There is some documentation on the Google Code project for the <a href="http://code.google.com/p/oauth-plugin/">OAuth Rails Plugin</a> :</p>
98
-
99
-
100
- <ul>
60
+ <p>For more detailed instructions I have written this <a href="http://stakeventures.com/articles/2008/02/23/developing-oauth-clients-in-ruby">OAuth Client Tutorial</a> and &quot;How to turn your rails site into an OAuth Provider &quot;:http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider.</p>
61
+ <p>Finally be sure to check out the <a href="http://oauth.rubyforge.org/rdoc/">OAuth RDoc Manual</a>.</p>
62
+ <h2>Documentation Wiki</h2>
63
+ <p>There is some documentation on the Google Code project for the <a href="http://code.google.com/p/oauth-plugin/">OAuth Rails Plugin</a> :</p>
64
+ <ul>
101
65
  <li><a href="http://code.google.com/p/oauth-plugin/wiki/RequestToken">RequestToken</a></li>
102
- <li><a href="http://code.google.com/p/oauth-plugin/wiki/AccessToken">AccessToken</a></li>
103
- </ul>
104
-
105
-
106
- <h2>Forum</h2>
107
-
108
-
109
- <p><a href="http://groups.google.com/group/oauth-ruby">http://groups.google.com/group/oauth-ruby</a></p>
110
-
111
-
112
- <h2>How to submit patches</h2>
113
-
114
-
115
- <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
116
-
117
-
118
- <p>The trunk repository is <code>http://oauth.rubyforge.org/svn/trunk/</code> for anonymous access.</p>
119
-
120
-
121
- <h2>License</h2>
122
-
123
-
124
- <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
125
-
126
-
127
- <h2>Contact</h2>
128
-
129
-
130
- <p>Comments are welcome. Send an email to <a href="mailto:pelleb@gmail.com">Pelle Braendgaard</a> email via the <a href="http://groups.google.com/group/oauth-ruby">OAuth Ruby mailing list</a></p>
66
+ <li><a href="http://code.google.com/p/oauth-plugin/wiki/AccessToken">AccessToken</a></li>
67
+ </ul>
68
+ <h2>Forum</h2>
69
+ <p><a href="http://groups.google.com/group/oauth-ruby">http://groups.google.com/group/oauth-ruby</a></p>
70
+ <h2>How to submit patches</h2>
71
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a>.</p>
72
+ <p>The source code is now hosted on the <a href="http://github.com/pelle/oauth/tree/master">OAuth GitHub Project</a></p>
73
+ <p>To submit a patch, please fork the oauth project and create a patch with tests. Once you&#8217;re happy with it send a pull request and post a message to the google group.</p>
74
+ <h2>License</h2>
75
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
76
+ <h2>Contact</h2>
77
+ <p>Comments are welcome. Send an email to <a href="mailto:pelleb@gmail.com">Pelle Braendgaard</a> email via the <a href="http://groups.google.com/group/oauth-ruby">OAuth Ruby mailing list</a></p>
131
78
  <p class="coda">
132
- <a href="FIXME email">FIXME full name</a>, 25th February 2008<br>
79
+ <a href="FIXME email">FIXME full name</a>, 8th September 2008<br>
133
80
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
134
81
  </p>
135
82
  </div>
data/website/index.txt CHANGED
@@ -12,6 +12,8 @@ h2. Installing
12
12
 
13
13
  You can also install it from the "oauth rubyforge project":http://rubyforge.org/projects/oauth/.
14
14
 
15
+ The source code is now hosted on the "OAuth GitHub Project":http://github.com/pelle/oauth/tree/master
16
+
15
17
  h2. The basics
16
18
 
17
19
  This is a ruby library which is intended to be used in creating Ruby Consumer and Service Provider applications. It is NOT a Rails plugin, but could easily be used for the foundation for such a Rails plugin.
@@ -55,9 +57,11 @@ h2. Forum
55
57
 
56
58
  h2. How to submit patches
57
59
 
58
- Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
60
+ Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/.
61
+
62
+ The source code is now hosted on the "OAuth GitHub Project":http://github.com/pelle/oauth/tree/master
59
63
 
60
- The trunk repository is <code>http://oauth.rubyforge.org/svn/trunk/</code> for anonymous access.
64
+ To submit a patch, please fork the oauth project and create a patch with tests. Once you're happy with it send a pull request and post a message to the google group.
61
65
 
62
66
  h2. License
63
67
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pelle Braendgaard
@@ -14,11 +14,12 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2008-04-27 00:00:00 -07:00
17
+ date: 2008-09-09 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: ruby-hmac
22
+ type: :runtime
22
23
  version_requirement:
23
24
  version_requirements: !ruby/object:Gem::Requirement
24
25
  requirements:
@@ -26,6 +27,16 @@ dependencies:
26
27
  - !ruby/object:Gem::Version
27
28
  version: 0.3.1
28
29
  version:
30
+ - !ruby/object:Gem::Dependency
31
+ name: hoe
32
+ type: :development
33
+ version_requirement:
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 1.7.0
39
+ version:
29
40
  description: OAuth Core Ruby implementation
30
41
  email: pelleb@gmail.com
31
42
  executables: []
@@ -117,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
128
  requirements: []
118
129
 
119
130
  rubyforge_project: oauth
120
- rubygems_version: 1.1.1
131
+ rubygems_version: 1.2.0
121
132
  signing_key:
122
133
  specification_version: 2
123
134
  summary: OAuth Core Ruby implementation
@@ -129,6 +140,7 @@ test_files:
129
140
  - test/test_net_http_client.rb
130
141
  - test/test_net_http_request_proxy.rb
131
142
  - test/test_rack_request_proxy.rb
143
+ - test/test_rsa_sha1.rb
132
144
  - test/test_server.rb
133
145
  - test/test_signature.rb
134
146
  - test/test_signature_base.rb