Working Example of oAuth and XERO

Questions and answers on developing, deploying and using plugins and JavaBeans

Working Example of oAuth and XERO

Postby d.pearce1417196993 » Sun Dec 28, 2014 7:13 pm

Hi,

does anyone have a few snippets of code for authenticating with XERO accounts with or without the oAuth plugin.

Just doing some XMAS research whilst I have some downtime. I see some people have tried this, but I think the code snippets available appear to be after the initial requesting of authentication.

It would be a great shortcut if anyone has a couple of routines to do the authentication and then a basic call to XERO.

Thanks in advance

David
d.pearce1417196993
 
Posts: 22
Joined: Fri Nov 28, 2014 7:49 pm

Re: Working Example of oAuth and XERO

Postby antonio » Thu Jan 08, 2015 2:01 pm

Hi David,

I use the oAuth plugin https://www.servoyforge.net/projects/oauth-plugin (but happy to be shown another way :-)

I've built methods for GET, POST and PUT, but you could collapse these into a generic method.
I'll post some examples of how I call these shortly.

Code: Select all
function OAuthXeroGET(vLive, vEndpoint, vAttributeName, vAccept) {
   try
   {
      if (!vAccept) // default to json for backwards compatability.
         vAccept = "json"
            
      vEndpoint = globals.UrlEncode(vEndpoint);
      plugins.oauth // initialise
      var oauth_api = OAuthAPI.XERO
      var client_id = vLive?gvClientId:gvClientIdDemo;
      var secret = vLive?gvSecret:gvSecretDemo   
      var resource_url = gvXeroURL + vEndpoint;
      var method = Methods.GET;
      var request = plugins.oauth.createOAuthRequest(oauth_api, client_id, secret, method);
      if (!request)
         throw "No request object returned"
      request.setResourceUrl(resource_url);
      request.setHeader("Accept","application/" + vAccept);
      request.execute();
      var response = request.getResponse();
      if (!response)
         return null

      if (vAccept == "xml" ||vAccept == "pdf")
      {
         var vContent = request.getResponse().getContent();
         return vContent
      }
      else if (vAccept == "json")
      {
         var vAttribute = response.getAttributeValue(vAttributeName)
         var json = eval('(' + vAttribute + ')')
         return json
      }
      else
         throw "OAuthXeroGET Unsupported content type " + vAccept
   }
   catch(e)
   {
      var vMsg = "OAuthXeroGET Error - " + e + "\nvEndpoint = " + vEndpoint + "\nvAttributeName = " + vAttributeName
      //...   
   }
}


Code: Select all
function OAuthXeroPOST(vLive, vEndpoint, vAttributeName, vXML, vAccept) {
   try
   {
      if (!vAccept) // XML in POST body, but want response as json for easy parsing.
         vAccept = "json";
      plugins.oauth // initialise
      var oauth_api = OAuthAPI.XERO
      var client_id = vLive?gvClientId:gvClientIdDemo;
      var secret = vLive?gvSecret:gvSecretDemo   
      var resource_url = gvXeroURL + vEndpoint;
      var method = Methods.POST;
      var request = plugins.oauth.createOAuthRequest(oauth_api, client_id, secret, method);
      request.setPostData("xml",vXML);
      request.setResourceUrl(resource_url);
      request.setHeader("Accept","application/" + vAccept);
      request.execute();
      var response = request.getResponse();
      if (!response)
         return null
      if (vAccept == "xml")
      {
         var vContent = request.getResponse().getContent();
         return vContent
      }
      else if (vAccept == "json")
      {
         var vAttribute = response.getAttributeValue(vAttributeName)
         var json = eval('(' + vAttribute + ')')
         return json
      }
      else
         throw "OAuthXeroPOST Unsupported content type " + vAccept
   }
   catch(e)
   {
      var vMsg = "OAuthXeroPOST Error - " + e + "\nvEndpoint = " + vEndpoint + "\nvAttributeName = " + vAttributeName + "\nvXML = " + vXML
      //...   
   }
}


