Hello again everyone, and thanks for all of your detailed and enthusiastic responses. My thought with prioritizing "Offline-capable, multi-submission surveys done by enumerators" as the first thing to tackle is that it would actually require minimal work (and hopefully be broadly useful). @issa, I'll outline my understanding below—please let me know if I make any missteps.
ODK Central is already an OpenRosa server supporting one OpenRosa client (ODK Collect), and my approach would be to treat Enketo as simply another OpenRosa client. Where Central seems to differ from other OpenRosa servers is that usernames and passwords are not used at all; instead, each "App User" authenticates with a unique URL made hard-to-guess by containing a 64-byte token.
Just as ODK Collect does, Enketo could interact with unique formList
and submission
URLs provided by ODK Central for each App User, forgoing usernames and passwords. Enketo would, in turn, generate its own unique, token-containing URLs: one per form per App User. For example, assuming all the forms are in the same project (ID 1
):
Form |
App User |
Central OpenRosa URL Prefix |
Enketo URL |
Well Pumps |
Meredith |
https://central/v1/key/{meredith-random-key}/projects/1/ |
https://enketo/::{meredith-well-pumps-random-key} |
Well Pumps |
Jorge |
https://central/v1/key/{jorge-random-key}/projects/1/ |
https://enketo/::{jorge-well-pumps-random-key} |
Well Pumps |
Ricki |
https://central/v1/key/{ricki-random-key}/projects/1/ |
https://enketo/::{ricki-well-pumps-random-key} |
Cisterns |
Ricki |
https://central/v1/key/{ricki-random-key}/projects/1/ |
https://enketo/::{ricki-cisterns-random-key} |
The workflow would be something like this:
- The system administrator of the ODK Central instance configures an Enketo URL and API key for use by the entire instance;
- [UX help, please!] ODK Central provides a UI element to retrieve an Enketo data-collection URL. This would be similar to "See code" in the "Configure Client" column of the App Users list, but there must be a way to select a particular form in addition to an App User;
- Once an App User and form have been selected, ODK Central
POST
s that App User's token-containing OpenRosa URL and the <formID>
of the form to the appropriate Enketo endpoint;
- Enketo stores the form and the OpenRosa URL in its Redis database, associating them with a unique key;
- Enketo returns a URL containing that unique key;
- ODK Central displays this URL;
- The project manager communicates that URL to the enumerator;
- The enumerator uses this URL to enter data and submits an instance;
- Enketo receives the submission and forwards it to Central's OpenRosa
submission
endpoint for this particular enumerator, which was stored in Enketo's Redis DB;
- Central recognizes the OpenRosa URL as containing a valid App User token and accepts the submission.
To respond to a few specific questions:
I propose that (at first) ODK Central does not ship Enketo at all. Instead, use of Enketo would be entirely optional, and the administrator of a Central instance could use any Enketo server reachable via HTTPS. Enketo already runs well in a Docker container, so savvy folks could set up Enketo immediately alongside their Central instance. If later there's a desire to include Enketo along with Central in a more streamlined way, I could help with the Docker aspect of that.
Central trusts that it can send blank forms and App User tokens to a particular Enketo that's been explicitly configured by the Central administrator. Central requires the Enketo server to use HTTPS with a certificate from a trusted authority to frustrate MITM and eavesdropping attempts. Central allows an instance to be submitted when it's POST
ed to a valid, token-containing OpenRosa submission
URL, no matter whether the client is Enketo or ODK Collect.
This sounds like it could be fun, but I'd like to avoid relying on anything but HTTPS over public interfaces. I may want to run my own Central but connect it to someone else's Enketo, or I might need a distributed cluster of Centrals and Enketos using something other than Docker's swarm mode.
Thanks for reading