oauth 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -116
  3. data/CODE_OF_CONDUCT.md +0 -0
  4. data/CONTRIBUTING.md +0 -0
  5. data/LICENSE +0 -0
  6. data/README.md +250 -63
  7. data/SECURITY.md +7 -9
  8. data/TODO +0 -0
  9. data/bin/oauth +8 -4
  10. data/lib/oauth/cli/authorize_command.rb +57 -55
  11. data/lib/oauth/cli/base_command.rb +163 -157
  12. data/lib/oauth/cli/help_command.rb +9 -5
  13. data/lib/oauth/cli/query_command.rb +26 -17
  14. data/lib/oauth/cli/sign_command.rb +58 -55
  15. data/lib/oauth/cli/version_command.rb +8 -4
  16. data/lib/oauth/cli.rb +4 -2
  17. data/lib/oauth/client/action_controller_request.rb +17 -15
  18. data/lib/oauth/client/em_http.rb +31 -29
  19. data/lib/oauth/client/helper.rb +76 -75
  20. data/lib/oauth/client/net_http.rb +109 -102
  21. data/lib/oauth/client.rb +2 -0
  22. data/lib/oauth/consumer.rb +96 -88
  23. data/lib/oauth/errors/error.rb +2 -0
  24. data/lib/oauth/errors/problem.rb +3 -0
  25. data/lib/oauth/errors/unauthorized.rb +4 -0
  26. data/lib/oauth/errors.rb +2 -0
  27. data/lib/oauth/helper.rb +16 -12
  28. data/lib/oauth/oauth.rb +6 -4
  29. data/lib/oauth/oauth_test_helper.rb +2 -0
  30. data/lib/oauth/request_proxy/action_controller_request.rb +0 -0
  31. data/lib/oauth/request_proxy/action_dispatch_request.rb +0 -0
  32. data/lib/oauth/request_proxy/base.rb +2 -2
  33. data/lib/oauth/request_proxy/curb_request.rb +0 -0
  34. data/lib/oauth/request_proxy/em_http_request.rb +0 -0
  35. data/lib/oauth/request_proxy/jabber_request.rb +0 -0
  36. data/lib/oauth/request_proxy/mock_request.rb +1 -1
  37. data/lib/oauth/request_proxy/net_http.rb +8 -8
  38. data/lib/oauth/request_proxy/rack_request.rb +0 -0
  39. data/lib/oauth/request_proxy/rest_client_request.rb +2 -1
  40. data/lib/oauth/request_proxy/typhoeus_request.rb +0 -0
  41. data/lib/oauth/request_proxy.rb +7 -4
  42. data/lib/oauth/server.rb +12 -10
  43. data/lib/oauth/signature/base.rb +73 -66
  44. data/lib/oauth/signature/hmac/sha1.rb +15 -9
  45. data/lib/oauth/signature/hmac/sha256.rb +15 -9
  46. data/lib/oauth/signature/plaintext.rb +18 -20
  47. data/lib/oauth/signature/rsa/sha1.rb +46 -38
  48. data/lib/oauth/signature.rb +8 -5
  49. data/lib/oauth/token.rb +2 -0
  50. data/lib/oauth/tokens/access_token.rb +2 -0
  51. data/lib/oauth/tokens/consumer_token.rb +4 -2
  52. data/lib/oauth/tokens/request_token.rb +12 -10
  53. data/lib/oauth/tokens/server_token.rb +2 -1
  54. data/lib/oauth/tokens/token.rb +2 -0
  55. data/lib/oauth/version.rb +5 -1
  56. data/lib/oauth.rb +8 -2
  57. metadata +34 -32
data/lib/oauth/server.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/helper"
2
4
  require "oauth/consumer"
3
5
 
@@ -8,9 +10,9 @@ module OAuth
8
10
  attr_accessor :base_url
9
11
 
10
12
  @@server_paths = {
11
- :request_token_path => "/oauth/request_token",
12
- :authorize_path => "/oauth/authorize",
13
- :access_token_path => "/oauth/access_token"
13
+ request_token_path: "/oauth/request_token",
14
+ authorize_path: "/oauth/authorize",
15
+ access_token_path: "/oauth/access_token"
14
16
  }
15
17
 
16
18
  # Create a new server instance
@@ -23,7 +25,7 @@ module OAuth
23
25
  [generate_key(16), generate_key]
24
26
  end
25
27
 
26
- def generate_consumer_credentials(params = {})
28
+ def generate_consumer_credentials(_params = {})
27
29
  Consumer.new(*generate_credentials)
