DataFlex Requires Chilkat v11.0.0+
DataFlex
Xero API through an SSH Tunnel
This example demonstrates connecting through an SSH Tunnel w/ 2-legged OAuth for a Xero private application.Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Handle hoTunnel
String sSshHostname
Integer iSshPort
Handle hoRest
Boolean iBTls
Integer iPort
Integer iMaxWaitMs
Variant vChannel
Handle hoChannel
String sConsumerKey
String sConsumerSecret
Handle hoPfx
Variant vPrivKeyFromPfx
Handle hoPrivKeyFromPfx
Handle hoPrivKeyFromPem
Variant vOauth1
Handle hoOauth1
Variant vSbXml
Handle hoSbXml
Boolean iBAutoTrim
Handle hoXml
Integer iRecordCount
Integer i
String sTemp1
Integer iTemp1
Move False To iSuccess
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
Get Create (RefClass(cComChilkatSocket)) To hoTunnel
If (Not(IsComObjectCreated(hoTunnel))) Begin
Send CreateComObject of hoTunnel
End
Move "sftp.example.com" To sSshHostname
Move 22 To iSshPort
// Connect to an SSH server and establish the SSH tunnel:
Get ComSshOpenTunnel Of hoTunnel sSshHostname iSshPort To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoTunnel To sTemp1
Showln sTemp1
Procedure_Return
End
// Authenticate with the SSH server via a login/password
// or with a public key.
// This example demonstrates SSH password authentication.
Get ComSshAuthenticatePw Of hoTunnel "mySshLogin" "mySshPassword" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoTunnel To sTemp1
Showln sTemp1
Procedure_Return
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.
Get Create (RefClass(cComChilkatRest)) To hoRest
If (Not(IsComObjectCreated(hoRest))) Begin
Send CreateComObject of hoRest
End
Move True To iBTls
Move 443 To iPort
Move 7000 To iMaxWaitMs
// This returns a socket object that is a single channel within the SSH tunnel.
Get Create (RefClass(cComChilkatSocket)) To hoChannel
If (Not(IsComObjectCreated(hoChannel))) Begin
Send CreateComObject of hoChannel
End
Get pvComObject of hoChannel to vChannel
Get ComSshNewChannel Of hoTunnel "api.xero.com" iPort iBTls iMaxWaitMs vChannel To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoTunnel To sTemp1
Showln sTemp1
Procedure_Return
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.)
Get pvComObject of hoChannel to vChannel
Get ComUseConnection Of hoRest vChannel True To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoRest To sTemp1
Showln sTemp1
Procedure_Return
End
// OK, we're connected.
// -----------------------------------------------------------------
// Now setup the OAuth1 authenticator..
Move "XERO_PRIVATE_APP_KEY" To sConsumerKey
Move "XERO_PRIVATE_APP_SECRET" To sConsumerSecret
// 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.
Get Create (RefClass(cComChilkatPfx)) To hoPfx
If (Not(IsComObjectCreated(hoPfx))) Begin
Send CreateComObject of hoPfx
End
Get ComLoadPfxFile Of hoPfx "qa_data/certs/xero_private_app/public_privatekey.pfx" "PFX_PASSWORD" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPfx To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatPrivateKey)) To hoPrivKeyFromPfx
If (Not(IsComObjectCreated(hoPrivKeyFromPfx))) Begin
Send CreateComObject of hoPrivKeyFromPfx
End
Get pvComObject of hoPrivKeyFromPfx to vPrivKeyFromPfx
Get ComPrivateKeyAt Of hoPfx 0 vPrivKeyFromPfx To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPfx To sTemp1
Showln sTemp1
Procedure_Return
End
// Or we can load from a PEM..
Get Create (RefClass(cComChilkatPrivateKey)) To hoPrivKeyFromPem
If (Not(IsComObjectCreated(hoPrivKeyFromPem))) Begin
Send CreateComObject of hoPrivKeyFromPem
End
Get ComLoadPemFile Of hoPrivKeyFromPem "qa_data/certs/xero_private_app/privatekey.pem" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoPrivKeyFromPem To sTemp1
Showln sTemp1
Procedure_Return
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).
Get Create (RefClass(cComChilkatOAuth1)) To hoOauth1
If (Not(IsComObjectCreated(hoOauth1))) Begin
Send CreateComObject of hoOauth1
End
Set ComConsumerKey Of hoOauth1 To sConsumerKey
Set ComConsumerSecret Of hoOauth1 To sConsumerSecret
Set ComToken Of hoOauth1 To sConsumerKey
Set ComTokenSecret Of hoOauth1 To sConsumerSecret
Set ComSignatureMethod Of hoOauth1 To "RSA-SHA1"
Get pvComObject of hoPrivKeyFromPfx to vPrivKeyFromPfx
Get ComSetRsaKey Of hoOauth1 vPrivKeyFromPfx To iSuccess
// Install the OAuth1 authenticator.
Get pvComObject of hoOauth1 to vOauth1
Get ComSetAuthOAuth1 Of hoRest vOauth1 False To iSuccess
Showln "OK, the Xero OAuth1 is initialized and the REST object is ready to make REST API calls.."
// -----------------------------------------------------------------
// Make a call to verify that OAuth1 through an HTTP proxy works..
// Get the full list of contacts.
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbXml
If (Not(IsComObjectCreated(hoSbXml))) Begin
Send CreateComObject of hoSbXml
End
Get pvComObject of hoSbXml to vSbXml
Get ComFullRequestNoBodySb Of hoRest "GET" "/api.xro/2.0/Contacts" vSbXml To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoRest To sTemp1
Showln sTemp1
Procedure_Return
End
// A 200 response is expected for actual success.
Get ComResponseStatusCode Of hoRest To iTemp1
If (iTemp1 <> 200) Begin
Get ComGetAsString Of hoSbXml To sTemp1
Showln sTemp1
Procedure_Return
End
// Iterate over the contacts..
Move False To iBAutoTrim
Get Create (RefClass(cComChilkatXml)) To hoXml
If (Not(IsComObjectCreated(hoXml))) Begin
Send CreateComObject of hoXml
End
Get pvComObject of hoSbXml to vSbXml
Get ComLoadSb Of hoXml vSbXml iBAutoTrim To iSuccess
Get ComSaveXml Of hoXml "qa_cache/xero_contacts.xml" To iSuccess
// How many records exist?
Get ComNumChildrenAt Of hoXml "Contacts" To iRecordCount
Showln "numRecords = " iRecordCount
Move 0 To i
While (i < iRecordCount)
Set ComI Of hoXml To i
Get ComGetChildContent Of hoXml "Contacts|Contact[i]|ContactID" To sTemp1
Showln "ContactID: " sTemp1
Move (i + 1) To i
Loop
End_Procedure