xero_gateway 2.0.12 → 2.0.13
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.
- 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
|