monkeyhelper-oauth 0.3.1 → 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.
Files changed (54) hide show
  1. data/History.txt +62 -17
  2. data/Manifest.txt +14 -1
  3. data/README.rdoc +7 -9
  4. data/Rakefile +7 -5
  5. data/TODO +17 -0
  6. data/bin/oauth +2 -2
  7. data/examples/yql.rb +44 -0
  8. data/lib/oauth/cli.rb +267 -31
  9. data/lib/oauth/client/action_controller_request.rb +14 -12
  10. data/lib/oauth/client/helper.rb +22 -14
  11. data/lib/oauth/client/net_http.rb +53 -22
  12. data/lib/oauth/consumer.rb +217 -111
  13. data/lib/oauth/errors/error.rb +4 -0
  14. data/lib/oauth/errors/problem.rb +14 -0
  15. data/lib/oauth/errors/unauthorized.rb +12 -0
  16. data/lib/oauth/errors.rb +3 -0
  17. data/lib/oauth/helper.rb +67 -6
  18. data/lib/oauth/oauth.rb +11 -0
  19. data/lib/oauth/oauth_test_helper.rb +12 -13
  20. data/lib/oauth/request_proxy/action_controller_request.rb +8 -8
  21. data/lib/oauth/request_proxy/base.rb +102 -44
  22. data/lib/oauth/request_proxy/jabber_request.rb +1 -2
  23. data/lib/oauth/request_proxy/mock_request.rb +8 -0
  24. data/lib/oauth/request_proxy/net_http.rb +2 -2
  25. data/lib/oauth/request_proxy/rack_request.rb +7 -7
  26. data/lib/oauth/server.rb +31 -33
  27. data/lib/oauth/signature/base.rb +23 -21
  28. data/lib/oauth/signature/hmac/base.rb +1 -1
  29. data/lib/oauth/signature/hmac/sha1.rb +0 -1
  30. data/lib/oauth/signature/plaintext.rb +2 -2
  31. data/lib/oauth/signature/rsa/sha1.rb +5 -4
  32. data/lib/oauth/signature.rb +9 -0
  33. data/lib/oauth/token.rb +6 -136
  34. data/lib/oauth/tokens/access_token.rb +68 -0
  35. data/lib/oauth/tokens/consumer_token.rb +33 -0
  36. data/lib/oauth/tokens/request_token.rb +32 -0
  37. data/lib/oauth/tokens/server_token.rb +9 -0
  38. data/lib/oauth/tokens/token.rb +17 -0
  39. data/lib/oauth/version.rb +1 -1
  40. data/lib/oauth.rb +1 -0
  41. data/oauth.gemspec +12 -6
  42. data/test/cases/spec/1_0-final/test_construct_request_url.rb +1 -1
  43. data/test/test_access_token.rb +28 -0
  44. data/test/test_action_controller_request_proxy.rb +105 -6
  45. data/test/test_consumer.rb +41 -5
  46. data/test/test_helper.rb +0 -5
  47. data/test/test_net_http_client.rb +38 -20
  48. data/test/test_net_http_request_proxy.rb +43 -8
  49. data/test/test_oauth_helper.rb +50 -0
  50. data/test/test_request_token.rb +53 -0
  51. data/test/test_server.rb +1 -1
  52. data/test/test_signature.rb +19 -11
  53. data/website/index.html +2 -2
  54. metadata +41 -3
@@ -16,70 +16,133 @@ module OAuth::RequestProxy
16
16
  @options = options
17
17
  end
18
18
 
19
- def token
20
- parameters['oauth_token']
21
- end
19
+ ## OAuth parameters
22
20
 
23
- def consumer_key
24
- parameters['oauth_consumer_key']
21
+ def oauth_callback
22
+ parameters['oauth_callback']
25
23
  end
26
24
 
27
- def parameters_for_signature
28
- p = parameters.dup
29
- p.delete("oauth_signature")
30
- p
25
+ def oauth_consumer_key
26
+ parameters['oauth_consumer_key']
31
27
  end
32
28
 
33
- def nonce
29
+ def oauth_nonce
34
30
  parameters['oauth_nonce']
35
31
  end
36
32
 
37
- def timestamp
38
- parameters['oauth_timestamp']
33
+ def oauth_signature
34
+ # TODO can this be nil?
35
+ parameters['oauth_signature'] || ""
39
36
  end
