Authentication and Apps Script

1,020 views
Skip to first unread message

Brendan Small

unread,
Sep 29, 2014, 5:25:53 PM9/29/14
to commcare-...@googlegroups.com
Hello,
I am trying to connect to the Forms API through Google Apps Script and can't seem to get through authentication. Any help would be great. This is what I am currently attempting to use:

function getFormInfo(formName) {
  
  //If not set, set name to Client_Visits_20130726 for testing.
  var settings, formName = formName || '[form_id]';
  
  settings = {
    user: '[user]',
    module: '[module]',
    password: '[password]',
    form: formName,
    headers: {
      contentType: 'application/json',
      headers: {
        Authorization: ''
      },
      validateHttpsCertificates: false,
      muteHttpExceptions: true
    }
  };
  
  settings.url =  settings.base  + settings.module  +  '/api/v0.5/form/' +  settings.form  ;
  settings.headers.headers.Authorization = 'Basic ' + Utilities.base64Encode(settings.user + ':' + settings.password);
  return settings;
}

Thanks,
Brendan

Cory Zue

unread,
Sep 29, 2014, 5:30:16 PM9/29/14
to commcare-developers
Hi Brendan,

Have you been able to successfully authenticate via the equivalent curl command with the same user/module/password?

Are you getting any additional information in the response?

thanks,
Cory

--

---
You received this message because you are subscribed to the Google Groups "CommCare Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to commcare-develo...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Craig A.

unread,
Sep 30, 2014, 3:44:26 AM9/30/14
to commcare-...@googlegroups.com
Hi Brendan,

I did something similar for Formhub. Make sure you run the URL fetch command within the UrlFetchApp.fetch() function. Test the basic authentication with www.hurl.it to see if you can at least authenticate then try it in GAS.

This repo is for formhub, but may be helpful for GAS interaction with CommCare.

There's also a working example of pulling all data in to a spreadsheet. Again, this is for formhub, but may be helpful for you :)

Please post an update when you get it working!

Sincerely,
Craig

Dave Greene

unread,
Oct 1, 2014, 9:05:43 AM10/1/14
to commcare-...@googlegroups.com
Hi Cory,

I'm working with Brendan on this issue and can give you more information if you need it.

It looks like the only API authentication method available is via Digest Authentication. Is that the case? If so, may I ask why? Digest Auth is difficult, to say the least, with JavaScript and, as we're finding, near impossible with Apps Script.

We'd like the opportunity to speak to someone regarding this issue as one of the reasons that we're actually paying for an account is to gain access to the API.

Thanks,
Dave
To unsubscribe from this group and stop receiving emails from it, send an email to commcare-developers+unsub...@googlegroups.com.

Cory Zue

unread,
Oct 1, 2014, 9:59:25 AM10/1/14
to commcare-developers
Hi Dave,

We can likely extend the APIs to support basic authentication. Which APIs are you using? Feel free to email commcareh...@dimagi.com with your exact request and someone on our team will follow up.

thanks,
Cory


To unsubscribe from this group and stop receiving emails from it, send an email to commcare-develo...@googlegroups.com.

Dave Greene

unread,
Oct 1, 2014, 2:04:06 PM10/1/14
to commcare-...@googlegroups.com
Hi Cory,

I'll get in touch with commcarehq support, but just to provide more information here in case anyone searches for this issue:

We're using Google Apps Script and, because it's JavaScript-ish, we're rolling our own call and response process to implement Digest Auth. Basically the process is this:
  1. Send a request to the API for a specific resource
  2. Capture returned headers (the WWW-Authenticate one, specifically.) The following are provided by the CommcareHQ server:
    • nonce
    • realm
    • algorithm
    • opaque
    • qop
    • stale
  3. Following the Digest Auth spec, we generate HA1 by MD5 hashing "username:realm:password" then converting the returned bytes to hex
  4. Generate HA2 by MD5 hashing "request_type:uri" then converting the returned bytes to hex
  5. Generate response by MD5 hashing "HA1:nonce:nonce_count:cnonce:qop:HA2" then converting the returned bytes to hex.
    • nonce_count is an arbitrary value that we set at "00000001". I've confirmed this is fine by running the same request via CURL and examining the headers.
    • cnonce is generated by Date().getTime().toString(16). From my reading, cnonce only needs to be a uniquely supplied value from the client.
  6. Construct the "Authorization" header:
    • Digest username="username", realm="[supplied by server]", nonce="[supplied by server]", uri="uri", cnonce="cnonce", nc=nc, qop="[supplied by server]", response="response", algorithm="[supplied by server]"
    • The text in bold (especially uri, cnonce, nc, and response) are references to variables discussed above.
  7. Send the request to the API for the same resource with the generated Authorization header
  8. This is where we'd expect a 200 response with the requested data. When using the exact same headers in CURL, it works. Instead we get the same 401.
Obviously there's an issue with either MD5 hashing on our end, the cnonce being interpreted on your end, or something else in the handshake on your end.

Basic Auth is absolutely the preferable method for us, so adding it to the API would be great.

Thanks,
Dave
To unsubscribe from this group and stop receiving emails from it, send an email to commcare-developers+unsubscribe...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Cory Zue

unread,
Oct 1, 2014, 9:14:58 PM10/1/14
to commcare-developers
Hi Dave,

Thanks. We got your ticket and will follow up soon after we've had a chance to scope out basic auth.

best,
Cory

To unsubscribe from this group and stop receiving emails from it, send an email to commcare-develo...@googlegroups.com.

Craig A.

unread,
Oct 2, 2014, 12:47:15 AM10/2/14
to commcare-...@googlegroups.com
Hi Dave,

Thanks for this write up. Could you share your working version of the script? I'll get to testing on my end.

These are some rough ideas: 
- Are you using the computeDigest Utility This utility also has a character encoding extension. I don't know if this should be UTF-8 as well.
- This isn't ideal, but you could use the form and case forwarding in CommCare to post the data to GAS. You would have to create a doPost(e) function in GAS to receive the POST command and then XML.parse() to a spreadsheet or HTML file on your Google Drive. If you go this route, you have to allow your GAS to be run anonymously because there is no authentication support for the case forwarding.

Sincerely,
Craig

--

---
You received this message because you are subscribed to a topic in the Google Groups "CommCare Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/commcare-developers/iHgVHw3Em5A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to commcare-develo...@googlegroups.com.

Dave Greene

unread,
Oct 2, 2014, 10:40:16 AM10/2/14
to commcare-...@googlegroups.com
Hi Craig,

Unfortunately the script doesn't work, even though theoretically it should.

We are using Utilities.computeDigest() to calculate the MD5 hash. Unfortunately it's just not working. My guess is that there's some kind of issue between the way your application is expecting the digest response vs the way that computeDigest() is calculating the hash.

I don't have the time to dive too deeply into this issue, so my absolute preference would be if you guys implemented basic auth.

Thanks,
Dave

--

---
You received this message because you are subscribed to a topic in the Google Groups "CommCare Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/commcare-developers/iHgVHw3Em5A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to commcare-developers+unsub...@googlegroups.com.

Cory Zue

unread,
Oct 2, 2014, 3:55:56 PM10/2/14
to commcare-developers
Hi Dave,

I'm pleased to announce that we just rolled out basic auth support for all APIs. Let us know if you have any problems.

Cory

To unsubscribe from this group and stop receiving emails from it, send an email to commcare-develo...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages