hoodiehq / hoodie-server

:dog: Hapi plugin for Hoodie’s server core module
Apache License 2.0
244 stars 48 forks source link

Cloudant vendor configuration #515

Closed jameswestnz closed 7 years ago

jameswestnz commented 7 years ago

As per https://github.com/hoodiehq/hoodie-server/issues/514, Cloudant doesn't allow access to the /_config endpoint, so hoodie is currently not compatible.

This PR aims to resolve Cloudant incompatibility.

jameswestnz commented 7 years ago

Just an FYI at this point - I'm yet to test other features such as actually adding accounts etc. Looking into that now!

jameswestnz commented 7 years ago

So a bit of a road-block... https://twitter.com/jameswestnz/status/786049377336823808

Adding a user works perfectly - except Cloudant doesn't respond in a timely manor, so the request fails. I'm talking to Cloudant support at present hoping there is a solution. If they don't have an easy answer, we may need to put this on hold...

gr2m commented 7 years ago

A good way to test things is to clone the [hoodie-app-tracker]() repository, run npm install in it, then npm link hoodie-server into it. Make sure you use npm v3 because of the flat install.

Once you have that, run npm start -- --dbUrl=https://user:password@cloudantdburl.com to see if the app starts. If it does, run npm test -- --dbUrl=https://user:password@cloudantdburl.com. It runs acceptance tests using selenium. If they all pass we should be good. Server & Selenium logs are going into log/* files

gr2m commented 7 years ago

I was thinking a bit more about this. We put a lot of effort into moving CouchDB-specific logic around user accounts and authentication into Hoodie to be more flexible, mostly in terms of using PouchDB with different adapters as a backend.

Now with the /_config APIs not being supported by CouchDB-compatible hosters, I wonder if we should work around that as well? All we need right now is a server secret that we use to sign session IDs. We might need or want to store admin accounts in future but don’t have to right now, so we can probably get rid of it.

I wonder if we should create a custom database like hoodie-server-store does (it creates hoodie-store to keep track of databases & replications) in which we store a document with "_id": "config" and store all the things in there? The benefit would be that we then could do the exact same thing, no matter if CouchDB or PouchDB in the backend. Currently we create a JSON config file for PouchDB instead.

What do you think?

jameswestnz commented 7 years ago

A slight update for getting the authentication_db property - it is available when requesting GET /_session, although this assume you're using cookie auth. I'm not sure this is a solution yet.

Agree with you on your thoughts on the custom database. I'm reading through Cloudant's docs to see if there's any other work-around, will post back here soon :)

jameswestnz commented 7 years ago

So after some research, I think that your approach may be the best moving forward - as you say, it's inline with what Hoodie has done with hoodie-store-server, and in theory means that we may have less issues with future providers doing things differently again.

To recap, here's what's stopping hoodie from working (with Cloudant) at present:

  1. No access to the /_config endpoint on some providers (specifically Cloudant here) which means we cannot access some required information - specifics follow.
  2. We cannot access authentication_db to determine where users are stored.
  3. We cannot access secret, so we cannot hash user passwords using couchdb-calculate-session-id - with a null value, passwords would still be calculated, but not securely.
  4. We cannot access admins - I'm not 100% sure on how this is used at present?

Although I mentioned that @gr2m's solution may be the best, there is another option...

My breakdown above is leading me to think that this information could be configured in hoodie's main config file (or passed to @hoodie/server as an object). If the required information isn't found, then we try to extract from couchdb. If on start we can't find the information from either of those sources, we'd throw an error letting the user know we can't configure CouchDB.

This approach would reduce the amount of database lookups we need to do to simply start hoodie. The catch being that someone wanting to use a 3rd party CouchDB provider (such as Cloudant) will likely need to have a few more properties in their hoodie config to get started.

gr2m commented 7 years ago

Gave this some more thought today. We can get rid of these, they are no longer relevant

Instead of using couch_httpd_auth.secret we should create a server secret and store it in .hoodierc unless its set as ENV variable, we could do that during setup which is run in postinstall. For hapi usage, the server secret would be another option that we would pass.

What I’m conflicted about is admins. To keep things simple, one admin password is enough for now. It should be changeable in production while the app is running, so I think the right place to store it is the database. Probably the simplest thing would be this:

The first time a user opens /hoodie/admin a form is shown to set the admin password. For security reasons, the server secret must be provided, too. The admin user will be stored with normal user accounts in the users database, only difference would be an admin role.

Thoughts?

gr2m commented 7 years ago

We are now compatible with Cloudant via https://github.com/hoodiehq/hoodie/releases/tag/v26.0.0 🎉 Please give it a try!

I plan to write a short blog post on it next week to make it official :)