40
37
 
41
- def signature_method
38
+ def oauth_signature_method
42
39
  case parameters['oauth_signature_method']
43
- when Array: parameters['oauth_signature_method'].first
40
+ when Array
41
+ parameters['oauth_signature_method'].first
44
42
  else
45
43
  parameters['oauth_signature_method']
46
44
  end
47
45
  end
48
46
 
49
- def signature
50
- parameters['oauth_signature'] || ""
47
+ def oauth_timestamp
48
+ parameters['oauth_timestamp']
49
+ end
50
+
51
+ def oauth_token
52
+ parameters['oauth_token']
53
+ end
54
+
55
+ def oauth_verifier
56
+ parameters['oauth_verifier']
57
+ end
58
+
59
+ def oauth_version
60
+ parameters["oauth_version"]
61
+ end
62
+
63
+ # TODO deprecate these
64
+ alias_method :consumer_key, :oauth_consumer_key
65
+ alias_method :token, :oauth_token
66
+ alias_method :nonce, :oauth_nonce
67
+ alias_method :timestamp, :oauth_timestamp
68
+ alias_method :signature, :oauth_signature
69
+ alias_method :signature_method, :oauth_signature_method
70
+
71
+ ## Parameter accessors
72
+
73
+ def parameters
74
+ raise NotImplementedError, "Must be implemented by subclasses"
51
75
  end
52
-
76
+
77
+ def parameters_for_signature
78
+ parameters.reject { |k,v| k == "oauth_signature" }
79
+ end
80
+
81
+ def oauth_parameters
82
+ parameters.select { |k,v| OAuth::PARAMETERS.include?(k) }.reject { |k,v| v == "" }
83
+ end
84
+
85
+ def non_oauth_parameters
86
+ parameters.reject { |k,v| OAuth::PARAMETERS.include?(k) }
87
+ end
88
+
53
89
  # See 9.1.2 in specs
54
90
  def normalized_uri
55
- u=URI.parse(uri)
56
- "#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.downcase=='http'&&u.port!=80)||(u.scheme.downcase=='https'&&u.port!=443) ? ":#{u.port}" : ""}#{(u.path&&u.path!='') ? u.path : '/'}"
91
+ u = URI.parse(uri)
92
+ "#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.downcase == 'http' && u.port != 80) || (u.scheme.downcase == 'https' && u.port != 443) ? ":#{u.port}" : ""}#{(u.path && u.path != '') ? u.path : '/'}"
57
93
  end
58
-
94
+
59
95
  # See 9.1.1. in specs Normalize Request Parameters
60
96
  def normalized_parameters
61
- parameters_for_signature.sort.map do |k, values|
97
+ normalize(parameters_for_signature)
98
+ end
62
99
 
63
- if values.is_a?(Array)
64
- # multiple values were provided for a single key
65
- values.sort.collect do |v|
66
- [escape(k),escape(v)] * "="
67
- end
68
- else
69
- [escape(k),escape(values)] * "="
70
- end
71
- end * "&"
100
+ def sign(options = {})
101
+ OAuth::Signature.sign(self, options)
72
102
  end
73
-
103
+
104
+ def sign!(options = {})
105
+ parameters["oauth_signature"] = sign(options)
106
+ @signed = true
107
+ signature
108
+ end
109
+
74
110
  # See 9.1 in specs
75
111
  def signature_base_string
76
112
  base = [method, normalized_uri, normalized_parameters]
77
113
  base.map { |v| escape(v) }.join("&")
78
114
  end
79
-
80
-
81
- protected
82
-
115
+
116
+ # Has this request been signed yet?
117
+ def signed?
118
+ @signed
119
+ end
120
+
121
+ # URI, including OAuth parameters
122
+ def signed_uri(with_oauth = true)
123
+ if signed?
124
+ if with_oauth
125
+ params = parameters
126
+ else
127
+ params = non_oauth_parameters
128
+ end
129
+
130
+ [uri, normalize(params)] * "?"
131
+ else
132
+ STDERR.puts "This request has not yet been signed!"
133
+ end
134
+ end
135
+
136
+ # Authorization header for OAuth
137
+ def oauth_header(options = {})
138
+ header_params_str = oauth_parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
139
+
140
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
141
+ "OAuth #{realm}#{header_params_str}"
142
+ end
143
+
144
+ protected
145
+
83
146
  def header_params
