oauth 0.5.6 → 1.1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +4 -0
- data/CHANGELOG.md +848 -0
- data/CITATION.cff +20 -0
- data/CODE_OF_CONDUCT.md +134 -0
- data/CONTRIBUTING.md +218 -0
- data/FUNDING.md +77 -0
- data/LICENSE.txt +22 -0
- data/README.md +662 -0
- data/REEK +2 -0
- data/RUBOCOP.md +71 -0
- data/SECURITY.md +24 -0
- data/lib/oauth/auth_sanitizer.rb +36 -0
- data/lib/oauth/client/action_controller_request.rb +33 -22
- data/lib/oauth/client/em_http.rb +110 -103
- data/lib/oauth/client/helper.rb +87 -82
- data/lib/oauth/client/net_http.rb +140 -107
- data/lib/oauth/client.rb +2 -0
- data/lib/oauth/consumer.rb +222 -141
- data/lib/oauth/errors/error.rb +2 -0
- data/lib/oauth/errors/problem.rb +4 -1
- data/lib/oauth/errors/unauthorized.rb +7 -1
- data/lib/oauth/errors.rb +5 -3
- data/lib/oauth/helper.rb +48 -18
- data/lib/oauth/oauth.rb +31 -7
- data/lib/oauth/oauth_test_helper.rb +6 -4
- data/lib/oauth/optional.rb +20 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +53 -71
- data/lib/oauth/request_proxy/action_dispatch_request.rb +42 -4
- data/lib/oauth/request_proxy/base.rb +146 -131
- data/lib/oauth/request_proxy/curb_request.rb +49 -43
- data/lib/oauth/request_proxy/em_http_request.rb +60 -49
- data/lib/oauth/request_proxy/jabber_request.rb +19 -9
- data/lib/oauth/request_proxy/mock_request.rb +5 -3
- data/lib/oauth/request_proxy/net_http.rb +61 -54
- data/lib/oauth/request_proxy/rack_request.rb +31 -31
- data/lib/oauth/request_proxy/rest_client_request.rb +55 -50
- data/lib/oauth/request_proxy/typhoeus_request.rb +51 -45
- data/lib/oauth/request_proxy.rb +21 -14
- data/lib/oauth/server.rb +18 -12
- data/lib/oauth/signature/base.rb +88 -71
- data/lib/oauth/signature/hmac/sha1.rb +16 -10
- data/lib/oauth/signature/hmac/sha256.rb +16 -10
- data/lib/oauth/signature/plaintext.rb +18 -20
- data/lib/oauth/signature/rsa/sha1.rb +53 -38
- data/lib/oauth/signature.rb +41 -34
- data/lib/oauth/token.rb +7 -5
- data/lib/oauth/tokens/access_token.rb +6 -4
- data/lib/oauth/tokens/consumer_token.rb +11 -7
- data/lib/oauth/tokens/request_token.rb +17 -10
- data/lib/oauth/tokens/server_token.rb +2 -1
- data/lib/oauth/tokens/token.rb +15 -1
- data/lib/oauth/version.rb +6 -1
- data/lib/oauth.rb +18 -9
- data/sig/oauth/consumer.rbs +9 -0
- data/sig/oauth/signature/base.rbs +12 -0
- data/sig/oauth/tokens/token.rbs +8 -0
- data.tar.gz.sig +3 -0
- metadata +301 -82
- metadata.gz.sig +2 -0
- data/LICENSE +0 -20
- data/README.rdoc +0 -88
- data/TODO +0 -32
- data/bin/oauth +0 -11
- data/lib/oauth/cli/authorize_command.rb +0 -71
- data/lib/oauth/cli/base_command.rb +0 -208
- data/lib/oauth/cli/help_command.rb +0 -22
- data/lib/oauth/cli/query_command.rb +0 -25
- data/lib/oauth/cli/sign_command.rb +0 -81
- data/lib/oauth/cli/version_command.rb +0 -7
- data/lib/oauth/cli.rb +0 -56
data/lib/oauth/signature/base.rb
CHANGED
|
@@ -1,96 +1,113 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
OAuth::
|
|
17
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "oauth/signature"
|
|
4
|
+
require "oauth/helper"
|
|
5
|
+
require "oauth/request_proxy/base"
|
|
6
|
+
require "base64"
|
|
7
|
+
|
|
8
|
+
module OAuth
|
|
9
|
+
module Signature
|
|
10
|
+
# Base class for OAuth signature implementations.
|
|
11
|
+
#
|
|
12
|
+
# Includes {OAuth::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts
|
|
13
|
+
# secret-bearing fields captured during signature construction.
|
|
14
|
+
class Base
|
|
15
|
+
include OAuth::Helper
|
|
16
|
+
include OAuth::AUTH_SANITIZER::FilteredAttributes
|
|
17
|
+
|
|
18
|
+
# Signature construction options.
|
|
19
|
+
#
|
|
20
|
+
# @return [Hash]
|
|
21
|
+
attr_accessor :options
|
|
22
|
+
attr_reader :token_secret, :consumer_secret, :request
|
|
23
|
+
filtered_attributes :options, :consumer_secret, :token_secret
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def implements(signature_method = nil)
|
|
27
|
+
return OAuth::Signature.available_methods.key(self) if signature_method.nil?
|
|
28
|
+
|
|
29
|
+
OAuth::Signature.available_methods[signature_method] = self
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def initialize(request, options = {}, &block)
|
|
34
|
+
raise TypeError unless request.is_a?(OAuth::RequestProxy::Base)
|
|
18
35
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@request = request
|
|
22
|
-
@options = options
|
|
36
|
+
@request = request
|
|
37
|
+
@options = options
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
## consumer secret was determined beforehand
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
@consumer_secret = options[:consumer].secret if options[:consumer]
|
|
27
42
|
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
# presence of :consumer_secret option will override any Consumer that's provided
|
|
44
|
+
@consumer_secret = options[:consumer_secret] if options[:consumer_secret]
|
|
30
45
|
|
|
31
|
-
|
|
46
|
+
## token secret was determined beforehand
|
|
32
47
|
|
|
33
|
-
|
|
48
|
+
@token_secret = options[:token].secret if options[:token]
|
|
34
49
|
|
|
35
|
-
|
|
36
|
-
|
|
50
|
+
# presence of :token_secret option will override any Token that's provided
|
|
51
|
+
@token_secret = options[:token_secret] if options[:token_secret]
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
# override secrets based on the values returned from the block (if any)
|
|
54
|
+
if block
|
|
55
|
+
# consumer secret and token secret need to be looked up based on pieces of the request
|
|
56
|
+
secrets = yield (block.arity == 1) ? request : [token, consumer_key, nonce, request.timestamp]
|
|
57
|
+
if secrets.is_a?(Array) && secrets.size == 2
|
|
58
|
+
@token_secret = secrets[0]
|
|
59
|
+
@consumer_secret = secrets[1]
|
|
60
|
+
end
|
|
45
61
|
end
|
|
46
62
|
end
|
|
47
|
-
end
|
|
48
63
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
def signature
|
|
65
|
+
Base64.encode64(digest).chomp.delete("\n")
|
|
66
|
+
end
|
|
52
67
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
def ==(other)
|
|
69
|
+
check = signature.bytesize ^ other.bytesize
|
|
70
|
+
signature.bytes.zip(other.bytes) { |x, y| check |= x ^ y.to_i }
|
|
71
|
+
check.zero?
|
|
72
|
+
end
|
|
56
73
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
def verify
|
|
75
|
+
self == request.signature
|
|
76
|
+
end
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
def signature_base_string
|
|
79
|
+
request.signature_base_string
|
|
80
|
+
end
|
|
64
81
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
def body_hash
|
|
83
|
+
raise_instantiation_error
|
|
84
|
+
end
|
|
68
85
|
|
|
69
|
-
|
|
86
|
+
private
|
|
70
87
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
def token
|
|
89
|
+
request.token
|
|
90
|
+
end
|
|
74
91
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
92
|
+
def consumer_key
|
|
93
|
+
request.consumer_key
|
|
94
|
+
end
|
|
78
95
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
def nonce
|
|
97
|
+
request.nonce
|
|
98
|
+
end
|
|
82
99
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
def secret
|
|
101
|
+
"#{escape(consumer_secret)}&#{escape(token_secret)}"
|
|
102
|
+
end
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
def digest
|
|
105
|
+
raise_instantiation_error
|
|
106
|
+
end
|
|
90
107
|
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
def raise_instantiation_error
|
|
109
|
+
raise NotImplementedError, "Cannot instantiate #{self.class.name} class directly."
|
|
110
|
+
end
|
|
93
111
|
end
|
|
94
|
-
|
|
95
112
|
end
|
|
96
113
|
end
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class SHA1 < OAuth::Signature::Base
|
|
5
|
-
implements 'hmac-sha1'
|
|
3
|
+
require "oauth/signature/base"
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module OAuth
|
|
6
|
+
module Signature
|
|
7
|
+
module HMAC
|
|
8
|
+
class SHA1 < OAuth::Signature::Base
|
|
9
|
+
implements "hmac-sha1"
|
|
10
|
+
|
|
11
|
+
def body_hash
|
|
12
|
+
Base64.encode64(OpenSSL::Digest.digest("SHA1", request.body || "")).chomp.delete("\n")
|
|
13
|
+
end
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
private
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class SHA256 < OAuth::Signature::Base
|
|
5
|
-
implements 'hmac-sha256'
|
|
3
|
+
require "oauth/signature/base"
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module OAuth
|
|
6
|
+
module Signature
|
|
7
|
+
module HMAC
|
|
8
|
+
class SHA256 < OAuth::Signature::Base
|
|
9
|
+
implements "hmac-sha256"
|
|
10
|
+
|
|
11
|
+
def body_hash
|
|
12
|
+
Base64.encode64(OpenSSL::Digest.digest("SHA256", request.body || "")).chomp.delete("\n")
|
|
13
|
+
end
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
private
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class PLAINTEXT < Base
|
|
5
|
-
implements 'plaintext'
|
|
3
|
+
require "oauth/signature/base"
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module OAuth
|
|
6
|
+
module Signature
|
|
7
|
+
class PLAINTEXT < Base
|
|
8
|
+
implements "plaintext"
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
def signature
|
|
11
|
+
signature_base_string
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def body_hash
|
|
20
|
-
nil
|
|
21
|
-
end
|
|
14
|
+
def ==(other)
|
|
15
|
+
signature.to_s == other.to_s
|
|
16
|
+
end
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
def signature_base_string
|
|
19
|
+
secret
|
|
20
|
+
end
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
def body_hash
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
27
25
|
end
|
|
28
26
|
end
|
|
29
27
|
end
|
|
@@ -1,50 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class SHA1 < OAuth::Signature::Base
|
|
5
|
-
implements 'rsa-sha1'
|
|
3
|
+
require "oauth/signature/base"
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module OAuth
|
|
6
|
+
module Signature
|
|
7
|
+
module RSA
|
|
8
|
+
class SHA1 < OAuth::Signature::Base
|
|
9
|
+
implements "rsa-sha1"
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
consumer_secret.public_key
|
|
16
|
-
else
|
|
17
|
-
consumer_secret
|
|
18
|
-
end
|
|
19
|
-
end
|
|
11
|
+
def ==(other)
|
|
12
|
+
decoded = Base64.decode64(other.is_a?(Array) ? other.first : other)
|
|
13
|
+
public_key.verify(OpenSSL::Digest.new("SHA1"), decoded, signature_base_string)
|
|
14
|
+
end
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
+
def body_hash
|
|
28
|
+
# Use SHA1 body hash with compatibility across OpenSSL versions
|
|
29
|
+
data = request.body || ""
|
|
30
|
+
begin
|
|
31
|
+
digest_bytes = OpenSSL::Digest.digest("SHA1", data)
|
|
32
|
+
rescue StandardError
|
|
33
|
+
digest_bytes = ::Digest::SHA1.digest(data)
|
|
34
|
+
end
|
|
35
|
+
Base64.encode64(digest_bytes).chomp.delete("\n")
|
|
36
|
+
end
|
|
26
37
|
|
|
27
|
-
|
|
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
|
|
38
|
+
private
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
consumer_secret
|
|
40
|
+
def decode_public_key
|
|
41
|
+
case consumer_secret
|
|
42
|
+
when /-----BEGIN CERTIFICATE-----/
|
|
43
|
+
OpenSSL::X509::Certificate.new(consumer_secret).public_key
|
|
44
|
+
else
|
|
45
|
+
OpenSSL::PKey::RSA.new(consumer_secret)
|
|
46
|
+
end
|
|
44
47
|
end
|
|
45
|
-
)
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
def digest
|
|
50
|
+
private_key = OpenSSL::PKey::RSA.new(
|
|
51
|
+
if options[:private_key_file]
|
|
52
|
+
File.read(options[:private_key_file])
|
|
53
|
+
elsif options[:private_key]
|
|
54
|
+
options[:private_key]
|
|
55
|
+
else
|
|
56
|
+
consumer_secret
|
|
57
|
+
end,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
private_key.sign(OpenSSL::Digest.new("SHA1"), signature_base_string)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
48
63
|
end
|
|
49
64
|
end
|
|
50
65
|
end
|
data/lib/oauth/signature.rb
CHANGED
|
@@ -1,45 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module OAuth
|
|
2
4
|
module Signature
|
|
3
|
-
|
|
4
|
-
def self.available_methods
|
|
5
|
-
@available_methods ||= {}
|
|
6
|
-
end
|
|
5
|
+
AVAILABLE_METHODS = {}
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
klass = available_methods[
|
|
14
|
-
(request.signature_method ||
|
|
15
|
-
((c = request.options[:consumer]) && c.options[:signature_method]) ||
|
|
16
|
-
"").downcase]
|
|
17
|
-
raise UnknownSignatureMethod, request.signature_method unless klass
|
|
18
|
-
klass.new(request, options, &block)
|
|
19
|
-
end
|
|
7
|
+
class << self
|
|
8
|
+
# Returns a list of available signature methods
|
|
9
|
+
def available_methods
|
|
10
|
+
AVAILABLE_METHODS
|
|
11
|
+
end
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
# Build a signature from a +request+.
|
|
14
|
+
#
|
|
15
|
+
# Raises UnknownSignatureMethod exception if the signature method is unknown.
|
|
16
|
+
def build(request, options = {}, &block)
|
|
17
|
+
request = OAuth::RequestProxy.proxy(request, options)
|
|
18
|
+
klass = available_methods[
|
|
19
|
+
(request.signature_method ||
|
|
20
|
+
((c = request.options[:consumer]) && c.options[:signature_method]) ||
|
|
21
|
+
"").downcase]
|
|
22
|
+
raise UnknownSignatureMethod, request.signature_method unless klass
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
self.build(request, options, &block).verify
|
|
29
|
-
end
|
|
24
|
+
klass.new(request, options, &block)
|
|
25
|
+
end
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
# Sign a +request+
|
|
28
|
+
def sign(request, options = {}, &block)
|
|
29
|
+
build(request, options, &block).signature
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Verify the signature of +request+
|
|
33
|
+
def verify(request, options = {}, &block)
|
|
34
|
+
build(request, options, &block).verify
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Create the signature base string for +request+. This string is the normalized parameter information.
|
|
38
|
+
#
|
|
39
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
|
40
|
+
def signature_base_string(request, options = {}, &block)
|
|
41
|
+
build(request, options, &block).signature_base_string
|
|
42
|
+
end
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
# Create the body hash for a request
|
|
45
|
+
def body_hash(request, options = {}, &block)
|
|
46
|
+
build(request, options, &block).body_hash
|
|
47
|
+
end
|
|
41
48
|
end
|
|
42
49
|
|
|
43
|
-
class UnknownSignatureMethod <
|
|
50
|
+
class UnknownSignatureMethod < RuntimeError; end
|
|
44
51
|
end
|
|
45
52
|
end
|
data/lib/oauth/token.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# this exists for backwards-compatibility
|
|
2
4
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
5
|
+
require "oauth/tokens/token"
|
|
6
|
+
require "oauth/tokens/server_token"
|
|
7
|
+
require "oauth/tokens/consumer_token"
|
|
8
|
+
require "oauth/tokens/request_token"
|
|
9
|
+
require "oauth/tokens/access_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
|
|
@@ -6,7 +8,7 @@ module OAuth
|
|
|
6
8
|
def request(http_method, path, *arguments)
|
|
7
9
|
request_uri = URI.parse(path)
|
|
8
10
|
site_uri = consumer.uri
|
|
9
|
-
is_service_uri_different =
|
|
11
|
+
is_service_uri_different = request_uri.absolute? && request_uri != site_uri
|
|
10
12
|
begin
|
|
11
13
|
consumer.uri(request_uri) if is_service_uri_different
|
|
12
14
|
@response = super(http_method, path, *arguments)
|
|
@@ -43,7 +45,7 @@ module OAuth
|
|
|
43
45
|
# @response = @token.post('/people', nil, {'Accept' => 'application/xml' })
|
|
44
46
|
# @response = @token.post('/people', @person.to_xml, { 'Accept'=>'application/xml', 'Content-Type' => 'application/xml' })
|
|
45
47
|
#
|
|
46
|
-
def post(path, body =
|
|
48
|
+
def post(path, body = "", headers = {})
|
|
47
49
|
request(:post, path, body, headers)
|
|
48
50
|
end
|
|
49
51
|
|
|
@@ -55,7 +57,7 @@ module OAuth
|
|
|
55
57
|
# @response = @token.put('/people/123', nil, { 'Accept' => 'application/xml' })
|
|
56
58
|
# @response = @token.put('/people/123', @person.to_xml, { 'Accept' => 'application/xml', 'Content-Type' => 'application/xml' })
|
|
57
59
|
#
|
|
58
|
-
def put(path, body =
|
|
60
|
+
def put(path, body = "", headers = {})
|
|
59
61
|
request(:put, path, body, headers)
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -67,7 +69,7 @@ module OAuth
|
|
|
67
69
|
# @response = @token.patch('/people/123', nil, { 'Accept' => 'application/xml' })
|
|
68
70
|
# @response = @token.patch('/people/123', @person.to_xml, { 'Accept' => 'application/xml', 'Content-Type' => 'application/xml' })
|
|
69
71
|
#
|
|
70
|
-
def patch(path, body =
|
|
72
|
+
def patch(path, body = "", headers = {})
|
|
71
73
|
request(:patch, path, body, headers)
|
|
72
74
|
end
|
|
73
75
|
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module OAuth
|
|
2
4
|
# Superclass for tokens used by OAuth Clients
|
|
3
5
|
class ConsumerToken < Token
|
|
4
6
|
attr_accessor :consumer, :params
|
|
5
|
-
attr_reader
|
|
7
|
+
attr_reader :response
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
class << self
|
|
10
|
+
def from_hash(consumer, hash)
|
|
11
|
+
token = new(consumer, hash[:oauth_token], hash[:oauth_token_secret])
|
|
12
|
+
token.params = hash
|
|
13
|
+
token
|
|
14
|
+
end
|
|
11
15
|
end
|
|
12
16
|
|
|
13
|
-
def initialize(consumer, token="", secret="")
|
|
17
|
+
def initialize(consumer, token = "", secret = "")
|
|
14
18
|
super(token, secret)
|
|
15
19
|
@consumer = consumer
|
|
16
|
-
@params
|
|
20
|
+
@params = {}
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
# Make a signed request using given http_method to the path
|
|
@@ -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
|
|
9
|
+
return if token.nil?
|
|
9
10
|
|
|
10
|
-
params = (params || {}).merge(:
|
|
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
|
|
16
|
+
return if token.nil?
|
|
16
17
|
|
|
17
|
-
params = (params || {}).merge(:
|
|
18
|
+
params = (params || {}).merge(oauth_token: token)
|
|
18
19
|
build_url(consumer.authenticate_url, params)
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -24,20 +25,26 @@ module OAuth
|
|
|
24
25
|
|
|
25
26
|
# exchange for AccessToken on server
|
|
26
27
|
def get_access_token(options = {}, *arguments)
|
|
27
|
-
response = consumer.token_request(
|
|
28
|
+
response = consumer.token_request(
|
|
29
|
+
consumer.http_method,
|
|
30
|
+
(consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path),
|
|
31
|
+
self,
|
|
32
|
+
options,
|
|
33
|
+
*arguments,
|
|
34
|
+
)
|
|
28
35
|
OAuth::AccessToken.from_hash(consumer, response)
|
|
29
36
|
end
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
protected
|
|
32
39
|
|
|
33
40
|
# construct an authorization or authentication url
|
|
34
41
|
def build_url(base_url, params)
|
|
35
42
|
uri = URI.parse(base_url.to_s)
|
|
36
43
|
queries = {}
|
|
37
|
-
queries =
|
|
38
|
-
# TODO doesn't handle array values correctly
|
|
44
|
+
queries = URI.decode_www_form(uri.query).to_h if uri.query
|
|
45
|
+
# TODO: doesn't handle array values correctly
|
|
39
46
|
queries.merge!(params) if params
|
|
40
|
-
uri.query = URI.encode_www_form(queries)
|
|
47
|
+
uri.query = URI.encode_www_form(queries) unless queries.empty?
|
|
41
48
|
uri.to_s
|
|
42
49
|
end
|
|
43
50
|
end
|