A Node.js client library to centralise the process of determining user permissions for prison services and data.
We welcome feedback on this library and README here in order to improve it.
- Introduction
- What checks are made?
- Where does the data come from?
- How do I implement this library?
- For library developers
Determining whether a user has access to a particular resource (e.g. a service, or prisoner data) consists of a number of checks and is not necessarily just determined by what roles a user has been assigned.
This permissions library aims to share the logic centrally so that all services agree on what a user should and should not be able to access. It is used by the prisoner profile to determine if a user can access certain parts of the prisoner's profile for example.
The permissions use a variety of checks, based on:
- The user's DPS roles
- The user's case load list (and active case load)
- The prisoner's location (which prison they are at, or whether they are transferring or out of prison)
- The prisoner's restricted patient status
We do not yet have a centralised permissions service, so this library requires some input data to determine the user permissions.
We expect that the user's roles and case loads are already available at:
-
res.locals.user.userRoles
, -
res.locals.user.caseLoads
, -
res.locals.user.activeCaseLoad
, -
res.locals.user.activeCaseLoadId
,
User roles are already part of the Typescript Template project here and the retrieval of case load data is available in hmpps-connect-dps-components middleware.
The library will retrieve data about a prisoner
from hmpps-prisoner-search
and store it at req.middleware.prisonerData
if it is not already provided there.
npm install @ministryofjustice/hmpps-prison-permissions-lib
The permissions service should be created just like any other of your services. It requires the following:
-
prisonerSearchConfig
: Prisoner Search configuration conforming to thehmpps-typescript-lib
' sApiConfig
interface -
authenticationClient
: AnAuthenticationClient
instance ( see hmpps-typescript-lib) in order to make authorized client credentials calls to Prisoner Search. -
logger
: Bunyan logger for logging permissions events. Defaults to usingconsole
. -
telemetryClient
: Optional but recommended. Instead of just logging permissions events, this provides richer metadata to Application Insights.
e.g.
import { PermissionsService } from '@ministryofjustice/hmpps-prison-permissions-lib'
...
const prisonPermissionsService = PermissionsService.create({
prisonerSearchConfig: config.apis.prisonerSearchApi,
authenticationClient: new AuthenticationClient(config.apis.hmppsAuth, logger, tokenStore),
logger,
telemetryClient,
})
...in order to be able to successfully call Prisoner Search (see Swagger docs).
e.g.
import { PrisonerBasePermission, prisonerPermissionsGuard } from '@ministryofjustice/hmpps-prison-permissions-lib'
...
get(
`prisoner/{prisonerNumber}/somepage`,
...
prisonerPermissionsGuard(permissionsService, { requestDependentOn: [PrisonerBasePermission.read] }),
async (req, res, next) => {
...
If the user does not have the required permissions listed in requestDependentOn
, then the middleware will
throw a PrisonerPermissionError
with a status code of 403. The Typescript Template by default logs the user
out when encountering an error status of 403,
see here.
You can check if a particular permission is granted in your code simply by using the isGranted method, for example:
isGranted(PrisonerMoneyPermission.read, res.locals.prisonerPermissions)
You also can check permissions directly in nunjucks templates by:
- Configuring the nunjucks environment in your
nunjucksSetup.ts
file or equivalent:
// Enable permissions checking in templates:
setupNunjucksPermissions(njkEnv)
- Using the permissions check in the template, for example:
{% if isGranted(PrisonerMoneyPermission.read, res.locals.prisonerPermissions) %}
...
{% endif %}