monkeyhelper-oauth 0.3.1 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
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