Roles in Sync Gateway are often overlooked because they seem more complex to use than Users and Channels. However, they provide one additional layer of abstraction and can greatly simplify your data model. Take the example of an application to share reviews of restaurants by city. Different users could have different privileges such as moderators and guest users. In this tutorial, you will configure the Sync Function to allow authenticated users of such an application to approve, post reviews or assign roles to other users.

In total, there will be 3 types of roles in the application:

  • level-1: users with the level-1 role can post reviews but they must be accepted by users with the level-3 role (i.e. moderators) to be public.
  • level-2: users can post reviews without validation needed from moderators. This means they can post a comment without requiring an approval.
  • level-3: users can approve reviews or reject them.

    Let’s get started!

Download Sync Gateway

Download Sync Gateway and unzip the file:

http://www.couchbase.com/nosql-databases/downloads#Couchbase_Mobile

You will find the Sync Gateway binary in the bin folder and examples of configuration files in the examples folder. Copy the users-role.json file to the root of your project:

In the next section, you will update the configuration file to create users and roles.

Editing the Config File

In sync-gateway-config.json, update the db object to read:

A couple of things are happening above:

  1. You create the user jens with the level-1 role.
  2. You create the user andy with the level-2 role.
  3. You create the user william without any role.
  4. You create the user traun with the level-3 role.
  5. You define the 3 roles. Just like users, roles must be explicitly created on the Admin REST API or in the config file.

Note on creating roles

The easiest way to create roles is in the configuration file as you did above.

Another way to create roles is through the admin REST API. Provided that you expose an endpoint to create those roles from the application, you can create roles dynamically by sending a request to your app server (blue arrows) which will create the role and send back a 201 Created if it was successful (green arrows).

In the next section, you will add the Sync Function to handle write and read operations for the three different types of documents (restaurant, review, profile).

Adding the Sync Function

Roles and users can both be granted access to channels. Users can be granted roles, and inherit any channel access for those roles.

Channel access determines a user’s read security. Write security can also be based on channels (using requireAccess), but can also be based on user/role (requireUser and requireRole), or document content (using throw).

Read and write access to documents are independent. In fact write access is entirely governed by your sync function: unless the sync function rejects the revision, a client can modify any document. All the require* functions act as validators but also write access APIs.

It’s very common to see sync function creating lots and lots of channels. This is absolutely fine. However, it can get cumbersome to assign each user in turn to a channel. Instead you can use a role!

Let this sink in one more time, users can be granted roles and inherit any channel access for those roles.

This means you can grant a user access to multiple channels by simply assigning a role. This is very powerful because you don’t need to assign every single user to a channel. You simply grant the role access to the channel and assign the users to the role.

With that in mind, replace the sync function in sync-gateway-config.json:

Here’s what’s happening:

  1. Users with the level-1 role have write access because you call the channel function. Then grant that user and the level-3 access to this channel. This is where the power of roles really shines. By granting a role access, you are granting all the users with that role access to the channel. The call to requireRole will grant the write permission.
  2. Documents of type review created by a level-2 role: the document should go in the same channel as the restaurant it belongs to. The call to requireRole will grant the write permission.
  3. Documents of type review created by a level-3 role: the document should go in the channel for that restaurant. level-3 users also have read access to all the {user_name}-in-review channels. They can approve/reject the pending reviews of other users.

Start Sync Gateway with the updated configuration file:

In this example, you are utilising the 3 main features of roles:

  • Granting a role access to a channel and indirectly to all the users with that role.
  • Granting write permission using a requireRole.
  • Assigning a role to a user.

Now you can test the Sync Function behaves as expected with the following HTTP requests.

Running Different Scenarios

Scenario 1

Documents of type review created by a level-1 user: the document should go in the {user_name}-in-review channel and the users with the level-3 role should have access to this channel too.

Login as the user jens:

Save a new document of type review (substitute the token with the one returned in the Set-Cookie header above):

  • Check that user jens has access to the channel jens-in-review and the comment document is in there.

  • Check that user traun has access to channel jens-in-review.

You can also view the channels this document belongs to and roles/users that have access to it in the Documents tab:

Scenario 2

Granting write access using a role.

Login as andy and replace the token with the one you got back from the login request.

  • Check that the comment was added to the restaurant channel (named 123 in this example).

Scenario 3

Assigning a role to a user.

Login as traun and replace the token with the one you got back from the login request.

  • Check that william has role level-3.
  • Check that william has access to the jens-in-review channel.

Conclusion

In this tutorial, you learnt how to use channels and requireRole to dynamically validate and perform write operations. You also assigned multiple channels at once to multiple users using the role API.

Posted by James Nocentini, Technical Writer, Mobile, Couchbase

James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.

Leave a reply