Privileges (privilege service) - SeedCompany/cord-docs GitHub Wiki

Intro

Recently we have changed from using the authorization service to the privilege service (Here is the PR for reference) for access controls of the data. In doing that, it brought about some new code patterns that will be laid out in this doc.

Setup

While we are doing away with the authorization service, the privileges still get imported from the authorization component. import { Privileges } from '../authorization';

As common practice with NestJS, you will need to list privileges as one of the services needed in the constructor of whatever service you are importing it into.

export class ExampleService {
  constructor(
    private readonly privileges: Privileges,
  ) {}

Usage

for

The general setup for privileges is going to require at least 2 of the following:

  • the user session
  • the shape of the resource you intend to get privileges for
  • (optional) the resource itself

These will be passed into the for() method meaning that we are getting privileges for a particular session and resource type.

this.privileges.for(session, ResourceType, Resource)

for example - Language Engagement

this.privileges.for(session, LanguageEngagement)

forUser

The forUser method optionally will scope the privileges down to a specific user session only.

forUser example

this.privileges.forUser(session)

forContext

TODO

The for, forUser, and forContext methods are the entry point for scoping the level of access. The following methods are used to determine the specific controls.

forEdge

If there is an edge node that uses the parent node's privileges, this gets used to get privilege information for that edge node. In the following example, you can see that we get the privileges for the Language Engagement and then grab the edge of product from it.

forEdge example - Language engagement => Product privileges

this.privileges.for(session, LanguageEngagement, engagement).forEdge('product');

can

The .can() method lets you see if the privileges for a node can read, edit, create or delete. It returns a boolean value.

Simple can example - Check read permission for field region

this.privileges.for(session, FieldRegion).can('read');

You also can use .can() with a specific resource type when determining the ability to create/read/edit. In the below example, the parent resource is the project and we are determining the ability to read on the project’s partnership nodes.

Specific resource can example - Project parent node => partnership read ability

const privs = this.privileges.for(session, IProject)

privs.can('read', 'partnership')

verifyCan

Like .can, this is used to determine read, create, edit or delete operations, however, it will throw an error the user can’t perform the operation.

verifyCan example - Can read a field region:

this.privileges.verifyCan(session, FieldRegion),verifyCan('read');

all

This is used to return all node privileges for the given reference. This can be used to grab properties for a given resource.

all example - Use all to get project readability

const privileges = this.privileges.for(session, User, user).all;

const canRead = privleges.project.read;

Note that this and the .can() method have a very similar return. It is preferred that we use .can unless there are multiple resources of the parent node you wish to check against in quick succession.

verifyChanges

When updating a resource, this can be used to verify that the correct access is available to be able to save the update. This will throw an error if the correct permissions aren’t available.

verifyChanges example - project changes example

const changes = {some: changes} 

this.privileges.for(session, Project, project).verifyChanges(changes)

// submit changes via repository here

secure

When dealing with secured resources, this unlocks the properties that are locked down.

secure example - product

When dealing with secured resources, this unlocks the properties that are locked down.

filterToReadable

This is used inside of the repository calls to make sure that only readable nodes are passed through. Note that this requires node & project to be defined where this cypher snippet is inserted.

Language Repository Example

dbFilter

TODO