28
30
  end
29
31
 
@@ -31,12 +33,12 @@ module OAuth
31
33
  def create_consumer
32
34
  creds = generate_credentials
33
35
  Consumer.new(creds[0], creds[1],
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
- })
36
+ {
37
+ site: base_url,
38
+ request_token_path: request_token_path,
39
+ authorize_path: authorize_path,
40
+ access_token_path: access_token_path
41
+ })
40
42
  end
41
43
 
42
44
  def request_token_path
@@ -1,98 +1,105 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/signature"
2
4
  require "oauth/helper"
3
5
  require "oauth/request_proxy/base"
4
6
  require "base64"
5
7
 
6
- module OAuth::Signature
7
- class Base
8
- include OAuth::Helper
8
+ module OAuth
9
+ module Signature
10
+ class Base
11
+ include OAuth::Helper
9
12
 
10
- attr_accessor :options
11
- attr_reader :token_secret, :consumer_secret, :request
13
+ attr_accessor :options
14
+ attr_reader :token_secret, :consumer_secret, :request
12
15
 
13
- def self.implements(signature_method = nil)
14
- return @implements if signature_method.nil?
15
- @implements = signature_method
16
- OAuth::Signature.available_methods[@implements] = self
17
- end
16
+ def self.implements(signature_method = nil)
17
+ return @implements if signature_method.nil?
18
+
19
+ @implements = signature_method
20
+ OAuth::Signature.available_methods[@implements] = self
21
+ end
18
22
 
19
- def initialize(request, options = {}, &block)
20
- raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
21
- @request = request
22
- @options = options
23
+ def initialize(request, options = {}, &block)
24
+ raise TypeError unless request.is_a?(OAuth::RequestProxy::Base)
23
25
 
24
- ## consumer secret was determined beforehand
26
+ @request = request
27
+ @options = options
25
28
 
26
- @consumer_secret = options[:consumer].secret if options[:consumer]
29
+ ## consumer secret was determined beforehand
27
30
 
28
- # presence of :consumer_secret option will override any Consumer that's provided
29
- @consumer_secret = options[:consumer_secret] if options[:consumer_secret]
31
+ @consumer_secret = options[:consumer].secret if options[:consumer]
30
32
 
31
- ## token secret was determined beforehand
33
+ # presence of :consumer_secret option will override any Consumer that's provided
34
+ if options[:consumer_secret]
35
+ @consumer_secret = options[:consumer_secret]
36
+ end
37
+
38
+ ## token secret was determined beforehand
32
39
 
33
- @token_secret = options[:token].secret if options[:token]
40
+ @token_secret = options[:token].secret if options[:token]
34
41
 
35
- # presence of :token_secret option will override any Token that's provided
36
- @token_secret = options[:token_secret] if options[:token_secret]
42
+ # presence of :token_secret option will override any Token that's provided
43
+ @token_secret = options[:token_secret] if options[:token_secret]
37
44
 
38
- # override secrets based on the values returned from the block (if any)
39
- if block_given?
40
- # consumer secret and token secret need to be looked up based on pieces of the request
41
- secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
42
- if secrets.is_a?(Array) && secrets.size == 2
43
- @token_secret = secrets[0]
44
- @consumer_secret = secrets[1]
45
+ # override secrets based on the values returned from the block (if any)
46
+ if block
47
+ # consumer secret and token secret need to be looked up based on pieces of the request
48
+ secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
49
+ if secrets.is_a?(Array) && secrets.size == 2
50
+ @token_secret = secrets[0]
51
+ @consumer_secret = secrets[1]
52
+ end
45
53
  end
46
54
  end
47
- end
48
55
 
49
- def signature
50
- Base64.encode64(digest).chomp.gsub(/\n/,"")
51
- end
56
+ def signature
57
+ Base64.encode64(digest).chomp.delete("\n")
58
+ end
52
59
 
53
- def ==(cmp_signature)
54
- check = signature.bytesize ^ cmp_signature.bytesize
55
- signature.bytes.zip(cmp_signature.bytes) { |x, y| check |= x ^ y.to_i }
56
- check.zero?
57
- end
60
+ def ==(other)
61
+ check = signature.bytesize ^ other.bytesize
62
+ signature.bytes.zip(other.bytes) { |x, y| check |= x ^ y.to_i }
63
+ check.zero?
64
+ end
58
65
 
59
- def verify
60
- self == self.request.signature
61
- end
66
+ def verify
67
+ self == request.signature
68
+ end
62
69
 