Code: Select all
function OAuthXeroPUT(vLive, vEndpoint, vAttributeName, vXML, vAccept) {
   try
   {
      if (!vAccept)
         vAccept = "json"
      plugins.oauth // initialise
      var oauth_api = OAuthAPI.XERO
      var client_id = vLive?gvClientId:gvClientIdDemo;
      var secret = vLive?gvSecret:gvSecretDemo   
      var resource_url = gvXeroURL + vEndpoint;
      var method = Methods.PUT;
      var request = plugins.oauth.createOAuthRequest(oauth_api, client_id, secret, method);
      request.setPostData("xml",vXML);
      request.setResourceUrl(resource_url);
      request.setHeader("Accept","application/" + vAccept);      
      request.execute();
      var response = request.getResponse();
      if (!response)
         return null
      if (vAccept == "xml")
      {
         var vContent = request.getResponse().getContent();
         return vContent
      }
      else if (vAccept == "json")
      {
         var vAttribute = response.getAttributeValue(vAttributeName)
         var json = eval('(' + vAttribute + ')')
         return json
      }
      else
         throw "OAuthXeroPUT Unsupported content type " + vAccept
   }
   catch (e)
   {
      var vMsg = "OAuthXeroPUT Error - " + e + "\nvEndpoint = " + vEndpoint + "\nvAttributeName = " + vAttributeName + "\nvXML = " + vXML
      //...   
   }
}
Last edited by antonio on Sun Jan 11, 2015 11:27 pm, edited 2 times in total.
Tony
Servoy 8 - 2022.03 LTS
antonio
 
Posts: 638
Joined: Sun Apr 02, 2006 2:14 am
Location: Australia

Re: Working Example of oAuth and XERO

Postby jasantana » Fri Jan 09, 2015 12:24 am

Great stuff Antonio. Thank you very much. Just one question. Does the OAuth plugin works in SmartClient?
Thanks again
Best regards,
Juan Antonio Santana Medina
jasantana@nephos-solutions.co.uk
Servoy MVP 2015
Servoy 6.x - Servoy 7.x - Servoy 8.x - MySQL - PostgreSQL - Visual Foxpro 9
User avatar
jasantana
 
Posts: 555
Joined: Tue Aug 10, 2010 11:40 am
Location: Leeds - West Yorkshire - United Kingdom

Re: Working Example of oAuth and XERO

Postby antonio » Fri Jan 09, 2015 3:48 pm

Yes, I just tried the plugin in SC in Dev environment, it works fine.
Here's an example of how I use the above code.

Code: Select all
function GetXeroInvoiceByID(vID) {
   // ID can be invoice number or UUID
   if (!vID)
      return
   var vLive = true      
   var vEndpoint = 'Invoices/' + vID
   var vAttributeName = "Invoices" // the part of the XML we want to get back
   var vResponse = globals.OAuthXeroGET(vLive, vEndpoint, vAttributeName, "xml")
   return vResponse // xml invoice object
}

Tony
Servoy 8 - 2022.03 LTS
antonio
 
Posts: 638
Joined: Sun Apr 02, 2006 2:14 am
Location: Australia

Re: Working Example of oAuth and XERO

Postby jasantana » Sun Jan 11, 2015 9:16 pm

Thanks Antonio, we'll give a go to your samples
Best regards,
Juan Antonio Santana Medina
jasantana@nephos-solutions.co.uk
Servoy MVP 2015
Servoy 6.x - Servoy 7.x - Servoy 8.x - MySQL - PostgreSQL - Visual Foxpro 9
User avatar
jasantana
 
Posts: 555
Joined: Tue Aug 10, 2010 11:40 am
Location: Leeds - West Yorkshire - United Kingdom

Re: Working Example of oAuth and XERO

Postby antonio » Wed Nov 30, 2016 5:42 pm

For some years I've been using the oAuth plugin (date stamped 08 March 2015) with the examples in this thread to connect with Xero. It's been working well with Java 6 and Servoy 5.2.16
I recently had to upgrade to Java 7 for TLS compatibility, and now I get the following error (full error log below).

Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

I tried the latest (Servoy 8) version with my Servoy 5.2.16 solution, but it doesn't appear under plugins in the Eclipse solution explorer.

Grateful for any tips on getting an oAuth connection working again, either using the plugin or with some other method. I've not in a position to change the solution from Servoy 5.2.16 any time soon.

