Skip to content

Commit 7e63ce2

Browse files
committed
[BTD-585] Audit service changes
1 parent a51e5f5 commit 7e63ce2

File tree

6 files changed

+90
-42
lines changed

6 files changed

+90
-42
lines changed

src/main/kotlin/uk/gov/justice/digital/hmpps/learnerrecordsapi/config/AuditEvent.kt

-20
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package uk.gov.justice.digital.hmpps.learnerrecordsapi.config
2+
3+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.MATCH_LE
4+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.MATCH_ULN
5+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.createAuditEvent
6+
import uk.gov.justice.hmpps.sqs.audit.HmppsAuditEvent
7+
import uk.gov.justice.hmpps.sqs.audit.HmppsAuditService
8+
import java.time.Instant
9+
import java.util.UUID
10+
11+
object AuditEvent {
12+
const val MATCH_ULN = "match-uln"
13+
const val MATCH_LE = "match-learner-events"
14+
15+
fun createAuditEvent(whatEvent: String, userName: String, requestParams: String): HmppsAuditEvent = HmppsAuditEvent(
16+
what = whatEvent,
17+
correlationId = UUID.randomUUID().toString(),
18+
`when` = Instant.now(),
19+
who = userName,
20+
service = "hmpps-learner-records-api",
21+
details = requestParams,
22+
)
23+
}
24+
25+
class AuditHelper(private val auditService: HmppsAuditService) {
26+
27+
private suspend fun publishAuditEvent(whatEvent: String, userName: String, requestParams: String) {
28+
val hmppsLRSEvent = createAuditEvent(
29+
whatEvent,
30+
userName,
31+
requestParams,
32+
)
33+
auditService.publishEvent(hmppsLRSEvent)
34+
}
35+
36+
suspend fun publishMatchAuditEvent(userName: String, nomisId: String) {
37+
publishAuditEvent(MATCH_ULN, userName, nomisId)
38+
}
39+
40+
suspend fun publishLearnerEventsAuditEvent(userName: String, nomisId: String) {
41+
publishAuditEvent(MATCH_LE, userName, nomisId)
42+
}
43+
}

src/main/kotlin/uk/gov/justice/digital/hmpps/learnerrecordsapi/resource/MatchResource.kt

+11-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody
1212
import org.springframework.web.bind.annotation.RequestHeader
1313
import org.springframework.web.bind.annotation.RequestMapping
1414
import org.springframework.web.bind.annotation.RestController
15-
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.createAuditEvent
15+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditHelper
1616
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_RO
1717
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_UI
1818
import uk.gov.justice.digital.hmpps.learnerrecordsapi.logging.LoggerUtil
@@ -27,6 +27,7 @@ import uk.gov.justice.digital.hmpps.learnerrecordsapi.openapi.MatchCheckApi
2727
import uk.gov.justice.digital.hmpps.learnerrecordsapi.openapi.MatchConfirmApi
2828
import uk.gov.justice.digital.hmpps.learnerrecordsapi.service.LearnerEventsService
2929
import uk.gov.justice.digital.hmpps.learnerrecordsapi.service.MatchService
30+
import uk.gov.justice.hmpps.kotlin.auth.HmppsAuthenticationHolder
3031
import uk.gov.justice.hmpps.sqs.audit.HmppsAuditService
3132
import java.net.URI
3233

