xero_gateway 2.0.12 → 2.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/partner_app.rb +36 -0
- data/lib/oauth/oauth_consumer.rb +14 -0
- data/lib/xero_gateway/gateway.rb +1 -1
- data/lib/xero_gateway/invoice.rb +2 -1
- data/lib/xero_gateway/oauth.rb +30 -1
- data/lib/xero_gateway/organisation.rb +27 -16
- data/lib/xero_gateway/partner_app.rb +30 -0
- data/lib/xero_gateway.rb +4 -1
- data/test/integration/get_invoices_test.rb +2 -0
- data/xero_gateway.gemspec +2 -2
- metadata +9 -6
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/../lib/xero_gateway.rb'
|
5
|
+
|
6
|
+
XERO_CONSUMER_KEY = "YOUR CONSUMER KEY"
|
7
|
+
XERO_CONSUMER_SECRET = "YOUR CONSUMER SERET"
|
8
|
+
|
9
|
+
ENTRUST_CERT_NAME = "YOUR_ENTRUST_CERT.pem"
|
10
|
+
ENTRUST_KEY_NAME = "YOUR_ENTRUST_KEY.pem"
|
11
|
+
PRIVATE_KEY = "YOUR_PRIVATE_KEY.pem"
|
12
|
+
|
13
|
+
gateway = XeroGateway::PartnerApp.new(XERO_CONSUMER_KEY, XERO_CONSUMER_SECRET,
|
14
|
+
:ssl_client_cert => File.join(File.dirname(__FILE__), ENTRUST_CERT_NAME)
|
15
|
+
:ssl_client_key => File.join(File.dirname(__FILE__), ENTRUST_KEY_NAME),
|
16
|
+
:private_key_file => File.join(File.dirname(__FILE__), PRIVATE_KEY))
|
17
|
+
|
18
|
+
# authorize in browser
|
19
|
+
%x(open #{gateway.request_token.authorize_url})
|
20
|
+
|
21
|
+
puts "Enter the verification code from Xero?"
|
22
|
+
oauth_verifier = gets.chomp
|
23
|
+
|
24
|
+
gateway.authorize_from_request(gateway.request_token.token, gateway.request_token.secret, :oauth_verifier => oauth_verifier)
|
25
|
+
|
26
|
+
puts "Your access token/secret: #{gateway.access_token.token}, #{gateway.access_token.secret}. Expires: #{gateway.authorization_expires_at}"
|
27
|
+
puts "(Good for 30 Minutes - but we can renew it!)"
|
28
|
+
|
29
|
+
puts "Session Handle: #{gateway.session_handle}"
|
30
|
+
|
31
|
+
# Example API Call
|
32
|
+
pp gateway.get_contacts.contacts.map(&:name)
|
33
|
+
|
34
|
+
# Renew!
|
35
|
+
gateway.renew_access_token(gateway.access_token.token, gateway.access_token.secret, gateway.session_handle)
|
36
|
+
puts "Your renewed access token/secret is: #{gateway.access_token.token}, #{gateway.access_token.secret}. Expires: #{gateway.authorization_expires_at}"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module OAuth
|
2
|
+
class Consumer
|
3
|
+
|
4
|
+
def http_with_ssl_client_certificates(*args)
|
5
|
+
@http ||= http_without_ssl_client_certificates(*args).tap do |http|
|
6
|
+
http.cert = options[:ssl_client_cert]
|
7
|
+
http.key = options[:ssl_client_key]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method_chain :http, :ssl_client_certificates
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
data/lib/xero_gateway/gateway.rb
CHANGED
@@ -7,7 +7,7 @@ module XeroGateway
|
|
7
7
|
attr_accessor :client, :xero_url, :logger
|
8
8
|
|
9
9
|
extend Forwardable
|
10
|
-
def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access
|
10
|
+
def_delegators :client, :request_token, :access_token, :authorize_from_request, :authorize_from_access, :authorization_expires_at
|
11
11
|
|
12
12
|
#
|
13
13
|
# The consumer key and secret here correspond to those provided
|
data/lib/xero_gateway/invoice.rb
CHANGED
@@ -39,7 +39,7 @@ module XeroGateway
|
|
39
39
|
attr_accessor :line_items_downloaded
|
40
40
|
|
41
41
|
# All accessible fields
|
42
|
-
attr_accessor :invoice_id, :invoice_number, :invoice_type, :invoice_status, :date, :due_date, :reference, :line_amount_types, :currency_code, :line_items, :contact, :payments, :fully_paid_on, :amount_due, :amount_paid, :amount_credited
|
42
|
+
attr_accessor :invoice_id, :invoice_number, :invoice_type, :invoice_status, :date, :due_date, :reference, :line_amount_types, :currency_code, :line_items, :contact, :payments, :fully_paid_on, :amount_due, :amount_paid, :amount_credited, :sent_to_contact
|
43
43
|
|
44
44
|
|
45
45
|
def initialize(params = {})
|
@@ -278,6 +278,7 @@ module XeroGateway
|
|
278
278
|
when "AmountDue" then invoice.amount_due = BigDecimal.new(element.text)
|
279
279
|
when "AmountPaid" then invoice.amount_paid = BigDecimal.new(element.text)
|
280
280
|
when "AmountCredited" then invoice.amount_credited = BigDecimal.new(element.text)
|
281
|
+
when "SentToContact" then invoice.sent_to_contact = (element.text.strip.downcase == "true")
|
281
282
|
end
|
282
283
|
end
|
283
284
|
invoice
|
data/lib/xero_gateway/oauth.rb
CHANGED
@@ -25,7 +25,7 @@ module XeroGateway
|
|
25
25
|
extend Forwardable
|
26
26
|
def_delegators :access_token, :get, :post, :put, :delete
|
27
27
|
|
28
|
-
attr_reader :ctoken, :csecret, :consumer_options
|
28
|
+
attr_reader :ctoken, :csecret, :consumer_options, :session_handle, :authorization_expires_at
|
29
29
|
|
30
30
|
def initialize(ctoken, csecret, options = {})
|
31
31
|
@ctoken, @csecret = ctoken, csecret
|
@@ -44,6 +44,8 @@ module XeroGateway
|
|
44
44
|
request_token = ::OAuth::RequestToken.new(consumer, rtoken, rsecret)
|
45
45
|
access_token = request_token.get_access_token(params)
|
46
46
|
@atoken, @asecret = access_token.token, access_token.secret
|
47
|
+
|
48
|
+
update_attributes_from_token(access_token)
|
47
49
|
end
|
48
50
|
|
49
51
|
def access_token
|
@@ -53,6 +55,33 @@ module XeroGateway
|
|
53
55
|
def authorize_from_access(atoken, asecret)
|
54
56
|
@atoken, @asecret = atoken, asecret
|
55
57
|
end
|
58
|
+
|
59
|
+
# Renewing access tokens only works for Partner applications
|
60
|
+
def renew_access_token(access_token = nil, access_secret = nil, session_handle = nil)
|
61
|
+
access_token ||= @atoken
|
62
|
+
access_secret ||= @asecret
|
63
|
+
session_handle ||= @session_handle
|
64
|
+
|
65
|
+
old_token = ::OAuth::RequestToken.new(consumer, access_token, access_secret)
|
66
|
+
|
67
|
+
access_token = old_token.get_access_token({
|
68
|
+
:oauth_session_handle => session_handle,
|
69
|
+
:token => old_token
|
70
|
+
})
|
71
|
+
|
72
|
+
update_attributes_from_token(access_token)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Update instance variables with those from the AccessToken.
|
78
|
+
def update_attributes_from_token(access_token)
|
79
|
+
@expires_at = Time.now + access_token.params[:oauth_expires_in].to_i
|
80
|
+
@authorization_expires_at = Time.now + access_token.params[:oauth_authorization_expires_in].to_i
|
81
|
+
@session_handle = access_token.params[:oauth_session_handle]
|
82
|
+
@atoken, @asecret = access_token.token, access_token.secret
|
83
|
+
@access_token = nil
|
84
|
+
end
|
56
85
|
|
57
86
|
end
|
58
87
|
end
|
@@ -3,16 +3,21 @@ module XeroGateway
|
|
3
3
|
|
4
4
|
unless defined? ATTRS
|
5
5
|
ATTRS = {
|
6
|
-
"Name"
|
7
|
-
"LegalName"
|
8
|
-
"PaysTax"
|
9
|
-
"Version"
|
10
|
-
"BaseCurrency"
|
11
|
-
"OrganisationType"
|
12
|
-
"OrganisationStatus"
|
13
|
-
"IsDemoCompany"
|
14
|
-
"APIKey"
|
15
|
-
"CountryCode"
|
6
|
+
"Name" => :string, # Display name of organisation shown in Xero
|
7
|
+
"LegalName" => :string, # Organisation name shown on Reports
|
8
|
+
"PaysTax" => :boolean, # Boolean to describe if organisation is registered with a local tax authority i.e. true, false
|
9
|
+
"Version" => :string, # See Version Types
|
10
|
+
"BaseCurrency" => :string, # Default currency for organisation. See Currency types
|
11
|
+
"OrganisationType" => :string, # UNDOCUMENTED parameter, only returned for "real" (i.e non-demo) companies
|
12
|
+
"OrganisationStatus" => :string, # UNDOCUMENTED parameter
|
13
|
+
"IsDemoCompany" => :boolean, # UNDOCUMENTED parameter
|
14
|
+
"APIKey" => :string, # UNDOCUMENTED paramater, returned if organisations are linked via Xero Network
|
15
|
+
"CountryCode" => :string, # UNDOCUMENTED parameter
|
16
|
+
"TaxNumber" => :string,
|
17
|
+
"FinancialYearEndDay" => :string,
|
18
|
+
"FinancialYearEndMonth" => :string,
|
19
|
+
"PeriodLockDate" => :string,
|
20
|
+
"CreatedDateUTC" => :string
|
16
21
|
}
|
17
22
|
end
|
18
23
|
|
@@ -48,12 +53,18 @@ module XeroGateway
|
|
48
53
|
attribute = element.name
|
49
54
|
underscored_attribute = element.name.underscore
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
if ATTRS.keys.include?(attribute)
|
57
|
+
|
58
|
+
case (ATTRS[attribute])
|
59
|
+
when :boolean then org.send("#{underscored_attribute}=", (element.text == "true"))
|
60
|
+
when :float then org.send("#{underscored_attribute}=", element.text.to_f)
|
61
|
+
else org.send("#{underscored_attribute}=", element.text)
|
62
|
+
end
|
63
|
+
|
64
|
+
else
|
65
|
+
|
66
|
+
warn "Ignoring unknown attribute: #{attribute}"
|
67
|
+
|
57
68
|
end
|
58
69
|
|
59
70
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module XeroGateway
|
2
|
+
class PartnerApp < Gateway
|
3
|
+
|
4
|
+
class CertificateRequired < StandardError; end
|
5
|
+
|
6
|
+
NO_SSL_CLIENT_CERT_MESSAGE = "You need to provide a client ssl certificate and key pair (these are the ones you got from Entrust and should not be password protected) as :ssl_client_cert and :ssl_client_key (should be .crt or .pem files)"
|
7
|
+
NO_PRIVATE_KEY_ERROR_MESSAGE = "You need to provide your private key (corresponds to the public key you uploaded at api.xero.com) as :private_key_file (should be .crt or .pem files)"
|
8
|
+
|
9
|
+
def_delegators :client, :session_handle, :renew_access_token
|
10
|
+
|
11
|
+
def initialize(consumer_key, consumer_secret, options = {})
|
12
|
+
|
13
|
+
raise CertificateRequired.new(NO_SSL_CLIENT_CERT_MESSAGE) unless options[:ssl_client_cert]
|
14
|
+
raise CertificateRequired.new(NO_SSL_CLIENT_CERT_MESSAGE) unless options[:ssl_client_key]
|
15
|
+
raise CertificateRequired.new(NO_PRIVATE_KEY_ERROR_MESSAGE) unless options[:private_key_file]
|
16
|
+
|
17
|
+
options.merge!(
|
18
|
+
:site => "https://api-partner.network.xero.com",
|
19
|
+
:authorize_url => 'https://api.xero.com/oauth/Authorize',
|
20
|
+
:signature_method => 'RSA-SHA1',
|
21
|
+
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(options[:ssl_client_cert])),
|
22
|
+
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read(options[:ssl_client_key])),
|
23
|
+
:private_key_file => options[:private_key_file]
|
24
|
+
)
|
25
|
+
|
26
|
+
@xero_url = options[:xero_url] || "https://api-partner.xero.com/api.xro/2.0"
|
27
|
+
@client = OAuth.new(consumer_key, consumer_secret, options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/xero_gateway.rb
CHANGED
@@ -7,7 +7,9 @@ require "bigdecimal"
|
|
7
7
|
require "oauth"
|
8
8
|
require 'oauth/signature/rsa/sha1'
|
9
9
|
require "forwardable"
|
10
|
-
require "active_support/
|
10
|
+
require "active_support/all"
|
11
|
+
|
12
|
+
require File.join(File.dirname(__FILE__), 'oauth', 'oauth_consumer')
|
11
13
|
|
12
14
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'http_encoding_helper')
|
13
15
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'http')
|
@@ -32,3 +34,4 @@ require File.join(File.dirname(__FILE__), 'xero_gateway', 'oauth')
|
|
32
34
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'exceptions')
|
33
35
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'gateway')
|
34
36
|
require File.join(File.dirname(__FILE__), 'xero_gateway', 'private_app')
|
37
|
+
require File.join(File.dirname(__FILE__), 'xero_gateway', 'partner_app')
|
@@ -28,6 +28,8 @@ class GetInvoicesTest < Test::Unit::TestCase
|
|
28
28
|
assert !result.request_params.nil?
|
29
29
|
assert !result.response_xml.nil?
|
30
30
|
assert result.invoices.collect {|i| i.invoice_number}.include?(invoice.invoice_number)
|
31
|
+
assert result.invoices[0].sent_to_contact == true
|
32
|
+
assert result.invoices[1].sent_to_contact == false
|
31
33
|
end
|
32
34
|
|
33
35
|
def test_get_invoices_with_modified_since_date
|
data/xero_gateway.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "xero_gateway"
|
3
|
-
s.version = "2.0.
|
4
|
-
s.date = "2011-
|
3
|
+
s.version = "2.0.13"
|
4
|
+
s.date = "2011-09-14"
|
5
5
|
s.summary = "Enables ruby based applications to communicate with the Xero API"
|
6
6
|
s.email = "tim@connorsoftware.com"
|
7
7
|
s.homepage = "http://github.com/tlconnor/xero_gateway"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xero_gateway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 2.0.
|
9
|
+
- 13
|
10
|
+
version: 2.0.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tim Connor
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-09-14 00:00:00 +12:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -80,7 +80,9 @@ files:
|
|
80
80
|
- README.textile
|
81
81
|
- xero_gateway.gemspec
|
82
82
|
- examples/oauth.rb
|
83
|
+
- examples/partner_app.rb
|
83
84
|
- init.rb
|
85
|
+
- lib/oauth/oauth_consumer.rb
|
84
86
|
- lib/xero_gateway/account.rb
|
85
87
|
- lib/xero_gateway/accounts_list.rb
|
86
88
|
- lib/xero_gateway/address.rb
|
@@ -98,6 +100,7 @@ files:
|
|
98
100
|
- lib/xero_gateway/money.rb
|
99
101
|
- lib/xero_gateway/oauth.rb
|
100
102
|
- lib/xero_gateway/organisation.rb
|
103
|
+
- lib/xero_gateway/partner_app.rb
|
101
104
|
- lib/xero_gateway/payment.rb
|
102
105
|
- lib/xero_gateway/phone.rb
|
103
106
|
- lib/xero_gateway/private_app.rb
|
@@ -134,7 +137,7 @@ files:
|
|
134
137
|
- test/unit/tax_rate_test.rb
|
135
138
|
- test/unit/tracking_category_test.rb
|
136
139
|
- lib/xero_gateway/ca-certificates.crt
|
137
|
-
has_rdoc:
|
140
|
+
has_rdoc: true
|
138
141
|
homepage: http://github.com/tlconnor/xero_gateway
|
139
142
|
licenses: []
|
140
143
|
|
@@ -164,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
167
|
requirements: []
|
165
168
|
|
166
169
|
rubyforge_project:
|
167
|
-
rubygems_version: 1.
|
170
|
+
rubygems_version: 1.6.2
|
168
171
|
signing_key:
|
169
172
|
specification_version: 3
|
170
173
|
summary: Enables ruby based applications to communicate with the Xero API
|