84
147
  %w( X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION ).each do |header|
85
148
  next unless request.env.include?(header)
@@ -87,10 +150,10 @@ module OAuth::RequestProxy
87
150
  header = request.env[header]
88
151
  next unless header[0,6] == 'OAuth '
89
152
 
90
- oauth_param_string = header[6,header.length].split(/[,=]/)
91
- oauth_param_string.map! { |v| unescape(v.strip) }
92
- oauth_param_string.map! { |v| v =~ /^\".*\"$/ ? v[1..-2] : v }
93
- oauth_params = Hash[*oauth_param_string.flatten]
153
+ # parse the header into a Hash
154
+ oauth_params = OAuth::Helper.parse_header(header)
155
+
156
+ # remove non-OAuth parameters
94
157
  oauth_params.reject! { |k,v| k !~ /^oauth_/ }
95
158
 
96
159
  return oauth_params
@@ -98,10 +161,5 @@ module OAuth::RequestProxy
98
161
 
99
162
  return {}
100
163
  end
101
-
102
- def unescape(value)
103
- URI.unescape(value.gsub('+', '%2B'))
104
- end
105
-
106
164
  end
107
165
  end
@@ -32,11 +32,10 @@ module OAuth
32
32
  def uri
33
33
  [@request.from.strip.to_s, @request.to.strip.to_s].join("&")
34
34
  end
35
-
35
+
36
36
  def normalized_uri
37
37
  uri
38
38
  end
39
-
40
39
  end
41
40
  end
42
41
  end
@@ -28,6 +28,14 @@ module OAuth
28
28
  @request["method"]
29
29
  end
30
30
 
31
+ def normalized_uri
32
+ super
33
+ rescue
34
+ # if this is a non-standard URI, it may not parse properly
35
+ # in that case, assume that it's already been normalized
36
+ uri
37
+ end
38
+
31
39
  def uri
32
40
  @request["uri"]
33
41
  end
@@ -25,7 +25,7 @@ module OAuth::RequestProxy::Net
25
25
  end
26
26
  end
27
27
 
28
- private
28
+ private
29
29
 
30
30
  def all_parameters
31
31
  request_params = CGI.parse(query_string)
@@ -47,7 +47,7 @@ module OAuth::RequestProxy::Net
47
47
  params << post_params if method.to_s.upcase == 'POST' && is_form_urlencoded
48
48
  params.compact.join('&')
49
49
  end
50
-
50
+
51
51
  def query_params
52
52
  URI.parse(request.path).query
53
53
  end
@@ -5,11 +5,11 @@ require 'rack'
5
5
  module OAuth::RequestProxy
6
6
  class RackRequest < OAuth::RequestProxy::Base
7
7
  proxies Rack::Request
8
-
8
+
9
9
  def method
10
- request.request_method
10
+ request.env["rack.methodoverride.original_method"] || request.request_method
11
11
  end
12
-
12
+
13
13
  def uri
14
14
  request.url
15
15
  end
@@ -22,12 +22,12 @@ module OAuth::RequestProxy
22
22
  params.merge(options[:parameters] || {})
23
23
  end
24
24
  end
25
-
25
+
26
26
  def signature
27
27
  parameters['oauth_signature']
28
28
  end
29
-
30
- protected
29
+
30
+ protected
31
31
 
32
32
  def query_params
33
33
  request.GET
@@ -37,4 +37,4 @@ module OAuth::RequestProxy
37
37
  request.params
38
38
  end
39
39
  end
40
- end
40
+ end
data/lib/oauth/server.rb CHANGED
@@ -1,68 +1,66 @@
1
1
  require 'oauth/helper'
2
2
  require 'oauth/consumer'
3
+
3
4
  module OAuth
4
5
  # This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
5
6
  class Server
6
7
  include OAuth::Helper
7
8
  attr_accessor :base_url
8
-
9
- @@server_paths={
10
- :request_token_path=>"/oauth/request_token",
11
- :authorize_path=>"/oauth/authorize",
12
- :access_token_path=>"/oauth/access_token"
9
+
10
+ @@server_paths = {
11
+ :request_token_path => "/oauth/request_token",
12
+ :authorize_path => "/oauth/authorize",
13
+ :access_token_path => "/oauth/access_token"
13
14
  }
15
+
14
16
  # Create a new server instance
15
- def initialize(base_url,paths={})
16
- @base_url=base_url
17
- @paths=@@server_paths.merge(paths)
17
+ def initialize(base_url, paths = {})
18
+ @base_url = base_url
19
+ @paths = @@server_paths.merge(paths)
18
20
  end
19
-
20
- def generate_credentials()
21
- [generate_key(16),generate_key]
21
+
22
+ def generate_credentials
23
+ [generate_key(16), generate_key]
22
24
  end
23
-
24
- def generate_consumer_credentials(params={})
25
- Consumer.new( *generate_credentials)
25
+
26
+ def generate_consumer_credentials(params = {})
27
+ Consumer.new(*generate_credentials)
26
28
  end
27
29
 
28
30
  # mainly for testing purposes
29
31
  def create_consumer
30
- credentials=generate_credentials
31
- Consumer.new(
32
- credentials[0],
33
- credentials[1],
32
+ creds = generate_credentials
33
+ Consumer.new(creds[0], creds[1],
34
34
  {
35
- :site=>base_url,
36
- :request_token_path=>request_token_path,
37
- :authorize_path=>authorize_path,
38
- :access_token_path=>access_token_path
39
- })
35
+ :site => base_url,
36
+ :request_token_path => request_token_path,
37
+ :authorize_path => authorize_path,
38
+ :access_token_path => access_token_path
39
+ })
40
40
  end
41
-
41
+
42
42
  def request_token_path
43
43
  @paths[:request_token_path]
44
44
  end
45
-
45
+
46
46
  def request_token_url
47
- base_url+request_token_path
47
+ base_url + request_token_path
48
48
  end
49
-
49
+
50
50
  def authorize_path
51
51
  @paths[:authorize_path]
52
52
  end
53
-
53
+
54
54
  def authorize_url
55
- base_url+authorize_path
55
+ base_url + authorize_path
56
56
  end
57
-
57
+
58
58
  def access_token_path
59
59
  @paths[:access_token_path]
60
60
  end
61
61
 
62
62
  def access_token_url
63
- base_url+access_token_path
63
+ base_url + access_token_path
64
64
  end
65
-
66
-
67
65
  end
68
66
  end
@@ -6,9 +6,10 @@ require 'base64'
6
6
  module OAuth::Signature
7
7
  class Base
8
8
  include OAuth::Helper
9
-
9
+
10
10
  attr_accessor :options
11
-
11
+ attr_reader :token_secret, :consumer_secret, :request
12
+
12
13
  def self.implements(signature_method)
13
14
  OAuth::Signature.available_methods[signature_method] = self
14
15
  end
@@ -18,32 +19,34 @@ module OAuth::Signature
18
19
  @digest_class = digest_class
19
20
  end
20
21
 
21
- attr_reader :token_secret, :consumer_secret, :request
22
-
23
22
  def initialize(request, options = {}, &block)
24
23
  raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
25
24
  @request = request
26
25
  @options = options
27
26
 
28
- if block_given?
27
+ ## consumer secret was determined beforehand
29
28
 
30
- # consumer secret and token secret need to be looked up based on pieces of the request
31
- @token_secret, @consumer_secret = yield block.arity == 1 ? request : [token, consumer_key,nonce,request.timestamp]
29
+ @consumer_secret = options[:consumer].secret if options[:consumer]
32
30
 
33
- else
34
- ## consumer secret was determined beforehand
31
+ # presence of :consumer_secret option will override any Consumer that's provided
32
+ @consumer_secret = options[:consumer_secret] if options[:consumer_secret]
35
33
 
36
- @consumer_secret = options[:consumer].secret if options[:consumer]
34
+ ## token secret was determined beforehand
37
35
 
38
- # presence of :consumer_secret option will override any Consumer that's provided
39
- @consumer_secret = options[:consumer_secret] if options[:consumer_secret]
36
+ @token_secret = options[:token].secret if options[:token]
40
37
 
41
- ## token secret was determined beforehand
38
+ # presence of :token_secret option will override any Token that's provided
39
+ @token_secret = options[:token_secret] if options[:token_secret]
42
40
 
43
- @token_secret = options[:token].secret if options[:token]
44
41
 
45
- # presence of :token_secret option will override any Token that's provided
46
- @token_secret = options[:token_secret] if options[:token_secret]
42
+ # override secrets based on the values returned from the block (if any)
43
+ if block_given?
44
+ # consumer secret and token secret need to be looked up based on pieces of the request
45
+ secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
46
+ if secrets.is_a?(Array) && secrets.size == 2
47
+ @token_secret = secrets[0]
48
+ @consumer_secret = secrets[1]
49
+ end
47
50
  end
48
51
  end
49
52
 
@@ -62,17 +65,17 @@ module OAuth::Signature
62
65
  def signature_base_string
63
66
  request.signature_base_string
64
67
  end
65
-
66
- private
68
+
69
+ private
67
70
 
68
71
  def token
69
72
  request.token
70
73
  end
71
-
74
+
72
75
  def consumer_key
73
76
  request.consumer_key
74
77
  end
75
-
78
+
76
79
  def nonce
77
80
  request.nonce
78
81
  end
@@ -84,6 +87,5 @@ module OAuth::Signature
84
87
  def digest
85
88
  self.class.digest_class.digest(signature_base_string)
86
89
  end
87
-
88
90
  end
89
91
  end
@@ -3,7 +3,7 @@ require 'oauth/signature/base'
3
3
  module OAuth::Signature::HMAC
4
4
  class Base < OAuth::Signature::Base
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def digest
9
9
  self.class.digest_class.digest(secret, signature_base_string)
@@ -1,5 +1,4 @@
1
1
  require 'oauth/signature/hmac/base'
2
- require 'rubygems'
3
2
  require 'hmac-sha1'
4
3
 
5
4
  module OAuth::Signature::HMAC
@@ -15,9 +15,9 @@ module OAuth::Signature
15
15
  def signature_base_string
16
16
  secret
17
17
  end
18
-
18
+
19
19
  def secret
20
- escape super
20
+ escape(super)
21
21
  end
22
22
  end
23
23
  end
@@ -18,9 +18,9 @@ module OAuth::Signature::RSA
18
18
  consumer_secret
19
19
  end
20
20
  end
21
-
22
- private
23
-
21
+
22
+ private
23
+
24
24
  def decode_public_key
25
25
  case consumer_secret
26
26
  when /-----BEGIN CERTIFICATE-----/
@@ -29,7 +29,7 @@ module OAuth::Signature::RSA
29
29
  OpenSSL::PKey::RSA.new( consumer_secret)
30
30
  end
31
31
  end
32
-
32
+
33
33
  def digest
34
34
  private_key = OpenSSL::PKey::RSA.new(
35
35
  if options[:private_key_file]
@@ -38,6 +38,7 @@ module OAuth::Signature::RSA
38
38
  consumer_secret
39
39
  end
40
40
  )
41
+
41
42
  private_key.sign(OpenSSL::Digest::SHA1.new, signature_base_string)
42
43
  end
43
44
  end
@@ -1,9 +1,13 @@
1
1
  module OAuth
2
2
  module Signature
3
+ # Returns a list of available signature methods
3
4
  def self.available_methods
4
5
  @available_methods ||= {}
5
6
  end
6
7
 
8
+ # Build a signature from a +request+.
9
+ #
10
+ # Raises UnknownSignatureMethod exception if the signature method is unknown.
7
11
  def self.build(request, options = {}, &block)
8
12
  request = OAuth::RequestProxy.proxy(request, options)
9
13
  klass = available_methods[(request.signature_method || "").downcase]
@@ -11,14 +15,19 @@ module OAuth
11
15
  klass.new(request, options, &block)
12
16
  end
13
17
 
18
+ # Sign a +request+
14
19
  def self.sign(request, options = {}, &block)
15
20
  self.build(request, options, &block).signature
16
21
  end
17
22
 
23
+ # Verify the signature of +request+
18
24
  def self.verify(request, options = {}, &block)
19
25
  self.build(request, options, &block).verify
20
26
  end
21
27
 
28
+ # Create the signature base string for +request+. This string is the normalized parameter information.
29
+ #
30
+ # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
22
31
  def self.signature_base_string(request, options = {}, &block)
23
32
  self.build(request, options, &block).signature_base_string
24
33
  end