@@ -35,20 +36,25 @@ import java.net.URI
3536
class MatchResource(
3637
private val matchService: MatchService,
3738
private val learnerEventsService: LearnerEventsService,
38-
private val auditService: HmppsAuditService,
39+
auditService: HmppsAuditService,
40+
private val authHolder: HmppsAuthenticationHolder,
3941
) {
4042

4143
val logger = LoggerUtil.getLogger<MatchResource>()
42-
val searchLearnerEventsByNomisId = "SEARCH_LEARNER_EVENTS_BY_NOMISID"
44+
private val auditHelper = AuditHelper(auditService)
4345

4446
@PreAuthorize("hasAnyRole('$ROLE_LEARNERS_UI', '$ROLE_LEARNERS_RO')")
4547
@GetMapping("/{nomisId}")
4648
@Tag(name = "Match")
4749
@MatchCheckApi
48-
fun findMatch(
50+
suspend fun findMatch(
4951
@PathVariable(name = "nomisId", required = true) nomisId: String,
5052
@RequestHeader("X-Username", required = true) userName: String,
5153
): ResponseEntity<CheckMatchResponse> {
54+
val roles = authHolder.roles.map { it?.authority ?: "" }
55+
if (roles.contains(ROLE_LEARNERS_RO)) {
56+
auditHelper.publishMatchAuditEvent(userName, nomisId)
57+
}
5258
logger.log("Received a get request to match endpoint", nomisId)
5359
return matchService.findMatch(nomisId)?.let {
5460
ResponseEntity.status(HttpStatus.OK).body(
@@ -83,7 +89,7 @@ class MatchResource(
8389
@PathVariable(name = "nomisId", required = true) nomisId: String,
8490
@RequestHeader("X-Username", required = true) userName: String,
8591
): ResponseEntity<LearnerEventsResponse> {
86-
auditService.publishEvent(createAuditEvent(searchLearnerEventsByNomisId, userName, nomisId))
92+
auditHelper.publishLearnerEventsAuditEvent(userName, nomisId)
8793
logger.log("Received a post request to learner events by Nomis ID endpoint", nomisId)
8894
val checkMatchResponse: CheckMatchResponse? = learnerEventsService.getMatchEntityForNomisId(nomisId)
8995
if (checkMatchResponse == null) {

src/test/kotlin/uk/gov/justice/digital/hmpps/learnerrecordsapi/config/AuditEventTest.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
44
import org.junit.jupiter.api.Assertions.assertEquals
55
import org.junit.jupiter.api.Assertions.assertTrue
66
import org.junit.jupiter.api.Test
7+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.createAuditEvent
78
import uk.gov.justice.digital.hmpps.learnerrecordsapi.models.request.Gender
89
import uk.gov.justice.digital.hmpps.learnerrecordsapi.models.request.LearnersRequest
910
import java.time.Instant
@@ -20,7 +21,7 @@ class AuditEventTest {
2021
lastKnownPostCode = "NE2 2AS",
2122
emailAddress = "test@example.com",
2223
)
23-
val hmppsAuditEvent = AuditEvent.createAuditEvent("searchLearnersByDemographics", "User", request.toString())
24+
val hmppsAuditEvent = createAuditEvent("searchLearnersByDemographics", "User", request.toString())
2425
assertEquals("hmpps-learner-records-api", hmppsAuditEvent.service)
2526
assertEquals("searchLearnersByDemographics", hmppsAuditEvent.what)
2627
assertEquals("User", hmppsAuditEvent.who)

src/test/kotlin/uk/gov/justice/digital/hmpps/learnerrecordsapi/integration/MatchResourceIntTest.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.springframework.http.MediaType
2020
import org.springframework.test.web.reactive.server.WebTestClient
2121
import software.amazon.awssdk.services.sqs.model.PurgeQueueRequest
2222
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest
23+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.AuditEvent.MATCH_LE
2324
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.HmppsBoldLrsExceptionHandler
2425
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_RO
2526
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_UI
@@ -266,7 +267,7 @@ class MatchResourceIntTest : IntegrationTestBase() {
266267
HmppsAuditEvent::class.java,
267268
)
268269

269-
assertThat(receivedEvent.what).isEqualTo("SEARCH_LEARNER_EVENTS_BY_NOMISID")
270+
assertThat(receivedEvent.what).isEqualTo(MATCH_LE)
270271
assertThat(receivedEvent.who).isEqualTo("TestUser")
271272
assertThat(receivedEvent.service).isEqualTo("hmpps-learner-records-api")
272273
assertThat(receivedEvent.`when`).isBeforeOrEqualTo(Instant.now())

src/test/kotlin/uk/gov/justice/digital/hmpps/learnerrecordsapi/resource/MatchResourceTest.kt

+32-15
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ import org.mockito.Mockito.mock
1010
import org.mockito.Mockito.`when`
1111
import org.mockito.junit.jupiter.MockitoExtension
1212
import org.mockito.kotlin.any
13+
import org.mockito.kotlin.times
14+
import org.mockito.kotlin.verify
1315
import org.springframework.http.HttpStatus
16+
import org.springframework.security.core.GrantedAuthority
17+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_RO
18+
import uk.gov.justice.digital.hmpps.learnerrecordsapi.config.Roles.ROLE_LEARNERS_UI
1419
import uk.gov.justice.digital.hmpps.learnerrecordsapi.models.lrsapi.response.exceptions.MatchNotFoundException
1520
import uk.gov.justice.digital.hmpps.learnerrecordsapi.models.response.CheckMatchResponse
1621
import uk.gov.justice.digital.hmpps.learnerrecordsapi.models.response.CheckMatchStatus
1722
import uk.gov.justice.digital.hmpps.learnerrecordsapi.service.LearnerEventsService
1823
import uk.gov.justice.digital.hmpps.learnerrecordsapi.service.MatchService
24+
import uk.gov.justice.hmpps.kotlin.auth.HmppsAuthenticationHolder
1925
import uk.gov.justice.hmpps.sqs.audit.HmppsAuditService
2026
import java.time.LocalDate
2127

@@ -33,50 +39,60 @@ class MatchResourceTest {
3339
private lateinit var learnerEventsResource: LearnerEventsResource
3440
private lateinit var mockAuditService: HmppsAuditService
3541
private lateinit var mockLearnerEventsService: LearnerEventsService
42+
private lateinit var mockAuthHolder: HmppsAuthenticationHolder
3643

3744
@BeforeEach
3845
fun setup() {
3946
mockMatchService = mock(MatchService::class.java)
4047
mockLearnerEventsService = mock(LearnerEventsService::class.java)
4148
mockAuditService = mock(HmppsAuditService::class.java)
42-
matchResource = MatchResource(mockMatchService, mockLearnerEventsService, mockAuditService)
49+
mockAuthHolder = mock(HmppsAuthenticationHolder::class.java)
50+
matchResource = MatchResource(mockMatchService, mockLearnerEventsService, mockAuditService, mockAuthHolder)
4351
learnerEventsResource = LearnerEventsResource(mockLearnerEventsService)
4452
}
4553

54+
private fun setRoleAndUln(role: String, uln: String?) {
55+
`when`(mockAuthHolder.roles).thenReturn(
56+
listOf(GrantedAuthority { role }),
57+
)
58+
`when`(mockMatchService.findMatch(any())).thenReturn(
59+
uln?.let {
60+
CheckMatchResponse(
61+
matchedUln = it,
62+
)
63+
},
64+
)
65+
}
66+
4667
@Test
47-
fun `should return NOT_FOUND if no record found`() {
48-
`when`(mockMatchService.findMatch(any())).thenReturn(null)
68+
fun `should return NOT_FOUND if no record found`() = runTest {
69+
setRoleAndUln(ROLE_LEARNERS_UI, null)
4970

5071
val actual = matchResource.findMatch(nomisId, "")
5172
assertThat(actual.statusCode).isEqualTo(HttpStatus.NOT_FOUND)
5273
assertThat(actual.body?.status ?: "").isEqualTo(CheckMatchStatus.NotFound)
74+
verify(mockAuditService, times(0)).publishEvent(any())
5375
}
5476

5577
@Test
56-
fun `should return entity if record found`() {
57-
`when`(mockMatchService.findMatch(any())).thenReturn(
58-
CheckMatchResponse(
59-
matchedUln = matchedUln,
60-
),
61-
)
78+
fun `should return entity if record found`() = runTest {
79+
setRoleAndUln(ROLE_LEARNERS_RO, matchedUln)
6280

6381
val actual = matchResource.findMatch(nomisId, "")
6482
assertThat(actual.statusCode).isEqualTo(HttpStatus.OK)
6583
assertThat(actual.body?.matchedUln ?: "").isEqualTo(matchedUln)
6684
assertThat(actual.body?.status ?: "").isEqualTo(CheckMatchStatus.Found)
85+
verify(mockAuditService, times(1)).publishEvent(any())
6786
}
6887

6988
@Test
70-
fun `should return NO_MATCH if id cannot be matched`() {
71-
`when`(mockMatchService.findMatch(any())).thenReturn(
72-
CheckMatchResponse(
73-
matchedUln = "",
74-
),
75-
)
89+
fun `should return NO_MATCH if id cannot be matched`() = runTest {
90+
setRoleAndUln(ROLE_LEARNERS_UI, "")
7691

7792
val actual = matchResource.findMatch(nomisId, "")
7893
assertThat(actual.statusCode).isEqualTo(HttpStatus.OK)
7994
assertThat(actual.body?.status ?: "").isEqualTo(CheckMatchStatus.NoMatch)
95+
verify(mockAuditService, times(0)).publishEvent(any())
8096
}
8197

8298
@Test
@@ -86,6 +102,7 @@ class MatchResourceTest {
86102
matchResource.findLearnerEventsByNomisId(nomisId, "")
87103
}
88104
assertThat(exception.message).isEqualTo(nomisId)
105+
verify(mockAuditService, times(1)).publishEvent(any())
89106
}
90107

91108
@Test

0 commit comments

Comments
 (0)