Tony

org.scribe.exceptions.OAuthConnectionException: There was a problem while creating a connection to the remote service.
at org.scribe.model.Request.send(Request.java:69)
at org.scribe.model.Request.send(Request.java:75)
at com.donay.oauth.responses.ResponseFactory.create(ResponseFactory.java:23)
at com.donay.oauth.requests.JSOAuthRequest2Legged.js_execute(JSOAuthRequest2Legged.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:179)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:353)
at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3666)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2680)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:166)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:387)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3135)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:165)
at com.servoy.j2db.scripting.ScriptEngine.executeFunction(ScriptEngine.java:476)
at com.servoy.j2db.FormController.executeFunction(FormController.java:4003)
at com.servoy.j2db.FormController.executeFunction(FormController.java:3891)
at com.servoy.j2db.FormController.executeFunction(FormController.java:3813)
at com.servoy.j2db.FormController$ScriptExecuter.executeFunction(FormController.java:3668)
at com.servoy.j2db.ui.BaseEventExecutor.fireEventCommand(BaseEventExecutor.java:272)
at com.servoy.j2db.ui.BaseEventExecutor.fireEventCommand(BaseEventExecutor.java:242)
at com.servoy.j2db.ui.BaseEventExecutor.fireChangeCommand(BaseEventExecutor.java:173)
at com.servoy.j2db.server.headlessclient.dataui.WebDataComboBox$3.execute(WebDataComboBox.java:446)
at com.servoy.j2db.server.headlessclient.ServoyForm.processDelayedActions(ServoyForm.java:84)
at com.servoy.j2db.server.headlessclient.dataui.WebEventExecutor.onEvent(WebEventExecutor.java:352)
at com.servoy.j2db.server.headlessclient.dataui.WebEventExecutor.onEvent(WebEventExecutor.java:341)
at com.servoy.j2db.server.headlessclient.dataui.ServoyFormComponentUpdatingBehavior.onUpdate(ServoyFormComponentUpdatingBehavior.java:65)
at org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior.onEvent(AjaxFormComponentUpdatingBehavior.java:158)
at org.apache.wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:177)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxBehavior.java:312)
at org.apache.wicket.request.target.component.listener.BehaviorRequestTarget.processEvents(BehaviorRequestTarget.java:157)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1279)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1358)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1465)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:486)
at com.servoy.j2db.server.servlets.Zl.doGet(Zl.java:7)
at org.apache.wicket.protocol.http.WicketServlet.doPost(WicketServlet.java:160)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:567)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Handshaker.java:470)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1438)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1308)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.scribe.model.Response.<init>(Response.java:28)
at org.scribe.model.Request.doSend(Request.java:115)
at org.scribe.model.Request.send(Request.java:65)
... 55 more

I also note a small change in syntax in the oAuth plugin examples on servoyforge -

Old code
Code: Select all
      plugins.oauth // initialise
      var oauth_api = OAuthAPI.XERO

New code

Code: Select all
   var oauth_api = plugins.oauth.OAuthAPI.XERO;

Is that correct?
Tony
Servoy 8 - 2022.03 LTS
antonio
 
Posts: 638
Joined: Sun Apr 02, 2006 2:14 am
Location: Australia

Re: Working Example of oAuth and XERO

Postby sbutler » Wed Nov 30, 2016 6:41 pm

That old code seems like it would never have worked. You can set a variable and do something similar, but this is essentially the same as the new code you have. The new code seems like it would be correct.

Code: Select all
var oauth = plugins.oauth;
var oauth_api = oauth.OAuthAPI.XERO;


Same as:

Code: Select all
var oauth_api = plugins.oauth.OAuthAPI.XERO;
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 759
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: Working Example of oAuth and XERO

Postby antonio » Wed Nov 30, 2016 11:09 pm

thanks Scott, the new syntax does look better, but the old code worked fine, and curiously didn't work with out the initialize line.
Tony
Servoy 8 - 2022.03 LTS
antonio
 
Posts: 638
Joined: Sun Apr 02, 2006 2:14 am
Location: Australia


Return to Plugins and Beans

Who is online

Users browsing this forum: No registered users and 10 guests