colinskow / superlogin

Powerful authentication for APIs and single page apps using the CouchDB ecosystem which supports a variety of providers.
MIT License
370 stars 116 forks source link

Accessing private databases across multiple sessions #159

Open markdturner opened 7 years ago

markdturner commented 7 years ago

I'm trying to develop a system where each user stores documents in their own private database. To do this I use the handy Superlogin feature in the config to create a private database at user creation time that belongs to an individual user. However, I'm confused by this line in the documentation:

You can also use the same token and password combination to access your personal database. But as soon as you log out your session that access will be revoked.

This would imply that the user only has access to their private database with the session that gets generated when the user is created. If the user were to log out and log back in, they'd have a different session and therefore not be able to access their own private database. Is that how it works? Or am I missing something?

peteruithoven commented 7 years ago

I've been looking into how this works myself in the last week. One thing to keep in your mind is that Superlogin supports two security models, CouchDB's and Cloudant model. Which one are you using? (this is set in the superlogin config dbServer.cloudant)

How I understand it in regards to Cloudant is that on login a session is created, a part of that is that one API key is generated that is added to each database('s _security doc) that user has access to. These databases are listed in the userDoc's personalDBs. This list is updated on login according to the superlogin config (userDBs.defaultDBs). You can view these api keys and their permissions on the Permissions page. When a user logs out the session and API key is removed. When a user logs in again this process is simply repeated. More info: https://console.ng.bluemix.net/docs/services/Cloudant/api/authorization.html

With the CouchDB model the session is added to the members.names. More info: http://docs.couchdb.org/en/1.6.1/intro/security.html#authentication-database

You might find my questions on this topic interesting in the following issue: https://github.com/colinskow/superlogin/issues/152

So long story short, they will regain access to their private or shared databases when they login.

markdturner commented 7 years ago

Thanks for the detailed response @peteruithoven, the responses on the other thread are helpful too.

I'm using CouchDB's model, with a sort of ownership model on some databases. A user has a private database that they have admin priveledges on. They can add other users to that database as members, allowing them to read and write documents. At some point in the future, the admin could revoke access for a member.

Superlogin doesn't have a method in it's API to do that last bit of adding and removing members from a database, so I'll have to do that using the CouchDB API.

peteruithoven commented 7 years ago

Sounds like an interesting challenge. I'm not sure, I'd look into the superlogin's addUserDB function. I see this will add databases to the userDoc's personalDBs. I also think I was wrong earlier, I think the userDoc's personalDBs gets updated according to the config but in the end the user is authenticated to all the personalDB's in userDoc's personalDBs.

markdturner commented 7 years ago

Good tip on using the addUserDB function @peteruithoven - I've got my add/remove members logic working but have a problem with refreshing sessions. If a user has a new database added to their personalDBs using addUserDB, their session doesn't get added to the _security design document of the database until the next time the user logs in. Have you got any ideas how I could force this to happen immediately after addUserDB?

peteruithoven commented 7 years ago

I'm thinking this should happen when you add it. dbauth/index.js's addUserDB is called, which then calls couchdb.js's authorizeKeys, looks like at that point the key should be added to the _security document's members.names array. Maybe you could add some console.log's, see if that actually happens?

markdturner commented 7 years ago

I've traced it as far as the point it persists the updated _security document and everything seems to be fine, that call returns a 200 response. However when I get the security design document immediately after or view it in Fauxton the newly added sessions are not there!

The only thing I can think of is some sort of bug in PouchDB that is causing it not persist changes to the design document.

peteruithoven commented 7 years ago

Damn. Any change at some point the wrong _rev is queried? I didn't understand the db.request part, I understand now it's usage is controversial: https://github.com/pouchdb/pouchdb/issues/3525 So that might be an interesting read.

micky2be commented 7 years ago

It's open to debate but I would suggest to use superlogin only for pure auth and session management, and write something custom for your data base rights and management.