-
Notifications
You must be signed in to change notification settings - Fork 0
Privileges (privilege service)
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.
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,
) {}
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)
this.privileges.for(session, LanguageEngagement)
The forUser
method optionally will scope the privileges down to a specific user session only.
this.privileges.forUser(session)
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.
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.
this.privileges.for(session, LanguageEngagement, engagement).forEdge('product');
The .can()
method lets you see if the privileges for a node can read, edit, create or delete. It returns a boolean value.
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.
const privs = this.privileges.for(session, IProject)
privs.can('read', 'partnership')
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.
this.privileges.verifyCan(session, FieldRegion),verifyCan('read');
This is used to return all node privileges for the given reference. This can be used to grab properties for a given resource.
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.
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.
const changes = {some: changes}
this.privileges.for(session, Project, project).verifyChanges(changes)
// submit changes via repository here
When dealing with secured resources, this unlocks the properties that are locked down.
When dealing with secured resources, this unlocks the properties that are locked down.
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.
TODO