partner_api 0.11.2
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 +7 -0
- data/.github/workflows/release.yml +18 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +18 -0
- data/.rspec +4 -0
- data/CHANGELOG.md +105 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +85 -0
- data/Rakefile +6 -0
- data/bin/console +17 -0
- data/bin/setup +8 -0
- data/docs/anz_api.md +67 -0
- data/docs/bnz_api.md +103 -0
- data/docs/fab_api.md +206 -0
- data/docs/gemini_api.md +184 -0
- data/docs/vma_api.md +167 -0
- data/docs/westpac_api.md +106 -0
- data/lib/anz_api/client.rb +24 -0
- data/lib/anz_api/endpoint.rb +29 -0
- data/lib/anz_api/endpoints/fetch_jwk.rb +35 -0
- data/lib/anz_api/failure_response.rb +33 -0
- data/lib/anz_api.rb +15 -0
- data/lib/bnz_api/client.rb +45 -0
- data/lib/bnz_api/configuration.rb +21 -0
- data/lib/bnz_api/endpoint.rb +56 -0
- data/lib/bnz_api/endpoints/fetch_id_token.rb +73 -0
- data/lib/bnz_api/endpoints/fetch_jwk.rb +35 -0
- data/lib/bnz_api/failure_response.rb +33 -0
- data/lib/bnz_api/httpx.rb +75 -0
- data/lib/bnz_api.rb +18 -0
- data/lib/fab_api/client.rb +36 -0
- data/lib/fab_api/configuration.rb +26 -0
- data/lib/fab_api/endpoint.rb +70 -0
- data/lib/fab_api/endpoints/deliver_email.rb +56 -0
- data/lib/fab_api/endpoints/deliver_sms.rb +51 -0
- data/lib/fab_api/endpoints/exchange_token.rb +49 -0
- data/lib/fab_api/endpoints/invalidate_token.rb +53 -0
- data/lib/fab_api/endpoints/refresh_token.rb +60 -0
- data/lib/fab_api/failure_response.rb +39 -0
- data/lib/fab_api/utils/id.rb +13 -0
- data/lib/fab_api.rb +18 -0
- data/lib/gemini_api/address.rb +23 -0
- data/lib/gemini_api/balance.rb +24 -0
- data/lib/gemini_api/client.rb +37 -0
- data/lib/gemini_api/endpoint.rb +62 -0
- data/lib/gemini_api/endpoints/create_address_request.rb +39 -0
- data/lib/gemini_api/endpoints/get_available_balances.rb +39 -0
- data/lib/gemini_api/endpoints/view_approved_addresses.rb +40 -0
- data/lib/gemini_api/endpoints/view_transfers.rb +49 -0
- data/lib/gemini_api/endpoints/withdraw_crypto_fund.rb +49 -0
- data/lib/gemini_api/failure_response.rb +47 -0
- data/lib/gemini_api/transaction.rb +14 -0
- data/lib/gemini_api/transfer.rb +44 -0
- data/lib/gemini_api.rb +16 -0
- data/lib/partner_api/endpoints/base.rb +152 -0
- data/lib/partner_api/errors.rb +18 -0
- data/lib/partner_api/utils/hash.rb +21 -0
- data/lib/partner_api/utils/read_cert.rb +38 -0
- data/lib/vma_api/client.rb +33 -0
- data/lib/vma_api/configuration.rb +24 -0
- data/lib/vma_api/endpoint.rb +29 -0
- data/lib/vma_api/endpoints/access_token.rb +60 -0
- data/lib/vma_api/endpoints/client_credentials.rb +60 -0
- data/lib/vma_api/endpoints/refresh_token.rb +60 -0
- data/lib/vma_api/endpoints/revoke_token.rb +55 -0
- data/lib/vma_api/failure_response.rb +42 -0
- data/lib/vma_api.rb +20 -0
- data/lib/westpac_api/client.rb +29 -0
- data/lib/westpac_api/configuration.rb +28 -0
- data/lib/westpac_api/endpoint.rb +26 -0
- data/lib/westpac_api/endpoints/fetch_jwk.rb +33 -0
- data/lib/westpac_api/endpoints/fetch_user.rb +96 -0
- data/lib/westpac_api/failure_response.rb +33 -0
- data/lib/westpac_api.rb +28 -0
- data/partner_api.gemspec +31 -0
- metadata +191 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GeminiApi
|
4
|
+
Transfer = Struct.new(
|
5
|
+
:type,
|
6
|
+
:status,
|
7
|
+
:timestampms,
|
8
|
+
:eid,
|
9
|
+
:advance_eid,
|
10
|
+
:currency,
|
11
|
+
:amount,
|
12
|
+
:fee_amount,
|
13
|
+
:fee_currency,
|
14
|
+
:method,
|
15
|
+
:tx_hash,
|
16
|
+
:withdrawal_id,
|
17
|
+
:output_idx,
|
18
|
+
:destination,
|
19
|
+
:purpose,
|
20
|
+
:raw_data,
|
21
|
+
keyword_init: true
|
22
|
+
) do
|
23
|
+
def self.build(raw_data)
|
24
|
+
new(
|
25
|
+
type: raw_data['type'],
|
26
|
+
status: raw_data['status'],
|
27
|
+
timestampms: raw_data['timestampms'],
|
28
|
+
eid: raw_data['eid'],
|
29
|
+
advance_eid: raw_data['advanceEid'],
|
30
|
+
currency: raw_data['currency'],
|
31
|
+
amount: raw_data['amount'],
|
32
|
+
fee_amount: raw_data['feeAmount'],
|
33
|
+
fee_currency: raw_data['feeCurrency'],
|
34
|
+
method: raw_data['method'],
|
35
|
+
tx_hash: raw_data['txHash'],
|
36
|
+
withdrawal_id: raw_data['withdrawalId'],
|
37
|
+
output_idx: raw_data['outputIdx'],
|
38
|
+
destination: raw_data['destination'],
|
39
|
+
purpose: raw_data['purpose'],
|
40
|
+
raw_data: raw_data
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/gemini_api.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-configurable'
|
4
|
+
require 'gemini_api/client'
|
5
|
+
|
6
|
+
module GeminiApi
|
7
|
+
extend Dry::Configurable
|
8
|
+
|
9
|
+
setting :instrumentation, default: -> (action:, tenant_id: nil, &block) { block.call }
|
10
|
+
setting :logger, default: Logger.new($stdout, level: :info)
|
11
|
+
setting :base_url, constructor: proc { |value| URI.parse(value) }
|
12
|
+
setting :api_key
|
13
|
+
setting :api_secret
|
14
|
+
setting :default_headers, default: -> { {} }
|
15
|
+
setting :default_parameters, default: -> { {} }
|
16
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-monads'
|
4
|
+
require 'hanami/utils/hash'
|
5
|
+
require 'http'
|
6
|
+
require 'openssl'
|
7
|
+
|
8
|
+
require 'partner_api/utils/hash'
|
9
|
+
require 'partner_api/utils/read_cert'
|
10
|
+
require 'partner_api/errors'
|
11
|
+
|
12
|
+
module PartnerApi
|
13
|
+
module Endpoints
|
14
|
+
class Base
|
15
|
+
include Dry::Monads[:result]
|
16
|
+
|
17
|
+
def call
|
18
|
+
config.logger.info(**logging_params.merge(class: self.class.name))
|
19
|
+
|
20
|
+
response = config.instrumentation.call(action: self.class.name) do
|
21
|
+
client.request(method, url, **request_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
if successful?(response)
|
25
|
+
Success(decode(response))
|
26
|
+
else
|
27
|
+
Failure(decode_error(response))
|
28
|
+
end
|
29
|
+
rescue HTTP::Error, OpenSSL::SSL::SSLError => e
|
30
|
+
raise Errors::ConnectionError, e.message
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def client
|
36
|
+
@client ||= HTTP::Client.new(**connection_options)
|
37
|
+
.use(logging: { logger: config.logger })
|
38
|
+
end
|
39
|
+
|
40
|
+
def logging_params
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# To be implemented by concrete end-point class.
|
45
|
+
#
|
46
|
+
def connection_options
|
47
|
+
raise NotImplementedError
|
48
|
+
end
|
49
|
+
|
50
|
+
# To be implemented by concrete end-point class.
|
51
|
+
#
|
52
|
+
def method
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
def url
|
57
|
+
config.base_url.dup.tap { |uri| uri.path = path }
|
58
|
+
end
|
59
|
+
|
60
|
+
# To be implemented by concrete end-point class.
|
61
|
+
#
|
62
|
+
def path
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
|
66
|
+
def request_options
|
67
|
+
{
|
68
|
+
headers: combined_headers,
|
69
|
+
body: JSON.dump(combined_payload)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def default_headers
|
74
|
+
{}
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_parameters
|
78
|
+
{}
|
79
|
+
end
|
80
|
+
|
81
|
+
def combined_headers
|
82
|
+
Utils::Hash.deep_merge(
|
83
|
+
default_headers,
|
84
|
+
Hanami::Utils::Hash.deep_stringify(config.default_headers.call),
|
85
|
+
Hanami::Utils::Hash.deep_stringify(headers)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def combined_payload
|
90
|
+
Utils::Hash.deep_merge(
|
91
|
+
default_parameters,
|
92
|
+
Hanami::Utils::Hash.deep_stringify(config.default_parameters.call),
|
93
|
+
Hanami::Utils::Hash.deep_stringify(parameters)
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
# To be implemented by concrete end-point class.
|
98
|
+
#
|
99
|
+
def headers
|
100
|
+
{}
|
101
|
+
end
|
102
|
+
|
103
|
+
# To be implemented by concrete end-point class.
|
104
|
+
#
|
105
|
+
def parameters
|
106
|
+
{}
|
107
|
+
end
|
108
|
+
|
109
|
+
# To be implemented by concrete end-point class.
|
110
|
+
#
|
111
|
+
def successful?(response)
|
112
|
+
raise NotImplementedError
|
113
|
+
end
|
114
|
+
|
115
|
+
# To be implemented by concrete end-point class.
|
116
|
+
#
|
117
|
+
def decode(response)
|
118
|
+
raise NotImplementedError
|
119
|
+
end
|
120
|
+
|
121
|
+
# To be implemented by concrete end-point class.
|
122
|
+
#
|
123
|
+
def decode_error(response)
|
124
|
+
raise NotImplementedError
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
module Initializer
|
129
|
+
def self.prepended(klass)
|
130
|
+
klass.class_eval do
|
131
|
+
def self.call(config, **params)
|
132
|
+
new(config, **params).call
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def initialize(config, **params)
|
138
|
+
@config = config
|
139
|
+
|
140
|
+
if params.empty?
|
141
|
+
super()
|
142
|
+
else
|
143
|
+
super(**params)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
attr_reader :config
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module PartnerApi
|
2
|
+
module Errors
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# Used to re-wrap connection errors from http.rb.
|
6
|
+
#
|
7
|
+
class ConnectionError < Error; end
|
8
|
+
|
9
|
+
class RequestError < Error
|
10
|
+
attr_reader :code
|
11
|
+
|
12
|
+
def initialize(code: nil, message:)
|
13
|
+
@code = code
|
14
|
+
super(message)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PartnerApi
|
2
|
+
module Utils
|
3
|
+
class Hash
|
4
|
+
# This a simplify version of deep merging
|
5
|
+
#
|
6
|
+
# In case both conflict items are hash, continue to merge recursively.
|
7
|
+
# Otherwise, prioritize the hash in later order
|
8
|
+
def self.deep_merge(*hashes)
|
9
|
+
hashes.inject({}) do |result, hash|
|
10
|
+
result.merge(hash) do |_key, item_1, item_2|
|
11
|
+
if item_1.is_a?(::Hash) && item_2.is_a?(::Hash)
|
12
|
+
deep_merge(item_1, item_2)
|
13
|
+
else
|
14
|
+
item_2 || item_1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module PartnerApi
|
2
|
+
module Utils
|
3
|
+
class ReadCert
|
4
|
+
# A workaround for this issue related to OpenSSL
|
5
|
+
# https://github.com/ruby/openssl/issues/254
|
6
|
+
CERT_PATTERN = /-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----/
|
7
|
+
|
8
|
+
def initialize(public_certs, private_key)
|
9
|
+
@certs = public_certs.scan(CERT_PATTERN)
|
10
|
+
@private_key = private_key
|
11
|
+
end
|
12
|
+
|
13
|
+
def ssl_context
|
14
|
+
OpenSSL::SSL::SSLContext.new(:TLSv1_2).tap do |ctx|
|
15
|
+
ctx.set_params(
|
16
|
+
cert: cert,
|
17
|
+
key: OpenSSL::PKey::RSA.new(private_key),
|
18
|
+
extra_chain_cert: extra_chain_cert
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :certs, :private_key
|
26
|
+
|
27
|
+
def cert
|
28
|
+
OpenSSL::X509::Certificate.new(certs.first)
|
29
|
+
end
|
30
|
+
|
31
|
+
def extra_chain_cert
|
32
|
+
return [] if certs.length < 2
|
33
|
+
|
34
|
+
certs[1..-1].map { |cert| OpenSSL::X509::Certificate.new(cert) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'hanami/utils/string'
|
2
|
+
require 'hanami/utils/class'
|
3
|
+
|
4
|
+
require 'vma_api/endpoints/access_token'
|
5
|
+
require 'vma_api/endpoints/refresh_token'
|
6
|
+
require 'vma_api/endpoints/client_credentials'
|
7
|
+
require 'vma_api/endpoints/revoke_token'
|
8
|
+
|
9
|
+
module VmaApi
|
10
|
+
class Client
|
11
|
+
def self.endpoint(name)
|
12
|
+
define_method(name) do |**args|
|
13
|
+
klass_name = Hanami::Utils::String.classify(name)
|
14
|
+
endpoint_klass = Hanami::Utils::Class.load!("VmaApi::Endpoints::#{klass_name}")
|
15
|
+
|
16
|
+
endpoint_klass.(config, **args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
endpoint :access_token
|
21
|
+
endpoint :refresh_token
|
22
|
+
endpoint :client_credentials
|
23
|
+
endpoint :revoke_token
|
24
|
+
|
25
|
+
def initialize(config: VmaApi.config)
|
26
|
+
@config = config
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :config
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'dry-configurable'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
class Configuration
|
5
|
+
include Dry::Configurable
|
6
|
+
|
7
|
+
setting :logger, default: Logger.new(STDOUT, level: :info)
|
8
|
+
|
9
|
+
setting :base_url
|
10
|
+
setting :client_id
|
11
|
+
setting :client_secret
|
12
|
+
|
13
|
+
setting :auth_base_url
|
14
|
+
setting :auth_client_id
|
15
|
+
setting :auth_client_secret
|
16
|
+
|
17
|
+
setting :subscription_key
|
18
|
+
setting :system_id
|
19
|
+
|
20
|
+
setting :default_parameters, default: -> { {} }
|
21
|
+
setting :default_headers, default: -> { {} }
|
22
|
+
setting :instrumentation, default: -> (action:, tenant_id: nil, &block) { block.call }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'partner_api/endpoints/base'
|
4
|
+
require 'vma_api/failure_response'
|
5
|
+
|
6
|
+
module VmaApi
|
7
|
+
class Endpoint < PartnerApi::Endpoints::Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# VMA at time of writing this does not need mTLS or proxies
|
12
|
+
#
|
13
|
+
def connection_options
|
14
|
+
{}
|
15
|
+
end
|
16
|
+
|
17
|
+
def successful?(response)
|
18
|
+
response.status.success? && response.parse["code"].nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def decode_error(response)
|
22
|
+
FailureResponse.new(response)
|
23
|
+
end
|
24
|
+
|
25
|
+
def logging_params
|
26
|
+
{ request_id: request_id }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'vma_api/endpoint'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
module Endpoints
|
5
|
+
class AccessToken < Endpoint
|
6
|
+
prepend PartnerApi::Endpoints::Initializer
|
7
|
+
|
8
|
+
AUTH_TOKEN = 'authToken'.freeze
|
9
|
+
|
10
|
+
def initialize(short_token:, request_id: SecureRandom.uuid)
|
11
|
+
@short_token = short_token
|
12
|
+
@request_id = request_id
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :short_token, :request_id
|
18
|
+
|
19
|
+
def url
|
20
|
+
URI.parse(config.auth_base_url).tap { |uri| uri.path = path }
|
21
|
+
end
|
22
|
+
|
23
|
+
def headers
|
24
|
+
{
|
25
|
+
'Content-Type' => 'application/json',
|
26
|
+
'Accept' => 'application/json',
|
27
|
+
'Ocp-Apim-Subscription-Key': config.subscription_key,
|
28
|
+
'Request-Id': request_id,
|
29
|
+
'Timestamp': Time.now.utc.iso8601,
|
30
|
+
'Sending-System-Version': SYSTEM_VERSION,
|
31
|
+
'Sending-System-Id': config.system_id,
|
32
|
+
'Initiating-System-Version': SYSTEM_VERSION,
|
33
|
+
'Initiating-System-Id': config.system_id,
|
34
|
+
'Ocp-Apim-Trace': 'true'
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def method
|
39
|
+
'POST'
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
'/customerIdentity/v1.0/token'
|
44
|
+
end
|
45
|
+
|
46
|
+
def parameters
|
47
|
+
{
|
48
|
+
client_id: config.auth_client_id,
|
49
|
+
client_secret: config.auth_client_secret,
|
50
|
+
track_token: short_token,
|
51
|
+
credentials_type: AUTH_TOKEN
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode(response)
|
56
|
+
response.parse.dig('access_token')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'vma_api/endpoint'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
module Endpoints
|
5
|
+
class ClientCredentials < Endpoint
|
6
|
+
prepend PartnerApi::Endpoints::Initializer
|
7
|
+
|
8
|
+
VMA_CLIENT_CREDENTIALS = 'client_credentials'.freeze
|
9
|
+
|
10
|
+
def initialize(tenant_id:, resource:, request_id: SecureRandom.uuid)
|
11
|
+
@tenant_id = tenant_id
|
12
|
+
@resource = resource
|
13
|
+
@request_id = request_id
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :tenant_id, :resource, :request_id
|
19
|
+
|
20
|
+
def url
|
21
|
+
URI.parse(config.base_url).tap { |uri| uri.path = path }
|
22
|
+
end
|
23
|
+
|
24
|
+
def headers
|
25
|
+
{
|
26
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
27
|
+
'Request-Id' => request_id
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def method
|
32
|
+
'POST'
|
33
|
+
end
|
34
|
+
|
35
|
+
def path
|
36
|
+
"/#{tenant_id}/oauth2/token"
|
37
|
+
end
|
38
|
+
|
39
|
+
def parameters
|
40
|
+
{
|
41
|
+
client_id: config.client_id,
|
42
|
+
client_secret: config.client_secret,
|
43
|
+
grant_type: VMA_CLIENT_CREDENTIALS,
|
44
|
+
resource: resource
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def decode(response)
|
49
|
+
response.parse.dig('access_token')
|
50
|
+
end
|
51
|
+
|
52
|
+
def request_options
|
53
|
+
{
|
54
|
+
headers: combined_headers,
|
55
|
+
form: combined_payload
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'vma_api/endpoint'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
module Endpoints
|
5
|
+
class RefreshToken < Endpoint
|
6
|
+
prepend PartnerApi::Endpoints::Initializer
|
7
|
+
|
8
|
+
REFRESH_TOKEN = 'refreshToken'.freeze
|
9
|
+
|
10
|
+
def initialize(refresh_token:, request_id: SecureRandom.uuid)
|
11
|
+
@refresh_token = refresh_token
|
12
|
+
@request_id = request_id
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :refresh_token, :request_id
|
18
|
+
|
19
|
+
def url
|
20
|
+
URI.parse(config.auth_base_url).tap { |uri| uri.path = path }
|
21
|
+
end
|
22
|
+
|
23
|
+
def headers
|
24
|
+
{
|
25
|
+
'Content-Type' => 'application/json',
|
26
|
+
'Accept' => 'application/json',
|
27
|
+
'Ocp-Apim-Subscription-Key': config.subscription_key,
|
28
|
+
'Request-Id': request_id,
|
29
|
+
'Timestamp': Time.now.utc.iso8601,
|
30
|
+
'Sending-System-Version': SYSTEM_VERSION,
|
31
|
+
'Sending-System-Id': config.system_id,
|
32
|
+
'Initiating-System-Version': SYSTEM_VERSION,
|
33
|
+
'Initiating-System-Id': config.system_id,
|
34
|
+
'Ocp-Apim-Trace': 'true'
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def method
|
39
|
+
'POST'
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
'/customerIdentity/v1.0/token'
|
44
|
+
end
|
45
|
+
|
46
|
+
def parameters
|
47
|
+
{
|
48
|
+
client_id: config.auth_client_id,
|
49
|
+
client_secret: config.auth_client_secret,
|
50
|
+
refresh_token: refresh_token,
|
51
|
+
credentials_type: REFRESH_TOKEN
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode(response)
|
56
|
+
response.parse.dig('access_token')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'vma_api/endpoint'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
module Endpoints
|
5
|
+
class RevokeToken < Endpoint
|
6
|
+
prepend PartnerApi::Endpoints::Initializer
|
7
|
+
|
8
|
+
def initialize(token:, request_id: SecureRandom.uuid)
|
9
|
+
@token = token
|
10
|
+
@request_id = request_id
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :token, :request_id
|
16
|
+
|
17
|
+
def url
|
18
|
+
URI.parse(config.auth_base_url).tap { |uri| uri.path = path }
|
19
|
+
end
|
20
|
+
|
21
|
+
def headers
|
22
|
+
{
|
23
|
+
'Content-Type' => 'application/json',
|
24
|
+
'Accept' => 'application/json',
|
25
|
+
'Ocp-Apim-Subscription-Key': config.subscription_key,
|
26
|
+
'Request-Id': request_id,
|
27
|
+
'Timestamp': Time.now.utc.iso8601,
|
28
|
+
'Sending-System-Version': SYSTEM_VERSION,
|
29
|
+
'Sending-System-Id': config.system_id,
|
30
|
+
'Initiating-System-Version': SYSTEM_VERSION,
|
31
|
+
'Initiating-System-Id': config.system_id,
|
32
|
+
'Ocp-Apim-Trace': 'true'
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def method
|
37
|
+
'POST'
|
38
|
+
end
|
39
|
+
|
40
|
+
def path
|
41
|
+
'/customerIdentity/v1.0/revoke'
|
42
|
+
end
|
43
|
+
|
44
|
+
def parameters
|
45
|
+
{
|
46
|
+
client_id: config.auth_client_id,
|
47
|
+
client_secret: config.auth_client_secret,
|
48
|
+
token: token
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def decode(_response); end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'partner_api/errors'
|
2
|
+
|
3
|
+
module VmaApi
|
4
|
+
class FailureResponse
|
5
|
+
def initialize(response)
|
6
|
+
@response = response
|
7
|
+
end
|
8
|
+
|
9
|
+
def errors
|
10
|
+
if json?
|
11
|
+
parsed_response = response.parse
|
12
|
+
[PartnerApi::Errors::RequestError.new(code: parsed_response['code'], message: parsed_response['message'])]
|
13
|
+
else
|
14
|
+
[PartnerApi::Errors::RequestError.new(message: "Invalid Response: #{body}")]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def error
|
19
|
+
errors.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def status
|
23
|
+
response.status
|
24
|
+
end
|
25
|
+
|
26
|
+
def body
|
27
|
+
response.body
|
28
|
+
end
|
29
|
+
|
30
|
+
def headers
|
31
|
+
response.headers.to_h
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :response
|
37
|
+
|
38
|
+
def json?
|
39
|
+
response.content_type.mime_type == 'application/json'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/vma_api.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'concurrent-ruby'
|
3
|
+
|
4
|
+
require 'vma_api/client'
|
5
|
+
require 'vma_api/configuration'
|
6
|
+
|
7
|
+
module VmaApi
|
8
|
+
extend self
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
SYSTEM_VERSION = 'v1.0'.freeze
|
12
|
+
|
13
|
+
@configurations = Concurrent::Hash.new
|
14
|
+
|
15
|
+
def_delegators 'configuration(:default)', :config, :configure
|
16
|
+
|
17
|
+
def configuration(key)
|
18
|
+
@configurations[key] ||= Configuration.new
|
19
|
+
end
|
20
|
+
end
|