gocoin 0.1.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/Gemfile +2 -0
- data/LICENSE +191 -0
- data/README.md +242 -0
- data/Rakefile +7 -0
- data/VERSION +1 -0
- data/history.md +21 -0
- data/lib/gocoin.rb +27 -0
- data/lib/gocoin/api.rb +35 -0
- data/lib/gocoin/api/accounts.rb +16 -0
- data/lib/gocoin/api/invoices.rb +33 -0
- data/lib/gocoin/api/merchant.rb +38 -0
- data/lib/gocoin/api/merchants/currencies.rb +35 -0
- data/lib/gocoin/api/merchants/currency_conversions.rb +35 -0
- data/lib/gocoin/api/merchants/payouts.rb +35 -0
- data/lib/gocoin/api/user.rb +43 -0
- data/lib/gocoin/auth.rb +51 -0
- data/lib/gocoin/client.rb +201 -0
- data/lib/gocoin/errors/api_connection_error.rb +4 -0
- data/lib/gocoin/errors/api_error.rb +4 -0
- data/lib/gocoin/errors/authentication_error.rb +4 -0
- data/lib/gocoin/errors/gocoin_error.rb +20 -0
- data/lib/gocoin/errors/invalid_request_error.rb +10 -0
- data/lib/gocoin/util.rb +29 -0
- data/lib/gocoin/version.rb +3 -0
- data/lib/gocoin/xrate.rb +28 -0
- data/spec/gocoin/api/accounts_spec.rb +32 -0
- data/spec/gocoin/api/invoices_spec.rb +67 -0
- data/spec/gocoin/api/merchant_spec.rb +66 -0
- data/spec/gocoin/api/merchants/currencies_spec.rb +64 -0
- data/spec/gocoin/api/merchants/currency_conversions_spec.rb +63 -0
- data/spec/gocoin/api/merchants/payouts_spec.rb +63 -0
- data/spec/gocoin/api/user_spec.rb +88 -0
- data/spec/gocoin/api_spec.rb +19 -0
- data/spec/gocoin/auth_spec.rb +40 -0
- data/spec/gocoin/client_spec.rb +139 -0
- data/spec/gocoin/xrate_spec.rb +37 -0
- data/spec/spec_helper.rb +6 -0
- metadata +136 -0
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.2
|
data/history.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
###Changelog
|
|
2
|
+
|
|
3
|
+
###### v0.1.1:
|
|
4
|
+
Initial release: <br>
|
|
5
|
+
Selected methods for User, Merchant, and Invoices
|
|
6
|
+
|
|
7
|
+
###### v0.1.2:
|
|
8
|
+
Decapitalized all instances of gocoin (except class name Gocoin). <br>
|
|
9
|
+
This includes the gem name itself
|
|
10
|
+
|
|
11
|
+
Added methods:
|
|
12
|
+
* client.accounts.transactions
|
|
13
|
+
* client.merchant.currencies.get
|
|
14
|
+
* client.merchant.currencies.list
|
|
15
|
+
* client.merchant.currencies.update
|
|
16
|
+
* client.merchant.currency_conversions.get
|
|
17
|
+
* client.merchant.currency_conversions.list
|
|
18
|
+
* client.merchant.currency_conversions.request
|
|
19
|
+
* client.merchant.payouts.get
|
|
20
|
+
* client.merchant.payouts.list
|
|
21
|
+
* client.merchant.payouts.request
|
data/lib/gocoin.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'socket'
|
|
4
|
+
require 'rest_client'
|
|
5
|
+
require 'logger'
|
|
6
|
+
|
|
7
|
+
require 'gocoin/version'
|
|
8
|
+
require 'gocoin/util'
|
|
9
|
+
|
|
10
|
+
require 'gocoin/errors/gocoin_error'
|
|
11
|
+
require 'gocoin/errors/api_connection_error'
|
|
12
|
+
require 'gocoin/errors/api_error'
|
|
13
|
+
require 'gocoin/errors/authentication_error'
|
|
14
|
+
require 'gocoin/errors/invalid_request_error'
|
|
15
|
+
|
|
16
|
+
require 'gocoin/client'
|
|
17
|
+
require 'gocoin/auth'
|
|
18
|
+
require 'gocoin/api'
|
|
19
|
+
require 'gocoin/xrate'
|
|
20
|
+
|
|
21
|
+
require 'gocoin/api/invoices'
|
|
22
|
+
require 'gocoin/api/merchant'
|
|
23
|
+
require 'gocoin/api/user'
|
|
24
|
+
require 'gocoin/api/accounts'
|
|
25
|
+
require 'gocoin/api/merchants/currencies'
|
|
26
|
+
require 'gocoin/api/merchants/currency_conversions'
|
|
27
|
+
require 'gocoin/api/merchants/payouts'
|
data/lib/gocoin/api.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class API
|
|
3
|
+
|
|
4
|
+
attr_reader :client, :user, :merchant, :invoices, :accounts
|
|
5
|
+
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
@accounts = Gocoin::Accounts.new(self)
|
|
9
|
+
@invoices = Gocoin::Invoices.new(self)
|
|
10
|
+
@merchant = Gocoin::Merchant.new(self)
|
|
11
|
+
@user = Gocoin::User.new(self)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def request(route, options = {})
|
|
15
|
+
@client.logger.debug 'Gocoin::API#request called.'
|
|
16
|
+
raise 'Gocoin::API#request: Options is not a hash object' unless options.nil? || options.kind_of?(Hash)
|
|
17
|
+
raise 'Gocoin::API#request: API not ready. Token was not defined' unless @client.token
|
|
18
|
+
|
|
19
|
+
headers = options[:headers] ? @client.headers.merge(options[:headers]) : @client.headers.dup
|
|
20
|
+
headers['Authorization'] = "Bearer #{@client.token}"
|
|
21
|
+
|
|
22
|
+
options = @client.options.merge(options)
|
|
23
|
+
payload = options[:payload] ? options[:payload].to_json : nil
|
|
24
|
+
|
|
25
|
+
config = {
|
|
26
|
+
url: "#{@client.http_prefix(options[:secure])}#{options[:host]}#{@client.port}#{options[:path]}/#{options[:api_version]}#{route}",
|
|
27
|
+
method: options[:method],
|
|
28
|
+
headers: headers,
|
|
29
|
+
}
|
|
30
|
+
config[:payload] = options[:payload].to_json if options[:payload]
|
|
31
|
+
@client.raw_request config
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class Accounts
|
|
3
|
+
|
|
4
|
+
def initialize(api)
|
|
5
|
+
@api = api
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def transactions(account_id, params = {})
|
|
9
|
+
@api.client.logger.debug 'Gocoin::Accounts#transactions called.'
|
|
10
|
+
route = "/accounts/#{account_id}/transactions?#{Util.hash_to_url_params(params)}"
|
|
11
|
+
options = {}
|
|
12
|
+
@api.request route, options
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class Invoices
|
|
3
|
+
|
|
4
|
+
def initialize(api)
|
|
5
|
+
@api = api
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def create(merchant_id, params)
|
|
9
|
+
@api.client.logger.debug 'Gocoin::Invoices#create called.'
|
|
10
|
+
route = "/merchants/#{merchant_id}/invoices"
|
|
11
|
+
options = {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
payload: params
|
|
14
|
+
}
|
|
15
|
+
@api.request route, options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get(id)
|
|
19
|
+
@api.client.logger.debug 'Gocoin::Invoices#get called.'
|
|
20
|
+
route = "/invoices/#{id}"
|
|
21
|
+
options = {}
|
|
22
|
+
@api.request route, options
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def search(params = {})
|
|
26
|
+
@api.client.logger.debug 'Gocoin::Invoices#search called.'
|
|
27
|
+
route = "/invoices/search?#{Util.hash_to_url_params(params)}"
|
|
28
|
+
options = {}
|
|
29
|
+
@api.request route, options
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class Merchant
|
|
3
|
+
|
|
4
|
+
attr_reader :currencies, :currency_conversions, :payouts
|
|
5
|
+
|
|
6
|
+
def initialize(api)
|
|
7
|
+
@api = api
|
|
8
|
+
@currencies = Gocoin::Merchants::Currencies.new(api)
|
|
9
|
+
@currency_conversions = Gocoin::Merchants::CurrencyConversions.new(api)
|
|
10
|
+
@payouts = Gocoin::Merchants::Payouts.new(api)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(id)
|
|
14
|
+
@api.client.logger.debug 'Gocoin::Merchant#get called.'
|
|
15
|
+
route = "/merchants/#{id}"
|
|
16
|
+
options = {}
|
|
17
|
+
@api.request route, options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update(id, params)
|
|
21
|
+
@api.client.logger.debug 'Gocoin::Merchant#update called.'
|
|
22
|
+
route = "/merchants/#{id}"
|
|
23
|
+
options = {
|
|
24
|
+
method: 'PATCH',
|
|
25
|
+
payload: params
|
|
26
|
+
}
|
|
27
|
+
@api.request route, options
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def accounts(id)
|
|
31
|
+
@api.client.logger.debug 'Gocoin::Merchant#accounts called.'
|
|
32
|
+
route = "/merchants/#{id}/accounts"
|
|
33
|
+
options = {}
|
|
34
|
+
@api.request route, options
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
module Merchants
|
|
3
|
+
class Currencies
|
|
4
|
+
|
|
5
|
+
def initialize(api)
|
|
6
|
+
@api = api
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def get(merchant_id, currency_code)
|
|
10
|
+
@api.client.logger.debug 'Gocoin::Merchants::Currencies#get called.'
|
|
11
|
+
route = "/merchants/#{merchant_id}/currencies/#{currency_code}"
|
|
12
|
+
options = {}
|
|
13
|
+
@api.request route, options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def list(merchant_id)
|
|
17
|
+
@api.client.logger.debug 'Gocoin::Merchants::Currencies#list called.'
|
|
18
|
+
route = "/merchants/#{merchant_id}/currencies"
|
|
19
|
+
options = {}
|
|
20
|
+
@api.request route, options
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def update(merchant_id, currency_code, params)
|
|
24
|
+
@api.client.logger.debug 'Gocoin::Merchants::Currencies#update called.'
|
|
25
|
+
route = "/merchants/#{merchant_id}/currencies/#{currency_code}"
|
|
26
|
+
options = {
|
|
27
|
+
method: 'PATCH',
|
|
28
|
+
payload: params
|
|
29
|
+
}
|
|
30
|
+
@api.request route, options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
module Merchants
|
|
3
|
+
class CurrencyConversions
|
|
4
|
+
|
|
5
|
+
def initialize(api)
|
|
6
|
+
@api = api
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def get(merchant_id, currency_conversion_id)
|
|
10
|
+
@api.client.logger.debug 'Gocoin::Merchants::CurrencyConversion#get called.'
|
|
11
|
+
route = "/merchants/#{merchant_id}/currency_conversions/#{currency_conversion_id}"
|
|
12
|
+
options = {}
|
|
13
|
+
@api.request route, options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def list(merchant_id)
|
|
17
|
+
@api.client.logger.debug 'Gocoin::Merchants::CurrencyConversion#list called.'
|
|
18
|
+
route = "/merchants/#{merchant_id}/currency_conversions"
|
|
19
|
+
options = {}
|
|
20
|
+
@api.request route, options
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def request(merchant_id, params)
|
|
24
|
+
@api.client.logger.debug 'Gocoin::Merchants::CurrencyConversion#request called.'
|
|
25
|
+
route = "/merchants/#{merchant_id}/currency_conversions"
|
|
26
|
+
options = {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
payload: params
|
|
29
|
+
}
|
|
30
|
+
@api.request route, options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
module Merchants
|
|
3
|
+
class Payouts
|
|
4
|
+
|
|
5
|
+
def initialize(api)
|
|
6
|
+
@api = api
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def get(merchant_id, payout_id)
|
|
10
|
+
@api.client.logger.debug 'Gocoin::Merchants::Payouts#get called.'
|
|
11
|
+
route = "/merchants/#{merchant_id}/payouts/#{payout_id}"
|
|
12
|
+
options = {}
|
|
13
|
+
@api.request route, options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def list(merchant_id)
|
|
17
|
+
@api.client.logger.debug 'Gocoin::Merchants::Payouts#list called.'
|
|
18
|
+
route = "/merchants/#{merchant_id}/payouts"
|
|
19
|
+
options = {}
|
|
20
|
+
@api.request route, options
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def request(merchant_id, params)
|
|
24
|
+
@api.client.logger.debug 'Gocoin::Merchants::Payouts#request called.'
|
|
25
|
+
route = "/merchants/#{merchant_id}/payouts"
|
|
26
|
+
options = {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
payload: params
|
|
29
|
+
}
|
|
30
|
+
@api.request route, options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class User
|
|
3
|
+
|
|
4
|
+
def initialize(api)
|
|
5
|
+
@api = api
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def get(id)
|
|
9
|
+
@api.client.logger.debug 'Gocoin::User#get called.'
|
|
10
|
+
route = "/users/#{id}"
|
|
11
|
+
options = {}
|
|
12
|
+
@api.request route, options
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self
|
|
16
|
+
@api.client.logger.debug 'Gocoin::User#self called.'
|
|
17
|
+
route = "/user"
|
|
18
|
+
options = {}
|
|
19
|
+
@api.request route, options
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update(id, params)
|
|
23
|
+
@api.client.logger.debug 'Gocoin::User#update called.'
|
|
24
|
+
route = "/users/#{id}"
|
|
25
|
+
options = {
|
|
26
|
+
method: 'PATCH',
|
|
27
|
+
payload: params
|
|
28
|
+
}
|
|
29
|
+
@api.request route, options
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def update_password(id, params)
|
|
33
|
+
@api.client.logger.debug 'Gocoin::User#update_password called.'
|
|
34
|
+
route = "/users/#{id}/password"
|
|
35
|
+
options = {
|
|
36
|
+
method: 'PATCH',
|
|
37
|
+
payload: params
|
|
38
|
+
}
|
|
39
|
+
@api.request route, options
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/gocoin/auth.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class Auth
|
|
3
|
+
|
|
4
|
+
REQUIRED_CODE_PARAMS = %w[grant_type client_id client_secret code redirect_uri]
|
|
5
|
+
|
|
6
|
+
attr_reader :client
|
|
7
|
+
|
|
8
|
+
def initialize(client)
|
|
9
|
+
@client = client
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def authenticate(options = {})
|
|
13
|
+
@client.logger.debug 'Gocoin::Auth#authenticate method called.'
|
|
14
|
+
|
|
15
|
+
headers = @client.headers.merge(options[:headers] || {})
|
|
16
|
+
options = @client.options.merge options
|
|
17
|
+
verify_required_params options
|
|
18
|
+
route = '/oauth/token'
|
|
19
|
+
|
|
20
|
+
config = {
|
|
21
|
+
url: "#{@client.http_prefix}#{@client.options[:host]}#{@client.port}#{@client.options[:path]}/#{@client.options[:api_version]}#{route}",
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: headers,
|
|
24
|
+
payload: options.to_json
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@client.raw_request config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def construct_code_url(params)
|
|
31
|
+
"https://#{@client.options[:dashboard_host]}/auth?#{Util.hash_to_url_params(params)}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def verify_required_params(options)
|
|
37
|
+
if options[:grant_type] == 'authorization_code'
|
|
38
|
+
required = REQUIRED_CODE_PARAMS
|
|
39
|
+
else
|
|
40
|
+
raise 'Gocoin::Auth#authenticate: grant_type was not defined properly or is unsupported'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@client.logger.debug "Required params: #{required}"
|
|
44
|
+
required.each do |required_attribute|
|
|
45
|
+
raise "Gocoin::Auth#authenticate requires '#{required_attribute}' option." unless options[required_attribute.to_sym]
|
|
46
|
+
end
|
|
47
|
+
options
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
module Gocoin
|
|
2
|
+
class Client
|
|
3
|
+
|
|
4
|
+
attr_reader :api, :auth, :xrate, :user, :merchant, :accounts, :invoices, :apps, :headers, :options, :logger
|
|
5
|
+
attr_accessor :token
|
|
6
|
+
|
|
7
|
+
def initialize(options = {})
|
|
8
|
+
@defaults = {
|
|
9
|
+
client_id: nil,
|
|
10
|
+
client_secret: nil,
|
|
11
|
+
host: 'api.gocoin.com',
|
|
12
|
+
port: nil,
|
|
13
|
+
path: '/api',
|
|
14
|
+
api_version: 'v1',
|
|
15
|
+
secure: true,
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: nil,
|
|
18
|
+
grant_type: 'authorization_code',
|
|
19
|
+
request_id: nil,
|
|
20
|
+
dashboard_host: 'dashboard.gocoin.com',
|
|
21
|
+
xrate_host: 'x.g0cn.com',
|
|
22
|
+
log_file: nil
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@default_headers = {
|
|
26
|
+
'Content-Type' => 'application/json'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@options = @defaults.merge options
|
|
30
|
+
@logger = Logger.new(@options[:log_file] || STDOUT)
|
|
31
|
+
@headers = @options[:headers] || @default_headers
|
|
32
|
+
@headers['X-Request-Id'] = @options[:request_id] if @options[:request_id]
|
|
33
|
+
|
|
34
|
+
@auth = Gocoin::Auth.new(self)
|
|
35
|
+
@api = Gocoin::API.new(self)
|
|
36
|
+
@xrate = Gocoin::Xrate.new(self)
|
|
37
|
+
|
|
38
|
+
@accounts = @api.accounts
|
|
39
|
+
@invoices = @api.invoices
|
|
40
|
+
@merchant = @api.merchant
|
|
41
|
+
@user = @api.user
|
|
42
|
+
|
|
43
|
+
@options[:secure] = false if @options[:secure] == 'false'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def authenticate(options)
|
|
47
|
+
@logger.debug 'Gocoin::Client#authenticate method called.'
|
|
48
|
+
@auth.authenticate options
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def http_prefix(secure = true)
|
|
52
|
+
secure ? 'https://' : 'http://'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def port
|
|
56
|
+
@options[:port] ? ":#{@options[:port]}" : nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def raw_request(config)
|
|
60
|
+
unless config[:payload].nil?
|
|
61
|
+
config[:headers]['Content-Length'] = config[:payload].length
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
log_config = config.dup
|
|
65
|
+
log_config[:headers] = config[:headers].dup
|
|
66
|
+
@logger.debug 'Raw request made' + strip_secure_from_raw(log_config).to_s
|
|
67
|
+
|
|
68
|
+
error_response = nil
|
|
69
|
+
begin
|
|
70
|
+
response = RestClient::Request.execute(
|
|
71
|
+
config.merge(
|
|
72
|
+
open_timeout: 30,
|
|
73
|
+
timeout: 80
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
rescue SocketError => error_response
|
|
77
|
+
handle_restclient_error error_response
|
|
78
|
+
rescue NoMethodError => error_response
|
|
79
|
+
if error_response.message =~ /\WRequestFailed\W/
|
|
80
|
+
error_response = APIConnectionError.new('Unexpected HTTP response code')
|
|
81
|
+
handle_restclient_error error_response
|
|
82
|
+
else
|
|
83
|
+
raise
|
|
84
|
+
end
|
|
85
|
+
rescue RestClient::ExceptionWithResponse => error_response
|
|
86
|
+
if rcode = error_response.http_code and rbody = error_response.http_body
|
|
87
|
+
handle_api_error rcode, rbody
|
|
88
|
+
else
|
|
89
|
+
handle_restclient_error error_response
|
|
90
|
+
end
|
|
91
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => error_response
|
|
92
|
+
handle_restclient_error error_response
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return parse_error(error_response) if error_response
|
|
96
|
+
parse response
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def strip_secure_from_raw(obj)
|
|
102
|
+
strippable = %w[client_secret password current_password password_confirmation]
|
|
103
|
+
if obj[:payload]
|
|
104
|
+
obj[:payload] = JSON.parse obj[:payload]
|
|
105
|
+
strippable.each do |k|
|
|
106
|
+
obj[:payload][k] = "<#{k}>" if obj[:payload][k]
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
obj[:headers]['Authorization'] = '<bearer>' if obj[:headers]['Authorization']
|
|
110
|
+
|
|
111
|
+
obj
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def parse(response)
|
|
115
|
+
begin
|
|
116
|
+
response = JSON.parse response.body
|
|
117
|
+
rescue JSON::ParserError
|
|
118
|
+
raise general_api_error response.code, response.body
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
Util.symbolize_names response
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def parse_error(error_response)
|
|
125
|
+
begin
|
|
126
|
+
response = JSON.parse error_response.http_body
|
|
127
|
+
rescue JSON::ParserError
|
|
128
|
+
raise general_api_error error_response.http_code, error_response.error_body
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
response[:status] = error_response.http_code
|
|
132
|
+
|
|
133
|
+
Util.symbolize_names response
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def general_api_error(rcode, rbody)
|
|
137
|
+
APIError.new( "Invalid response object from API: #{rbody.inspect} " +
|
|
138
|
+
"(HTTP response code was #{rcode}", rcode, rbody)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def handle_api_error(rcode, rbody)
|
|
142
|
+
begin
|
|
143
|
+
error_obj = JSON.parse rbody
|
|
144
|
+
error_obj = Util.symbolize_names(error_obj)
|
|
145
|
+
error = error_obj[:error_description] or error_obj[:errors] or raise GocoinError.new
|
|
146
|
+
rescue JSON::ParserError, GocoinError
|
|
147
|
+
raise general_api_error(rcode, rbody)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
case rcode
|
|
151
|
+
when 400, 404
|
|
152
|
+
raise invalid_request_error error, rcode, rbody, error_obj
|
|
153
|
+
when 401
|
|
154
|
+
raise authentication_error error, rcode, rbody, error_obj
|
|
155
|
+
when 422 # Don't raise an error. Pass back a JSON object
|
|
156
|
+
return
|
|
157
|
+
else
|
|
158
|
+
raise api_error error, rcode, rbody, error_obj
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def invalid_request_error(error, rcode, rbody, error_obj)
|
|
163
|
+
InvalidRequestError.new(error, rcode, rbody, error_obj)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def authentication_error(error, rcode, rbody, error_obj)
|
|
167
|
+
AuthenticationError.new(error, rbody, error_obj)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def api_error(error, rcode, rbody, error_obj)
|
|
171
|
+
APIError.new(error, rcode, rbody, error_obj)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def handle_restclient_error(e)
|
|
175
|
+
case e
|
|
176
|
+
when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
|
|
177
|
+
message = "Could not connect to GoCoin (#{@options[:host]}). " +
|
|
178
|
+
"Please check your internet connection and try again. " +
|
|
179
|
+
"If this problem persists, let us know at tech@gocoin.com."
|
|
180
|
+
|
|
181
|
+
when RestClient::SSLCertificateNotVerified
|
|
182
|
+
message = "Could not verify GoCoin's SSL certificate. " +
|
|
183
|
+
"Please make sure that your network is not intercepting certificates. " +
|
|
184
|
+
"(Try going to https://#{options[:host]}/#{options[:api_version]} in your browser.) " +
|
|
185
|
+
"If this problem persists, let us know at tech@gocoin.com."
|
|
186
|
+
|
|
187
|
+
when SocketError
|
|
188
|
+
message = "Unexpected error communicating when trying to connect to GoCoin. " +
|
|
189
|
+
"You may be seeing this message because your DNS is not working. " +
|
|
190
|
+
"To check, try running 'host gocoin.com' from the command line."
|
|
191
|
+
|
|
192
|
+
else
|
|
193
|
+
message = "Unexpected error communicating with GoCoin. " +
|
|
194
|
+
"If this problem persists, let us know at tech@gocoin.com."
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
end
|
|
201
|
+
end
|