Skip to content

How access() calls work

snej edited this page Sep 19, 2014 · 1 revision

The sync function calls access("bob", "ABC"), and now user bob has access to channel ABC. How is this implemented? It's actually a fairly complex process.

The first part happens when the document is updated:

  1. App sync function calls access()
  2. Implementation of access (in channels.addValueForUser) remembers this user-to-channel mapping
  3. db.getChannelsAndAccess collects and returns a channels.AccessMap that contains all of the channel access grants made by the sync function
  4. The document's _sync/access property is updated with a JSON translation of this map (db.updateDoc, around crud.go:571)
  5. bob's account doc is updated to invalidate its channel membership (db.invalUserOrRoleChannels)

At some point in the near future when Couchbase Server's view indexer runs:

  1. The updated document is fed to the sync_gateway/access view's map function
  2. The map function (defined near database.go:247) iterates the doc's _sync/access property and emits a row for each user-to-channel-set pair. That is, it will emit a row whose key is "bob" and whose value is a dictionary that maps each channel name to the sequence when that channel was granted, e.g. {"ABC": 1337} assuming the doc update was sequence 1337.

The next time bob sends a request (or immediately, if bob's client has an active changes feed):

  1. auth.getPrincipal loads bob's account into a User object, and notices the invalidated channel membership
  2. It calls auth.rebuildChannels, which calls db.ComputeChannelsForPrincipal to rebuild the channel membership
  3. This queries the sync_gateway/access view; the only key queried is "bob". The resulting rows' values are the access grants made to bob by each document in the database, including the one from the doc updated in this example. db.ComputeChannelsForPrincipal merges all these dictionaries together to determine the aggregate access granted to bob by all documents in the database, and returns it.
  4. Back in auth.rebuildChannels , this mapping is in turn merged with the channels explicitly assigned to bob by the admin API, and stored into bob's account document and User object.
  5. The code handling bob's HTTP request now sees the up-to-date list of bob's channels and can authenticate that a request to channel ABC is valid.

If this document is later updated, the same thing happens again. If the new revision stops granting bob access to ABC (and no other document still grants access), the ComputeChannelsForPrincipal method will rebuild the aggregate channel set, which now won't include ABC since no document emitted it into the view.

Clone this wiki locally