Managing syncs between databases with different permissions

Viewed 102

I am building an app using pouchdb and couchdb. The structure is that each user has its own database (I have activated per user option).

Then, to simplify let say there is a database that aggregates data for all users, a location database.

This database syncs with user databases.

For each user database, the user has role admin.

The location database, has an admin user as admin. Regular users are not added as admin to this database. Each document has a userId attribute. The sync between userdb and locationdb will be filtered by userID.

Now, when I login in the app as user, I have permissions to launch the sync between let say localdb on pouchdb and userdb on couchdb. Since user is admin on userdb. So far so good.

var remoteUser =
      new PouchDB(
        'https://domain:6984/' + 'userdb-' + hex,
        {
          auth: {
            username: 'user',
            password: 'password'
          }
        }
      )
    db.replicate.from(remoteUser).on('complete', function () {
      db.sync(remoteUser, { live: true, retry: true })
        .on('change', function (info) {
          dispatch('syncPrintQueue')
          console.log('sync remote user')
        }).on('pause', function () {
          console.log('user remote syncing done')
        })
    })

But then from the app I want to sync userdb to locationdb. As user I cannot do that. So I add auth as admin. And now I can launch the sync.

  var remoteLocation =
          new PouchDB(
            'https://domain:6984/' + 'locationdb-' + locationHex,
            {
              auth: {
                username: 'admin',
                password: 'password'
              }
            }
          )

        remoteUser.replicate.from(remoteLocation).on('complete', function () {
          remoteUser.sync(remoteLocation, {
            live: true,
            retry: true
          })
            .on('change', function (info) {
              console.log('location remote syncing ')
            }).on('pause', function () {
              console.log('location remote syncing done')
            })
        })
        dispatch('syncCompany', remoteLocation)
      },

The problem is that now im logged in as admin in the current session.

What I am doing right now is store user info on localStorage right after login. And I use that for filtering or validating on couch. Instead of user returned from checking current session. Which would allow me to correctly filter server side.

Adding each user to the general database as admin is not an option. So the only idea I have is to move all the syncs and authorizations to a middleware in say rails or node.

Is there a solution within couchdb to manage this situation?

1 Answers

The standard persistent replication generally didn't scale to replicating infrequent updates from (or to) many databases. It has been improving with support for cycling through many permanent replications using a scheduler, so you could look at that to see if it is currently sufficient.

The interim solution has been the spiegel project which has listener processes that observe the _global_changes feed and match database names by regex pattern to identify which source databases have changed and need to be re-examined by one of its change or replicator processes.

Related