63
- def signature_base_string
64
- request.signature_base_string
65
- end
70
+ def signature_base_string
71
+ request.signature_base_string
72
+ end
66
73
 
67
- def body_hash
68
- raise_instantiation_error
69
- end
74
+ def body_hash
75
+ raise_instantiation_error
76
+ end
70
77
 
71
- private
78
+ private
72
79
 
73
- def token
74
- request.token
75
- end
80
+ def token
81
+ request.token
82
+ end
76
83
 
77
- def consumer_key
78
- request.consumer_key
79
- end
84
+ def consumer_key
85
+ request.consumer_key
86
+ end
80
87
 
81
- def nonce
82
- request.nonce
83
- end
88
+ def nonce
89
+ request.nonce
90
+ end
84
91
 
85
- def secret
86
- "#{escape(consumer_secret)}&#{escape(token_secret)}"
87
- end
92
+ def secret
93
+ "#{escape(consumer_secret)}&#{escape(token_secret)}"
94
+ end
88
95
 
89
- def digest
90
- raise_instantiation_error
91
- end
96
+ def digest
97
+ raise_instantiation_error
98
+ end
92
99
 
93
- def raise_instantiation_error
94
- raise NotImplementedError, "Cannot instantiate #{self.class.name} class directly."
100
+ def raise_instantiation_error
101
+ raise NotImplementedError, "Cannot instantiate #{self.class.name} class directly."
102
+ end
95
103
  end
96
-
97
104
  end
98
105
  end
@@ -1,17 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/signature/base"
2
4
 
3
- module OAuth::Signature::HMAC
4
- class SHA1 < OAuth::Signature::Base
5
- implements "hmac-sha1"
5
+ module OAuth
6
+ module Signature
7
+ module HMAC
8
+ class SHA1 < OAuth::Signature::Base
9
+ implements "hmac-sha1"
6
10
 
7
- def body_hash
8
- Base64.encode64(OpenSSL::Digest::SHA1.digest(request.body || "")).chomp.gsub(/\n/,"")
9
- end
11
+ def body_hash
12
+ Base64.encode64(OpenSSL::Digest.digest("SHA1", request.body || "")).chomp.delete("\n")
13
+ end
10
14
 
11
- private
15
+ private
12
16
 
13
- def digest
14
- OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha1"), secret, signature_base_string)
17
+ def digest
18
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha1"), secret, signature_base_string)
19
+ end
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -1,17 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/signature/base"
2
4
 
3
- module OAuth::Signature::HMAC
4
- class SHA256 < OAuth::Signature::Base
5
- implements "hmac-sha256"
5
+ module OAuth
6
+ module Signature
7
+ module HMAC
8
+ class SHA256 < OAuth::Signature::Base
9
+ implements "hmac-sha256"
6
10
 
7
- def body_hash
8
- Base64.encode64(OpenSSL::Digest::SHA256.digest(request.body || "")).chomp.gsub(/\n/,"")
9
- end
11
+ def body_hash
12
+ Base64.encode64(OpenSSL::Digest.digest("SHA256", request.body || "")).chomp.delete("\n")
13
+ end
10
14
 
11
- private
15
+ private
12
16
 
13
- def digest
14
- OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), secret, signature_base_string)
17
+ def digest
18
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), secret, signature_base_string)
19
+ end
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -1,29 +1,27 @@
1
- require "oauth/signature/base"
1
+ # frozen_string_literal: true
2
2
 
3
- module OAuth::Signature
4
- class PLAINTEXT < Base
5
- implements "plaintext"
3
+ require "oauth/signature/base"
6
4
 
7
- def signature
8
- signature_base_string
9
- end
5
+ module OAuth
6
+ module Signature
7
+ class PLAINTEXT < Base
8
+ implements "plaintext"
10
9
 
11
- def ==(cmp_signature)
12
- signature.to_s == cmp_signature.to_s
13
- end
10
+ def signature
11
+ signature_base_string
12
+ end
14
13
 
15
- def signature_base_string
16
- secret
17
- end
18
-
19
- def body_hash
20
- nil
21
- end
14
+ def ==(other)
15
+ signature.to_s == other.to_s
16
+ end
22
17
 
23
- private
18
+ def signature_base_string
19
+ secret
20
+ end
24
21
 
25
- def secret
26
- super
22
+ def body_hash
23
+ nil
24
+ end
27
25
  end
28
26
  end
29
27
  end
@@ -1,50 +1,58 @@
1
- require "oauth/signature/base"
1
+ # frozen_string_literal: true
2
2
 
