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.
can
example - Check read permission for field region
Simple 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.
can
example - Project parent node => partnership read ability
Specific resource 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.
dbFilter
TODO