-
Notifications
You must be signed in to change notification settings - Fork 138
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:
- App sync function calls
access()
- Implementation of
access
(inchannels.addValueForUser
) remembers this user-to-channel mapping -
db.getChannelsAndAccess
collects and returns achannels.AccessMap
that contains all of the channel access grants made by the sync function - The document's
_sync/access
property is updated with a JSON translation of this map (db.updateDoc
, around crud.go:571) -
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:
- The updated document is fed to the
sync_gateway/access
view's map function - 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):
-
auth.getPrincipal
loadsbob
's account into aUser
object, and notices the invalidated channel membership - It calls
auth.rebuildChannels
, which callsdb.ComputeChannelsForPrincipal
to rebuild the channel membership - This queries the
sync_gateway/access
view; the only key queried is"bob"
. The resulting rows' values are the access grants made tobob
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 tobob
by all documents in the database, and returns it. - Back in
auth.rebuildChannels
, this mapping is in turn merged with the channels explicitly assigned tobob
by the admin API, and stored intobob
's account document andUser
object. - The code handling
bob
's HTTP request now sees the up-to-date list ofbob
's channels and can authenticate that a request to channelABC
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.