To integrate the library into your project you will need to add the dependency to your build.gradle file, e.g:
implementation("uk.gov.justice.service.hmpps:hmpps-digital-prison-reporting-lib:1.0.0")
You will also need to use or extended the AuthAwareAuthenticationToken class in your Spring Security configuration as your Authentication implementation in order to pass the list of active caseload ids since this is used for row level security in the library. The JWT token is needed to retrieve the caseload user details and this can be done simply by calling the getActiveCaseloadIds method of the CaseloadProvider and passing the JWT as a parameter. An example can be found here. The AuthAwareAuthenticationToken can then be used in your controllers to retrieve the caseload ids should you need to implement row level security.
The API documentation is generated via the following dependency:
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0")
By using this for your Open API configuration you will be able to see the API docs on the swagger endpoint exposed by your application.
The following interfaces have default implementations that can be implemented in the client application and/or configured:
Interface | Purpose | Default implementation | Default configuration |
---|---|---|---|
AuthAwareTokenConverter | Convert a JWT token to an AuthAwareAuthenticationToken , and delegates to the CaseloadProvider . |
DefaultAuthAwareTokenConverter : Extracts roles and delegates caseload provision - uses the CaseloadProvider implementation in the context. |
N/A |
CaseloadProvider | Provides the caseloads the current user has access to. |
DefaultCaseloadProvider : Requests caseloads from the configured endpoint. |
Set dpr.lib.caseloads.host to the Nomis User API host. Optionally set dpr.lib.caseloads.path (defaults to me/caseloads ). |
LocalDateTypeAdaptor | Converts JSON date-times to the required format. |
IsoLocalDateTypeAdaptor : Converts to the format "yyyy-MM-dd". |
N/A |
ProductDefinitionRepository | Returns a list of product definitions to be used by the API. | See below. | |
N/A (Spring Security configuration) | Ensure only authorised users have access to the API, and delegates to the AuthAwareTokenConverter . |
ResourceServerConfiguration : Requires the user to have the specified role - uses the AuthAwareTokenConverter implementation in the context. |
Set dpr.lib.user.role to the required user role. If not set, this implementation is disabled. Additionally, spring.security.oauth2.resourceserver.jwt.jwk-set-uri should be set to the authentication server's JWKS file (e.g. ${hmpps.auth.url}/.well-known/jwks.json ). |
N/A (Spring DataSource configuration) | The DataSource to be used by the JdbcTemplate. | By default the library will use the Spring default DataSource requiring its configuration properties under spring.datasource
|
No default properties set. These will need to be set under spring.datasource for the default DataSource. If you wish to use your own DataSource you will need to create a DataSource Bean inside a @Configuration class with the name of the Datasource being the same as the datasource name defined in your data product definition. For example: @Bean("external-movements") fun createExternalMovementsDataSource(): DataSource {...} . You can name the DataSource properties as you prefer as this is your custom DataSource. |
N/A (URL_ENV_SUFFIX env variable to be used in make_url Formula Host Configuration) |
The environment to be used as your service host suffix when you make use of make_url formulas. |
There is no default value. You will need to set the value of the URL_ENV_SUFFIX env variable to be used as your service host suffix when you make use of make_url formulas. Example formula: make_url('https://prisoner-${env}.digital.prison.service.justice.gov.uk/prisoner/${prisonNumber}',${name},TRUE) The ${env} placeholder will be replaced by the value of your URL_ENV_SUFFIX env variable. If you do not set this the -${env} part will be removed from the interpolated formula. |
N/A |
N/A format_date(fieldName,dateFormat) Formula |
The format_date formula can be used to format a date to a LocalDate or LocalDateTime compatible format . | There is no default value. The first parameter is the name of the date column in this format: ${date} and the second parameter is a string with the date format. Examples for a given date time of 1st June 2023 12:00 : (1) format_date(${date},"dd/MM/yyyy") Results in: 01/06/2023 (2) format_date(${date},"dd/MM/yyyy hh:mm") Results in: 01/06/2023 12:00. | N/A |
There are three default implementations. You will need to configure which one your application will use. If more than one implementation is configured, they will take precedence in the order below (first having the highest priority):
Implementation | Caching Supported | Description | Properties to configure |
---|---|---|---|
JsonFileProductDefinitionRepository | No | Uses a list of JSON file sources for the product definitions. | In order to read from a list of definition files set dpr.lib.definition.locations to a comma separated list of the locations of the source files which can be created in the client application. |
ClientDataProductDefinitionsRepository | Yes | Uses a web client to call a service to retrieve the definition files based on a configured host and a directory passed as a query parameter in the request | In order to retrieve the data product definition files form another service with the use of a web client set dpr.lib.dataProductDefinitions.host to the host name of the application which will serve your definition files. The path to the definitions directory will need to be passed as a query parameter to your requests |
DynamoDbProductDefinitionRepository | Yes | Retrieves definitions from a DynamoDB table, either in the current account, or cross-account using the STS configuration. | Setting dpr.lib.aws.dynamodb.enabled to true enables the DynamoDB table source. Further configuration can be found in the AwsProperties.DynamoDB class. |
You can set dpr.lib.dataProductDefinitions.cache.enabled
to true
if you would like to cache the definitions in memory for a given duration which can be set with the dpr.lib.dataProductDefinitions.durationMinutes
property.
By default, caching is disabled.
The SQL query is constructed from the query defined in the data product definition, the result of the policy engine execution which is a WHERE clause,
filters received from the client added to another WHERE clause and finally pagination.
This mean Strings are concatenated to create the final query which effectively is SQL injection.
Since Common Table Expressions are used to delineate functionality in the query, SELECT is the only possible DML statement and there are no UPDATE, INSERT or DELETE operations.
The values of the filters coming from the client are sanitised in a prepared statements and the column names of the filters are validated against the schema field filter names of the report definition.
So there has been careful consideration regarding the sanitization of the query to the extent possible, however, there is limited control over what the actual query will be and this is dependent upon what is defined in the DPD.
Note: If you have hmpps/veracode_pipeline_scan
enabled in your CircleCI pipeline it will produce the below warning:
CWE-89: Improper Neutralization of Special Elements used in an SQL Command
This is is due to what has been mentioned above regarding the construction of the query and it is not an actual issue.
The documentation of the changes in each library version is contained in the changelog.