qbo_api 1.4.2 → 1.5.0
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
- data/README.md +33 -1
- data/example/app.rb +48 -1
- data/example/qbo_oauth2.rb +38 -0
- data/example/views/index.erb +1 -0
- data/example/views/oauth2.erb +25 -0
- data/lib/qbo_api.rb +12 -5
- data/lib/qbo_api/version.rb +1 -1
- data/qbo_api.gemspec +2 -0
- metadata +32 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 602ff37e3feee0e447a15566efe439d1f9beb61b
|
|
4
|
+
data.tar.gz: c709006d7f4bd704e9a1011824da9812b0edb6da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5511399b404ad719752fc1a5fd6359e8be2386fdcc9d2e99e792abebeca3fd1e470cf838d6a6c4ecb5e9fd9a29bf25175f892a0d4fca872b1da6f39af18cd440
|
|
7
|
+
data.tar.gz: 32dcda594b2f9a63395a67d5e38cf76eee7dbbf00e85f6184d6fd690becbbe3c371cf47514a8269909b775cd55777b709c816fd77aafa2d11ddb99d4dbe51f58
|
data/README.md
CHANGED
|
@@ -41,6 +41,7 @@ Or install it yourself as:
|
|
|
41
41
|
## Usage
|
|
42
42
|
|
|
43
43
|
### Initialize
|
|
44
|
+
#### OAuth
|
|
44
45
|
```ruby
|
|
45
46
|
q = account.qbo_account # or wherever you are storing the OAuth creds
|
|
46
47
|
qbo_api = QboApi.new(token: q.token,
|
|
@@ -49,6 +50,10 @@ Or install it yourself as:
|
|
|
49
50
|
consumer_key: '*****',
|
|
50
51
|
consumer_secret: '********')
|
|
51
52
|
```
|
|
53
|
+
#### OAuth2
|
|
54
|
+
```ruby
|
|
55
|
+
qbo_api = QboApi.new(access_token: 'REWR342532asdfae!$4asdfa', realm_id: 32095430444)
|
|
56
|
+
```
|
|
52
57
|
|
|
53
58
|
### Super fast way to use QboApi no matter your current tech stack as long as Ruby > 2.2.2 is installed
|
|
54
59
|
```
|
|
@@ -57,11 +62,14 @@ Or install it yourself as:
|
|
|
57
62
|
- bundle
|
|
58
63
|
- bin/console
|
|
59
64
|
- QboApi.production = true
|
|
65
|
+
- # OAuth 1
|
|
60
66
|
- qboapi = QboApi.new(token: "qyprd2uvCOdRq8xzoSSiiiiii",
|
|
61
67
|
token_secret:"g8wcyQEtwxxxxxxm",
|
|
62
68
|
realm_id: "12314xxxxxx7",
|
|
63
69
|
consumer_key: "qyprdwzcxxxxxxbIWsIMIy9PYI",
|
|
64
70
|
consumer_secret: "CyDN4wpxxxxxxxPMv7hDhmh4")
|
|
71
|
+
- # OAuth 2
|
|
72
|
+
- qboapi = QboApi.new(access_token: "qyprd2uvCOdRq8xzoSSiiiiii", realm_id: "12314xxxxxx7")
|
|
65
73
|
- qboapi.get :customer, 1
|
|
66
74
|
```
|
|
67
75
|
|
|
@@ -264,8 +272,31 @@ See [docs](https://developer.intuit.com/docs/0100_quickbooks_online/0100_essenti
|
|
|
264
272
|
p qbo_api.is_transaction_entity?(:customer) # => false
|
|
265
273
|
p qbo_api.is_name_list_entity?(:vendors) # => true
|
|
266
274
|
```
|
|
275
|
+
## OAuth2: Spin up an example
|
|
276
|
+
### If you signed up for a Intuit developer account after July 17th, 2017 follow this example
|
|
277
|
+
- `git clone git://github.com/minimul/qbo_api && cd qbo_api`
|
|
278
|
+
- `bundle`
|
|
279
|
+
- Create a `.env` file
|
|
280
|
+
- If needed create an account at [https://developer.intuit.com](https://developer.intuit.com)
|
|
281
|
+
- Click `Get started coding`
|
|
282
|
+
- Create an app with both the `Accounting` & `Payments` selected.
|
|
283
|
+
- Go to the `Development` tab and copy and paste the client id and client secret into the `.env` file.
|
|
284
|
+
```ruby
|
|
285
|
+
export QBO_API_CLIENT_ID=<Your QuickBooks Apps Client ID>
|
|
286
|
+
export QBO_API_CONSUMER_SECRET=<Your QuickBooks Apps Client Secret>
|
|
287
|
+
```
|
|
288
|
+
- Note: the `.env` file will be automatically loaded after you run the next step.
|
|
289
|
+
- Start up the example app
|
|
290
|
+
- `ruby example/app.rb`
|
|
291
|
+
- Goto `http://localhost:9393/oauth2`
|
|
292
|
+
- Use the `Connect to QuickBooks` button to connect to your QuickBooks sandbox, which you receive when signing up at [https://developer.intuit.com](https://developer.intuit.com).
|
|
293
|
+
- After successfully connecting to your sandbox run:
|
|
294
|
+
- `http://localhost:9393/oauth2/customer/5`
|
|
295
|
+
- You should see "Dukes Basketball Camp" displayed
|
|
296
|
+
- Checkout [`example/app.rb`](https://github.com/minimul/qbo_api/blob/master/example/app.rb) to see what is going on under the hood.
|
|
267
297
|
|
|
268
|
-
## Spin up an example
|
|
298
|
+
## OAuth1: Spin up an example
|
|
299
|
+
### OLD LEGACY - SEE OAUTH2 EXAMPLE ABOVE
|
|
269
300
|
- <a href="http://minimul.com/getting-started-with-the-modern-ruby-quickbooks-online-client-qbo_api-part-1.html" target="_blank">Check out this tutorial and screencast on spinning up an example</a>.
|
|
270
301
|
- `git clone git://github.com/minimul/qbo_api && cd qbo_api`
|
|
271
302
|
- `bundle`
|
|
@@ -306,6 +337,7 @@ export QBO_API_CONSUMER_KEY=
|
|
|
306
337
|
export QBO_API_CONSUMER_SECRET=
|
|
307
338
|
export QBO_API_ACCESS_TOKEN=
|
|
308
339
|
export QBO_API_ACCESS_TOKEN_SECRET=
|
|
340
|
+
export QBO_API_OAUTH2_ACCESS_TOKEN=
|
|
309
341
|
export QBO_API_COMPANY_ID=12345
|
|
310
342
|
```
|
|
311
343
|
- `bundle exec rspec spec/`
|
data/example/app.rb
CHANGED
|
@@ -6,16 +6,20 @@ require 'base64'
|
|
|
6
6
|
require 'omniauth'
|
|
7
7
|
require 'omniauth-quickbooks'
|
|
8
8
|
require 'dotenv'
|
|
9
|
+
require 'rack/oauth2'
|
|
9
10
|
require 'qbo_api'
|
|
11
|
+
|
|
10
12
|
Dotenv.load "#{__dir__}/../.env"
|
|
11
13
|
|
|
12
14
|
PORT = 9393
|
|
13
15
|
CONSUMER_KEY = ENV['QBO_API_CONSUMER_KEY']
|
|
14
16
|
CONSUMER_SECRET = ENV['QBO_API_CONSUMER_SECRET']
|
|
17
|
+
CLIENT_ID = ENV['QBO_API_CLIENT_ID']
|
|
18
|
+
CLIENT_SECRET = ENV['QBO_API_CLIENT_SECRET']
|
|
15
19
|
VERIFIER_TOKEN = ENV['QBO_API_VERIFIER_TOKEN']
|
|
16
20
|
|
|
17
21
|
set :port, PORT
|
|
18
|
-
use Rack::Session::Cookie, secret: '34233adasf'
|
|
22
|
+
use Rack::Session::Cookie, secret: '34233adasf/qewrq453agqr9(lasfa)'
|
|
19
23
|
use OmniAuth::Builder do
|
|
20
24
|
provider :quickbooks, CONSUMER_KEY, CONSUMER_SECRET
|
|
21
25
|
end
|
|
@@ -26,6 +30,16 @@ helpers do
|
|
|
26
30
|
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, VERIFIER_TOKEN, data)).strip
|
|
27
31
|
calculated_hmac == hmac_header
|
|
28
32
|
end
|
|
33
|
+
|
|
34
|
+
def oauth2_client
|
|
35
|
+
client = Rack::OAuth2::Client.new(
|
|
36
|
+
identifier: CLIENT_ID,
|
|
37
|
+
secret: CLIENT_SECRET,
|
|
38
|
+
redirect_uri: "http://localhost:#{PORT}/oauth2-redirect",
|
|
39
|
+
authorization_endpoint: "https://appcenter.intuit.com/connect/oauth2",
|
|
40
|
+
token_endpoint: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
|
|
41
|
+
)
|
|
42
|
+
end
|
|
29
43
|
end
|
|
30
44
|
|
|
31
45
|
get '/' do
|
|
@@ -35,6 +49,39 @@ get '/' do
|
|
|
35
49
|
erb :index
|
|
36
50
|
end
|
|
37
51
|
|
|
52
|
+
get '/oauth2' do
|
|
53
|
+
session[:state] = SecureRandom.uuid
|
|
54
|
+
@client = oauth2_client
|
|
55
|
+
erb :oauth2
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
get '/oauth2-redirect' do
|
|
59
|
+
state = params[:state]
|
|
60
|
+
error = params[:error]
|
|
61
|
+
code = params[:code]
|
|
62
|
+
if state == session[:state]
|
|
63
|
+
client = oauth2_client
|
|
64
|
+
client.authorization_code = code
|
|
65
|
+
if resp = client.access_token!
|
|
66
|
+
session[:access_token] = resp.access_token
|
|
67
|
+
session[:realm_id] = params[:realmId]
|
|
68
|
+
"<p>Success! Here is your access_token => #{resp.access_token}</p><p><a href='/oauth2/customer/5'>Click here</a> to make an API call</p>"
|
|
69
|
+
else
|
|
70
|
+
"Something went wrong. Try the process again"
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
"Error: #{error}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
get '/oauth2/customer/:id' do
|
|
78
|
+
if access_token = session[:access_token]
|
|
79
|
+
api = QboApi.new(access_token: access_token, realm_id: session[:realm_id])
|
|
80
|
+
@resp = api.get :customer, params[:id]
|
|
81
|
+
end
|
|
82
|
+
erb :customer
|
|
83
|
+
end
|
|
84
|
+
|
|
38
85
|
get '/customer/:id' do
|
|
39
86
|
if session[:token]
|
|
40
87
|
api = QboApi.new(oauth_data)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'omniauth-oauth2'
|
|
2
|
+
|
|
3
|
+
module OmniAuth
|
|
4
|
+
module Strategies
|
|
5
|
+
class QboOAuth2 < OmniAuth::Strategies::OAuth2
|
|
6
|
+
# Give your strategy a name.
|
|
7
|
+
option :name, "qbo"
|
|
8
|
+
|
|
9
|
+
# This is where you pass the options you would pass when
|
|
10
|
+
# initializing your consumer from the OAuth gem.
|
|
11
|
+
option :client_options, {:site => "https://appcenter.intuit.com/connect/oauth2"}
|
|
12
|
+
|
|
13
|
+
# These are called after authentication has succeeded. If
|
|
14
|
+
# possible, you should try to set the UID without making
|
|
15
|
+
# additional calls (if the user id is returned with the token
|
|
16
|
+
# or as a URI parameter). This may not be possible with all
|
|
17
|
+
# providers.
|
|
18
|
+
uid{ raw_info['id'] }
|
|
19
|
+
|
|
20
|
+
info do
|
|
21
|
+
{
|
|
22
|
+
:name => raw_info['name'],
|
|
23
|
+
:email => raw_info['email']
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
extra do
|
|
28
|
+
{
|
|
29
|
+
'raw_info' => raw_info
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def raw_info
|
|
34
|
+
@raw_info ||= access_token.get('/me').parsed
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/example/views/index.erb
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>QBO Connect via OAuth2</title>
|
|
6
|
+
|
|
7
|
+
<script type="text/javascript" src="<%= QboApi::APP_CENTER_BASE %>/Content/IA/intuit.ipp.anywhere-1.3.1.js"></script>
|
|
8
|
+
<script>
|
|
9
|
+
intuit.ipp.anywhere.setup({
|
|
10
|
+
grantUrl: "<%= @client.authorization_uri(scope: 'com.intuit.quickbooks.accounting', state: session[:state]) %>",
|
|
11
|
+
datasources: {
|
|
12
|
+
quickbooks : true,
|
|
13
|
+
payments : true
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
</script>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<% if session[:token] %>
|
|
20
|
+
<p><%= @auth_data %></p>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
<ipp:connectToIntuit></ipp:connectToIntuit>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
data/lib/qbo_api.rb
CHANGED
|
@@ -28,12 +28,13 @@ class QboApi
|
|
|
28
28
|
PAYMENTS_API_BASE_URL = 'https://sandbox.api.intuit.com/quickbooks/v4/payments'
|
|
29
29
|
APP_CONNECTION_URL = APP_CENTER_BASE + '/api/v1/connection'
|
|
30
30
|
|
|
31
|
-
def initialize(token
|
|
32
|
-
consumer_secret:
|
|
33
|
-
@consumer_key = consumer_key
|
|
34
|
-
@consumer_secret = consumer_secret
|
|
31
|
+
def initialize(token: nil, token_secret: nil, access_token: nil, realm_id:,
|
|
32
|
+
consumer_key: nil, consumer_secret: nil, endpoint: :accounting)
|
|
33
|
+
@consumer_key = consumer_key || (defined?(CONSUMER_KEY) ? CONSUMER_KEY : nil)
|
|
34
|
+
@consumer_secret = consumer_secret || (defined?(CONSUMER_SECRET) ? CONSUMER_SECRET : nil)
|
|
35
35
|
@token = token
|
|
36
36
|
@token_secret = token_secret
|
|
37
|
+
@access_token = access_token
|
|
37
38
|
@realm_id = realm_id
|
|
38
39
|
@endpoint = endpoint
|
|
39
40
|
end
|
|
@@ -42,7 +43,13 @@ class QboApi
|
|
|
42
43
|
Faraday.new(url: url) do |faraday|
|
|
43
44
|
faraday.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
|
44
45
|
faraday.headers['Accept'] = "application/json"
|
|
45
|
-
|
|
46
|
+
if @token != nil
|
|
47
|
+
faraday.request :oauth, oauth_data
|
|
48
|
+
elsif @access_token != nil
|
|
49
|
+
faraday.request :oauth2, @access_token, token_type: 'bearer'
|
|
50
|
+
else
|
|
51
|
+
raise QboApi::Error.new error_body: "Must set either the token or access_token"
|
|
52
|
+
end
|
|
46
53
|
faraday.request :url_encoded
|
|
47
54
|
faraday.use FaradayMiddleware::RaiseHttpException
|
|
48
55
|
faraday.response :detailed_logger, QboApi.logger if QboApi.log
|
data/lib/qbo_api/version.rb
CHANGED
data/qbo_api.gemspec
CHANGED
|
@@ -23,8 +23,10 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.add_development_dependency "rspec"
|
|
24
24
|
spec.add_development_dependency 'webmock'
|
|
25
25
|
spec.add_development_dependency 'sinatra'
|
|
26
|
+
spec.add_development_dependency 'rack-oauth2'
|
|
26
27
|
spec.add_development_dependency 'omniauth'
|
|
27
28
|
spec.add_development_dependency 'omniauth-quickbooks'
|
|
29
|
+
spec.add_development_dependency 'shotgun'
|
|
28
30
|
spec.add_development_dependency 'dotenv'
|
|
29
31
|
spec.add_development_dependency 'vcr'
|
|
30
32
|
spec.add_development_dependency 'awesome_print'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: qbo_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christian Pelczarski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-07-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rack-oauth2
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: omniauth
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,6 +122,20 @@ dependencies:
|
|
|
108
122
|
- - ">="
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: shotgun
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
111
139
|
- !ruby/object:Gem::Dependency
|
|
112
140
|
name: dotenv
|
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -236,8 +264,10 @@ files:
|
|
|
236
264
|
- bin/console
|
|
237
265
|
- bin/setup
|
|
238
266
|
- example/app.rb
|
|
267
|
+
- example/qbo_oauth2.rb
|
|
239
268
|
- example/views/customer.erb
|
|
240
269
|
- example/views/index.erb
|
|
270
|
+
- example/views/oauth2.erb
|
|
241
271
|
- lib/qbo_api.rb
|
|
242
272
|
- lib/qbo_api/configuration.rb
|
|
243
273
|
- lib/qbo_api/entity.rb
|