3
- module OAuth::Signature::RSA
4
- class SHA1 < OAuth::Signature::Base
5
- implements "rsa-sha1"
3
+ require "oauth/signature/base"
6
4
 
7
- def ==(cmp_signature)
8
- public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(cmp_signature.is_a?(Array) ? cmp_signature.first : cmp_signature), signature_base_string)
9
- end
5
+ module OAuth
6
+ module Signature
7
+ module RSA
8
+ class SHA1 < OAuth::Signature::Base
9
+ implements "rsa-sha1"
10
10
 
11
- def public_key
12
- if consumer_secret.is_a?(String)
13
- decode_public_key
14
- elsif consumer_secret.is_a?(OpenSSL::X509::Certificate)
15
- consumer_secret.public_key
16
- else
17
- consumer_secret
18
- end
19
- end
11
+ def ==(other)
12
+ public_key.verify(OpenSSL::Digest.new("SHA1"),
13
+ Base64.decode64(other.is_a?(Array) ? other.first : other), signature_base_string)
14
+ end
20
15
 
21
- def body_hash
22
- Base64.encode64(OpenSSL::Digest::SHA1.digest(request.body || "")).chomp.gsub(/\n/,"")
23
- end
16
+ def public_key
17
+ case consumer_secret
18
+ when String
19
+ decode_public_key
20
+ when OpenSSL::X509::Certificate
21
+ consumer_secret.public_key
22
+ else
23
+ consumer_secret
24
+ end
25
+ end
24
26
 
25
- private
27
+ def body_hash
28
+ Base64.encode64(OpenSSL::Digest.digest("SHA1", request.body || "")).chomp.delete("\n")
29
+ end
26
30
 
27
- def decode_public_key
28
- case consumer_secret
29
- when /-----BEGIN CERTIFICATE-----/
30
- OpenSSL::X509::Certificate.new( consumer_secret).public_key
31
- else
32
- OpenSSL::PKey::RSA.new( consumer_secret)
33
- end
34
- end
31
+ private
35
32
 
36
- def digest
37
- private_key = OpenSSL::PKey::RSA.new(
38
- if options[:private_key_file]
39
- IO.read(options[:private_key_file])
40
- elsif options[:private_key]
41
- options[:private_key]
42
- else
43
- consumer_secret
33
+ def decode_public_key
34
+ case consumer_secret
35
+ when /-----BEGIN CERTIFICATE-----/
36
+ OpenSSL::X509::Certificate.new(consumer_secret).public_key
37
+ else
38
+ OpenSSL::PKey::RSA.new(consumer_secret)
39
+ end
44
40
  end
45
- )
46
41
 
47
- private_key.sign(OpenSSL::Digest::SHA1.new, signature_base_string)
42
+ def digest
43
+ private_key = OpenSSL::PKey::RSA.new(
44
+ if options[:private_key_file]
45
+ File.read(options[:private_key_file])
46
+ elsif options[:private_key]
47
+ options[:private_key]
48
+ else
49
+ consumer_secret
50
+ end
51
+ )
52
+
53
+ private_key.sign(OpenSSL::Digest.new("SHA1"), signature_base_string)
54
+ end
55
+ end
48
56
  end
49
57
  end
50
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  module Signature
3
5
  # Returns a list of available signature methods
@@ -15,31 +17,32 @@ module OAuth
15
17
  ((c = request.options[:consumer]) && c.options[:signature_method]) ||
16
18
  "").downcase]
17
19
  raise UnknownSignatureMethod, request.signature_method unless klass
20
+
18
21
  klass.new(request, options, &block)
19
22
  end
20
23
 
21
24
  # Sign a +request+
22
25
  def self.sign(request, options = {}, &block)
23
- self.build(request, options, &block).signature
26
+ build(request, options, &block).signature
24
27
  end
25
28
 
26
29
  # Verify the signature of +request+
27
30
  def self.verify(request, options = {}, &block)
28
- self.build(request, options, &block).verify
31
+ build(request, options, &block).verify
29
32
  end
30
33
 
31
34
  # Create the signature base string for +request+. This string is the normalized parameter information.
32
35
  #
33
36
  # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
34
37
  def self.signature_base_string(request, options = {}, &block)
35
- self.build(request, options, &block).signature_base_string
38
+ build(request, options, &block).signature_base_string
36
39
  end
37
40
 
38
41
  # Create the body hash for a request
39
42
  def self.body_hash(request, options = {}, &block)
