Sample code for 30+ languages & platforms
Ruby Requires Chilkat v11.0.0+

Xero API through an SSH Tunnel

This example demonstrates connecting through an SSH Tunnel w/ 2-legged OAuth for a Xero private application.

Chilkat Ruby Downloads

Ruby
require 'chilkat'

success = false

#  This example requires the Chilkat API to have been previously unlocked.
#  See Global Unlock Sample for sample code.

tunnel = Chilkat::CkSocket.new()

sshHostname = "sftp.example.com"
sshPort = 22

#  Connect to an SSH server and establish the SSH tunnel:
success = tunnel.SshOpenTunnel(sshHostname,sshPort)
if (success == false)
    print tunnel.lastErrorText() + "\n";
    exit
end

#  Authenticate with the SSH server via a login/password
#  or with a public key.
#  This example demonstrates SSH password authentication.
success = tunnel.SshAuthenticatePw("mySshLogin","mySshPassword")
if (success == false)
    print tunnel.lastErrorText() + "\n";
    exit
end

#   OK, the SSH tunnel is setup.  Now open a channel within the tunnel.
#   (Any number of channels may be created from the same SSH tunnel.
#   Multiple channels may coexist at the same time.)

#  This sample code would typically be placed in a subroutine or function
#  where the rest object is passed by reference.
#  It does the OAuth1 setup and makes the initial connection.
rest = Chilkat::CkRest.new()

bTls = true
port = 443
maxWaitMs = 7000

#  This returns a socket object that is a single channel within the SSH tunnel.
channel = Chilkat::CkSocket.new()
success = tunnel.SshNewChannel("api.xero.com",port,bTls,maxWaitMs,channel)
if (success == false)
    print tunnel.lastErrorText() + "\n";
    exit
end

#  Use the connection.  (This connection is a TLS running on an SSH channel through an SSH tunnel.
#  In other words, TLS is wrapped within the SSH tunnel.)
success = rest.UseConnection(channel,true)
if (success == false)
    print rest.lastErrorText() + "\n";
    exit
end

#  OK, we're connected.  
#  -----------------------------------------------------------------
#  Now setup the OAuth1 authenticator..

consumerKey = "XERO_PRIVATE_APP_KEY"
consumerSecret = "XERO_PRIVATE_APP_SECRET"

#  Let's get our private key from our PFX (password protected), or the PEM (unprotected).
#  You can decide which to use.  Either is OK, although I would recommend keeping your
#  private keys in a PFX and not in an unprotected PEM.
pfx = Chilkat::CkPfx.new()
success = pfx.LoadPfxFile("qa_data/certs/xero_private_app/public_privatekey.pfx","PFX_PASSWORD")
if (success == false)
    print pfx.lastErrorText() + "\n";
    exit
end

privKeyFromPfx = Chilkat::CkPrivateKey.new()
success = pfx.PrivateKeyAt(0,privKeyFromPfx)
if (success == false)
    print pfx.lastErrorText() + "\n";
    exit
end

#  Or we can load from a PEM..
privKeyFromPem = Chilkat::CkPrivateKey.new()
success = privKeyFromPem.LoadPemFile("qa_data/certs/xero_private_app/privatekey.pem")
if (success == false)
    print privKeyFromPem.lastErrorText() + "\n";
    exit
end

#  Note: There are many other means for loading a private key, including
#  from other formats and directly from memory (i.e. not file-based).

oauth1 = Chilkat::CkOAuth1.new()
oauth1.put_ConsumerKey(consumerKey)
oauth1.put_ConsumerSecret(consumerSecret)
oauth1.put_Token(consumerKey)
oauth1.put_TokenSecret(consumerSecret)
oauth1.put_SignatureMethod("RSA-SHA1")
oauth1.SetRsaKey(privKeyFromPfx)

#  Install the OAuth1 authenticator.
rest.SetAuthOAuth1(oauth1,false)

print "OK, the Xero OAuth1 is initialized and the REST object is ready to make REST API calls.." + "\n";

#  -----------------------------------------------------------------
#  Make a call to verify that OAuth1 through an HTTP proxy works..

#  Get the full list of contacts.
sbXml = Chilkat::CkStringBuilder.new()
success = rest.FullRequestNoBodySb("GET","/api.xro/2.0/Contacts",sbXml)
if (success == false)
    print rest.lastErrorText() + "\n";
    exit
end

#  A 200 response is expected for actual success.
if (rest.get_ResponseStatusCode() != 200)
    print sbXml.getAsString() + "\n";
    exit
end

#  Iterate over the contacts..
bAutoTrim = false
xml = Chilkat::CkXml.new()
xml.LoadSb(sbXml,bAutoTrim)
xml.SaveXml("qa_cache/xero_contacts.xml")

#  How many records exist?
recordCount = xml.NumChildrenAt("Contacts")
print "numRecords = " + recordCount.to_s() + "\n";

i = 0
while i < recordCount
    xml.put_I(i)
    print "ContactID: " + xml.getChildContent("Contacts|Contact[i]|ContactID") + "\n";
    i = i + 1
end