why deepstreamHub? compare us getting started feature roadmap faq
use cases pricing
developers
company
enterprise blog contact

Valve

This tutorial covers aspects of Valve – deepstreamHub’s realtime permission language. You can specify Valve rules in the permission section of the dashboard or upload them via the HTTP API.

Valve Permission Section on deepstreamHub dashboard

Oh dear...permissions! Permissions are always super-hard to explain. I've read tutorials using The Simpsons, The Fellowship of the Ring and even the Olsen Twins to explain concepts like "access groups" and "right-inheritance".

With deepstreamHub, things can be equally tricky at times - but for different reasons. deepstreamHub is a realtime data platform. And even its permissions can be - if you want them to be - shared with both clients and backend processes in realtime.

The good news is that deepstream makes realtime permissions extremely easy using a permission language called "Valve". This tutorial assumes that you already know your way around Valve. If you haven't come across it yet, make sure to read the Simple Valve and Advanced Valve tutorials first.

But hold on: Why would I want realtime permissions?

A lot of times you'll want the same set of permissions in two places:

-Within the platform to enforce the permission-rules within a trusted environment.

-On the client to provide instant validation and a defensive design that avoids user frustration by making forbidden options unavailable.

As permissions change - e.g. a user being kicked out of a chat-group or a trader no longer being allowed to buy a certain stock - you'd want those permissions not only to take effect immediatly, but also gently and gracefully remove the associated options from the client's UI - the exact moment they become unavailable.

The goal of this tutorial

This tutorial won't be using The Simpsons or any other metaphor. Instead, it will use colors (hurray!). Here's what we want to achieve:

there will be three users and one admin with individual credentials Screenshot login form

there is one global color record that can be set by any user to red, green or blue

each user gets three buttons, one for each color. When clicked, they set the global color. Screenshot user GUI

the admin user can decide which user is allowed to set the global color to which value Screenshot Admin User GUI

Any change to a user's permission needs to reflect on their GUI in realtime and needs to be enforcable by the server Animation interaction

Please note: You can find the code for this example on Github

Creating users

list of users for this tutorial For this tutorial we'll create four users via the deepstreamHub dashboard, using email authentication. Our users will be userA, userB and userC@example.com as well as admin@example.com.

Each user will be configured with two identical bits of serverData and clientData, namely

{
  "permissionRecord": "permissions/usera",
  "role": "user"
}

adding a user via the deepstreamHub dashboard Okay, let's quickly go through what we've done here

serverData is user-specific information that can be used within Valve rules to decide if a specific action is permitted. It is purely used within the platform and won't be exposed to the client.

clientData is user-specific data that will be sent to the client upon login. deepstreamHub will add an extra field id with the user-id to this. clientData is passed as the second argument to the .login() callback, e.g.

var ds = deepstream('wss://154.deepstreamhub.com?apiKey=xxx');
var loginData = {
  type: 'email',
  email: 'userA@example.com',
  password: 'usera-pass'
}

ds.login( loginData, function( success, data ){
  /* data will be
  {
    id: "1425f045-9b1d-4938-affc-5dbf60035c0e",
    permissionRecord: "permissions/usera",
    role: "user"
  }
  */
});

role can be either 'user' or 'admin'. Admins will be shown the admin GUI on the client and are allowed to set a user's permissions. Users can set the global color - if they are permissioned to set it to a particular value.

permissionRecord is the name of a record that will contain the actual permission information in the following format:

{
  red: true,
  blue: true,
  green: false
}

The permissions

Permission section on deepstreamHub dashboard

Valve rules can be edited in the permissions section of the deepstreamHub dashboard. The section on records will look as follows

record:
  "*":
    create: true
    write: true
    read: true
    delete: false

  "global-color":
    write: "_(user.data.permissionRecord)[data.color]"

  "permissions/*":
    write: "user.data.role === 'admin'"

Default permissions

Lets look at this file step by step: Our example won't use events, RPCs or presence, so we turn all these off. For records we generally allow everything, but turn off deletion as this features won't be used in our example.

Allowing users to set global color

Here we decide whether a user is allowed to set the global color to a specific value. user.data.permissionRecord is the name of the permission-record specified in our serverData section.

_() is the cross-reference-function used to load a record's data into our permission rule. data.color is the color value in the incoming data the user tries to write.

  "global-color":
    write: "_(user.data.permissionRecord)[data.color]"

Allowing only admins to set permissions

Next up we need to make sure that only admins can set a user's permission. Similar to before we check for every write to any of the permission records (permissions/usera etc.) if the role of the user attempting the write is admin.

  "permissions/*":
    write: "user.data.role === 'admin'"

To summarize

This mechanism is all we need to ensure the above permissions on both client and server. Everytime a user tries to write to the global-color record, her permissions are checked accordingly. Everytime an admin enables or disables a permission, the associated button on the user's GUI is turned on or off.