40
- self.build(request, options, &block).body_hash
43
+ build(request, options, &block).body_hash
41
44
  end
42
45
 
43
- class UnknownSignatureMethod < Exception; end
46
+ class UnknownSignatureMethod < RuntimeError; end
44
47
  end
45
48
  end
data/lib/oauth/token.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # this exists for backwards-compatibility
2
4
 
3
5
  require "oauth/tokens/token"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  # The Access Token is used for the actual "real" web service calls that you perform against the server
3
5
  class AccessToken < ConsumerToken
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  # Superclass for tokens used by OAuth Clients
3
5
  class ConsumerToken < Token
@@ -5,12 +7,12 @@ module OAuth
5
7
  attr_reader :response
6
8
 
7
9
  def self.from_hash(consumer, hash)
8
- token = self.new(consumer, hash[:oauth_token], hash[:oauth_token_secret])
10
+ token = new(consumer, hash[:oauth_token], hash[:oauth_token_secret])
9
11
  token.params = hash
10
12
  token
11
13
  end
12
14
 
13
- def initialize(consumer, token="", secret="")
15
+ def initialize(consumer, token = "", secret = "")
14
16
  super(token, secret)
15
17
  @consumer = consumer
16
18
  @params = {}
@@ -1,20 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  # The RequestToken is used for the initial Request.
3
5
  # This is normally created by the Consumer object.
4
6
  class RequestToken < ConsumerToken
5
-
6
7
  # Generate an authorization URL for user authorization
7
8
  def authorize_url(params = nil)
8
- return nil if self.token.nil?
9
+ return nil if token.nil?
9
10
 
10
- params = (params || {}).merge(:oauth_token => self.token)
11
+ params = (params || {}).merge(oauth_token: token)
11
12
  build_url(consumer.authorize_url, params)
12
13
  end
13
14
 
14
15
  def authenticate_url(params = nil)
15
- return nil if self.token.nil?
16
+ return nil if token.nil?
16
17
 
17
- params = (params || {}).merge(:oauth_token => self.token)
18
+ params = (params || {}).merge(oauth_token: token)
18
19
  build_url(consumer.authenticate_url, params)
19
20
  end
20
21
 
@@ -24,20 +25,21 @@ module OAuth
24
25
 
25
26
  # exchange for AccessToken on server
26
27
  def get_access_token(options = {}, *arguments)
27
- response = consumer.token_request(consumer.http_method, (consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path), self, options, *arguments)
28
+ response = consumer.token_request(consumer.http_method,
29
+ (consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path), self, options, *arguments)
28
30
  OAuth::AccessToken.from_hash(consumer, response)
29
31
  end
30
32
 
31
- protected
33
+ protected
32
34
 
33
35
  # construct an authorization or authentication url
34
36
  def build_url(base_url, params)
35
37
  uri = URI.parse(base_url.to_s)
36
38
  queries = {}
37
- queries = Hash[URI.decode_www_form(uri.query)] if uri.query
38
- # TODO doesn't handle array values correctly
39
+ queries = URI.decode_www_form(uri.query).to_h if uri.query
40
+ # TODO: doesn't handle array values correctly
39
41
  queries.merge!(params) if params
40
- uri.query = URI.encode_www_form(queries) if !queries.empty?
42
+ uri.query = URI.encode_www_form(queries) unless queries.empty?
41
43
  uri.to_s
42
44
  end
43
45
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  # Used on the server for generating tokens
3
5
  class ServerToken < Token
4
-
5
6
  def initialize
6
7
  super(generate_key(16), generate_key)
7
8
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  # Superclass for the various tokens used by OAuth
3
5
  class Token
data/lib/oauth/version.rb CHANGED
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
- VERSION = "0.5.8"
4
+ module Version
5
+ VERSION = "0.6.0"
6
+ end
3
7
  end
data/lib/oauth.rb CHANGED
@@ -1,5 +1,7 @@
1
- root = File.dirname(__FILE__)
2
- $LOAD_PATH << root unless $LOAD_PATH.include?(root)
1
+ # frozen_string_literal: true
2
+
3
+ # third party gems
4
+ require "version_gem"
3
5
 
4
6
  require "oauth/version"
5
7
 
@@ -11,3 +13,7 @@ require "oauth/signature/hmac/sha1"
11
13
  require "oauth/signature/hmac/sha256"
12
14
  require "oauth/signature/rsa/sha1"
13
15
  require "oauth/request_proxy/mock_request"
16
+
17
+ OAuth::Version.class_eval do
18
+ extend VersionGem::Basic
19
+ end